diff options
author | Randall Spangler <rspangler@chromium.org> | 2014-11-17 14:24:59 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-27 06:34:56 +0000 |
commit | 59c29202d2d67b97f587152b5457ed89f7430a77 (patch) | |
tree | 89d5995e3be5ea937d327f1ecb44113e655edaab /firmware/2lib | |
parent | 02e11b323b819140590d99b6af440d36c12d161b (diff) | |
download | vboot_reference-59c29202d2d67b97f587152b5457ed89f7430a77.tar.gz |
vboot2: Add host library functions to read/write new-format key objects
And unit tests for them.
BUG=chromium:423882
BRANCH=none
TEST=make runtests && VBOOT2=1 make runtests
Change-Id: I720bfb2537bae60f05b5ce28ab196a331a82eedf
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/230931
Diffstat (limited to 'firmware/2lib')
-rw-r--r-- | firmware/2lib/2packed_key2.c | 57 | ||||
-rw-r--r-- | firmware/2lib/include/2common.h | 14 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 77 | ||||
-rw-r--r-- | firmware/2lib/include/2struct.h | 52 |
4 files changed, 172 insertions, 28 deletions
diff --git a/firmware/2lib/2packed_key2.c b/firmware/2lib/2packed_key2.c index c009c2b1..91000dfb 100644 --- a/firmware/2lib/2packed_key2.c +++ b/firmware/2lib/2packed_key2.c @@ -9,9 +9,36 @@ #include "2common.h" #include "2rsa.h" -const uint8_t *vb2_packed_key2_data(const struct vb2_packed_key2 *key) +int vb2_unpack_key2_data(struct vb2_public_key *key, + const uint8_t *key_data, + uint32_t key_size) { - return (const uint8_t *)key + key->key_offset; + const uint32_t *buf32 = (const uint32_t *)key_data; + uint32_t expected_key_size = vb2_packed_key_size(key->sig_alg); + + /* Make sure buffer is the correct length */ + if (!expected_key_size || expected_key_size != key_size) { + VB2_DEBUG("Wrong key size for algorithm\n"); + return VB2_ERROR_UNPACK_KEY_SIZE; + } + + /* Check for alignment */ + if (!vb2_aligned(buf32, sizeof(uint32_t))) + return VB2_ERROR_UNPACK_KEY_ALIGN; + + key->arrsize = buf32[0]; + + /* Sanity check key array size */ + if (key->arrsize * sizeof(uint32_t) != vb2_rsa_sig_size(key->sig_alg)) + return VB2_ERROR_UNPACK_KEY_ARRAY_SIZE; + + key->n0inv = buf32[1]; + + /* Arrays point inside the key data */ + key->n = buf32 + 2; + key->rr = buf32 + 2 + key->arrsize; + + return VB2_SUCCESS; } int vb2_unpack_key2(struct vb2_public_key *key, @@ -20,8 +47,6 @@ int vb2_unpack_key2(struct vb2_public_key *key, { const struct vb2_packed_key2 *pkey = (const struct vb2_packed_key2 *)buf; - const uint32_t *buf32; - uint32_t expected_key_size; uint32_t sig_size; uint32_t min_offset = 0; int rv; @@ -65,25 +90,11 @@ int vb2_unpack_key2(struct vb2_public_key *key, if (!vb2_digest_size(key->hash_alg)) return VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM; - expected_key_size = vb2_packed_key_size(key->sig_alg); - if (!expected_key_size || expected_key_size != pkey->key_size) { - VB2_DEBUG("Wrong key size for algorithm\n"); - return VB2_ERROR_UNPACK_KEY_SIZE; - } - - /* Unpack key data */ - buf32 = (const uint32_t *)vb2_packed_key2_data(pkey); - - /* Sanity check key array size */ - key->arrsize = buf32[0]; - if (key->arrsize * sizeof(uint32_t) != sig_size) - return VB2_ERROR_UNPACK_KEY_ARRAY_SIZE; - - key->n0inv = buf32[1]; - - /* Arrays point inside the key data */ - key->n = buf32 + 2; - key->rr = buf32 + 2 + key->arrsize; + 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) diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h index d26ccfce..a0c82d3c 100644 --- a/firmware/2lib/include/2common.h +++ b/firmware/2lib/include/2common.h @@ -289,6 +289,20 @@ int vb2_unpack_key2(struct vb2_public_key *key, uint32_t size); /** + * Unpack the RSA data fields for a public key + * + * This is called by vb2_unpack_key2() to extract the arrays from a packed key. + * These elements of *key will point inside the key_data buffer. + * + * @param key Destination key for RSA data fields + * @param key_data Packed key data (from inside a packed key buffer) + * @param key_size Size of packed key data in bytes + */ +int vb2_unpack_key2_data(struct vb2_public_key *key, + const uint8_t *key_data, + uint32_t key_size); + +/** * Return expected signature size for a signature/hash algorithm pair * * @param sig_alg Signature algorithm diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index 69a9494f..deae9140 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -473,6 +473,83 @@ enum vb2_return_code { VB2_ERROR_WRITE_FILE_DATA, /********************************************************************** + * Errors generated by host library key functions + */ + VB2_ERROR_HOST_KEY = VB2_ERROR_HOST_BASE + 0x020000, + + /* Unable to allocate key in vb2_private_key_read_pem() */ + VB2_ERROR_READ_PEM_ALLOC, + + /* Unable to open .pem file in vb2_private_key_read_pem() */ + VB2_ERROR_READ_PEM_FILE_OPEN, + + /* Bad RSA data from .pem file in vb2_private_key_read_pem() */ + VB2_ERROR_READ_PEM_RSA, + + /* Unable to set private key description */ + VB2_ERROR_PRIVATE_KEY_SET_DESC, + + /* Bad magic number in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_MAGIC, + + /* Bad common header in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_HEADER, + + /* Bad key data in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_DATA, + + /* Bad struct version in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_STRUCT_VERSION, + + /* Unable to allocate buffer in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_ALLOC, + + /* Unable to unpack RSA key in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_RSA, + + /* Unable to set description in vb2_private_key_unpack() */ + VB2_ERROR_UNPACK_PRIVATE_KEY_DESC, + + /* Unable to create RSA data in vb2_private_key_write() */ + VB2_ERROR_PRIVATE_KEY_WRITE_RSA, + + /* Unable to allocate packed key buffer in vb2_private_key_write() */ + VB2_ERROR_PRIVATE_KEY_WRITE_ALLOC, + + /* Unable to write file in vb2_private_key_write() */ + VB2_ERROR_PRIVATE_KEY_WRITE_FILE, + + /* Unable to determine key size in vb2_public_key_alloc() */ + VB2_ERROR_PUBLIC_KEY_ALLOC_SIZE, + + /* Unable to allocate buffer in vb2_public_key_alloc() */ + VB2_ERROR_PUBLIC_KEY_ALLOC, + + /* Unable to set public key description */ + VB2_ERROR_PUBLIC_KEY_SET_DESC, + + /* Unable to read key data in vb2_public_key_read_keyb() */ + VB2_ERROR_READ_KEYB_DATA, + + /* Wrong amount of data read in vb2_public_key_read_keyb() */ + VB2_ERROR_READ_KEYB_SIZE, + + /* Unable to allocate key buffer in vb2_public_key_read_keyb() */ + VB2_ERROR_READ_KEYB_ALLOC, + + /* Error unpacking RSA arrays in vb2_public_key_read_keyb() */ + VB2_ERROR_READ_KEYB_UNPACK, + + /* Unable to read key data in vb2_packed_key_read() */ + VB2_ERROR_READ_PACKED_KEY_DATA, + + /* Bad key data in vb2_packed_key_read() */ + VB2_ERROR_READ_PACKED_KEY, + + /* Unable to determine key size in vb2_public_key_pack() */ + VB2_ERROR_PUBLIC_KEY_PACK_SIZE, + + /********************************************************************** * Highest non-zero error generated inside vboot library. Note that * error codes passed through vboot when it calls external APIs may * still be outside this range. diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h index dd956219..e4aaf607 100644 --- a/firmware/2lib/include/2struct.h +++ b/firmware/2lib/include/2struct.h @@ -208,19 +208,22 @@ struct vb2_fw_preamble { */ enum vb2_struct_common_magic { /* "Vb2B" = vb2_keyblock2.c.magic */ - VB2_MAGIC_KEYBLOCK2 = 0x42326256, + VB2_MAGIC_KEYBLOCK2 = 0x42326256, /* "Vb2F" = vb2_fw_preamble.c.magic */ - VB2_MAGIC_FW_PREAMBLE2 = 0x46326256, + VB2_MAGIC_FW_PREAMBLE2 = 0x46326256, + + /* "Vb2I" = vb2_packed_private_key2.c.magic */ + VB2_MAGIC_PACKED_PRIVATE_KEY2 = 0x49326256, /* "Vb2K" = vb2_kernel_preamble.c.magic */ - VB2_MAGIC_KERNEL_PREAMBLE2 = 0x4b326256, + VB2_MAGIC_KERNEL_PREAMBLE2 = 0x4b326256, /* "Vb2P" = vb2_packed_key2.c.magic */ - VB2_MAGIC_PACKED_KEY2 = 0x50326256, + VB2_MAGIC_PACKED_KEY2 = 0x50326256, /* "Vb2S" = vb2_signature.c.magic */ - VB2_MAGIC_SIGNATURE2 = 0x53326256, + VB2_MAGIC_SIGNATURE2 = 0x53326256, }; @@ -356,6 +359,45 @@ struct vb2_packed_key2 { #define EXPECTED_VB2_PACKED_KEY2_SIZE \ (EXPECTED_VB2_STRUCT_COMMON_SIZE + EXPECTED_GUID_SIZE + 16) +/* Current version of vb2_packed_private_key2 struct */ +#define VB2_PACKED_PRIVATE_KEY2_VERSION_MAJOR 3 +#define VB2_PACKED_PRIVATE_KEY2_VERSION_MINOR 0 + +/* + * Packed private key data, version 2 + * + * The key data must be arranged like this: + * 1) vb2_packed_private_key2 header struct h + * 2) Key description (pointed to by h.c.fixed_size) + * 3) Key data key (pointed to by h.key_offset) + */ +struct vb2_packed_private_key2 { + /* Common header fields */ + struct vb2_struct_common c; + + /* Offset of key data from start of this struct */ + uint32_t key_offset; + + /* Size of key data in bytes (NOT strength of key in bits) */ + uint32_t key_size; + + /* Signature algorithm used by the key (enum vb2_signature_algorithm) */ + uint16_t sig_alg; + + /* + * Hash digest algorithm used with the key (enum vb2_hash_algorithm). + * This is explicitly specified as part of the key to prevent use of a + * strong key with a weak hash. + */ + uint16_t hash_alg; + + /* Key GUID */ + struct vb2_guid guid; +} __attribute__((packed)); + +#define EXPECTED_VB2_PACKED_PRIVATE_KEY2_SIZE \ + (EXPECTED_VB2_STRUCT_COMMON_SIZE + EXPECTED_GUID_SIZE + 12) + /* Current version of vb2_signature2 struct */ #define VB2_SIGNATURE2_VERSION_MAJOR 3 #define VB2_SIGNATURE2_VERSION_MINOR 0 |