diff options
Diffstat (limited to 'bdb/bdb_test.c')
-rw-r--r-- | bdb/bdb_test.c | 492 |
1 files changed, 0 insertions, 492 deletions
diff --git a/bdb/bdb_test.c b/bdb/bdb_test.c deleted file mode 100644 index 6c9022dc..00000000 --- a/bdb/bdb_test.c +++ /dev/null @@ -1,492 +0,0 @@ -/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Unit tests - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "bdb.h" -#include "host.h" - -#define TEST_EQ(got, want) test_eq(got, want, #got, #want, __LINE__) - -void test_eq(int got, int want, const char *gotstr, const char *wantstr, - int line) -{ - if (got == want) - return; - - fprintf(stderr, "Fail(%d): %s != %s\n" - "got: 0x%08x (%d)\n" - "wanted: 0x%08x (%d)\n", - line, gotstr, wantstr, got, got, want, want); - exit(1); -} - -void check_header_tests(void) -{ - struct bdb_header sgood = { - .struct_magic = BDB_HEADER_MAGIC, - .struct_major_version = BDB_HEADER_VERSION_MAJOR, - .struct_minor_version = BDB_HEADER_VERSION_MINOR, - .struct_size = sizeof(struct bdb_header), - .bdb_load_address = -1, - .bdb_size = 1024, - .signed_size = 512, - .oem_area_0_size = 256, - }; - const size_t ssize = sgood.struct_size; - struct bdb_header s; - - s = sgood; - TEST_EQ(bdb_check_header(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_header(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - s = sgood; - s.oem_area_0_size++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_OEM_AREA_SIZE); - - s = sgood; - s.bdb_size = ssize - 1; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_BDB_SIZE); -} - -void check_key_tests(void) -{ - struct bdb_key sgood = { - .struct_magic = BDB_KEY_MAGIC, - .struct_major_version = BDB_KEY_VERSION_MAJOR, - .struct_minor_version = BDB_KEY_VERSION_MINOR, - .struct_size = (sizeof(struct bdb_key) + - BDB_RSA4096_KEY_DATA_SIZE), - .hash_alg = BDB_HASH_ALG_SHA256, - .sig_alg = BDB_SIG_ALG_RSA4096, - .key_version = 1, - .description = "Test key", - }; - const size_t ssize = sgood.struct_size; - struct bdb_key s; - - s = sgood; - TEST_EQ(bdb_check_key(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_key(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ(bdb_check_key(&s, ssize), BDB_SUCCESS); - - /* Limited algorithm choices at present */ - s = sgood; - s.hash_alg = BDB_HASH_ALG_INVALID; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_HASH_ALG); - - /* This works because ECDSA521 signatures are smaller than RSA4096 */ - s = sgood; - s.sig_alg = BDB_SIG_ALG_ECSDSA521; - TEST_EQ(bdb_check_key(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.sig_alg = BDB_SIG_ALG_INVALID; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_SIG_ALG); -} - -void check_sig_tests(void) -{ - struct bdb_sig sgood = { - .struct_magic = BDB_SIG_MAGIC, - .struct_major_version = BDB_SIG_VERSION_MAJOR, - .struct_minor_version = BDB_SIG_VERSION_MINOR, - .struct_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE, - .hash_alg = BDB_HASH_ALG_SHA256, - .sig_alg = BDB_SIG_ALG_RSA4096, - .signed_size = 123, - .description = "Test sig", - }; - const size_t ssize = sgood.struct_size; - struct bdb_sig s; - - s = sgood; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_sig(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_SUCCESS); - - /* Limited algorithm choices at present */ - s = sgood; - s.hash_alg = BDB_HASH_ALG_INVALID; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_HASH_ALG); - - /* This works because ECDSA521 signatures are smaller than RSA4096 */ - s = sgood; - s.sig_alg = BDB_SIG_ALG_ECSDSA521; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.sig_alg = BDB_SIG_ALG_INVALID; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_SIG_ALG); -} - -void check_data_tests(void) -{ - struct bdb_data sgood = { - .struct_magic = BDB_DATA_MAGIC, - .struct_major_version = BDB_DATA_VERSION_MAJOR, - .struct_minor_version = BDB_DATA_VERSION_MINOR, - .struct_size = sizeof(struct bdb_data), - .data_version = 1, - .oem_area_1_size = 256, - .num_hashes = 3, - .hash_entry_size = sizeof(struct bdb_hash), - .signed_size = 2048, - .description = "Test data", - }; - const size_t ssize = sgood.signed_size; - struct bdb_data s; - - s = sgood; - TEST_EQ(bdb_check_data(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_data(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ(bdb_check_data(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.hash_entry_size--; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_HASH_ENTRY_SIZE); - - s = sgood; - s.oem_area_1_size++; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_OEM_AREA_SIZE); - - /* Check exact size needed */ - s = sgood; - s.signed_size = sizeof(s) + s.num_hashes * sizeof(struct bdb_hash) + - s.oem_area_1_size; - TEST_EQ(bdb_check_data(&s, ssize), BDB_SUCCESS); - s.signed_size--; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_SIGNED_SIZE); - - /* - * TODO: Verify wraparound check works. That can only be tested on a - * platform where size_t is uint32_t, because otherwise a 32-bit - * oem_area_1_size can't cause wraparound. - */ -} - -/** - * Test bdb_verify() and bdb_create() - */ -void check_bdb_verify(void) -{ - uint8_t oem_area_0[32] = "Some OEM area."; - uint8_t oem_area_1[64] = "Some other OEM area."; - - struct bdb_hash hash[2] = { - { - .offset = 0x10000, - .size = 0x18000, - .partition = 1, - .type = BDB_DATA_SP_RW, - .load_address = 0x100000, - .digest = {0x11, 0x11, 0x11, 0x10}, - }, - { - .offset = 0x28000, - .size = 0x20000, - .partition = 1, - .type = BDB_DATA_AP_RW, - .load_address = 0x200000, - .digest = {0x22, 0x22, 0x22, 0x20}, - }, - }; - - struct bdb_create_params p = { - .bdb_load_address = 0x11223344, - .oem_area_0 = oem_area_0, - .oem_area_0_size = sizeof(oem_area_0), - .oem_area_1 = oem_area_1, - .oem_area_1_size = sizeof(oem_area_1), - .header_sig_description = "The header sig", - .data_sig_description = "The data sig", - .data_description = "Test BDB data", - .data_version = 3, - .hash = hash, - .num_hashes = 2, - }; - - uint8_t bdbkey_digest[BDB_SHA256_DIGEST_SIZE]; - struct bdb_header *hgood, *h; - size_t hsize; - - /* Load keys */ - p.bdbkey = bdb_create_key("testkeys/bdbkey.keyb", 100, "BDB key"); - p.subkey = bdb_create_key("testkeys/subkey.keyb", 200, "Subkey"); - p.private_bdbkey = read_pem("testkeys/bdbkey.pem"); - p.private_subkey = read_pem("testkeys/subkey.pem"); - if (!p.bdbkey || !p.subkey || !p.private_bdbkey || !p.private_subkey) { - fprintf(stderr, "Unable to load test keys\n"); - exit(2); - } - - bdb_sha256(bdbkey_digest, p.bdbkey, p.bdbkey->struct_size); - - /* Create the test BDB */ - hgood = bdb_create(&p); - if (!hgood) { - fprintf(stderr, "Unable to create test BDB\n"); - exit(2); - } - hsize = hgood->bdb_size; - - /* Allocate a copy we can mangle */ - h = calloc(hsize, 1); - - /* As created, it should pass */ - memcpy(h, hgood, hsize); - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_SUCCESS); - - /* Mangle each component in turn */ - memcpy(h, hgood, hsize); - h->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_bdbkey(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_BDBKEY); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_bdbkey(h))->key_version++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_GOOD_OTHER_THAN_KEY); - - memcpy(h, hgood, hsize); - h->oem_area_0_size += hsize; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_OEM_AREA_0); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_subkey(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_SUBKEY); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_subkey(h))->struct_size += 4; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_BDB_SIGNED_SIZE); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->signed_size--; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->sig_data[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - /* Also make sure the header sig really covers all the fields */ - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_subkey(h))->key_version++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_0(h))[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_0(h))[p.oem_area_0_size - 1] ^= 0x24; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - /* Check data header */ - memcpy(h, hgood, hsize); - ((struct bdb_data *)bdb_get_data(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->signed_size--; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->sig_data[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - /* Also make sure the data sig really covers all the fields */ - memcpy(h, hgood, hsize); - ((struct bdb_data *)bdb_get_data(h))->data_version--; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_1(h))[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_1(h))[p.oem_area_1_size - 1] ^= 0x24; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_hash *)bdb_get_hash(h, BDB_DATA_SP_RW))->offset++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_hash *)bdb_get_hash(h, BDB_DATA_AP_RW))->digest[0] ^= 0x96; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - /* - * This is also a convenient place to test that all the parameters we - * fed into bdb_create() also worked. That also tests all the - * bdb_get_*() functions. - */ - memcpy(h, hgood, hsize); - TEST_EQ(h->bdb_load_address, p.bdb_load_address); - - TEST_EQ(strcmp(bdb_get_bdbkey(h)->description, - p.bdbkey->description), 0); - TEST_EQ(bdb_get_bdbkey(h)->key_version, p.bdbkey->key_version); - - TEST_EQ(h->oem_area_0_size, p.oem_area_0_size); - TEST_EQ(memcmp(bdb_get_oem_area_0(h), oem_area_0, sizeof(oem_area_0)), - 0); - - TEST_EQ(strcmp(bdb_get_subkey(h)->description, p.subkey->description), - 0); - TEST_EQ(bdb_get_subkey(h)->key_version, p.subkey->key_version); - - TEST_EQ(strcmp(bdb_get_header_sig(h)->description, - p.header_sig_description), 0); - - TEST_EQ(strcmp(bdb_get_data(h)->description, p.data_description), 0); - TEST_EQ(bdb_get_data(h)->data_version, p.data_version); - TEST_EQ(bdb_get_data(h)->num_hashes, p.num_hashes); - - TEST_EQ(bdb_get_data(h)->oem_area_1_size, p.oem_area_1_size); - TEST_EQ(memcmp(bdb_get_oem_area_1(h), oem_area_1, sizeof(oem_area_1)), - 0); - - TEST_EQ(strcmp(bdb_get_data_sig(h)->description, - p.data_sig_description), 0); - - /* Test getting hash entries */ - memcpy(h, hgood, hsize); - TEST_EQ(bdb_get_hash(h, BDB_DATA_SP_RW)->offset, hash[0].offset); - TEST_EQ(bdb_get_hash(h, BDB_DATA_AP_RW)->offset, hash[1].offset); - /* And a non-existent one */ - TEST_EQ(bdb_get_hash(h, BDB_DATA_MCU)!=NULL, 0); - - /* - * TODO: Verify wraparound checks works. That can only be tested on a - * platform where size_t is uint32_t, because otherwise a 32-bit - * oem_area_1_size can't cause wraparound. - */ - - /* Free keys and buffers */ - free(p.bdbkey); - free(p.subkey); - RSA_free(p.private_bdbkey); - RSA_free(p.private_subkey); - free(hgood); - free(h); -} - -/*****************************************************************************/ - -int main(void) -{ - printf("Running tests...\n"); - - check_header_tests(); - check_key_tests(); - check_sig_tests(); - check_data_tests(); - check_bdb_verify(); - - printf("All tests passed!\n"); - - return 0; -} |