diff options
Diffstat (limited to 'host/lib21')
-rw-r--r-- | host/lib21/host_common.c | 303 | ||||
-rw-r--r-- | host/lib21/host_key.c | 61 | ||||
-rw-r--r-- | host/lib21/host_misc.c | 4 | ||||
-rw-r--r-- | host/lib21/host_signature.c | 6 | ||||
-rw-r--r-- | host/lib21/include/host_common21.h | 124 | ||||
-rw-r--r-- | host/lib21/include/host_key21.h (renamed from host/lib21/include/host_key2.h) | 14 | ||||
-rw-r--r-- | host/lib21/include/host_misc21.h (renamed from host/lib21/include/host_misc2.h) | 0 | ||||
-rw-r--r-- | host/lib21/include/host_signature21.h (renamed from host/lib21/include/host_signature2.h) | 0 | ||||
-rw-r--r-- | host/lib21/include/host_struct21.h | 233 |
9 files changed, 738 insertions, 7 deletions
diff --git a/host/lib21/host_common.c b/host/lib21/host_common.c new file mode 100644 index 00000000..245b1885 --- /dev/null +++ b/host/lib21/host_common.c @@ -0,0 +1,303 @@ +/* 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. + * + * Signature validation functions + */ + +#include "2common.h" +#include "2rsa.h" +#include "2sha.h" +#include "2sysincludes.h" +#include "host_common21.h" + +const char *vb21_common_desc(const void *buf) +{ + const struct vb21_struct_common *c = buf; + + return c->desc_size ? (const char *)c + c->fixed_size : ""; +} + +vb2_error_t vb21_verify_common_header(const void *parent, uint32_t parent_size) +{ + const struct vb21_struct_common *c = parent; + + /* Parent buffer size must be at least the claimed total size */ + if (parent_size < c->total_size) + return VB2_ERROR_COMMON_TOTAL_SIZE; + + /* + * And big enough for the fixed size, which itself must be at least as + * big as the common struct header. + */ + if (c->total_size < c->fixed_size || c->fixed_size < sizeof(*c)) + return VB2_ERROR_COMMON_FIXED_SIZE; + + /* Make sure sizes are all multiples of 32 bits */ + if (!vb2_aligned(c->total_size, sizeof(uint32_t))) + return VB2_ERROR_COMMON_TOTAL_UNALIGNED; + if (!vb2_aligned(c->fixed_size, sizeof(uint32_t))) + return VB2_ERROR_COMMON_FIXED_UNALIGNED; + if (!vb2_aligned(c->desc_size, sizeof(uint32_t))) + return VB2_ERROR_COMMON_DESC_UNALIGNED; + + /* Check description */ + if (c->desc_size > 0) { + /* Make sure description fits and doesn't wrap */ + if (c->fixed_size + c->desc_size < c->fixed_size) + return VB2_ERROR_COMMON_DESC_WRAPS; + if (c->fixed_size + c->desc_size > c->total_size) + return VB2_ERROR_COMMON_DESC_SIZE; + + /* Description must be null-terminated */ + if (vb21_common_desc(c)[c->desc_size - 1] != 0) + return VB2_ERROR_COMMON_DESC_TERMINATOR; + } + + return VB2_SUCCESS; +} + +vb2_error_t vb21_verify_common_member(const void *parent, uint32_t *min_offset, + uint32_t member_offset, + uint32_t member_size) +{ + const struct vb21_struct_common *c = parent; + uint32_t member_end = member_offset + member_size; + + /* Make sure member doesn't wrap */ + if (member_end < member_offset) + return VB2_ERROR_COMMON_MEMBER_WRAPS; + + /* Member offset and size must be 32-bit aligned */ + if (!vb2_aligned(member_offset, sizeof(uint32_t)) || + !vb2_aligned(member_size, sizeof(uint32_t))) + return VB2_ERROR_COMMON_MEMBER_UNALIGNED; + + /* Initialize minimum offset if necessary */ + if (!*min_offset) + *min_offset = c->fixed_size + c->desc_size; + + /* Member must be after minimum offset */ + if (member_offset < *min_offset) + return VB2_ERROR_COMMON_MEMBER_OVERLAP; + + /* Member must end before total size */ + if (member_end > c->total_size) + return VB2_ERROR_COMMON_MEMBER_SIZE; + + /* Update minimum offset for subsequent checks */ + *min_offset = member_end; + + return VB2_SUCCESS; +} + +vb2_error_t vb21_verify_common_subobject(const void *parent, + uint32_t *min_offset, + uint32_t member_offset) +{ + const struct vb21_struct_common *p = parent; + const struct vb21_struct_common *m = + (const struct vb21_struct_common *) + ((const uint8_t *)parent + member_offset); + vb2_error_t rv; + + /* + * Verify the parent has space at the member offset for the common + * header. + */ + rv = vb21_verify_common_member(parent, min_offset, member_offset, + sizeof(*m)); + if (rv) + return rv; + + /* + * Now it's safe to look at the member's header, and verify any + * additional data for the object past its common header fits in the + * parent. + */ + rv = vb21_verify_common_header(m, p->total_size - member_offset); + if (rv) + return rv; + + /* Advance the min offset to the end of the subobject */ + *min_offset = member_offset + m->total_size; + + return VB2_SUCCESS; +} + +uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg, + enum vb2_hash_algorithm hash_alg) +{ + uint32_t digest_size = vb2_digest_size(hash_alg); + + /* Fail if we don't support the hash algorithm */ + if (!digest_size) + return 0; + + /* Handle unsigned hashes */ + if (sig_alg == VB2_SIG_NONE) + return digest_size; + + return vb2_rsa_sig_size(sig_alg); +} + +const struct vb2_id *vb2_hash_id(enum vb2_hash_algorithm hash_alg) +{ + switch(hash_alg) { +#ifdef VB2_SUPPORT_SHA1 + case VB2_HASH_SHA1: + { + static const struct vb2_id id = VB2_ID_NONE_SHA1; + return &id; + } +#endif +#ifdef VB2_SUPPORT_SHA256 + case VB2_HASH_SHA256: + { + static const struct vb2_id id = VB2_ID_NONE_SHA256; + return &id; + } +#endif +#ifdef VB2_SUPPORT_SHA512 + case VB2_HASH_SHA512: + { + static const struct vb2_id id = VB2_ID_NONE_SHA512; + return &id; + } +#endif + default: + return NULL; + } +} + +vb2_error_t vb21_verify_signature(const struct vb21_signature *sig, + uint32_t size) +{ + uint32_t min_offset = 0; + uint32_t expect_sig_size; + vb2_error_t rv; + + /* Check magic number */ + if (sig->c.magic != VB21_MAGIC_SIGNATURE) + return VB2_ERROR_SIG_MAGIC; + + /* Make sure common header is good */ + rv = vb21_verify_common_header(sig, size); + if (rv) + return rv; + + /* + * Check for compatible version. No need to check minor version, since + * that's compatible across readers matching the major version, and we + * haven't added any new fields. + */ + if (sig->c.struct_version_major != VB21_SIGNATURE_VERSION_MAJOR) + return VB2_ERROR_SIG_VERSION; + + /* Make sure header is big enough for signature */ + if (sig->c.fixed_size < sizeof(*sig)) + return VB2_ERROR_SIG_HEADER_SIZE; + + /* Make sure signature data is inside */ + rv = vb21_verify_common_member(sig, &min_offset, + sig->sig_offset, sig->sig_size); + if (rv) + return rv; + + /* Make sure signature size is correct for the algorithm */ + expect_sig_size = vb2_sig_size(sig->sig_alg, sig->hash_alg); + if (!expect_sig_size) + return VB2_ERROR_SIG_ALGORITHM; + if (sig->sig_size != expect_sig_size) + return VB2_ERROR_SIG_SIZE; + + return VB2_SUCCESS; +} + +/** + * Return the signature data for a signature + */ +static uint8_t *vb21_signature_data(struct vb21_signature *sig) +{ + return (uint8_t *)sig + sig->sig_offset; +} + +vb2_error_t vb21_verify_digest(const struct vb2_public_key *key, + struct vb21_signature *sig, + const uint8_t *digest, + const struct vb2_workbuf *wb) +{ + uint32_t key_sig_size = vb2_sig_size(key->sig_alg, key->hash_alg); + + /* If we can't figure out the signature size, key algorithm was bad */ + if (!key_sig_size) + return VB2_ERROR_VDATA_ALGORITHM; + + /* Make sure the signature and key algorithms match */ + if (key->sig_alg != sig->sig_alg || key->hash_alg != sig->hash_alg) + return VB2_ERROR_VDATA_ALGORITHM_MISMATCH; + + if (sig->sig_size != key_sig_size) + return VB2_ERROR_VDATA_SIG_SIZE; + + if (key->sig_alg == VB2_SIG_NONE) { + /* Bare hash */ + if (vb2_safe_memcmp(vb21_signature_data(sig), + digest, key_sig_size)) + return VB2_ERROR_VDATA_VERIFY_DIGEST; + + return VB2_SUCCESS; + } else { + /* RSA-signed digest */ + return vb2_rsa_verify_digest(key, + vb21_signature_data(sig), + digest, wb); + } +} + +vb2_error_t vb21_verify_data(const void *data, uint32_t size, + struct vb21_signature *sig, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb) +{ + struct vb2_workbuf wblocal = *wb; + struct vb2_digest_context *dc; + uint8_t *digest; + uint32_t digest_size; + vb2_error_t rv; + + if (sig->data_size != size) { + VB2_DEBUG("Wrong amount of data signed.\n"); + return VB2_ERROR_VDATA_SIZE; + } + + /* Digest goes at start of work buffer */ + digest_size = vb2_digest_size(key->hash_alg); + if (!digest_size) + return VB2_ERROR_VDATA_DIGEST_SIZE; + + digest = vb2_workbuf_alloc(&wblocal, digest_size); + if (!digest) + return VB2_ERROR_VDATA_WORKBUF_DIGEST; + + /* Hashing requires temp space for the context */ + dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc)); + if (!dc) + return VB2_ERROR_VDATA_WORKBUF_HASHING; + + rv = vb2_digest_init(dc, key->hash_alg); + if (rv) + return rv; + + rv = vb2_digest_extend(dc, data, size); + if (rv) + return rv; + + rv = vb2_digest_finalize(dc, digest, digest_size); + if (rv) + return rv; + + vb2_workbuf_free(&wblocal, sizeof(*dc)); + + return vb21_verify_digest(key, sig, digest, &wblocal); +} diff --git a/host/lib21/host_key.c b/host/lib21/host_key.c index 34e5a633..6e3a2765 100644 --- a/host/lib21/host_key.c +++ b/host/lib21/host_key.c @@ -14,10 +14,10 @@ #include "2sha.h" #include "2sysincludes.h" #include "host_common.h" -#include "host_key2.h" +#include "host_common21.h" +#include "host_key21.h" #include "host_misc.h" #include "openssl_compat.h" -#include "vb21_common.h" const struct vb2_text_vs_enum vb2_text_vs_sig[] = { {"RSA1024", VB2_SIG_RSA1024}, @@ -651,3 +651,60 @@ vb2_error_t vb21_public_key_write(const struct vb2_public_key *key, free(pkey); return ret; } + +vb2_error_t vb21_unpack_key(struct vb2_public_key *key, const uint8_t *buf, + uint32_t size) +{ + const struct vb21_packed_key *pkey = + (const struct vb21_packed_key *)buf; + uint32_t sig_size; + uint32_t min_offset = 0; + vb2_error_t rv; + + /* Check magic number */ + if (pkey->c.magic != VB21_MAGIC_PACKED_KEY) + return VB2_ERROR_UNPACK_KEY_MAGIC; + + rv = vb21_verify_common_header(buf, size); + if (rv) + return rv; + + /* Make sure key data is inside */ + rv = vb21_verify_common_member(pkey, &min_offset, + pkey->key_offset, pkey->key_size); + if (rv) + return rv; + + /* + * Check for compatible version. No need to check minor version, since + * that's compatible across readers matching the major version, and we + * haven't added any new fields. + */ + if (pkey->c.struct_version_major != VB21_PACKED_KEY_VERSION_MAJOR) + return VB2_ERROR_UNPACK_KEY_STRUCT_VERSION; + + /* Copy key algorithms */ + key->hash_alg = pkey->hash_alg; + if (!vb2_digest_size(key->hash_alg)) + return VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM; + + 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_key_data( + key, + (const uint8_t *)pkey + pkey->key_offset, + pkey->key_size); + if (rv) + return rv; + } + + /* Key description */ + key->desc = vb21_common_desc(pkey); + key->version = pkey->key_version; + key->id = &pkey->id; + + return VB2_SUCCESS; +} diff --git a/host/lib21/host_misc.c b/host/lib21/host_misc.c index 71a77c5d..ebc4eac5 100644 --- a/host/lib21/host_misc.c +++ b/host/lib21/host_misc.c @@ -14,8 +14,8 @@ #include "2sha.h" #include "2sysincludes.h" #include "host_common.h" -#include "host_misc2.h" -#include "vb21_common.h" +#include "host_common21.h" +#include "host_misc21.h" vb2_error_t vb2_read_file(const char *filename, uint8_t **data_ptr, uint32_t *size_ptr) diff --git a/host/lib21/host_signature.c b/host/lib21/host_signature.c index e4dead01..77ee448a 100644 --- a/host/lib21/host_signature.c +++ b/host/lib21/host_signature.c @@ -12,10 +12,10 @@ #include "2sha.h" #include "2sysincludes.h" #include "host_common.h" -#include "host_key2.h" +#include "host_common21.h" +#include "host_key21.h" #include "host_misc.h" -#include "host_signature2.h" -#include "vb21_common.h" +#include "host_signature21.h" vb2_error_t vb2_digest_info(enum vb2_hash_algorithm hash_alg, const uint8_t **buf_ptr, uint32_t *size_ptr) diff --git a/host/lib21/include/host_common21.h b/host/lib21/include/host_common21.h new file mode 100644 index 00000000..fa8086b8 --- /dev/null +++ b/host/lib21/include/host_common21.h @@ -0,0 +1,124 @@ +/* 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. + * + * Common functions between firmware and kernel verified boot. + */ + +#ifndef VBOOT_REFERENCE_VB21_COMMON_H_ +#define VBOOT_REFERENCE_VB21_COMMON_H_ + +#include "2common.h" +#include "2return_codes.h" +#include "2struct.h" +#include "host_struct21.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Return the description of an object starting with a vb21_struct_common + * header. + * + * Does not sanity-check the buffer; merely returns the pointer. + * + * @param buf Pointer to common object + * @return A pointer to description or an empty string if none. + */ +const char *vb21_common_desc(const void *buf); + +/** + * Verify the common struct header is fully contained in its parent data + * + * Also verifies the description is either zero-length or null-terminated. + * + * @param parent Parent data + * @param parent_size Parent size in bytes + * @return VB2_SUCCESS, or non-zero if error. + */ +vb2_error_t vb21_verify_common_header(const void *parent, uint32_t parent_size); + +/** + * Verify a member is within the data for a parent object + * + * @param parent Parent data (starts with struct vb21_struct_common) + * @param min_offset Pointer to minimum offset where member can be located. + * If this offset is 0 on input, uses the size of the + * fixed header (and description, if any). This will be + * updated on return to the end of the passed member. On + * error, the value of min_offset is undefined. + * @param member_offset Offset of member data from start of parent, in bytes + * @param member_size Size of member data, in bytes + * @return VB2_SUCCESS, or non-zero if error. + */ +vb2_error_t vb21_verify_common_member(const void *parent, uint32_t *min_offset, + uint32_t member_offset, + uint32_t member_size); + +/** + * Verify a member which starts with a common header is within the parent + * + * This does not verify the contents of the member or its header, only that the + * member's claimed total size fits within the parent's claimed total size at + * the specified offset. + * + * @param parent Parent data (starts with struct vb21_struct_common) + * @param min_offset Pointer to minimum offset where member can be located. + * If this offset is 0 on input, uses the size of the + * fixed header (and description, if any). This will be + * updated on return to the end of the passed member. On + * error, the value of min_offset is undefined. + * @param member_offset Offset of member data from start of parent, in bytes. + * This should be the start of the common header of the + * member. + * @return VB2_SUCCESS, or non-zero if error. + */ +vb2_error_t vb21_verify_common_subobject(const void *parent, + uint32_t *min_offset, + uint32_t member_offset); + +/** + * Verify the integrity of a signature struct + * @param sig Signature struct + * @param size Size of buffer containing signature struct + * @return VB2_SUCCESS, or non-zero if error. + */ +vb2_error_t vb21_verify_signature(const struct vb21_signature *sig, + uint32_t size); + +/** + * Verify a signature against an expected hash digest. + * + * @param key Key to use in signature verification + * @param sig Signature to verify (may be destroyed in process) + * @param digest Digest of signed data + * @param wb Work buffer + * @return VB2_SUCCESS, or non-zero if error. + */ +vb2_error_t vb21_verify_digest(const struct vb2_public_key *key, + struct vb21_signature *sig, + const uint8_t *digest, + const struct vb2_workbuf *wb); + +/** + * Verify data matches signature. + * + * @param data Data to verify + * @param size Size of data buffer. Note that amount of data to + * actually validate is contained in sig->data_size. + * @param sig Signature of data (destroyed in process) + * @param key Key to use to validate signature + * @param wb Work buffer + * @return VB2_SUCCESS, or non-zero error code if error. + */ +vb2_error_t vb21_verify_data(const void *data, uint32_t size, + struct vb21_signature *sig, + const struct vb2_public_key *key, + const struct vb2_workbuf *wb); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* VBOOT_REFERENCE_VB21_COMMON_H_ */ diff --git a/host/lib21/include/host_key2.h b/host/lib21/include/host_key21.h index d8a90f5f..219e98ab 100644 --- a/host/lib21/include/host_key2.h +++ b/host/lib21/include/host_key21.h @@ -267,4 +267,18 @@ enum vb2_signature_algorithm vb2_rsa_sig_alg(struct rsa_st *rsa); vb2_error_t vb21_public_key_write(const struct vb2_public_key *key, const char *filename); +/** + * Unpack a key for use in verification + * + * The elements of the unpacked key will point into the source buffer, so don't + * free the source buffer until you're done with the key. + * + * @param key Destintion for unpacked key + * @param buf Source buffer containing packed key + * @param size Size of buffer in bytes + * @return VB2_SUCCESS, or non-zero error code if error. + */ +vb2_error_t vb21_unpack_key(struct vb2_public_key *key, const uint8_t *buf, + uint32_t size); + #endif /* VBOOT_REFERENCE_HOST_KEY2_H_ */ diff --git a/host/lib21/include/host_misc2.h b/host/lib21/include/host_misc21.h index 795ebb23..795ebb23 100644 --- a/host/lib21/include/host_misc2.h +++ b/host/lib21/include/host_misc21.h diff --git a/host/lib21/include/host_signature2.h b/host/lib21/include/host_signature21.h index 0b1784af..0b1784af 100644 --- a/host/lib21/include/host_signature2.h +++ b/host/lib21/include/host_signature21.h diff --git a/host/lib21/include/host_struct21.h b/host/lib21/include/host_struct21.h new file mode 100644 index 00000000..6f91e36c --- /dev/null +++ b/host/lib21/include/host_struct21.h @@ -0,0 +1,233 @@ +/* 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. + * + * Vboot 2.1 data structures + * + * Offsets should be padded to 32-bit boundaries, since some architectures + * have trouble with accessing unaligned integers. + */ + +#ifndef VBOOT_REFERENCE_VB21_STRUCT_H_ +#define VBOOT_REFERENCE_VB21_STRUCT_H_ + +#include "2id.h" +#include "2sysincludes.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Magic numbers used by vb21_struct_common.magic. + * + * All valid numbers should be listed here to avoid accidental overlap. + * Numbers start at a large value, so that previous parsers (which stored + * things like lengths and offsets at that field) will detect and reject new + * structs as invalid. + */ +enum vb21_struct_common_magic { + /* "Vb2I" = vb21_packed_private_key.c.magic */ + VB21_MAGIC_PACKED_PRIVATE_KEY = 0x49326256, + + /* "Vb2P" = vb21_packed_key.c.magic */ + VB21_MAGIC_PACKED_KEY = 0x50326256, + + /* "Vb2S" = vb21_signature.c.magic */ + VB21_MAGIC_SIGNATURE = 0x53326256, +}; + + +/* + * Generic struct header for all vboot2.1 structs. This makes it easy to + * automatically parse and identify vboot structs (e.g., in futility). This + * must be the first member of the parent vboot2.1 struct. + */ +struct vb21_struct_common { + /* Magic number; see vb21_struct_common_magic for expected values */ + uint32_t magic; + + /* + * Parent struct version; see each struct for the expected value. + * + * How to handle struct version mismatches, if the parser is version + * A.b and the data is version C.d: + * 1) If A.b == C.d, we're good. + * 2) If A != C, the data cannot be parsed at all. + * 3) If b < d, C.d is a newer version of data which is backwards- + * compatible to old parsers. We're good. + * 4) If b > d, C.d is an older version of data. The parser should + * use default values for fields added after version d. We're + * good. + * + * Struct versions start at 3.0, since the highest version of the old + * structures was 2.1. This way, there is no possibility of collision + * for old code which depends on the version number. + */ + uint16_t struct_version_major; + uint16_t struct_version_minor; + + /* + * Size of the parent structure and all its data, including the + * description and any necessary padding. That is, all data must lie + * in a contiguous region of <total_size> bytes starting at the first + * byte of this header. + */ + uint32_t total_size; + + /* + * Size of the fixed portion of the parent structure. If a description + * is present, it must start at this offset. + */ + uint32_t fixed_size; + + /* + * The object may contain an ASCII description following the fixed + * portion of the structure. If it is present, it must be + * null-terminated, and padded with 0 (null) bytes to a multiple of 32 + * bits. + * + * Size of ASCII description in bytes, counting null terminator and + * padding (if any). Set 0 if no description is present. If non-zero, + * there must be a null terminator (0) at offset (fixed_size + + * desc_size - 1). + */ + uint32_t desc_size; +} __attribute__((packed)); + +#define EXPECTED_VB21_STRUCT_COMMON_SIZE 20 + +/* Current version of vb21_packed_key struct */ +#define VB21_PACKED_KEY_VERSION_MAJOR 3 +#define VB21_PACKED_KEY_VERSION_MINOR 0 + +/* + * Packed public key data + * + * The key data must be arranged like this: + * 1) vb21_packed_key header struct h + * 2) Key description (pointed to by h.c.fixed_size) + * 3) Key data key (pointed to by h.key_offset) + */ +struct vb21_packed_key { + /* Common header fields */ + struct vb21_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 version */ + uint32_t key_version; + + /* Key ID */ + struct vb2_id id; +} __attribute__((packed)); + +#define EXPECTED_VB21_PACKED_KEY_SIZE \ + (EXPECTED_VB21_STRUCT_COMMON_SIZE + 16 + EXPECTED_ID_SIZE) + +/* Current version of vb21_packed_private_key struct */ +#define VB21_PACKED_PRIVATE_KEY_VERSION_MAJOR 3 +#define VB21_PACKED_PRIVATE_KEY_VERSION_MINOR 0 + +/* + * Packed private key data + * + * The key data must be arranged like this: + * 1) vb21_packed_private_key header struct h + * 2) Key description (pointed to by h.c.fixed_size) + * 3) Key data key (pointed to by h.key_offset) + */ +struct vb21_packed_private_key { + /* Common header fields */ + struct vb21_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 ID */ + struct vb2_id id; +} __attribute__((packed)); + +#define EXPECTED_VB21_PACKED_PRIVATE_KEY_SIZE \ + (EXPECTED_VB21_STRUCT_COMMON_SIZE + 12 + EXPECTED_ID_SIZE) + +/* Current version of vb21_signature struct */ +#define VB21_SIGNATURE_VERSION_MAJOR 3 +#define VB21_SIGNATURE_VERSION_MINOR 0 + +/* + * Signature data + * + * The signature data must be arranged like this: + * 1) vb21_signature header struct h + * 2) Signature description (pointed to by h.c.fixed_size) + * 3) Signature data (pointed to by h.sig_offset) + */ +struct vb21_signature { + /* Common header fields */ + struct vb21_struct_common c; + + /* Offset of signature data from start of this struct */ + uint32_t sig_offset; + + /* Size of signature data in bytes */ + uint32_t sig_size; + + /* Size of the data block which was signed in bytes */ + uint32_t data_size; + + /* Signature algorithm used (enum vb2_signature_algorithm) */ + uint16_t sig_alg; + + /* Hash digest algorithm used (enum vb2_hash_algorithm) */ + uint16_t hash_alg; + + /* + * ID for the signature. + * + * If this is a keyblock signature entry, this is the ID of the key + * used to generate this signature. This allows the firmware to + * quickly determine which signature block (if any) goes with the key + * being used by the firmware. + * + * If this is a preamble hash entry, this is the ID of the data type + * being hashed. There is no key ID, because sig_alg=VB2_ALG_NONE. + */ + struct vb2_id id; +} __attribute__((packed)); + +#define EXPECTED_VB21_SIGNATURE_SIZE \ + (EXPECTED_VB21_STRUCT_COMMON_SIZE + 16 + EXPECTED_ID_SIZE) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* VBOOT_REFERENCE_VB21_STRUCT_H_ */ |