int VerifySignedKernel(const char* image_file,
                       const char* firmware_key_file) {
  int error, error_code = 0;
  uint64_t len;
  uint8_t* kernel_blob = BufferFromFile(image_file, &len);
  uint8_t* firmware_key_blob = BufferFromFile(firmware_key_file, &len);

  if (!firmware_key_blob) {
    fprintf(stderr, "Couldn't read pre-processed public firmware key.\n");
    error_code = 1;
  }

  if (!error_code && !kernel_blob) {
    fprintf(stderr, "Couldn't read kernel image or malformed image.\n");
    error_code = 1;
  }

  if (!error_code && (error = VerifyKernel(firmware_key_blob, kernel_blob,
                                           0))) { /* Trusted Mode. */
    fprintf(stderr, "%s\n", VerifyKernelErrorString(error));
    error_code = 1;
  }
  Free(firmware_key_blob);
  Free(kernel_blob);
  if (error_code)
    return 0;
  return 1;
}
int Resource::Load(const char *filename)
{
#ifdef MULTI_EVAL
	mgtk_print("Resource::Load> '%s'\n", filename);
#endif

	strncpy(mFilename, filename, 95);
	mFilename[95] = 0;

	if (_buffer)
	{
		delete [] _buffer;
	}

	if (_symbol)
	{
		delete [] _symbol;
	}

	if (_symbol_len < 65)
	{
		_symbol_len = 65;
	}

	_symbol = new char[_symbol_len];

	if (!BufferFromFile(filename, &_buffer, &_buffer_len))
	{
		if (!Eval(_buffer))
		{
			return 0;
		}
	}

	return -1;
}
/* Tests that check for correctness of the VerifyFirmwareDriver_f() logic
 * and rollback prevention. */
void VerifyKernelDriverTest(void) {
  uint64_t len;
  uint8_t* firmware_key_pub = BufferFromFile(kFirmwareKeyPublicFile, &len);

  /* TODO(gauravsh): Rebase this to use LoadKernel() (maybe by making
   * it a part of load_kernel_test.c */
#if 0
  /* Initialize kernel blobs, including their associated parition
   * table attributed. */
  kernel_entry valid_kernelA =  {
    GenerateRollbackTestKernelBlob(1, 1, 0),
    15,  /* Highest Priority. */
    5,  /* Enough for tests. */
    0  /* Assume we haven't boot off it yet. */
  };
  kernel_entry corrupt_kernelA = {
    GenerateRollbackTestKernelBlob(1, 1, 1),
    15,  /* Highest Priority. */
    5,  /* Enough for tests. */
    0  /* Assume we haven't boot off it yet. */
  };
  kernel_entry valid_kernelB = {
    GenerateRollbackTestKernelBlob(1, 1, 0),
    1,  /* Lower Priority. */
    5,  /* Enough for tests. */
    0  /* Assume we haven't boot off it yet. */
  };
  kernel_entry corrupt_kernelB = {
    GenerateRollbackTestKernelBlob(1, 1, 1),
    1,  /* Lower Priority. */
    5,  /* Enough for tests. */
    0  /* Assume we haven't boot off it yet. */
  };

  /* Initialize rollback index state. */
  g_kernel_key_version = 1;
  g_kernel_version = 1;

  /* Note: This test just checks the rollback prevention mechanism and not
   * the full blown kernel boot logic. Updates to the kernel attributes
   * in the paritition table are not tested.
   */
  VBDEBUG(("Kernel A boot priority(15) > Kernel B boot priority(1)\n"));
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &valid_kernelA, &valid_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_A_CONTINUE,
          "(Valid Kernel A (current version)\n"
          " Valid Kernel B (current version) runs A):");
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &corrupt_kernelA, &valid_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_B_CONTINUE,
          "(Corrupt Kernel A (current version)\n"
          " Valid Kernel B (current version) runs B):");
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &valid_kernelA, &corrupt_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_A_CONTINUE,
          "(Valid Kernel A (current version)\n"
          " Corrupt Kernel B (current version) runs A):");
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &corrupt_kernelA, &corrupt_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_RECOVERY_CONTINUE,
          "(Corrupt Kernel A (current version)\n"
          " Corrupt Kernel B (current version) runs Recovery):");

  VBDEBUG(("\nSwapping boot priorities...\n"
           "Kernel B boot priority(15) > Kernel A boot priority(1)\n"));
  valid_kernelA.boot_priority = corrupt_kernelA.boot_priority = 1;
  valid_kernelB.boot_priority = corrupt_kernelB.boot_priority = 15;
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &valid_kernelA, &valid_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_B_CONTINUE,
          "(Valid Kernel A (current version)\n"
          " Valid Kernel B (current version) runs B):");
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &corrupt_kernelA, &valid_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_B_CONTINUE,
          "(Corrupt Kernel A (current version)\n"
          " Valid Kernel B (current version) runs B):");
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &valid_kernelA, &corrupt_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_A_CONTINUE,
          "(Valid Kernel A (current version)\n"
          " Corrupt Kernel B (current version) runs A):");
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &corrupt_kernelA, &corrupt_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_RECOVERY_CONTINUE,
          "(Corrupt Kernel A (current version)\n"
          " Corrupt Kernel B (current version) runs Recovery):");

  VBDEBUG(("\nUpdating stored version information. Obsoleting "
           "exiting kernel images.\n"));
  g_kernel_key_version = 2;
  g_kernel_version = 2;
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &valid_kernelA, &valid_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_RECOVERY_CONTINUE,
          "(Valid Kernel A (old version)\n"
          " Valid Kernel B (old version) runs Recovery):");

  VBDEBUG(("\nGenerating updated Kernel A blob with "
           "new version.\n"));
  Free(valid_kernelA.kernel_blob);
  valid_kernelA.kernel_blob = GenerateRollbackTestKernelBlob(3, 3, 0);
  TEST_EQ(VerifyKernelDriver_f(firmware_key_pub,
                               &valid_kernelA, &valid_kernelB,
                               DEV_MODE_DISABLED),
          BOOT_KERNEL_A_CONTINUE,
          "(Valid Kernel A (new version)\n"
          " Valid Kernel B (old version) runs A):");
  Free(valid_kernelA.kernel_blob);
  Free(valid_kernelB.kernel_blob);
  Free(corrupt_kernelA.kernel_blob);
  Free(corrupt_kernelB.kernel_blob);
#endif

  Free(firmware_key_pub);
}
int SpeedTestAlgorithm(int algorithm) {
  int i, key_size;
  int error_code = 0;
  double speed, msecs;
  char file_name[FILE_NAME_SIZE];
  uint8_t* digest = NULL;
  uint8_t* signature = NULL;
  uint64_t digest_len, sig_len;
  RSAPublicKey* key = NULL;
  ClockTimerState ct;
  char* sha_strings[] = {  /* Maps algorithm->SHA algorithm. */
    "sha1", "sha256", "sha512",  /* RSA-1024 */
    "sha1", "sha256", "sha512",  /* RSA-2048 */
    "sha1", "sha256", "sha512",  /* RSA-4096 */
    "sha1", "sha256", "sha512",  /* RSA-8192 */
  };

  key_size = siglen_map[algorithm] * 8;  /* in bits. */
  /* Get key. */
  snprintf(file_name, FILE_NAME_SIZE, "testkeys/key_rsa%d.keyb", key_size);
  key = RSAPublicKeyFromFile(file_name);
  if (!key) {
    VBDEBUG(("Couldn't read RSA Public key from file: %s\n", file_name));
    error_code = 1;
    goto failure;
  }

  /* Get expected digest. */
  snprintf(file_name, FILE_NAME_SIZE, "testcases/test_file.%s.digest",
           sha_strings[algorithm]);
  digest = BufferFromFile(file_name, &digest_len);
  if (!digest) {
    VBDEBUG(("Couldn't read digest file.\n"));
    error_code = 1;
    goto failure;
  }

  /* Get signature to verify against. */
  snprintf(file_name, FILE_NAME_SIZE, "testcases/test_file.rsa%d_%s.sig",
           key_size, sha_strings[algorithm]);
  signature = BufferFromFile(file_name, &sig_len);
  if (!signature) {
    VBDEBUG(("Couldn't read signature file.\n"));
    error_code = 1;
    goto failure;
  }

  StartTimer(&ct);
  for (i = 0; i < NUM_OPERATIONS; i++) {
    if (!RSAVerify(key, signature, sig_len, algorithm, digest))
      VBDEBUG(("Warning: Signature Check Failed.\n"));
  }
  StopTimer(&ct);

  msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;
  speed = 1000.0 / msecs ;
  fprintf(stderr, "# rsa%d/%s:\tTime taken per verification = %.02f ms,"
          " Speed = %.02f verifications/s\n", key_size, sha_strings[algorithm],
          msecs, speed);
  fprintf(stdout, "ms_rsa%d_%s:%.02f\n", key_size, sha_strings[algorithm],
          msecs);

failure:
  free(signature);
  free(digest);
  RSAPublicKeyFree(key);
  return error_code;
}