aboutsummaryrefslogtreecommitdiff
path: root/firmware/2lib
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-11-01 17:56:46 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-11-05 06:05:19 +0000
commitb885c3bd3d35284af81a83c3f23be4f02ddfbf47 (patch)
tree2118bd4c032baefe36446ea59fa02f767ea28d4d /firmware/2lib
parentc0ce70b468cc469556d0f43c63a6d63ec8280c99 (diff)
downloadvboot_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.c120
-rw-r--r--firmware/2lib/include/2common.h39
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