summaryrefslogtreecommitdiff
path: root/firmware/lib/vboot_common.c
diff options
context:
space:
mode:
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) {