diff options
author | Randall Spangler <rspangler@chromium.org> | 2014-11-21 11:04:36 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-27 06:35:09 +0000 |
commit | c644a8c0f2df024798ac0e60c6028261ed389a16 (patch) | |
tree | e9d4e91959ffd0a22025f34515b6a3996b94c863 /tests | |
parent | fb9a216dd677d97f3d6963f668a9b84d349ef339 (diff) | |
download | vboot-c644a8c0f2df024798ac0e60c6028261ed389a16.tar.gz |
vboot2: Add host library functions for signing to new struct format
Including signing with bare hashes, and signing an object with more
than one signature. With unit tests, even.
BUG=chromium:423882
BRANCH=none
TEST=VBOOT2=1 make runtests
Change-Id: Iad0b9f9f6cca7129071aebf0cbc60c0daa94d382
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/231452
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/vb2_api2_tests.c | 2 | ||||
-rw-r--r-- | tests/vb2_common_tests.c | 1 | ||||
-rw-r--r-- | tests/vb2_convert_structs.c | 39 | ||||
-rw-r--r-- | tests/vb2_host_misc_tests.c | 5 | ||||
-rw-r--r-- | tests/vb2_host_sig_tests.c | 199 |
5 files changed, 214 insertions, 32 deletions
diff --git a/tests/vb2_api2_tests.c b/tests/vb2_api2_tests.c index 17fc3b96..b6db1850 100644 --- a/tests/vb2_api2_tests.c +++ b/tests/vb2_api2_tests.c @@ -15,6 +15,8 @@ #include "2rsa.h" #include "2secdata.h" +#include "host_signature2.h" + #include "test_common.h" #include "vb2_convert_structs.h" diff --git a/tests/vb2_common_tests.c b/tests/vb2_common_tests.c index 37996ae3..29adfe84 100644 --- a/tests/vb2_common_tests.c +++ b/tests/vb2_common_tests.c @@ -9,6 +9,7 @@ #include "2common.h" #include "2rsa.h" #include "host_key2.h" +#include "host_signature2.h" #include "vb2_convert_structs.h" #include "vboot_struct.h" /* For old struct sizes */ diff --git a/tests/vb2_convert_structs.c b/tests/vb2_convert_structs.c index d30b337f..68cb326d 100644 --- a/tests/vb2_convert_structs.c +++ b/tests/vb2_convert_structs.c @@ -9,7 +9,9 @@ #include "2common.h" #include "2rsa.h" #include "host_common.h" +#include "host_key2.h" #include "host_misc.h" +#include "host_signature2.h" #include "vb2_convert_structs.h" #include "vboot_struct.h" /* For old struct sizes */ @@ -117,41 +119,14 @@ struct vb2_signature2 *vb2_create_hash_sig(const uint8_t *data, uint32_t size, enum vb2_hash_algorithm hash_alg) { - const char desc[12] = "hash sig"; - struct vb2_signature2 s = { - .c.magic = VB2_MAGIC_SIGNATURE2, - .c.struct_version_major = VB2_SIGNATURE2_VERSION_MAJOR, - .c.struct_version_minor = VB2_SIGNATURE2_VERSION_MINOR, - .c.fixed_size = sizeof(s), - .c.desc_size = sizeof(desc), - .sig_alg = VB2_SIG_NONE, - .hash_alg = hash_alg, - .sig_size = vb2_sig_size(VB2_SIG_NONE, hash_alg), - .data_size = size, - }; - const struct vb2_guid *hash_guid = vb2_hash_guid(hash_alg); - struct vb2_digest_context dc; - uint8_t *buf; + const struct vb2_private_key *key; + struct vb2_signature2 *sig; - /* Make sure hash algorithm was supported */ - if (!hash_guid || !s.sig_size) + if (vb2_private_key_hash(&key, hash_alg)) return NULL; - memcpy(&s.guid, hash_guid, sizeof(s.guid)); - s.sig_offset = s.c.fixed_size + s.c.desc_size; - s.c.total_size = s.sig_offset + s.sig_size; - - buf = malloc(s.c.total_size); - memset(buf, 0, s.c.total_size); - memcpy(buf, &s, sizeof(s)); - memcpy(buf + s.c.fixed_size, desc, sizeof(desc)); - - if (vb2_digest_init(&dc, hash_alg) || - vb2_digest_extend(&dc, data, size) || - vb2_digest_finalize(&dc, buf + s.sig_offset, s.sig_size)) { - free(buf); + if (vb2_sign_data(&sig, data, size, key, NULL)) return NULL; - } - return (struct vb2_signature2 *)buf; + return sig; } diff --git a/tests/vb2_host_misc_tests.c b/tests/vb2_host_misc_tests.c index e8c2a588..a78c7450 100644 --- a/tests/vb2_host_misc_tests.c +++ b/tests/vb2_host_misc_tests.c @@ -19,6 +19,11 @@ static void misc_tests(void) TEST_EQ(roundup32(0), 0, "roundup32(0)"); TEST_EQ(roundup32(15), 16, "roundup32(15)"); TEST_EQ(roundup32(16), 16, "roundup32(16)"); + + TEST_EQ(vb2_desc_size(NULL), 0, "desc size null"); + TEST_EQ(vb2_desc_size(""), 0, "desc size empty"); + TEST_EQ(vb2_desc_size("foo"), 4, "desc size 'foo'"); + TEST_EQ(vb2_desc_size("foob"), 8, "desc size 'foob'"); } static void file_tests(void) diff --git a/tests/vb2_host_sig_tests.c b/tests/vb2_host_sig_tests.c new file mode 100644 index 00000000..a2793bc9 --- /dev/null +++ b/tests/vb2_host_sig_tests.c @@ -0,0 +1,199 @@ +/* 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 host library vboot2 key functions + */ + +#include <stdio.h> +#include <unistd.h> + +#include "2sysincludes.h" +#include "2common.h" +#include "2rsa.h" +#include "host_common.h" +#include "host_key2.h" +#include "host_signature2.h" +#include "test_common.h" + +/* Test only the algorithms we use */ +struct alg_combo { + const char *name; + enum vb2_signature_algorithm sig_alg; + enum vb2_hash_algorithm hash_alg; +}; + +static const struct alg_combo test_algs[] = { + {"RSA2048/SHA-256", VB2_SIG_RSA2048, VB2_HASH_SHA256}, + {"RSA4096/SHA-256", VB2_SIG_RSA4096, VB2_HASH_SHA256}, + {"RSA8192/SHA-512", VB2_SIG_RSA8192, VB2_HASH_SHA512}, +}; + +const struct vb2_guid test_guid = {.raw = {0xaa}}; +const char *test_desc = "The test key"; +const char *test_sig_desc = "The test signature"; +const uint8_t test_data[] = "Some test data"; +const uint32_t test_size = sizeof(test_data); + +static void sig_tests(const struct alg_combo *combo, + const char *pemfile, + const char *keybfile) +{ + struct vb2_private_key *prik, prik2; + const struct vb2_private_key *prihash, *priks[2]; + struct vb2_public_key *pubk, pubhash; + struct vb2_signature2 *sig, *sig2; + uint32_t size; + + uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES]; + struct vb2_workbuf wb; + + uint8_t *buf; + uint32_t bufsize; + struct vb2_struct_common *c; + uint32_t c_sig_offs; + + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + + /* Create test keys */ + /* TODO: should read these from .vbprik2, .vbpubk2 files */ + TEST_SUCC(vb2_private_key_read_pem(&prik, pemfile), "Read private key"); + prik->guid = test_guid; + prik->hash_alg = combo->hash_alg; + prik->sig_alg = combo->sig_alg; + vb2_private_key_set_desc(prik, test_desc); + + TEST_SUCC(vb2_public_key_read_keyb(&pubk, keybfile), "Read pub key"); + pubk->guid = &test_guid; + pubk->hash_alg = combo->hash_alg; + vb2_public_key_set_desc(pubk, test_desc); + + TEST_SUCC(vb2_private_key_hash(&prihash, combo->hash_alg), + "Private hash key"); + TEST_SUCC(vb2_public_key_hash(&pubhash, combo->hash_alg), + "Public hash key"); + + priks[0] = prik; + priks[1] = prihash; + + /* Sign test data */ + TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prik, NULL), + "Sign good"); + TEST_PTR_NEQ(sig, NULL, " sig_ptr"); + TEST_EQ(0, strcmp((char *)sig + sig->c.fixed_size, test_desc), + " desc"); + TEST_EQ(0, memcmp(&sig->guid, &test_guid, sizeof(test_guid)), " guid"); + TEST_EQ(sig->data_size, test_size, " data_size"); + TEST_SUCC(vb2_sig_size_for_key(&size, prik, NULL), "Sig size"); + TEST_EQ(size, sig->c.total_size, " size"); + TEST_SUCC(vb2_verify_data2(test_data, test_size, sig, pubk, &wb), + "Verify good"); + free(sig); + + TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prik, + test_sig_desc), + "Sign with desc"); + TEST_EQ(0, strcmp((char *)sig + sig->c.fixed_size, test_sig_desc), + " desc"); + free(sig); + + TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prik, ""), + "Sign with no desc"); + TEST_EQ(sig->c.desc_size, 0, " desc"); + TEST_SUCC(vb2_sig_size_for_key(&size, prik, ""), "Sig size"); + TEST_EQ(size, sig->c.total_size, " size"); + free(sig); + + TEST_SUCC(vb2_sign_data(&sig, test_data, test_size, prihash, NULL), + "Sign with hash"); + TEST_SUCC(vb2_verify_data2(test_data, test_size, sig, &pubhash, &wb), + "Verify with hash"); + free(sig); + + prik2 = *prik; + prik2.sig_alg = VB2_SIG_INVALID; + TEST_EQ(vb2_sign_data(&sig, test_data, test_size, &prik2, NULL), + VB2_SIGN_DATA_SIG_SIZE, "Sign bad sig alg"); + + /* Sign an object with a little (24 bytes) data */ + c_sig_offs = sizeof(*c) + 24; + TEST_SUCC(vb2_sig_size_for_key(&size, prik, NULL), "Sig size"); + bufsize = c_sig_offs + size; + buf = malloc(bufsize); + memset(buf, 0, bufsize); + memset(buf + sizeof(*c), 0x12, 24); + c = (struct vb2_struct_common *)buf; + c->total_size = bufsize; + + TEST_SUCC(vb2_sign_object(buf, c_sig_offs, prik, NULL), "Sign object"); + sig = (struct vb2_signature2 *)(buf + c_sig_offs); + TEST_SUCC(vb2_verify_data2(buf, c_sig_offs, sig, pubk, &wb), + "Verify object"); + + TEST_EQ(vb2_sign_object(buf, c_sig_offs + 4, prik, NULL), + VB2_SIGN_OBJECT_OVERFLOW, "Sign object overflow"); + free(buf); + + /* Multiply sign an object */ + TEST_SUCC(vb2_sig_size_for_keys(&size, priks, 2), "Sigs size"); + bufsize = c_sig_offs + size; + buf = malloc(bufsize); + memset(buf, 0, bufsize); + memset(buf + sizeof(*c), 0x12, 24); + c = (struct vb2_struct_common *)buf; + c->total_size = bufsize; + + TEST_SUCC(vb2_sign_object_multiple(buf, c_sig_offs, priks, 2), + "Sign multiple"); + sig = (struct vb2_signature2 *)(buf + c_sig_offs); + TEST_SUCC(vb2_verify_data2(buf, c_sig_offs, sig, pubk, &wb), + "Verify object with sig 1"); + sig2 = (struct vb2_signature2 *)(buf + c_sig_offs + sig->c.total_size); + TEST_SUCC(vb2_verify_data2(buf, c_sig_offs, sig2, &pubhash, &wb), + "Verify object with sig 2"); + + c->total_size -= 4; + TEST_EQ(vb2_sign_object_multiple(buf, c_sig_offs, priks, 2), + VB2_SIGN_OBJECT_OVERFLOW, "Sign multple overflow"); + + TEST_EQ(size, sig->c.total_size + sig2->c.total_size, + "Sigs size total"); + + free(buf); + + vb2_private_key_free(prik); + vb2_public_key_free(pubk); +} + +static int test_algorithm(const struct alg_combo *combo, const char *keys_dir) +{ + int rsa_bits = vb2_rsa_sig_size(combo->sig_alg) * 8; + char pemfile[1024]; + char keybfile[1024]; + + printf("***Testing algorithm: %s\n", combo->name); + + sprintf(pemfile, "%s/key_rsa%d.pem", keys_dir, rsa_bits); + sprintf(keybfile, "%s/key_rsa%d.keyb", keys_dir, rsa_bits); + + sig_tests(combo, pemfile, keybfile); + + return 0; +} + +int main(int argc, char *argv[]) { + + if (argc == 2) { + int i; + + for (i = 0; i < ARRAY_SIZE(test_algs); i++) { + if (test_algorithm(test_algs + i, argv[1])) + return 1; + } + } else { + fprintf(stderr, "Usage: %s <keys_dir>", argv[0]); + return -1; + } + + return gTestSuccess ? 0 : 255; +} |