vboot2: Add host lib support for bare hash keys

And use them in the other vboot2 unit tests.

BUG=chromium:423882
BRANCH=none
TEST=VBOOT2=1 make runtests

Change-Id: I0c3590649a0acf792e41e295ca4279ccba17a41f
Reviewed-on: https://chromium-review.googlesource.com/231345
Tested-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Randall Spangler
2014-11-20 11:27:38 -08:00
committed by chrome-internal-fetch
parent 59c29202d2
commit fb9a216dd6
8 changed files with 238 additions and 62 deletions

View File

@@ -988,6 +988,7 @@ ${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/host/linktest/main: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vb2_common_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vb2_common2_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vb2_common3_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vb2_host_key_tests: LDLIBS += ${CRYPTO_LIBS}

View File

@@ -81,20 +81,22 @@ int vb2_unpack_key2(struct vb2_public_key *key,
return VB2_ERROR_UNPACK_KEY_STRUCT_VERSION;
/* Copy key algorithms */
key->sig_alg = pkey->sig_alg;
sig_size = vb2_rsa_sig_size(key->sig_alg);
if (!sig_size)
return VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM;
key->hash_alg = pkey->hash_alg;
if (!vb2_digest_size(key->hash_alg))
return VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM;
rv = vb2_unpack_key2_data(key,
key->sig_alg = pkey->sig_alg;
if (key->sig_alg != VB2_SIG_NONE) {
sig_size = vb2_rsa_sig_size(key->sig_alg);
if (!sig_size)
return VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM;
rv = vb2_unpack_key2_data(
key,
(const uint8_t *)pkey + pkey->key_offset,
pkey->key_size);
if (rv)
return rv;
}
/* Key description */
if (pkey->c.desc_size)

View File

@@ -510,6 +510,9 @@ enum vb2_return_code {
/* Unable to set description in vb2_private_key_unpack() */
VB2_ERROR_UNPACK_PRIVATE_KEY_DESC,
/* Bad bare hash key in vb2_private_key_unpack() */
VB2_ERROR_UNPACK_PRIVATE_KEY_HASH,
/* Unable to create RSA data in vb2_private_key_write() */
VB2_ERROR_PRIVATE_KEY_WRITE_RSA,
@@ -519,6 +522,9 @@ enum vb2_return_code {
/* Unable to write file in vb2_private_key_write() */
VB2_ERROR_PRIVATE_KEY_WRITE_FILE,
/* Bad algorithm in vb2_private_key_hash() */
VB2_ERROR_PRIVATE_KEY_HASH,
/* Unable to determine key size in vb2_public_key_alloc() */
VB2_ERROR_PUBLIC_KEY_ALLOC_SIZE,
@@ -549,6 +555,9 @@ enum vb2_return_code {
/* Unable to determine key size in vb2_public_key_pack() */
VB2_ERROR_PUBLIC_KEY_PACK_SIZE,
/* Bad hash algorithm in vb2_publc_key_hash() */
VB2_ERROR_PUBLIC_KEY_HASH,
/**********************************************************************
* Highest non-zero error generated inside vboot library. Note that
* error codes passed through vboot when it calls external APIs may

View File

@@ -14,6 +14,7 @@
#include "2sysincludes.h"
#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "host_common.h"
#include "host_key2.h"
#include "host_misc.h"
@@ -82,12 +83,20 @@ int vb2_private_key_unpack(struct vb2_private_key **key_ptr,
key->guid = pkey->guid;
/* Unpack RSA key */
if (pkey->sig_alg == VB2_SIG_NONE) {
if (pkey->key_size != 0) {
free(key);
return VB2_ERROR_UNPACK_PRIVATE_KEY_HASH;
}
} else {
start = (const unsigned char *)(buf + pkey->key_offset);
key->rsa_private_key = d2i_RSAPrivateKey(0, &start, pkey->key_size);
key->rsa_private_key = d2i_RSAPrivateKey(0, &start,
pkey->key_size);
if (!key->rsa_private_key) {
free(key);
return VB2_ERROR_UNPACK_PRIVATE_KEY_RSA;
}
}
/* Key description */
if (pkey->c.desc_size) {
@@ -184,7 +193,7 @@ int vb2_private_key_write(const struct vb2_private_key *key,
};
uint8_t *buf;
uint8_t *rsabuf = NULL;
int rsalen;
int rsalen = 0;
int rv;
memcpy(&pkey.guid, &key->guid, sizeof(pkey.guid));
@@ -192,10 +201,12 @@ int vb2_private_key_write(const struct vb2_private_key *key,
if (key->desc)
pkey.c.desc_size = roundup32(strlen(key->desc) + 1);
if (key->sig_alg != VB2_SIG_NONE) {
/* Pack RSA key */
rsalen = i2d_RSAPrivateKey(key->rsa_private_key, &rsabuf);
if (rsalen <= 0)
if (rsalen <= 0 || !rsabuf)
return VB2_ERROR_PRIVATE_KEY_WRITE_RSA;
}
pkey.key_offset = pkey.c.fixed_size + pkey.c.desc_size;
pkey.key_size = roundup32(rsalen);
@@ -215,8 +226,10 @@ int vb2_private_key_write(const struct vb2_private_key *key,
if (key->desc)
strcpy((char *)buf + pkey.c.fixed_size, key->desc);
if (rsabuf) {
memcpy(buf + pkey.key_offset, rsabuf, rsalen);
free(rsabuf);
}
rv = vb2_write_object(filename, buf);
free(buf);
@@ -224,6 +237,56 @@ int vb2_private_key_write(const struct vb2_private_key *key,
return rv ? VB2_ERROR_PRIVATE_KEY_WRITE_FILE : VB2_SUCCESS;
}
int vb2_private_key_hash(const struct vb2_private_key **key_ptr,
enum vb2_hash_algorithm hash_alg)
{
*key_ptr = NULL;
switch (hash_alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
{
static const struct vb2_private_key key = {
.hash_alg = VB2_HASH_SHA1,
.sig_alg = VB2_SIG_NONE,
.desc = "Unsigned SHA1",
.guid = VB2_GUID_NONE_SHA1,
};
*key_ptr = &key;
return VB2_SUCCESS;
}
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA256:
{
static const struct vb2_private_key key = {
.hash_alg = VB2_HASH_SHA256,
.sig_alg = VB2_SIG_NONE,
.desc = "Unsigned SHA-256",
.guid = VB2_GUID_NONE_SHA256,
};
*key_ptr = &key;
return VB2_SUCCESS;
}
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA512:
{
static const struct vb2_private_key key = {
.hash_alg = VB2_HASH_SHA512,
.sig_alg = VB2_SIG_NONE,
.desc = "Unsigned SHA-512",
.guid = VB2_GUID_NONE_SHA512,
};
*key_ptr = &key;
return VB2_SUCCESS;
}
#endif
default:
return VB2_ERROR_PRIVATE_KEY_HASH;
}
}
/**
* Allocate a public key buffer of sufficient size for the signature algorithm.
*
@@ -347,11 +410,11 @@ int vb2_packed_key2_read(struct vb2_packed_key2 **key_ptr,
*key_ptr = NULL;
if (!vb2_read_file(filename, &buf, &size))
if (vb2_read_file(filename, &buf, &size))
return VB2_ERROR_READ_PACKED_KEY_DATA;
/* Sanity check: make sure key unpacks properly */
if (!vb2_unpack_key(&key, buf, size))
if (vb2_unpack_key2(&key, buf, size))
return VB2_ERROR_READ_PACKED_KEY;
*key_ptr = (struct vb2_packed_key2 *)buf;
@@ -375,14 +438,16 @@ int vb2_public_key_pack(struct vb2_packed_key2 **key_ptr,
/* Calculate sizes and offsets */
key.c.fixed_size = sizeof(key);
if (pubk->desc)
if (pubk->desc && *pubk->desc)
key.c.desc_size = roundup32(strlen(pubk->desc) + 1);
key.key_offset = key.c.fixed_size + key.c.desc_size;
if (pubk->sig_alg != VB2_SIG_NONE) {
key.key_size = vb2_packed_key_size(pubk->sig_alg);
if (!key.key_size)
return VB2_ERROR_PUBLIC_KEY_PACK_SIZE;
}
key.c.total_size = key.key_offset + key.key_size;
@@ -400,11 +465,12 @@ int vb2_public_key_pack(struct vb2_packed_key2 **key_ptr,
memcpy(buf, &key, sizeof(key));
/* strcpy() is safe because we allocated above based on strlen() */
if (pubk->desc) {
if (pubk->desc && *pubk->desc) {
strcpy((char *)(buf + key.c.fixed_size), pubk->desc);
buf[key.c.fixed_size + key.c.desc_size - 1] = 0;
}
if (pubk->sig_alg != VB2_SIG_NONE) {
/* Re-pack the key arrays */
buf32 = (uint32_t *)(buf + key.key_offset);
buf32[0] = pubk->arrsize;
@@ -412,8 +478,38 @@ int vb2_public_key_pack(struct vb2_packed_key2 **key_ptr,
memcpy(buf32 + 2, pubk->n, pubk->arrsize * sizeof(uint32_t));
memcpy(buf32 + 2 + pubk->arrsize, pubk->rr,
pubk->arrsize * sizeof(uint32_t));
}
*key_ptr = (struct vb2_packed_key2 *)buf;
return VB2_SUCCESS;
}
int vb2_public_key_hash(struct vb2_public_key *key,
enum vb2_hash_algorithm hash_alg)
{
switch (hash_alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
key->desc = "Unsigned SHA1";
break;
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA256:
key->desc = "Unsigned SHA-256";
break;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA512:
key->desc = "Unsigned SHA-512";
break;
#endif
default:
return VB2_ERROR_PUBLIC_KEY_HASH;
}
key->sig_alg = VB2_SIG_NONE;
key->hash_alg = hash_alg;
key->guid = vb2_hash_guid(hash_alg);
return VB2_SUCCESS;
}

View File

@@ -10,6 +10,7 @@
#include "2sysincludes.h"
#include "2common.h"
#include "2sha.h"
#include "host_common.h"
int vb2_read_file(const char *filename, uint8_t **data_ptr, uint32_t *size_ptr)

View File

@@ -83,6 +83,17 @@ int vb2_private_key_set_desc(struct vb2_private_key *key, const char *desc);
int vb2_private_key_write(const struct vb2_private_key *key,
const char *filename);
/**
* Get a private key for an unsigned hash
*
* @param key_ptr Destination for pointer to key. The key is statically
* allocated and must not be freed.
* @param hash_alg Hash algorithm to use
* @return VB2_SUCCESS, or non-zero error code if error.
*/
int vb2_private_key_hash(const struct vb2_private_key **key_ptr,
enum vb2_hash_algorithm hash_alg);
/**
* Free a public key allocated by one of the functions below.
*
@@ -141,4 +152,15 @@ int vb2_packed_key2_read(struct vb2_packed_key2 **key_ptr,
int vb2_public_key_pack(struct vb2_packed_key2 **key_ptr,
const struct vb2_public_key *pubk);
/**
* Get a public key for an unsigned hash.
*
* @param key Destination for key data.
* @param hash_alg Hash algorithm to use
* @return VB2_SUCCESS, or non-zero error code if error.
*/
int vb2_public_key_hash(struct vb2_public_key *key,
enum vb2_hash_algorithm hash_alg);
#endif /* VBOOT_REFERENCE_HOST_KEY2_H_ */

View File

@@ -8,6 +8,7 @@
#include "2sysincludes.h"
#include "2common.h"
#include "2rsa.h"
#include "host_key2.h"
#include "vb2_convert_structs.h"
#include "vboot_struct.h" /* For old struct sizes */
@@ -452,16 +453,15 @@ static void test_sig_size(void)
static void test_verify_hash(void)
{
struct vb2_signature2 *sig;
struct vb2_public_key pubk = {
.sig_alg = VB2_SIG_NONE,
.hash_alg = VB2_HASH_SHA256,
.guid = vb2_hash_guid(VB2_HASH_SHA256)
};
struct vb2_public_key pubk;
uint8_t workbuf[VB2_VERIFY_DATA_WORKBUF_BYTES];
struct vb2_workbuf wb;
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
TEST_SUCC(vb2_public_key_hash(&pubk, VB2_HASH_SHA256),
"create hash key");
/* Create the signature */
sig = vb2_create_hash_sig(test_data, sizeof(test_data), pubk.hash_alg);
TEST_PTR_NEQ(sig, NULL, "create hash sig");
@@ -483,6 +483,7 @@ static void test_verify_hash(void)
static void test_verify_keyblock(void)
{
const char desc[16] = "test keyblock";
struct vb2_public_key pubk, pubk2, pubk_not_present;
struct vb2_signature2 *sig;
struct vb2_keyblock2 *kbuf;
uint32_t buf_size;
@@ -491,21 +492,12 @@ static void test_verify_keyblock(void)
uint8_t workbuf[VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES];
struct vb2_workbuf wb;
const struct vb2_public_key pubk = {
.sig_alg = VB2_SIG_NONE,
.hash_alg = VB2_HASH_SHA256,
.guid = vb2_hash_guid(VB2_HASH_SHA256)
};
const struct vb2_public_key pubk2 = {
.sig_alg = VB2_SIG_NONE,
.hash_alg = VB2_HASH_SHA512,
.guid = vb2_hash_guid(VB2_HASH_SHA512)
};
const struct vb2_public_key pubk_not_present = {
.sig_alg = VB2_SIG_NONE,
.hash_alg = VB2_HASH_SHA1,
.guid = vb2_hash_guid(VB2_HASH_SHA1)
};
TEST_SUCC(vb2_public_key_hash(&pubk, VB2_HASH_SHA256),
"create hash key 1");
TEST_SUCC(vb2_public_key_hash(&pubk2, VB2_HASH_SHA512),
"create hash key 2");
TEST_SUCC(vb2_public_key_hash(&pubk_not_present, VB2_HASH_SHA1),
"create hash key 3");
/*
* Test packed key only needs to initialize the fields used by keyblock
@@ -663,6 +655,7 @@ static void test_verify_keyblock(void)
static void test_verify_fw_preamble(void)
{
const char desc[16] = "test preamble";
struct vb2_public_key pubk;
struct vb2_signature2 *sig;
struct vb2_fw_preamble2 *pre;
uint32_t buf_size;
@@ -678,11 +671,8 @@ static void test_verify_fw_preamble(void)
* bare hash here saves us from needing to have a private key to do
* this test.
*/
const struct vb2_public_key pubk = {
.sig_alg = VB2_SIG_NONE,
.hash_alg = VB2_HASH_SHA256,
.guid = vb2_hash_guid(VB2_HASH_SHA256)
};
TEST_SUCC(vb2_public_key_hash(&pubk, VB2_HASH_SHA256),
"create hash key");
struct vb2_fw_preamble2 fp = {
.c.magic = VB2_MAGIC_FW_PREAMBLE2,

View File

@@ -33,6 +33,7 @@ static void private_key_tests(const struct alg_combo *combo,
const char *pemfile)
{
struct vb2_private_key *key, *k2;
const struct vb2_private_key *ckey;
struct vb2_packed_private_key2 *pkey;
const char *testfile = "test.vbprik2";
const char *notapem = "not_a_pem";
@@ -136,11 +137,31 @@ static void private_key_tests(const struct alg_combo *combo,
VB2_ERROR_UNPACK_PRIVATE_KEY_RSA,
"Unpack private key bad rsa data");
memcpy(buf, buf2, bufsize);
pkey->sig_alg = VB2_SIG_NONE;
TEST_EQ(vb2_private_key_unpack(&k2, buf, bufsize),
VB2_ERROR_UNPACK_PRIVATE_KEY_HASH,
"Unpack private key hash but has data");
free(buf);
free(buf2);
unlink(testfile);
vb2_private_key_free(key);
TEST_EQ(vb2_private_key_hash(&ckey, VB2_HASH_INVALID),
VB2_ERROR_PRIVATE_KEY_HASH,
"Hash key invalid");
TEST_PTR_EQ(ckey, NULL, " key_ptr");
TEST_SUCC(vb2_private_key_hash(&ckey, combo->hash_alg), "Hash key");
TEST_PTR_NEQ(ckey, NULL, " key_ptr");
TEST_EQ(ckey->hash_alg, combo->hash_alg, " hash_alg");
TEST_EQ(ckey->sig_alg, VB2_SIG_NONE, " sig_alg");
TEST_EQ(memcmp(&ckey->guid, vb2_hash_guid(combo->hash_alg),
sizeof(ckey->guid)), 0, " guid");
TEST_SUCC(vb2_private_key_write(ckey, testfile), "Write hash key");
TEST_SUCC(vb2_private_key_read(&key, testfile), "Read hash key");
unlink(testfile);
}
static void public_key_tests(const struct alg_combo *combo,
@@ -213,13 +234,47 @@ static void public_key_tests(const struct alg_combo *combo,
" n");
TEST_EQ(memcmp(key->rr, k2.rr, key->arrsize * sizeof(uint32_t)), 0,
" rr");
TEST_SUCC(vb2_write_object(testfile, pkey), "Write packed key");
free(pkey);
TEST_SUCC(vb2_packed_key2_read(&pkey, testfile), "Read packed key");
TEST_PTR_NEQ(pkey, NULL, " key_ptr");
unlink(testfile);
pkey->hash_alg = VB2_HASH_INVALID;
TEST_SUCC(vb2_write_object(testfile, pkey), "Write bad packed key");
free(pkey);
TEST_EQ(vb2_packed_key2_read(&pkey, testfile),
VB2_ERROR_READ_PACKED_KEY, "Read bad packed key");
TEST_PTR_EQ(pkey, NULL, " key_ptr");
unlink(testfile);
TEST_EQ(vb2_packed_key2_read(&pkey, testfile),
VB2_ERROR_READ_PACKED_KEY_DATA, "Read missing packed key");
key->sig_alg = VB2_SIG_INVALID;
TEST_EQ(vb2_public_key_pack(&pkey, key),
VB2_ERROR_PUBLIC_KEY_PACK_SIZE,
"Pack invalid sig alg");
vb2_public_key_free(key);
TEST_EQ(vb2_public_key_hash(&k2, VB2_HASH_INVALID),
VB2_ERROR_PUBLIC_KEY_HASH,
"Hash key invalid");
TEST_SUCC(vb2_public_key_hash(&k2, combo->hash_alg), "Hash key");
TEST_EQ(k2.hash_alg, combo->hash_alg, " hash_alg");
TEST_EQ(k2.sig_alg, VB2_SIG_NONE, " sig_alg");
TEST_EQ(memcmp(k2.guid, vb2_hash_guid(combo->hash_alg),
sizeof(*k2.guid)), 0, " guid");
TEST_SUCC(vb2_public_key_pack(&pkey, &k2), "Pack public hash key");
TEST_PTR_NEQ(pkey, NULL, " key_ptr");
TEST_SUCC(vb2_unpack_key2(&k2, (uint8_t *)pkey, pkey->c.total_size),
"Unpack public hash key");
free(pkey);
}
static int test_algorithm(const struct alg_combo *combo, const char *keys_dir)