VBoot Reference: Fix splicing bugs in Firmware and Kernel verification.
BUG=670
TESTS=Adds new tests which verify this doesn't occur anymore. Existing tests still pass.
The existing code computes and verifies signatures on firmware/kernel data and firmware/kernel versions separately. This causes a image splicing bug where it is possible to combine together a version signature from a valid new firmware with firmware data and signature from an older version. The same problem exists with kernel verification.
This CL fixes this by changing the firmware/kernel signatures to also include the version information.
For the Firmware, there's a separate signature on the preamble (which contains the version) but the firmware signature now also includes this preamble in addition to the firmware data.
For the Kernel, there's a separate signature on the kernel config/options (wich also contains the version), but the kernel signature now also includes these config/options in addition to the kernel data.
Review URL: http://codereview.chromium.org/1430001
diff --git a/crypto/rsa_utility.c b/crypto/rsa_utility.c
index 9b419d0..3559dfd 100644
--- a/crypto/rsa_utility.c
+++ b/crypto/rsa_utility.c
@@ -100,3 +100,34 @@
RSAPublicKeyFree(verification_key); /* Only free if we allocated it. */
return success;
}
+
+/* Version of RSAVerifyBinary_f() where instead of the raw binary blob
+ * of data, its digest is passed as the argument. */
+int RSAVerifyBinaryWithDigest_f(const uint8_t* key_blob,
+ const RSAPublicKey* key,
+ const uint8_t* digest,
+ const uint8_t* sig,
+ int algorithm) {
+ RSAPublicKey* verification_key = NULL;
+ int key_size;
+ int sig_size;
+ int success;
+
+ if (algorithm >= kNumAlgorithms)
+ return 0; /* Invalid algorithm. */
+ key_size = RSAProcessedKeySize(algorithm);
+ sig_size = siglen_map[algorithm];
+
+ if (key_blob && !key)
+ verification_key = RSAPublicKeyFromBuf(key_blob, key_size);
+ else if (!key_blob && key)
+ verification_key = (RSAPublicKey*) key; /* Supress const warning. */
+ else
+ return 0; /* Both can't be NULL or non-NULL. */
+
+ success = RSAVerify(verification_key, sig, sig_size, algorithm, digest);
+
+ if (!key)
+ RSAPublicKeyFree(verification_key); /* Only free if we allocated it. */
+ return success;
+}