summaryrefslogtreecommitdiff
path: root/firmware/lib/vboot_common.c
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2012-05-03 08:40:44 -0700
committerGerrit <chrome-bot@google.com>2012-05-04 12:16:45 -0700
commit2448d3b3bc8e80232e7943c16b41eaab19faa1a2 (patch)
tree602ed9451ec91f58fd60ab055ab9f531f50a921e /firmware/lib/vboot_common.c
parentf47291926afce3235421f73811a04324195f3e13 (diff)
downloadvboot-2448d3b3bc8e80232e7943c16b41eaab19faa1a2.tar.gz
Create vbutil_ec tool for signing EC firmware.
This just adds the vbutil_ec tool (and a simple test of the library functions related to it). BUG=chrome-os-partner:7459, chromium-os:27142 TEST=manual make make runtests Change-Id: I2a2c4e7cfb8ac6ce2229c5de4252a5cc89321fa5 Reviewed-on: https://gerrit.chromium.org/gerrit/21868 Commit-Ready: Bill Richardson <wfrichar@chromium.org> Tested-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Stefan Reinauer <reinauer@google.com> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'firmware/lib/vboot_common.c')
-rw-r--r--firmware/lib/vboot_common.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c
index 5622d13b..e074d617 100644
--- a/firmware/lib/vboot_common.c
+++ b/firmware/lib/vboot_common.c
@@ -173,6 +173,28 @@ int VerifyDigest(const uint8_t* digest, const VbSignature *sig,
}
+int EqualData(const uint8_t* data, uint64_t size, const VbSignature *hash,
+ const RSAPublicKey* key) {
+ uint8_t* digest = NULL;
+ int rv;
+
+ if (hash->sig_size != hash_size_map[key->algorithm]) {
+ VBDEBUG(("Wrong hash size for algorithm.\n"));
+ return 1;
+ }
+ if (hash->data_size > size) {
+ VBDEBUG(("Data buffer smaller than length of signed data.\n"));
+ return 1;
+ }
+
+ digest = DigestBuf(data, hash->data_size, key->algorithm);
+
+ rv = SafeMemcmp(digest, GetSignatureDataC(hash), hash->sig_size);
+ VbExFree(digest);
+ return rv;
+}
+
+
int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
const VbPublicKey *key, int hash_only) {
@@ -291,6 +313,62 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size,
}
+int VerifyECPreamble(const VbECPreambleHeader* preamble,
+ uint64_t size, const RSAPublicKey* key) {
+
+ const VbSignature* sig = &preamble->preamble_signature;
+
+ /* Sanity checks before attempting signature of data */
+ if(size < EXPECTED_VB_EC_PREAMBLE_HEADER1_0_SIZE) {
+ VBDEBUG(("Not enough data for EC preamble header.\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+ if (preamble->header_version_major !=
+ EC_PREAMBLE_HEADER_VERSION_MAJOR) {
+ VBDEBUG(("Incompatible EC preamble header version (%d, not %d).\n",
+ preamble->header_version_major,
+ EC_PREAMBLE_HEADER_VERSION_MAJOR));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+ if (size < preamble->preamble_size) {
+ VBDEBUG(("Not enough data for EC preamble.\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+
+ /* Check signature */
+ if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) {
+ VBDEBUG(("EC preamble signature off end of preamble\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+
+ /* Make sure advertised signature data sizes are sane. */
+ if (preamble->preamble_size < sig->data_size) {
+ VBDEBUG(("EC signature calculated past end of the block\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+
+ if (VerifyData((const uint8_t*)preamble, size, sig, key)) {
+ VBDEBUG(("EC preamble signature validation failed\n"));
+ return VBOOT_PREAMBLE_SIGNATURE;
+ }
+
+ /* Verify we signed enough data */
+ if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) {
+ VBDEBUG(("Didn't sign enough data\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+
+ /* Verify body digest is inside the signed data */
+ if (VerifySignatureInside(preamble, sig->data_size,
+ &preamble->body_digest)) {
+ VBDEBUG(("EC body digest off end of preamble\n"));
+ return VBOOT_PREAMBLE_INVALID;
+ }
+
+ /* Success */
+ return VBOOT_SUCCESS;
+}
+
int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble,
uint64_t size, const RSAPublicKey* key) {