예제 #1
0
/* Test StatefulSkip */
static void StatefulSkipTest(void) {
  MemcpyState s;
  char buf[128];

  /* Small skip */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(&s, StatefulSkip(&s, 5), "StatefulSkip(5) retval");
  TEST_EQ(128 - 5, s.remaining_len, "StatefulSkip(5) len");
  TEST_PTR_EQ(buf + 5, s.remaining_buf, "StatefulSkip(5) buf");
  TEST_EQ(0, s.overrun, "StatefulSkip(5) overrun");

  /* Use entire buffer */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(&s, StatefulSkip(&s, 128), "StatefulSkip(all) retval");
  TEST_EQ(0, s.remaining_len, "StatefulSkip(all) len");
  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulSkip(all) buf");
  TEST_EQ(0, s.overrun, "StatefulSkip(all) overrun");

  /* Zero-length skip is ok (but meaningless) */
  TEST_PTR_EQ(&s, StatefulSkip(&s, 0), "StatefulSkip(0) retval");
  TEST_EQ(0, s.remaining_len, "StatefulSkip(0) len");
  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulSkip(0) buf");
  TEST_EQ(0, s.overrun, "StatefulSkip(0) overrun");

  /* Can't use even one byte past that */
  TEST_PTR_EQ(NULL, StatefulSkip(&s, 1), "StatefulSkip(+1) retval");
  TEST_EQ(0, s.remaining_len, "StatefulSkip(+1) len");
  TEST_EQ(1, s.overrun, "StatefulSkip(+1) overrun");

  /* Overrun */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(NULL, StatefulSkip(&s, 256), "StatefulSkip(256) retval");
  TEST_EQ(1, s.overrun, "StatefulSkip(256) overrun");
  /* Once overrun, always overrun, even if we now ask for a small skip */
  TEST_PTR_EQ(NULL, StatefulSkip(&s, 1), "StatefulSkip(256+1) retval");
  TEST_EQ(1, s.overrun, "StatefulSkip(256+1) overrun");

  /* Overrun with potential wraparound */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(NULL, StatefulSkip(&s, -1), "StatefulSkip(-1) retval");
  TEST_EQ(1, s.overrun, "StatefulSkip(-1) overrun");
}
예제 #2
0
static void VbRegionReadTest(void) {
	/* Should read GBB */
	ResetMocks();
	TEST_TRUE(1, "Normal call");
	TEST_EQ(VbSelectFirmware(&cparams, &fparams), VBERROR_SUCCESS,
		"  Success");
	TEST_EQ(mock_seen_region, 1 << VB_REGION_GBB, "  GBB region");
	TEST_PTR_EQ(cparams.gbb, NULL, "  GBB free");

	ResetMocks();
	TEST_EQ(VbSelectAndLoadKernel(&cparams, &kparams),
		VBERROR_NO_DISK_FOUND, "Kernel");
	TEST_PTR_EQ(cparams.gbb, NULL, "  GBB free");
	TEST_PTR_EQ(cparams.bmp, NULL, "  BMP free");

	ResetMocks();
	shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
	TEST_EQ(VbSelectAndLoadKernel(&cparams, &kparams),
		VBERROR_NO_DISK_FOUND, "Kernel");
}
예제 #3
0
/* Test StatefulInit */
static void StatefulInitTest(void) {
  MemcpyState s;
  char buf[128];

  memset(&s, 0, sizeof(s));
  s.overrun = 1;
  StatefulInit(&s, buf, 128);
  TEST_EQ(0, s.overrun, "StatefulInit() overrun");
  TEST_EQ(128, s.remaining_len, "StatefulInit() len");
  TEST_PTR_EQ(buf, s.remaining_buf, "StatefulInit() buf");
}
static void VbTryLoadKernelTest(void)
{
	int i;
	int num_tests =  sizeof(test) / sizeof(test[0]);

	for (i = 0; i < num_tests; i++) {
		printf("Test case: %s ...\n", test[i].name);
		ResetMocks(i);
		TEST_EQ(VbTryLoadKernel(0, &lkparams, test[i].want_flags),
			t->expected_return_val, "  return value");
		TEST_EQ(got_recovery_request_val,
			t->expected_recovery_request_val, "  recovery_request");
		if (t->expected_to_find_disk != DONT_CARE) {
			TEST_PTR_EQ(got_find_disk, t->expected_to_find_disk,
				    "  find disk");
			TEST_PTR_EQ(got_load_disk, t->expected_to_load_disk,
				    "  load disk");
		}
		TEST_EQ(got_external_mismatch, 0, "  external GPT errors");
	}
}
예제 #5
0
파일: tlcl_tests.c 프로젝트: latelee/vboot
/**
 * Test assorted tlcl functions
 */
static void TlclTest(void)
{
	uint8_t buf[32], buf2[32];

	ResetMocks();
	TEST_EQ(TlclLibInit(), VBERROR_SUCCESS, "Init");

	ResetMocks();
	mock_retval = VBERROR_SIMULATED;
	TEST_EQ(TlclLibInit(), mock_retval, "Init bad");

	ResetMocks();
	TEST_EQ(TlclLibClose(), VBERROR_SUCCESS, "Close");

	ResetMocks();
	mock_retval = VBERROR_SIMULATED;
	TEST_EQ(TlclLibClose(), mock_retval, "Close bad");

	ResetMocks();
	ToTpmUint32(buf + 2, 123);
	TEST_EQ(TlclPacketSize(buf), 123, "TlclPacketSize");

	ResetMocks();
	ToTpmUint32(buf + 2, 10);
	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), 0, "SendReceive");
	TEST_PTR_EQ(calls[0].req, buf, "SendReceive req ptr");
	TEST_EQ(calls[0].req_size, 10, "SendReceive size");

	ResetMocks();
	calls[0].retval = VBERROR_SIMULATED;
	ToTpmUint32(buf + 2, 10);
	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), VBERROR_SIMULATED,
		"SendReceive fail");

	ResetMocks();
	SetResponse(0, 123, 10);
	ToTpmUint32(buf + 2, 10);
	TEST_EQ(TlclSendReceive(buf, buf2, sizeof(buf2)), 123,
		"SendReceive error response");

	// TODO: continue self test (if needed or doing)
	// TODO: then retry doing self test

}
static void keyblock_tests(const char *keys_dir)
{
	struct vb2_public_key *pubk2048, *pubk4096, *pubk8192, pubkhash;
	struct vb2_private_key *prik4096, *prik8192;
	struct vb2_packed_key *pak, *pakgood;
	struct vb2_keyblock *kb;
	const struct vb2_private_key *prikhash;
	const struct vb2_private_key *prik[2];
	char fname[1024];
	const char test_desc[] = "Test keyblock";

	uint8_t workbuf[VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES]
		 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
	struct vb2_workbuf wb;

	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));

	/* Read keys */
	sprintf(fname, "%s/key_rsa2048.keyb", keys_dir);
	TEST_SUCC(vb2_public_key_read_keyb(&pubk2048, fname),
					   "Read public key 2");
	vb2_public_key_set_desc(pubk2048, "Test RSA2048 public key");
	pubk2048->hash_alg = VB2_HASH_SHA256;

	sprintf(fname, "%s/key_rsa4096.keyb", keys_dir);
	TEST_SUCC(vb2_public_key_read_keyb(&pubk4096, fname),
					   "Read public key 1");
	vb2_public_key_set_desc(pubk4096, "Test RSA4096 public key");
	pubk4096->hash_alg = VB2_HASH_SHA256;

	sprintf(fname, "%s/key_rsa8192.keyb", keys_dir);
	TEST_SUCC(vb2_public_key_read_keyb(&pubk8192, fname),
					   "Read public key 2");
	vb2_public_key_set_desc(pubk8192, "Test RSA8192 public key");
	pubk8192->hash_alg = VB2_HASH_SHA512;

	sprintf(fname, "%s/key_rsa4096.pem", keys_dir);
	TEST_SUCC(vb2_private_key_read_pem(&prik4096, fname),
		  "Read private key 2");
	vb2_private_key_set_desc(prik4096, "Test RSA4096 private key");
	prik4096->sig_alg = VB2_SIG_RSA4096;
	prik4096->hash_alg = VB2_HASH_SHA256;

	sprintf(fname, "%s/key_rsa8192.pem", keys_dir);
	TEST_SUCC(vb2_private_key_read_pem(&prik8192, fname),
		  "Read private key 1");
	vb2_private_key_set_desc(prik8192, "Test RSA8192 private key");
	prik8192->sig_alg = VB2_SIG_RSA8192;
	prik8192->hash_alg = VB2_HASH_SHA512;

	TEST_SUCC(vb2_private_key_hash(&prikhash, VB2_HASH_SHA512),
		  "Create private hash key");

	TEST_SUCC(vb2_public_key_hash(&pubkhash, VB2_HASH_SHA512),
		  "Create public hash key");

	TEST_SUCC(vb2_public_key_pack(&pakgood, pubk2048), "Test packed key");

	/* Sign a keyblock with one key */
	prik[0] = prik4096;
	TEST_SUCC(vb2_keyblock_create(&kb, pubk2048, prik, 1, 0x1234, NULL),
		  "Keyblock single");
	TEST_PTR_NEQ(kb, NULL, "  kb_ptr");
	TEST_SUCC(vb2_verify_keyblock(kb, kb->c.total_size, pubk4096, &wb),
		  "  verify");
	TEST_EQ(strcmp(vb2_common_desc(kb), pubk2048->desc), 0,	"  desc");
	TEST_EQ(kb->flags, 0x1234, "  flags");

	pak = (struct vb2_packed_key *)((uint8_t *)kb + kb->key_offset);
	TEST_EQ(0, memcmp(pak, pakgood, pakgood->c.total_size), "  data key");
	free(kb);

	/* Sign a keyblock with two keys */
	prik[0] = prik8192;
	prik[1] = prikhash;
	TEST_SUCC(vb2_keyblock_create(&kb, pubk4096, prik, 2, 0, test_desc),
		  "Keyblock multiple");
	TEST_SUCC(vb2_verify_keyblock(kb, kb->c.total_size, pubk8192, &wb),
		  "  verify 1");
	TEST_SUCC(vb2_verify_keyblock(kb, kb->c.total_size, &pubkhash, &wb),
		  "  verify 2");
	TEST_EQ(strcmp(vb2_common_desc(kb), test_desc), 0,	"  desc");
	TEST_EQ(kb->flags, 0, "  flags");
	free(kb);

	/* Test errors */
	prik[0] = prik8192;
	prik8192->hash_alg = VB2_HASH_INVALID;
	TEST_EQ(vb2_keyblock_create(&kb, pubk4096, prik, 1, 0, NULL),
		VB2_KEYBLOCK_CREATE_SIG_SIZE, "Keyblock bad sig size");
	TEST_PTR_EQ(kb, NULL, "  kb_ptr");

	prik[0] = prik4096;
	pubk4096->sig_alg = VB2_SIG_INVALID;
	TEST_EQ(vb2_keyblock_create(&kb, pubk4096, prik, 1, 0, NULL),
		VB2_KEYBLOCK_CREATE_DATA_KEY, "Keyblock bad data key");

	/* Free keys */
	free(pakgood);
	vb2_public_key_free(pubk2048);
	vb2_public_key_free(pubk4096);
	vb2_public_key_free(pubk8192);
	vb2_private_key_free(prik4096);
	vb2_private_key_free(prik8192);
}
예제 #7
0
/* Test StatefulMemset_r */
static void StatefulMemset_rTest(void) {
  MemcpyState s;
  char buf[129];
  char want[129];

  memset(want, 0, sizeof(want));
  memset(buf, 0, sizeof(buf));

  /* Small sets */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'A', 5), "StatefulMemset_r(5) retval");
  TEST_EQ(128 - 5, s.remaining_len, "StatefulMemset_r(5) len");
  TEST_PTR_EQ(buf + 5, s.remaining_buf, "StatefulMemset_r(5) buf");
  /* Using strcmp() is a convenient way to check that we didn't
   * overwrite the 0-byte following what we expected to set. */
  TEST_EQ(0, strcmp("AAAAA", buf), "StatefulMemset_r(5) contents");
  TEST_EQ(0, s.overrun, "StatefulMemset_r(5) overrun");
  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'B', 3), "StatefulMemset_r(3) retval");
  TEST_EQ(0, strcmp("AAAAABBB", buf), "StatefulMemset_r(3) contents");

  /* Use entire buffer */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'C', 128),
              "StatefulMemset_r(all) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemset_r(all) len");
  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulMemset_r(all) buf");
  TEST_EQ(0, s.overrun, "StatefulMemset_r(all) overrun");
  memset(want, 'C', 128);
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(all) contents");

  /* Zero-length set is ok (but meaningless) */
  TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'D', 0), "StatefulMemset_r(0) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemset_r(0) len");
  TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulMemset_r(0) buf");
  TEST_EQ(0, s.overrun, "StatefulMemset_r(0) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(0) contents");

  /* Can't use even one byte past that */
  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'E', 1),
              "StatefulMemset_r(+1) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemset_r(+1) len");
  TEST_EQ(1, s.overrun, "StatefulMemset_r(+1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");

  /* Overrun */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'F', 256),
              "StatefulMemset_r(256) retval");
  TEST_EQ(1, s.overrun, "StatefulMemset_r(256) overrun");
  /* Once overrun, always overrun, even if we now ask for a small skip */
  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'G', 1),
              "StatefulMemset_r(256+1) retval");
  TEST_EQ(1, s.overrun, "StatefulMemset_r(256+1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");

  /* Overrun with potential wraparound */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'H', -1),
              "StatefulMemset_r(-1) retval");
  TEST_EQ(1, s.overrun, "StatefulMemset_r(-1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
}
예제 #8
0
/* Test StatefulMemcpy */
static void StatefulMemcpyTest(void) {
  MemcpyState s;
  char buf[129];
  char want[129];
  char* src1 = "ThisIsATest";
  char* src2 = "ThisIsOnlyATest";

  memset(want, 0, sizeof(want));
  memset(buf, 0, sizeof(buf));

  /* Small copies */
  StatefulInit(&s, src1, 12);
  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 6), "StatefulMemcpy(6) retval");
  TEST_EQ(6, s.remaining_len, "StatefulMemcpy(6) len");
  TEST_PTR_EQ(src1 + 6, s.remaining_buf, "StatefulMemcpy(6) buf");
  /* Using strcmp() is a convenient way to check that we didn't
   * overwrite the 0-byte following what we expected to copy. */
  TEST_EQ(0, strcmp("ThisIs", buf), "StatefulMemcpy(6) contents");
  TEST_EQ(0, s.overrun, "StatefulMemcpy(6) overrun");
  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 5), "StatefulMemcpy(5) retval");
  /* Note that we shouldn't have copied the last byte out of the
   * stateful buffer, so we don't overwrite the last character of the
   * string that was in buf. */
  TEST_EQ(0, strcmp("ATests", buf), "StatefulMemcpy(5) contents");

  /* Use entire buffer */
  memset(buf, 1, sizeof(buf));
  StatefulInit(&s, src2, 16);
  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 16), "StatefulMemcpy(all) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemcpy(all) len");
  TEST_PTR_EQ(src2 + 16, s.remaining_buf, "StatefulMemcpy(all) buf");
  TEST_EQ(0, s.overrun, "StatefulMemcpy(all) overrun");
  TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(all) contents");

  /* Zero-length copy is ok (but meaningless) */
  TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 0),
              "StatefulMemcpy(0) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemcpy(0) len");
  TEST_PTR_EQ(src2 + 16, s.remaining_buf, "StatefulMemcpy(0) buf");
  TEST_EQ(0, s.overrun, "StatefulMemcpy(0) overrun");
  TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(0) contents");

  /* Can't use even one byte past that */
  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 1),
              "StatefulMemcpy(+1) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemcpy(+1) len");
  TEST_EQ(1, s.overrun, "StatefulMemcpy(+1) overrun");
  TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(+1) contents");

  /* Overrun */
  memset(buf, 0, sizeof(buf));
  StatefulInit(&s, "Small", 5);
  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 9), "StatefulMemcpy(9) retval");
  TEST_EQ(1, s.overrun, "StatefulMemcpy(9) overrun");
  /* Once overrun, always overrun, even if we now ask for a small skip */
  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 4),
              "StatefulMemcpy(9+1) retval");
  TEST_EQ(1, s.overrun, "StatefulMemcpy(9+1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy(+1) contents");

  /* Overrun with potential wraparound */
  StatefulInit(&s, "Larger", 6);
  TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, -1), "StatefulMemcpy(-1) retval");
  TEST_EQ(1, s.overrun, "StatefulMemcpy(-1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy(+1) contents");
}
예제 #9
0
/* Test StatefulMemcpy_r */
static void StatefulMemcpy_rTest(void) {
  MemcpyState s;
  char buf[129];
  char want[129];
  char* src1 = "Doogie";
  char* src2 = "Howserrr";
  char* src3 = "WholeBuffr";

  memset(want, 0, sizeof(want));
  memset(buf, 0, sizeof(buf));

  /* Small copies */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(src1, StatefulMemcpy_r(&s, src1, 6),
              "StatefulMemcpy_r(6) retval");
  TEST_EQ(128 - 6, s.remaining_len, "StatefulMemcpy_r(6) len");
  TEST_PTR_EQ(buf + 6, s.remaining_buf, "StatefulMemcpy_r(6) buf");
  /* Using strcmp() is a convenient way to check that we didn't
   * overwrite the 0-byte following what we expected to copy. */
  TEST_EQ(0, strcmp("Doogie", buf), "StatefulMemcpy_r(6) contents");
  TEST_EQ(0, s.overrun, "StatefulMemcpy_r(6) overrun");
  TEST_PTR_EQ(src2, StatefulMemcpy_r(&s, src2, 8),
              "StatefulMemcpy_r(8) retval");
  TEST_EQ(0, strcmp("DoogieHowserrr", buf), "StatefulMemcpy_r(8) contents");

  /* Use entire buffer */
  memset(buf, 42, sizeof(buf));
  StatefulInit(&s, buf, 10);
  TEST_PTR_EQ(src3, StatefulMemcpy_r(&s, src3, 10),
              "StatefulMemcpy_r(all) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(all) len");
  TEST_PTR_EQ(buf + 10, s.remaining_buf, "StatefulMemcpy_r(all) buf");
  TEST_EQ(0, s.overrun, "StatefulMemcpy_r(all) overrun");
  TEST_EQ(0, memcmp(src3, buf, 10), "StatefulMemcpy_r(all) contents");
  TEST_EQ(42, buf[10], "StatefulMemcpy_r(all) contents+1");

  /* Zero-length copy is ok (but meaningless) */
  TEST_PTR_EQ(src1, StatefulMemcpy_r(&s, src1, 0),
              "StatefulMemcpy_r(0) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(0) len");
  TEST_PTR_EQ(buf + 10, s.remaining_buf, "StatefulMemcpy_r(0) buf");
  TEST_EQ(0, s.overrun, "StatefulMemcpy_r(0) overrun");
  TEST_EQ(42, buf[10], "StatefulMemcpy_r(0) contents+1");

  /* Can't use even one byte past that */
  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, src1, 1),
              "StatefulMemcpy_r(+1) retval");
  TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(+1) len");
  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(+1) overrun");
  TEST_EQ(42, buf[10], "StatefulMemcpy_r(+1) contents");

  /* Overrun */
  memset(buf, 0, sizeof(buf));
  StatefulInit(&s, buf, 8);
  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "MoreThan8", 9),
              "StatefulMemcpy_r(9) retval");
  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(9) overrun");
  /* Once overrun, always overrun, even if we now ask for a small skip */
  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "Less", 4),
              "StatefulMemcpy_r(9+1) retval");
  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(9+1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy_r(+1) contents");

  /* Overrun with potential wraparound */
  StatefulInit(&s, buf, 128);
  TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "FOO", -1),
              "StatefulMemcpy_r(-1) retval");
  TEST_EQ(1, s.overrun, "StatefulMemcpy_r(-1) overrun");
  TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy_r(+1) contents");
}
예제 #10
0
static void init_context_tests(void)
{
	/* Use our own context struct so we can re-init it */
	struct vb2_context c = {
		.workbuf = workbuf,
		.workbuf_size = sizeof(workbuf),
	};

	reset_common_data();

	TEST_SUCC(vb2_init_context(&c), "Init context good");
	TEST_EQ(c.workbuf_used, sizeof(struct vb2_shared_data),
		"Init vbsd");

	/* Don't re-init if used is non-zero */
	c.workbuf_used = 200;
	TEST_SUCC(vb2_init_context(&c), "Re-init context good");
	TEST_EQ(c.workbuf_used, 200, "Didn't re-init");

	/* Handle workbuf errors */
	c.workbuf_used = 0;
	c.workbuf_size = sizeof(struct vb2_shared_data) - 1;
	TEST_EQ(vb2_init_context(&c),
		VB2_ERROR_INITCTX_WORKBUF_SMALL, "Init too small");
	c.workbuf_size = sizeof(workbuf);

	/* Handle workbuf unaligned */
	c.workbuf++;
	TEST_EQ(vb2_init_context(&c),
		VB2_ERROR_INITCTX_WORKBUF_ALIGN, "Init unaligned");
}

static void misc_tests(void)
{
	struct vb2_workbuf wb;

	reset_common_data();
	cc.workbuf_used = 16;

	vb2_workbuf_from_ctx(&cc, &wb);

	TEST_PTR_EQ(wb.buf, workbuf + 16, "vb_workbuf_from_ctx() buf");
	TEST_EQ(wb.size, cc.workbuf_size - 16, "vb_workbuf_from_ctx() size");
}

static void gbb_tests(void)
{
	struct vb2_gbb_header gbb = {
		.signature = {'$', 'G', 'B', 'B'},
		.major_version = VB2_GBB_MAJOR_VER,
		.minor_version = VB2_GBB_MINOR_VER,
		.header_size = sizeof(struct vb2_gbb_header),
		.flags = 0x1234,
		.rootkey_offset = 240,
		.rootkey_size = 1040,
	};

	struct vb2_gbb_header gbbdest;

	TEST_EQ(sizeof(struct vb2_gbb_header),
		EXPECTED_VB2_GBB_HEADER_SIZE,
		"sizeof(struct vb2_gbb_header)");

	reset_common_data();

	/* Good contents */
	mock_resource_index = VB2_RES_GBB;
	mock_resource_ptr = &gbb;
	mock_resource_size = sizeof(gbb);
	TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest), "read gbb header good");
	TEST_SUCC(memcmp(&gbb, &gbbdest, sizeof(gbb)), "read gbb contents");

	mock_resource_index = VB2_RES_GBB + 1;
	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
		VB2_ERROR_EX_READ_RESOURCE_INDEX, "read gbb header missing");
	mock_resource_index = VB2_RES_GBB;

	gbb.signature[0]++;
	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
		VB2_ERROR_GBB_MAGIC, "read gbb header bad magic");
	gbb.signature[0]--;

	gbb.major_version = VB2_GBB_MAJOR_VER + 1;
	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
		VB2_ERROR_GBB_VERSION, "read gbb header major version");
	gbb.major_version = VB2_GBB_MAJOR_VER;

	gbb.minor_version = VB2_GBB_MINOR_VER + 1;
	TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest),
		  "read gbb header minor++");
	gbb.minor_version = 1;
	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
		VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.1 fails");
	gbb.minor_version = 0;
	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
		VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.0 fails");
	gbb.minor_version = VB2_GBB_MINOR_VER;

	gbb.header_size--;
	TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
		VB2_ERROR_GBB_HEADER_SIZE, "read gbb header size");
	TEST_EQ(vb2_fw_parse_gbb(&cc),
		VB2_ERROR_GBB_HEADER_SIZE, "parse gbb failure");
	gbb.header_size++;

	/* Parse GBB */
	TEST_SUCC(vb2_fw_parse_gbb(&cc), "parse gbb");
	TEST_EQ(sd->gbb_flags, gbb.flags, "gbb flags");
	TEST_EQ(sd->gbb_rootkey_offset, gbb.rootkey_offset, "rootkey offset");
	TEST_EQ(sd->gbb_rootkey_size, gbb.rootkey_size, "rootkey size");

	/* Workbuf failure */
	reset_common_data();
	cc.workbuf_used = cc.workbuf_size - 4;
	TEST_EQ(vb2_fw_parse_gbb(&cc),
		VB2_ERROR_GBB_WORKBUF, "parse gbb no workbuf");
}

static void fail_tests(void)
{
	/* Early fail (before even NV init) */
	reset_common_data();
	sd->status &= ~VB2_SD_STATUS_NV_INIT;
	vb2_fail(&cc, 1, 2);
	TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT, 0, "vb2_fail inits NV");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
		1, "vb2_fail request");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
		2, "vb2_fail subcode");

	/* Repeated fail doesn't overwrite the error code */
	vb2_fail(&cc, 3, 4);
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
		1, "vb2_fail repeat");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
		2, "vb2_fail repeat2");

	/* Fail with other slot good doesn't trigger recovery */
	reset_common_data();
	vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
	vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
	sd->fw_slot = 0;
	sd->last_fw_slot = 1;
	sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
	vb2_fail(&cc, 5, 6);
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "vb2_failover");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
		VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 0, "vb2_fail use up tries");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "vb2_fail try other slot");

	/* Fail with other slot already failing triggers recovery */
	reset_common_data();
	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
	sd->fw_slot = 1;
	sd->last_fw_slot = 0;
	sd->last_fw_result = VB2_FW_RESULT_FAILURE;
	vb2_fail(&cc, 7, 8);
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 7,
		"vb2_fail both slots bad");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
		VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
	TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 0, "vb2_fail try other slot");
}