diff options
author | Randall Spangler <rspangler@chromium.org> | 2016-06-22 16:46:23 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-10 15:30:35 -0700 |
commit | d46461cec2aa7547b3722623b85dcfb2f298f859 (patch) | |
tree | 11b05a5b426a2608d38ae19d28a0e9af70b9ec64 /host | |
parent | 939cc3a5c25a3333fadafc7fc341d7e320f72fab (diff) | |
download | vboot-d46461cec2aa7547b3722623b85dcfb2f298f859.tar.gz |
futility: Use vboot 2.0 APIs for private keys
This replaces calls to the vboot 1 host library with their vboot 2.0
equivalents.
BUG=chromium:611535
BRANCH=none
TEST=make runtests
Change-Id: Id061554fd82ea3efe35d0fe1485693b47599a863
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/356540
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/host_common.c | 20 | ||||
-rw-r--r-- | host/lib/host_key.c | 124 | ||||
-rw-r--r-- | host/lib/host_key2.c | 67 | ||||
-rw-r--r-- | host/lib/host_signature.c | 56 | ||||
-rw-r--r-- | host/lib/include/host_common.h | 2 | ||||
-rw-r--r-- | host/lib/include/host_key.h | 62 | ||||
-rw-r--r-- | host/lib/include/host_signature.h | 17 | ||||
-rw-r--r-- | host/lib21/include/host_key2.h | 1 | ||||
-rw-r--r-- | host/linktest/main.c | 3 |
9 files changed, 128 insertions, 224 deletions
diff --git a/host/lib/host_common.c b/host/lib/host_common.c index a666e809..a8c1d977 100644 --- a/host/lib/host_common.c +++ b/host/lib/host_common.c @@ -9,7 +9,11 @@ #include <string.h> +#include "2sysincludes.h" +#include "2common.h" +#include "2rsa.h" #include "host_common.h" +#include "host_key2.h" #include "cryptolib.h" #include "utility.h" #include "vboot_common.h" @@ -24,26 +28,25 @@ VbKernelPreambleHeader *CreateKernelPreamble( uint64_t vmlinuz_header_size, uint32_t flags, uint64_t desired_size, - const VbPrivateKey *signing_key) + const struct vb2_private_key *signing_key) { VbKernelPreambleHeader *h; uint64_t signed_size = (sizeof(VbKernelPreambleHeader) + body_signature->sig_size); - uint64_t block_size = signed_size + siglen_map[signing_key->algorithm]; + uint32_t sig_size = vb2_rsa_sig_size(signing_key->sig_alg); + uint64_t block_size = signed_size + sig_size; uint8_t *body_sig_dest; uint8_t *block_sig_dest; - VbSignature *sigtmp; /* If the block size is smaller than the desired size, pad it */ if (block_size < desired_size) block_size = desired_size; /* Allocate key block */ - h = (VbKernelPreambleHeader *)malloc(block_size); + h = (VbKernelPreambleHeader *)calloc(block_size, 1); if (!h) return NULL; - Memset(h, 0, block_size); body_sig_dest = (uint8_t *)(h + 1); block_sig_dest = body_sig_dest + body_signature->sig_size; @@ -65,11 +68,12 @@ VbKernelPreambleHeader *CreateKernelPreamble( /* Set up signature struct so we can calculate the signature */ SignatureInit(&h->preamble_signature, block_sig_dest, - siglen_map[signing_key->algorithm], signed_size); + sig_size, signed_size); /* Calculate signature */ - sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key); - SignatureCopy(&h->preamble_signature, sigtmp); + struct vb2_signature *sigtmp = + vb2_calculate_signature((uint8_t *)h, signed_size, signing_key); + SignatureCopy(&h->preamble_signature, (VbSignature *)sigtmp); free(sigtmp); /* Return the header */ diff --git a/host/lib/host_key.c b/host/lib/host_key.c index e594b2cd..a8b05b53 100644 --- a/host/lib/host_key.c +++ b/host/lib/host_key.c @@ -20,130 +20,6 @@ #include "vb2_common.h" #include "vboot_common.h" - -VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm) { - - VbPrivateKey* key; - RSA* rsa_key; - FILE* f; - - if (algorithm >= kNumAlgorithms) { - VBDEBUG(("%s() called with invalid algorithm!\n", __FUNCTION__)); - return NULL; - } - - /* Read private key */ - f = fopen(filename, "r"); - if (!f) { - VBDEBUG(("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename)); - return NULL; - } - rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); - fclose(f); - if (!rsa_key) { - VBDEBUG(("%s(): Couldn't read private key from file: %s\n", __FUNCTION__, - filename)); - return NULL; - } - - /* Store key and algorithm in our struct */ - key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey)); - if (!key) { - RSA_free(rsa_key); - return NULL; - } - key->rsa_private_key = rsa_key; - key->algorithm = algorithm; - - /* Return the key */ - return key; -} - - -void PrivateKeyFree(VbPrivateKey* key) { - if (!key) - return; - if (key->rsa_private_key) - RSA_free(key->rsa_private_key); - free(key); -} - - -/* Write a private key to a file in .vbprivk format. */ -int PrivateKeyWrite(const char* filename, const VbPrivateKey* key) { - uint8_t *outbuf = 0; - int buflen; - FILE *f; - - buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf); - if (buflen <= 0) { - VbExError("Unable to write private key buffer\n"); - return 1; - } - - f = fopen(filename, "wb"); - if (!f) { - VbExError("Unable to open file %s\n", filename); - free(outbuf); - return 1; - } - - if (1 != fwrite(&key->algorithm, sizeof(key->algorithm), 1, f)) { - VbExError("Unable to write to file %s\n", filename); - fclose(f); - free(outbuf); - unlink(filename); /* Delete any partial file */ - } - - if (1 != fwrite(outbuf, buflen, 1, f)) { - VbExError("Unable to write to file %s\n", filename); - fclose(f); - unlink(filename); /* Delete any partial file */ - free(outbuf); - } - - fclose(f); - free(outbuf); - return 0; -} - -VbPrivateKey* PrivateKeyRead(const char* filename) { - VbPrivateKey *key; - uint64_t filelen = 0; - uint8_t *buffer; - const unsigned char *start; - - buffer = ReadFile(filename, &filelen); - if (!buffer) { - VbExError("unable to read from file %s\n", filename); - return 0; - } - - key = (VbPrivateKey*)malloc(sizeof(VbPrivateKey)); - if (!key) { - VbExError("Unable to allocate VbPrivateKey\n"); - free(buffer); - return 0; - } - - key->algorithm = *(typeof(key->algorithm) *)buffer; - start = buffer + sizeof(key->algorithm); - - key->rsa_private_key = d2i_RSAPrivateKey(0, &start, - filelen - sizeof(key->algorithm)); - - if (!key->rsa_private_key) { - VbExError("Unable to parse RSA private key\n"); - free(buffer); - free(key); - return 0; - } - - free(buffer); - return key; -} - - /* Allocate a new public key with space for a [key_size] byte key. */ VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, uint64_t version) { diff --git a/host/lib/host_key2.c b/host/lib/host_key2.c index a100455e..783ea5d9 100644 --- a/host/lib/host_key2.c +++ b/host/lib/host_key2.c @@ -25,6 +25,21 @@ #include "vb2_common.h" #include "vboot_common.h" +enum vb2_crypto_algorithm vb2_get_crypto_algorithm( + enum vb2_hash_algorithm hash_alg, + enum vb2_signature_algorithm sig_alg) +{ + /* Make sure algorithms are in the range supported by crypto alg */ + if (sig_alg < VB2_SIG_RSA1024 || sig_alg > VB2_SIG_RSA8192) + return VB2_ALG_COUNT; + if (hash_alg < VB2_HASH_SHA1 || hash_alg > VB2_HASH_SHA512) + return VB2_ALG_COUNT; + + return (sig_alg - VB2_SIG_RSA1024) + * (VB2_HASH_SHA512 - VB2_HASH_SHA1 + 1) + + (hash_alg - VB2_HASH_SHA1); +}; + struct vb2_private_key *vb2_read_private_key(const char *filename) { uint8_t *buf = NULL; @@ -65,9 +80,6 @@ struct vb2_private_key *vb2_read_private_key_pem( const char* filename, enum vb2_crypto_algorithm algorithm) { - RSA *rsa_key; - FILE *f; - if (algorithm >= VB2_ALG_COUNT) { VB2_DEBUG("%s() called with invalid algorithm!\n", __FUNCTION__); @@ -75,13 +87,13 @@ struct vb2_private_key *vb2_read_private_key_pem( } /* Read private key */ - f = fopen(filename, "r"); + FILE *f = fopen(filename, "r"); if (!f) { VB2_DEBUG("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename); return NULL; } - rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); + struct rsa_st *rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); fclose(f); if (!rsa_key) { VB2_DEBUG("%s(): Couldn't read private key from file: %s\n", @@ -104,6 +116,51 @@ struct vb2_private_key *vb2_read_private_key_pem( return key; } +void vb2_free_private_key(struct vb2_private_key *key) +{ + if (!key) + return; + if (key->rsa_private_key) + RSA_free(key->rsa_private_key); + free(key); +} + +int vb2_write_private_key(const char *filename, + const struct vb2_private_key *key) +{ + /* Convert back to legacy vb1 algorithm enum */ + uint64_t alg = vb2_get_crypto_algorithm(key->hash_alg, key->sig_alg); + if (alg == VB2_ALG_COUNT) + return VB2_ERROR_VB1_CRYPTO_ALGORITHM; + + uint8_t *outbuf = NULL; + int buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf); + if (buflen <= 0) { + fprintf(stderr, "Unable to write private key buffer\n"); + return VB2_ERROR_PRIVATE_KEY_WRITE_RSA; + } + + FILE *f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "Unable to open file %s\n", filename); + free(outbuf); + return VB2_ERROR_PRIVATE_KEY_WRITE_FILE; + } + + if (1 != fwrite(&alg, sizeof(alg), 1, f) || + 1 != fwrite(outbuf, buflen, 1, f)) { + fprintf(stderr, "Unable to write to file %s\n", filename); + fclose(f); + unlink(filename); /* Delete any partial file */ + free(outbuf); + return VB2_ERROR_PRIVATE_KEY_WRITE_FILE; + } + + fclose(f); + free(outbuf); + return VB2_SUCCESS; +} + void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data, uint32_t key_size) { diff --git a/host/lib/host_signature.c b/host/lib/host_signature.c index 33000f1f..db810f36 100644 --- a/host/lib/host_signature.c +++ b/host/lib/host_signature.c @@ -54,59 +54,6 @@ int SignatureCopy(VbSignature* dest, const VbSignature* src) { return 0; } -VbSignature* CalculateSignature(const uint8_t* data, uint64_t size, - const VbPrivateKey* key) { - int vb2_alg = vb2_crypto_to_hash(key->algorithm); - uint8_t digest[VB2_MAX_DIGEST_SIZE]; - int digest_size = vb2_digest_size(vb2_alg); - - const uint8_t* digestinfo = hash_digestinfo_map[key->algorithm]; - int digestinfo_size = digestinfo_size_map[key->algorithm]; - - uint8_t* signature_digest; - int signature_digest_len = digest_size + digestinfo_size; - - VbSignature* sig; - int rv; - - /* Calculate the digest */ - if (VB2_SUCCESS != vb2_digest_buffer(data, size, vb2_alg, - digest, sizeof(digest))) - return NULL; - - /* Prepend the digest info to the digest */ - signature_digest = malloc(signature_digest_len); - if (!signature_digest) - return NULL; - - Memcpy(signature_digest, digestinfo, digestinfo_size); - Memcpy(signature_digest + digestinfo_size, digest, digest_size); - - /* Allocate output signature */ - sig = SignatureAlloc(siglen_map[key->algorithm], size); - if (!sig) { - free(signature_digest); - return NULL; - } - - /* Sign the signature_digest into our output buffer */ - rv = RSA_private_encrypt(signature_digest_len, /* Input length */ - signature_digest, /* Input data */ - GetSignatureData(sig), /* Output sig */ - key->rsa_private_key, /* Key to use */ - RSA_PKCS1_PADDING); /* Padding to use */ - free(signature_digest); - - if (-1 == rv) { - VBDEBUG(("SignatureBuf(): RSA_private_encrypt() failed.\n")); - free(sig); - return NULL; - } - - /* Return the signature */ - return sig; -} - /* Invoke [external_signer] command with [pem_file] as * an argument, contents of [inbuf] passed redirected to stdin, * and the stdout of the command is put back into [outbuf]. @@ -192,9 +139,6 @@ int InvokeExternalSigner(uint64_t size, return rv; } -/* TODO(gauravsh): This could easily be integrated into CalculateSignature() - * since the code is almost a mirror - I have kept it as such to avoid changing - * the existing interface. */ VbSignature* CalculateSignature_external(const uint8_t* data, uint64_t size, const char* key_file, uint64_t key_algorithm, diff --git a/host/lib/include/host_common.h b/host/lib/include/host_common.h index c9f9713f..50684864 100644 --- a/host/lib/include/host_common.h +++ b/host/lib/include/host_common.h @@ -58,6 +58,6 @@ VbKernelPreambleHeader *CreateKernelPreamble( uint64_t vmlinuz_header_size, uint32_t flags, uint64_t desired_size, - const VbPrivateKey *signing_key); + const struct vb2_private_key *signing_key); #endif /* VBOOT_REFERENCE_HOST_COMMON_H_ */ diff --git a/host/lib/include/host_key.h b/host/lib/include/host_key.h index d355e228..0d4641b2 100644 --- a/host/lib/include/host_key.h +++ b/host/lib/include/host_key.h @@ -15,33 +15,57 @@ struct vb2_packed_key; struct vb2_private_key; -typedef struct rsa_st RSA; - -/* Private key data */ -typedef struct VbPrivateKey { - RSA* rsa_private_key; /* Private key data */ - uint64_t algorithm; /* Algorithm to use when signing */ -} VbPrivateKey; - +/** + * Convert a vb2 hash and crypto algorithm to a vb1 crypto algorithm. + * + * @param hash_alg Hash algorithm + * @param sig_alg Signature algorithm + * + * @return The equivalent vb1 crypto algorithm or VB2_ALG_COUNT if error. + */ +enum vb2_crypto_algorithm vb2_get_crypto_algorithm( + enum vb2_hash_algorithm hash_alg, + enum vb2_signature_algorithm sig_alg); -/* Read a private key from a .pem file. Caller owns the returned pointer, - * and must free() it. */ -VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm); +/** + * Read a private key from a .pem file. + * + * @param filename Filename to read from + * @param algorithm Algorithm to associate with file + * (enum vb2_crypto_algorithm) + * + * @return The private key or NULL if error. Caller must free() it. + */ struct vb2_private_key *vb2_read_private_key_pem( const char *filename, enum vb2_crypto_algorithm algorithm); -/* Free a private key. */ -void PrivateKeyFree(VbPrivateKey* key); +/** + * Free a private key. + * + * @param key Key to free; ok to pass NULL (ignored). + */ +void vb2_free_private_key(struct vb2_private_key *key); -/* Write a private key to a file in .vbprivk format. */ -int PrivateKeyWrite(const char* filename, const VbPrivateKey* key); +/** + * Write a private key to a file in .vbprivk format. + * + * @param filename Filename to write to + * @param key Key to write + * + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_write_private_key(const char *filename, + const struct vb2_private_key *key); -/* Read a private key from a .vbprivk file. Caller owns the returned - * pointer, and must free() it. + +/** + * Read a private key from a .vbprivk file. * - * Returns NULL if error. */ -VbPrivateKey* PrivateKeyRead(const char* filename); + * @param filename Filename to read key from. + * + * @return The private key or NULL if error. Caller must free() it. + */ struct vb2_private_key *vb2_read_private_key(const char *filename); /* Allocate a new public key with space for a [key_size] byte key. */ diff --git a/host/lib/include/host_signature.h b/host/lib/include/host_signature.h index 2c7f24ae..df907d28 100644 --- a/host/lib/include/host_signature.h +++ b/host/lib/include/host_signature.h @@ -56,21 +56,22 @@ int vb2_copy_signature(struct vb2_signature *dest, /** * Calculate a SHA-512 digest-only signature. * - * Caller owns the returned pointer, and must free() it. - * * @param data Pointer to data to hash * @param size Length of data in bytes * - * @return The signature, or NULL if error. + * @return The signature, or NULL if error. Caller must free() it. */ struct vb2_signature *vb2_sha512_signature(const uint8_t *data, uint32_t size); -/* Calculates a signature for the data using the specified key. - * Caller owns the returned pointer, and must free it with Free(). +/** + * Calculate a signature for the data using the specified key. * - * Returns NULL on error. */ -VbSignature* CalculateSignature(const uint8_t* data, uint64_t size, - const VbPrivateKey* key); + * @param data Pointer to data to sign + * @param size Length of data in bytes + * @param key Private key to use to sign data + * + * @return The signature, or NULL if error. Caller must free() it. + */ struct vb2_signature *vb2_calculate_signature( const uint8_t *data, uint32_t size, const struct vb2_private_key *key); diff --git a/host/lib21/include/host_key2.h b/host/lib21/include/host_key2.h index e58b37d7..e109cb19 100644 --- a/host/lib21/include/host_key2.h +++ b/host/lib21/include/host_key2.h @@ -8,6 +8,7 @@ #ifndef VBOOT_REFERENCE_HOST_KEY2_H_ #define VBOOT_REFERENCE_HOST_KEY2_H_ +#include "2id.h" #include "2struct.h" struct vb2_public_key; diff --git a/host/linktest/main.c b/host/linktest/main.c index 5d56b892..b98e8755 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -16,8 +16,6 @@ int main(void) { /* host_key.h */ - PrivateKeyReadPem(0, 0); - PrivateKeyFree(0); PublicKeyAlloc(0, 0, 0); PublicKeyRead(0); PublicKeyReadKeyb(0, 0, 0); @@ -31,7 +29,6 @@ int main(void) SignatureInit(0, 0, 0, 0); SignatureAlloc(0, 0); SignatureCopy(0, 0); - CalculateSignature(0, 0, 0); /* host_common.h */ CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |