summaryrefslogtreecommitdiff
path: root/verity
diff options
context:
space:
mode:
authorTao Bao <tbao@google.com>2016-10-19 14:59:31 -0700
committerTao Bao <tbao@google.com>2016-10-19 15:26:38 -0700
commit2a75a61e2aeb241b6bd75e4d3c648f98cfc4d3be (patch)
tree0d94c7c83216bc960dd7017dab99e4656f5eb110 /verity
parent4ab6af6787d7826e8c43282b5ad78b80b172d107 (diff)
downloadextras-2a75a61e2aeb241b6bd75e4d3c648f98cfc4d3be.tar.gz
Support verifying the boot signature against the given pubkey.
verify_boot_signature currently verifies the signature in the boot image (against the certificate embedded in the image). This CL supports additionally verifying the signature against the given OEM pubkey (a fixed, tamper-protected key available to the bootloader). Usage: verify_boot_signature <path-to-boot-image> verify_boot_signature <path-to-boot-image> <pubkey> - Locally built boot image is signed with the default key. $ openssl x509 -pubkey -noout -in build/target/product/security/verity.x509.pem > pubkey.pem $ verify_boot_signature $OUT/boot.img pubkey.pem; echo $? Signature is VALID 0 - Signed boot image should be verified with the OEM pubkey. $ verify_boot_signature boot.img bullhead_pub.pem; echo $? Signature is VALID 0 - Locally built boot image can be verified with its embedded certificate but not with the OEM pubkey. This will lead to the YELLOW boot state. $ verify_boot_signature $OUT/boot.img; echo $? Signature is VALID 0 $ verify_boot_signature $OUT/boot.img bullhead_pub.pem; echo $? <...> 1 Bug: 32173582 Test: See above. Change-Id: I11043eb796ccd128885e7412e65981cbd0183fb2
Diffstat (limited to 'verity')
-rw-r--r--verity/verify_boot_signature.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/verity/verify_boot_signature.c b/verity/verify_boot_signature.c
index b706e3ad..36760ad7 100644
--- a/verity/verify_boot_signature.c
+++ b/verity/verify_boot_signature.c
@@ -32,6 +32,7 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
+#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
@@ -305,16 +306,21 @@ hi_done:
}
/**
- * Verifies the RSA signature
+ * Verifies the RSA signature against the pubkey (certificate) in the
+ * BootSignature, and additionally against the pubkey file if provided.
* @param fd File descriptor to the boot image
* @param length Length of the boot image without the signature block
* @param bs The boot signature block
+ * @param pkey The external pubkey file
*/
-static int verify_signature(int fd, uint64_t length, const BootSignature *bs)
+static int verify_signature(int fd, uint64_t length, const BootSignature *bs,
+ const char *pkey)
{
int rc = -1;
- EVP_PKEY *pkey = NULL;
- RSA *rsa = NULL;
+ EVP_PKEY *pkey_bs = NULL;
+ RSA *rsa_bs = NULL;
+ RSA *rsa_pkey = NULL;
+ BIO *bio_pkey = NULL;
unsigned char digest[SHA256_DIGEST_LENGTH];
if (!bs) {
@@ -325,31 +331,57 @@ static int verify_signature(int fd, uint64_t length, const BootSignature *bs)
goto vs_done;
}
- if ((pkey = X509_get_pubkey(bs->certificate)) == NULL) {
+ if ((pkey_bs = X509_get_pubkey(bs->certificate)) == NULL) {
ERR_print_errors(g_error);
goto vs_done;
}
- if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) {
+ if ((rsa_bs = EVP_PKEY_get1_RSA(pkey_bs)) == NULL) {
ERR_print_errors(g_error);
goto vs_done;
}
if (!RSA_verify(NID_sha256, digest, SHA256_DIGEST_LENGTH,
- bs->signature->data, bs->signature->length, rsa)) {
+ bs->signature->data, bs->signature->length, rsa_bs)) {
ERR_print_errors(g_error);
goto vs_done;
}
+ if (pkey) {
+ if ((bio_pkey = BIO_new_file(pkey, "r")) == NULL) {
+ ERR_print_errors(g_error);
+ goto vs_done;
+ }
+
+ if ((rsa_pkey = PEM_read_bio_RSA_PUBKEY(bio_pkey, NULL, NULL, NULL)) == NULL) {
+ ERR_print_errors(g_error);
+ goto vs_done;
+ }
+
+ if (!RSA_verify(NID_sha256, digest, SHA256_DIGEST_LENGTH,
+ bs->signature->data, bs->signature->length, rsa_pkey)) {
+ ERR_print_errors(g_error);
+ goto vs_done;
+ }
+ }
+
rc = 0;
vs_done:
- if (pkey) {
- EVP_PKEY_free(pkey);
+ if (pkey_bs) {
+ EVP_PKEY_free(pkey_bs);
+ }
+
+ if (rsa_bs) {
+ RSA_free(rsa_bs);
}
- if (rsa) {
- RSA_free(rsa);
+ if (bio_pkey) {
+ BIO_free_all(bio_pkey);
+ }
+
+ if (rsa_pkey) {
+ RSA_free(rsa_pkey);
}
return rc;
@@ -359,7 +391,7 @@ vs_done:
* Given the file name of a signed boot image, verifies the signature
* @param image_file Name of the boot image file
*/
-static int verify(const char *image_file)
+static int verify(const char *image_file, const char *pkey)
{
BootSignature *bs = NULL;
int fd = -1;
@@ -386,7 +418,7 @@ static int verify(const char *image_file)
goto out;
}
- if (verify_signature(fd, offset, bs) == -1) {
+ if (verify_signature(fd, offset, bs, pkey) == -1) {
goto out;
}
@@ -407,12 +439,13 @@ out:
static void usage()
{
- printf("Usage: verify_boot_signature <path-to-boot-image>\n");
+ printf("Usage: verify_boot_signature <path-to-boot-image>\n"
+ " verify_boot_signature <path-to-boot-image> <pubkey>\n");
}
int main(int argc, char *argv[])
{
- if (argc != 2) {
+ if (argc != 2 && argc != 3) {
usage();
return 1;
}
@@ -425,5 +458,7 @@ int main(int argc, char *argv[])
ERR_load_crypto_strings();
- return verify(argv[1]);
+ const char *pkey = (argc == 2) ? NULL : argv[2];
+
+ return verify(argv[1], pkey);
}