diff options
author | Bill Richardson <wfrichar@chromium.org> | 2012-05-03 08:40:44 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-05-04 12:16:45 -0700 |
commit | 2448d3b3bc8e80232e7943c16b41eaab19faa1a2 (patch) | |
tree | 602ed9451ec91f58fd60ab055ab9f531f50a921e /firmware/lib/vboot_common.c | |
parent | f47291926afce3235421f73811a04324195f3e13 (diff) | |
download | vboot-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.c | 78 |
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) { |