diff options
Diffstat (limited to 'tests/vb21_host_common_tests.c')
-rw-r--r-- | tests/vb21_host_common_tests.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/tests/vb21_host_common_tests.c b/tests/vb21_host_common_tests.c new file mode 100644 index 00000000..3ab5dbc3 --- /dev/null +++ b/tests/vb21_host_common_tests.c @@ -0,0 +1,247 @@ +/* Copyright (c) 2014 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. + * + * Tests for firmware 2common.c + */ + +#include "2common.h" +#include "2rsa.h" +#include "2sysincludes.h" +#include "host_common21.h" +#include "host_key21.h" +#include "host_signature21.h" +#include "test_common.h" + +static const uint8_t test_data[] = "This is some test data to sign."; + +/* + * Test struct packing for vboot_struct.h structs which are passed between + * firmware and OS, or passed between different phases of firmware. + */ +static void test_struct_packing(void) +{ + /* Test new struct sizes */ + TEST_EQ(EXPECTED_ID_SIZE, + sizeof(struct vb2_id), + "sizeof(vb2_id)"); + TEST_EQ(EXPECTED_VB21_STRUCT_COMMON_SIZE, + sizeof(struct vb21_struct_common), + "sizeof(vb21_struct_common)"); + TEST_EQ(EXPECTED_VB21_PACKED_KEY_SIZE, + sizeof(struct vb21_packed_key), + "sizeof(vb21_packed_key)"); + TEST_EQ(EXPECTED_VB21_SIGNATURE_SIZE, + sizeof(struct vb21_signature), + "sizeof(vb21_signature)"); +} + +/** + * Common header functions + */ +static void test_common_header_functions(void) +{ + uint8_t cbuf[sizeof(struct vb21_struct_common) + 128]; + uint8_t cbufgood[sizeof(cbuf)]; + struct vb21_struct_common *c = (struct vb21_struct_common *)cbuf; + struct vb21_struct_common *c2; + const char test_desc[32] = "test desc"; + uint32_t desc_end, m; + + c->total_size = sizeof(cbuf); + c->fixed_size = sizeof(*c); + c->desc_size = sizeof(test_desc); + memcpy(cbuf + c->fixed_size, test_desc, sizeof(test_desc)); + desc_end = c->fixed_size + c->desc_size; + + c2 = (struct vb21_struct_common *)(cbuf + desc_end); + c2->total_size = c->total_size - desc_end; + c2->fixed_size = sizeof(*c2); + c2->desc_size = 0; + + /* Description helper */ + TEST_EQ(0, strcmp(vb21_common_desc(c), test_desc), "vb21_common_desc()"); + TEST_EQ(0, strcmp(vb21_common_desc(c2), ""), "vb21_common_desc() empty"); + + TEST_SUCC(vb21_verify_common_header(cbuf, sizeof(cbuf)), + "vb21_verify_common_header() good"); + memcpy(cbufgood, cbuf, sizeof(cbufgood)); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->total_size += 4; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_TOTAL_SIZE, + "vb21_verify_common_header() total size"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->fixed_size = c->total_size + 4; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_FIXED_SIZE, + "vb21_verify_common_header() fixed size"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->desc_size = c->total_size - c->fixed_size + 4; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_DESC_SIZE, + "vb21_verify_common_header() desc size"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->total_size--; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_TOTAL_UNALIGNED, + "vb21_verify_common_header() total unaligned"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->fixed_size++; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_FIXED_UNALIGNED, + "vb21_verify_common_header() fixed unaligned"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->desc_size--; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_DESC_UNALIGNED, + "vb21_verify_common_header() desc unaligned"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + c->desc_size = -4; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_DESC_WRAPS, + "vb21_verify_common_header() desc wraps"); + + memcpy(cbuf, cbufgood, sizeof(cbuf)); + cbuf[desc_end - 1] = 1; + TEST_EQ(vb21_verify_common_header(cbuf, sizeof(cbuf)), + VB2_ERROR_COMMON_DESC_TERMINATOR, + "vb21_verify_common_header() desc not terminated"); + + /* Member checking function */ + memcpy(cbuf, cbufgood, sizeof(cbuf)); + m = 0; + TEST_SUCC(vb21_verify_common_member(cbuf, &m, c->total_size - 8, 4), + "vb21_verify_common_member()"); + TEST_EQ(m, c->total_size - 4, " new minimum"); + + m = desc_end; + TEST_SUCC(vb21_verify_common_member(cbuf, &m, desc_end, 4), + "vb21_verify_common_member() good offset"); + TEST_EQ(m, desc_end + 4, " new minimum"); + + m = 0; + TEST_EQ(vb21_verify_common_member(cbuf, &m, c->total_size - 8, -4), + VB2_ERROR_COMMON_MEMBER_WRAPS, + "vb21_verify_common_member() wraps"); + + m = 0; + TEST_EQ(vb21_verify_common_member(cbuf, &m, c->total_size - 7, 4), + VB2_ERROR_COMMON_MEMBER_UNALIGNED, + "vb21_verify_common_member() offset unaligned"); + + m = 0; + TEST_EQ(vb21_verify_common_member(cbuf, &m, c->total_size - 8, 5), + VB2_ERROR_COMMON_MEMBER_UNALIGNED, + "vb21_verify_common_member() size unaligned"); + + m = 0; + TEST_EQ(vb21_verify_common_member(cbuf, &m, desc_end - 4, 4), + VB2_ERROR_COMMON_MEMBER_OVERLAP, + "vb21_verify_common_member() overlap"); + + m = desc_end + 4; + TEST_EQ(vb21_verify_common_member(cbuf, &m, desc_end, 4), + VB2_ERROR_COMMON_MEMBER_OVERLAP, + "vb21_verify_common_member() overlap 2"); + + m = 0; + TEST_EQ(vb21_verify_common_member(cbuf, &m, c->total_size - 4, 8), + VB2_ERROR_COMMON_MEMBER_SIZE, + "vb21_verify_common_member() size"); + + /* Subobject checking */ + m = 0; + TEST_SUCC(vb21_verify_common_subobject(cbuf, &m, desc_end), + "vb21_verify_common_subobject() good offset"); + TEST_EQ(m, sizeof(cbuf), " new minimum"); + + m = desc_end + 4; + TEST_EQ(vb21_verify_common_subobject(cbuf, &m, desc_end), + VB2_ERROR_COMMON_MEMBER_OVERLAP, + "vb21_verify_common_subobject() overlap"); + + m = 0; + c2->total_size += 4; + TEST_EQ(vb21_verify_common_subobject(cbuf, &m, desc_end), + VB2_ERROR_COMMON_TOTAL_SIZE, + "vb21_verify_common_subobject() size"); +} + +/** + * Signature size + */ +static void test_sig_size(void) +{ + TEST_EQ(vb2_sig_size(VB2_SIG_INVALID, VB2_HASH_SHA256), 0, + "vb2_sig_size() sig invalid"); + + TEST_EQ(vb2_sig_size(VB2_SIG_RSA2048, VB2_HASH_INVALID), 0, + "vb2_sig_size() hash invalid"); + + TEST_EQ(vb2_sig_size(VB2_SIG_RSA2048, VB2_HASH_SHA256), 2048 / 8, + "vb2_sig_size() RSA2048"); + TEST_EQ(vb2_sig_size(VB2_SIG_RSA4096, VB2_HASH_SHA256), 4096 / 8, + "vb2_sig_size() RSA4096"); + TEST_EQ(vb2_sig_size(VB2_SIG_RSA8192, VB2_HASH_SHA512), 8192 / 8, + "vb2_sig_size() RSA8192"); + + TEST_EQ(vb2_sig_size(VB2_SIG_NONE, VB2_HASH_SHA1), + VB2_SHA1_DIGEST_SIZE, "vb2_sig_size() SHA1"); + TEST_EQ(vb2_sig_size(VB2_SIG_NONE, VB2_HASH_SHA256), + VB2_SHA256_DIGEST_SIZE, "vb2_sig_size() SHA256"); + TEST_EQ(vb2_sig_size(VB2_SIG_NONE, VB2_HASH_SHA512), + VB2_SHA512_DIGEST_SIZE, "vb2_sig_size() SHA512"); +} + +/** + * Verify data on bare hash + */ +static void test_verify_hash(void) +{ + struct vb21_signature *sig; + const struct vb2_private_key *prik; + struct vb2_public_key pubk; + uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES] + __attribute__((aligned(VB2_WORKBUF_ALIGN))); + struct vb2_workbuf wb; + + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + + TEST_SUCC(vb2_private_key_hash(&prik, VB2_HASH_SHA256), + "create private hash key"); + TEST_SUCC(vb2_public_key_hash(&pubk, VB2_HASH_SHA256), + "create hash key"); + + /* Create the signature */ + TEST_SUCC(vb21_sign_data(&sig, test_data, sizeof(test_data), + prik, NULL), + "create hash sig"); + + TEST_SUCC(vb21_verify_data(test_data, sizeof(test_data), + sig, &pubk, &wb), + "vb21_verify_data() hash ok"); + + *((uint8_t *)sig + sig->sig_offset) ^= 0xab; + TEST_EQ(vb21_verify_data(test_data, sizeof(test_data), sig, &pubk, &wb), + VB2_ERROR_VDATA_VERIFY_DIGEST, "vb21_verify_data() hash bad"); + + free(sig); +} + +int main(int argc, char* argv[]) +{ + test_struct_packing(); + test_common_header_functions(); + test_sig_size(); + test_verify_hash(); + + return gTestSuccess ? 0 : 255; +} |