diff options
author | Randall Spangler <rspangler@chromium.org> | 2014-11-01 17:56:46 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-05 06:05:19 +0000 |
commit | b885c3bd3d35284af81a83c3f23be4f02ddfbf47 (patch) | |
tree | 2118bd4c032baefe36446ea59fa02f767ea28d4d /firmware/2lib | |
parent | c0ce70b468cc469556d0f43c63a6d63ec8280c99 (diff) | |
download | vboot_reference-b885c3bd3d35284af81a83c3f23be4f02ddfbf47.tar.gz |
vboot2: add support for verify data / digest using new signature struct
This adds the vb2_signature2 equivalents of vb2_verify_digest() and
vb2_verify_data(), including support for bare hash signatures.
BUG=chromium:423882
BRANCH=none
TEST=VBOOT2=1 make runtests
Change-Id: I372c9e5f0be926a833e4ca8f84665cfb05907481
Reviewed-on: https://chromium-review.googlesource.com/226950
Tested-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'firmware/2lib')
-rw-r--r-- | firmware/2lib/2common2.c | 120 | ||||
-rw-r--r-- | firmware/2lib/include/2common.h | 39 |
2 files changed, 157 insertions, 2 deletions
diff --git a/firmware/2lib/2common2.c b/firmware/2lib/2common2.c index f35d575e..32d218d8 100644 --- a/firmware/2lib/2common2.c +++ b/firmware/2lib/2common2.c @@ -135,6 +135,37 @@ uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg, return vb2_rsa_sig_size(sig_alg); } +const struct vb2_guid *vb2_hash_guid(enum vb2_hash_algorithm hash_alg) +{ + switch(hash_alg) { +#ifdef VB2_SUPPORT_SHA1 + case VB2_HASH_SHA1: + { + static const struct vb2_guid guid = VB2_GUID_NONE_SHA1; + return &guid; + } +#endif +#ifdef VB2_SUPPORT_SHA256 + case VB2_HASH_SHA256: + { + static const struct vb2_guid guid = + VB2_GUID_NONE_SHA256; + return &guid; + } +#endif +#ifdef VB2_SUPPORT_SHA512 + case VB2_HASH_SHA512: + { + static const struct vb2_guid guid = + VB2_GUID_NONE_SHA512; + return &guid; + } +#endif + default: + return NULL; + } +} + int vb2_verify_signature2(const struct vb2_signature2 *sig, uint32_t size) { @@ -178,3 +209,92 @@ int vb2_verify_signature2(const struct vb2_signature2 *sig, return VB2_SUCCESS; } + +/** + * Return the signature data for a signature + */ +static uint8_t *vb2_signature2_data(struct vb2_signature2 *sig) +{ + return (uint8_t *)sig + sig->sig_offset; +} + +int vb2_verify_digest2(const struct vb2_public_key *key, + struct vb2_signature2 *sig, + const uint8_t *digest, + 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(vb2_signature2_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, + vb2_signature2_data(sig), + digest, wb); + } +} + +int vb2_verify_data2(const void *data, + uint32_t size, + struct vb2_signature2 *sig, + const struct vb2_public_key *key, + struct vb2_workbuf *wb) +{ + struct vb2_workbuf wblocal = *wb; + struct vb2_digest_context *dc; + uint8_t *digest; + uint32_t digest_size; + int 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 vb2_verify_digest2(key, sig, digest, &wblocal); +} diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h index 1c57d3fa..219a5f0f 100644 --- a/firmware/2lib/include/2common.h +++ b/firmware/2lib/include/2common.h @@ -292,6 +292,15 @@ uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg, enum vb2_hash_algorithm hash_alg); /** + * Return a key_guid for an unsigned hash algorithm. + * + * @param hash_alg Hash algorithm to return key for + * @return A pointer to the key_guid for that hash algorithm and + * sig_alg=VB2_SIG_NONE, or NULL if error. + */ +const struct vb2_guid *vb2_hash_guid(enum vb2_hash_algorithm hash_alg); + +/** * Verify the integrity of a signature struct * @param sig Signature struct * @param size Size of buffer containing signature struct @@ -300,7 +309,10 @@ uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg, int vb2_verify_signature2(const struct vb2_signature2 *sig, uint32_t size); -/* Size of work buffer sufficient for vb2_rsa_verify_digest() worst case */ +/* + * Size of work buffer sufficient for vb2_verify_digest() or + * vb2_verify_digest2() worst case. + */ #define VB2_VERIFY_DIGEST_WORKBUF_BYTES VB2_VERIFY_RSA_DIGEST_WORKBUF_BYTES /** @@ -317,7 +329,24 @@ int vb2_verify_digest(const struct vb2_public_key *key, const uint8_t *digest, struct vb2_workbuf *wb); -/* Size of work buffer sufficient for vb2_verify_data() worst case */ +/** + * 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. + */ +int vb2_verify_digest2(const struct vb2_public_key *key, + struct vb2_signature2 *sig, + const uint8_t *digest, + struct vb2_workbuf *wb); + +/* + * Size of work buffer sufficient for vb2_verify_data() or vb2_verify_data2() + * worst case. + */ #define VB2_VERIFY_DATA_WORKBUF_BYTES \ (VB2_SHA512_DIGEST_SIZE + \ VB2_MAX(VB2_VERIFY_DIGEST_WORKBUF_BYTES, \ @@ -340,6 +369,12 @@ int vb2_verify_data(const uint8_t *data, const struct vb2_public_key *key, struct vb2_workbuf *wb); +int vb2_verify_data2(const void *data, + uint32_t size, + struct vb2_signature2 *sig, + const struct vb2_public_key *key, + struct vb2_workbuf *wb); + /* Size of work buffer sufficient for vb2_verify_keyblock() worst case */ #define VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES |