futility: Use vboot 2.0 APIs for private keys
authorRandall Spangler <rspangler@chromium.org>
Wed, 22 Jun 2016 23:46:23 +0000 (16:46 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Wed, 10 Aug 2016 22:30:35 +0000 (15:30 -0700)
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>
21 files changed:
firmware/2lib/include/2return_codes.h
futility/cmd_create.c
futility/cmd_sign.c
futility/cmd_vbutil_firmware.c
futility/cmd_vbutil_kernel.c
futility/cmd_vbutil_key.c
futility/file_type.inc
futility/futility_options.h
futility/vb1_helper.c
futility/vb1_helper.h
host/lib/host_common.c
host/lib/host_key.c
host/lib/host_key2.c
host/lib/host_signature.c
host/lib/include/host_common.h
host/lib/include/host_key.h
host/lib/include/host_signature.h
host/lib21/include/host_key2.h
host/linktest/main.c
tests/vb20_common3_tests.c
tests/vboot_common2_tests.c

index b697992..e0bc6f2 100644 (file)
@@ -673,6 +673,9 @@ enum vb2_return_code {
        /* Bad key size in vb2_copy_packed_key() */
        VB2_ERROR_COPY_KEY_SIZE,
 
+       /* Unable to convert back to vb1 crypto algorithm */
+       VB2_ERROR_VB1_CRYPTO_ALGORITHM,
+
         /**********************************************************************
         * Errors generated by host library signature functions
         */
index a134179..748ce2f 100644 (file)
@@ -80,51 +80,50 @@ static void print_help(int argc, char *argv[])
 
 static int vb1_make_keypair()
 {
-       VbPrivateKey *privkey = 0;
+       struct vb2_private_key *privkey = NULL;
        VbPublicKey *pubkey = 0;
-       RSA *rsa_key = 0;
+       struct rsa_st *rsa_key = NULL;
        uint8_t *keyb_data = 0;
        uint32_t keyb_size;
-       enum vb2_signature_algorithm sig_alg;
-       uint64_t vb1_algorithm;
-       FILE *fp;
        int ret = 1;
 
-       fp = fopen(infile, "rb");
+       FILE *fp = fopen(infile, "rb");
        if (!fp) {
                fprintf(stderr, "Unable to open %s\n", infile);
                goto done;
        }
 
+       /* TODO: this is very similar to vb2_read_private_key_pem() */
+
        rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
        fclose(fp);
-
        if (!rsa_key) {
                fprintf(stderr, "Unable to read RSA key from %s\n", infile);
                goto done;
        }
 
-       sig_alg = vb2_rsa_sig_alg(rsa_key);
+       enum vb2_signature_algorithm sig_alg = vb2_rsa_sig_alg(rsa_key);
        if (sig_alg == VB2_SIG_INVALID) {
                fprintf(stderr, "Unsupported sig algorithm in RSA key\n");
                goto done;
        }
 
-       /* combine the sig_alg with the hash_alg to get the vb1 algorithm */
-       vb1_algorithm = (sig_alg - VB2_SIG_RSA1024) * 3
-               + opt_hash_alg - VB2_HASH_SHA1;
+       /* Combine the sig_alg with the hash_alg to get the vb1 algorithm */
+       uint64_t vb1_algorithm =
+               vb2_get_crypto_algorithm(opt_hash_alg, sig_alg);
 
        /* Create the private key */
-       privkey = (VbPrivateKey *)malloc(sizeof(VbPrivateKey));
+       privkey = (struct vb2_private_key *)calloc(sizeof(*privkey), 1);
        if (!privkey)
                goto done;
 
        privkey->rsa_private_key = rsa_key;
-       privkey->algorithm = vb1_algorithm;
+       privkey->sig_alg = sig_alg;
+       privkey->hash_alg = opt_hash_alg;
 
        /* Write it out */
        strcpy(outext, ".vbprivk");
-       if (0 != PrivateKeyWrite(outfile, privkey)) {
+       if (0 != vb2_write_private_key(outfile, privkey)) {
                fprintf(stderr, "unable to write private key\n");
                goto done;
        }
index 23e298b..3ff6dda 100644 (file)
@@ -78,15 +78,6 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
                                sign_option.flags,
                                sign_option.pem_external);
                } else {
-                       sign_option.signprivate = PrivateKeyReadPem(
-                               sign_option.pem_signpriv,
-                               sign_option.pem_algo);
-                       if (!sign_option.signprivate) {
-                               fprintf(stderr,
-                                       "Unable to read PEM signing key: %s\n",
-                                       strerror(errno));
-                               return 1;
-                       }
                        sign_option.signprivate2 = vb2_read_private_key_pem(
                                sign_option.pem_signpriv,
                                sign_option.pem_algo);
@@ -139,7 +130,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
                                     sign_option.version,
                                     sign_option.kloadaddr,
                                     sign_option.keyblock,
-                                    sign_option.signprivate,
+                                    sign_option.signprivate2,
                                     sign_option.flags, &vblock_size);
        if (!vblock_data) {
                fprintf(stderr, "Unable to sign kernel blob\n");
@@ -226,7 +217,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
                                     sign_option.version,
                                     sign_option.kloadaddr,
                                     keyblock,
-                                    sign_option.signprivate,
+                                    sign_option.signprivate2,
                                     sign_option.flags,
                                     &vblock_size);
        if (!vblock_data) {
@@ -663,11 +654,6 @@ static int do_sign(int argc, char *argv[])
                                &longindex)) != -1) {
                switch (i) {
                case 's':
-                       sign_option.signprivate = PrivateKeyRead(optarg);
-                       if (!sign_option.signprivate) {
-                               fprintf(stderr, "Error reading %s\n", optarg);
-                               errorcnt++;
-                       }
                        sign_option.signprivate2 = vb2_read_private_key(optarg);
                        if (!sign_option.signprivate2) {
                                fprintf(stderr, "Error reading %s\n", optarg);
@@ -922,13 +908,13 @@ static int do_sign(int argc, char *argv[])
        switch (sign_option.type) {
        case FILE_TYPE_PUBKEY:
                sign_option.create_new_outfile = 1;
-               if (sign_option.signprivate && sign_option.pem_signpriv) {
+               if (sign_option.signprivate2 && sign_option.pem_signpriv) {
                        fprintf(stderr,
                                "Only one of --signprivate and --pem_signpriv"
                                " can be specified\n");
                        errorcnt++;
                }
-               if ((sign_option.signprivate &&
+               if ((sign_option.signprivate2 &&
                     sign_option.pem_algo_specified) ||
                    (sign_option.pem_signpriv &&
                     !sign_option.pem_algo_specified)) {
@@ -946,18 +932,18 @@ static int do_sign(int argc, char *argv[])
                break;
        case FILE_TYPE_BIOS_IMAGE:
        case FILE_TYPE_OLD_BIOS_IMAGE:
-               errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+               errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
                errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
                errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
                break;
        case FILE_TYPE_KERN_PREAMBLE:
-               errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+               errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
                if (sign_option.vblockonly || sign_option.inout_file_count > 1)
                        sign_option.create_new_outfile = 1;
                break;
        case FILE_TYPE_RAW_FIRMWARE:
                sign_option.create_new_outfile = 1;
-               errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+               errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
                errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
                errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
                errorcnt += no_opt_if(!sign_option.version_specified,
@@ -965,7 +951,7 @@ static int do_sign(int argc, char *argv[])
                break;
        case FILE_TYPE_RAW_KERNEL:
                sign_option.create_new_outfile = 1;
-               errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+               errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
                errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
                errorcnt += no_opt_if(!sign_option.version_specified,
                                      "version");
@@ -1058,8 +1044,6 @@ done:
                        strerror(errno));
        }
 
-       if (sign_option.signprivate)
-               free(sign_option.signprivate);
        if (sign_option.signprivate2)
                free(sign_option.signprivate2);
        if (sign_option.keyblock)
index 253add5..4f44426 100644 (file)
@@ -84,19 +84,11 @@ static void print_help(int argc, char *argv[])
 }
 
 /* Create a firmware .vblock */
-static int Vblock(const char *outfile, const char *keyblock_file,
-                 const char *signprivate, uint64_t version,
-                 const char *fv_file, const char *kernelkey_file,
-                 uint32_t preamble_flags)
+static int do_vblock(const char *outfile, const char *keyblock_file,
+                    const char *signprivate, uint32_t version,
+                    const char *fv_file, const char *kernelkey_file,
+                    uint32_t preamble_flags)
 {
-
-       VbPrivateKey *signing_key;
-       VbPublicKey *kernel_subkey;
-       uint8_t *fv_data;
-       uint64_t fv_size;
-       FILE *f;
-       uint64_t i;
-
        if (!outfile) {
                VbExError("Must specify output filename\n");
                return 1;
@@ -117,34 +109,30 @@ static int Vblock(const char *outfile, const char *keyblock_file,
                return 1;
        }
 
-       signing_key = PrivateKeyRead(signprivate);
+       struct vb2_private_key *signing_key = vb2_read_private_key(signprivate);
        if (!signing_key) {
                VbExError("Error reading signing key.\n");
                return 1;
        }
-       struct vb2_private_key *signing_key2 =
-               vb2_read_private_key(signprivate);
-       if (!signing_key2) {
-               VbExError("Error reading signing key.\n");
-               return 1;
-       }
 
-       kernel_subkey = PublicKeyRead(kernelkey_file);
+       struct vb2_packed_key *kernel_subkey =
+               vb2_read_packed_key(kernelkey_file);
        if (!kernel_subkey) {
                VbExError("Error reading kernel subkey.\n");
                return 1;
        }
 
        /* Read and sign the firmware volume */
-       fv_data = ReadFile(fv_file, &fv_size);
-       if (!fv_data)
+       uint8_t *fv_data;
+       uint32_t fv_size;
+       if (VB2_SUCCESS != vb2_read_file(fv_file, &fv_data, &fv_size))
                return 1;
        if (!fv_size) {
                VbExError("Empty firmware volume file\n");
                return 1;
        }
        struct vb2_signature *body_sig =
-               vb2_calculate_signature(fv_data, fv_size, signing_key2);
+               vb2_calculate_signature(fv_data, fv_size, signing_key);
        if (!body_sig) {
                VbExError("Error calculating body signature\n");
                return 1;
@@ -153,22 +141,21 @@ static int Vblock(const char *outfile, const char *keyblock_file,
 
        /* Create preamble */
        struct vb2_fw_preamble *preamble =
-               vb2_create_fw_preamble(version,
-                                      (struct vb2_packed_key *)kernel_subkey,
-                                      body_sig, signing_key2, preamble_flags);
+               vb2_create_fw_preamble(version, kernel_subkey, body_sig,
+                                      signing_key, preamble_flags);
        if (!preamble) {
                VbExError("Error creating preamble.\n");
                return 1;
        }
 
        /* Write the output file */
-       f = fopen(outfile, "wb");
+       FILE *f = fopen(outfile, "wb");
        if (!f) {
                VbExError("Can't open output file %s\n", outfile);
                return 1;
        }
-       i = ((1 != fwrite(keyblock, keyblock->keyblock_size, 1, f)) ||
-            (1 != fwrite(preamble, preamble->preamble_size, 1, f)));
+       int i = ((1 != fwrite(keyblock, keyblock->keyblock_size, 1, f)) ||
+                (1 != fwrite(preamble, preamble->preamble_size, 1, f)));
        fclose(f);
        if (i) {
                VbExError("Can't write output file %s\n", outfile);
@@ -180,8 +167,8 @@ static int Vblock(const char *outfile, const char *keyblock_file,
        return 0;
 }
 
-static int Verify(const char *infile, const char *signpubkey,
-                 const char *fv_file, const char *kernelkey_file)
+static int do_verify(const char *infile, const char *signpubkey,
+                    const char *fv_file, const char *kernelkey_file)
 {
        uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
        struct vb2_workbuf wb;
@@ -316,7 +303,7 @@ static int do_vbutil_firmware(int argc, char *argv[])
        char *key_block_file = NULL;
        char *signpubkey = NULL;
        char *signprivate = NULL;
-       uint64_t version = 0;
+       uint32_t version = 0;
        char *fv_file = NULL;
        char *kernelkey_file = NULL;
        uint32_t preamble_flags = 0;
@@ -387,10 +374,10 @@ static int do_vbutil_firmware(int argc, char *argv[])
 
        switch (mode) {
        case OPT_MODE_VBLOCK:
-               return Vblock(filename, key_block_file, signprivate, version,
-                             fv_file, kernelkey_file, preamble_flags);
+               return do_vblock(filename, key_block_file, signprivate, version,
+                                fv_file, kernelkey_file, preamble_flags);
        case OPT_MODE_VERIFY:
-               return Verify(filename, signpubkey, fv_file, kernelkey_file);
+               return do_verify(filename, signpubkey, fv_file, kernelkey_file);
        default:
                fprintf(stderr, "Must specify a mode.\n");
                print_help(argc, argv);
index cf8b26e..274ea75 100644 (file)
@@ -239,7 +239,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
        int rv;
        struct vb2_keyblock *keyblock = NULL;
        struct vb2_keyblock *t_keyblock = NULL;
-       VbPrivateKey *signpriv_key = NULL;
+       struct vb2_private_key *signpriv_key = NULL;
        VbPublicKey *signpub_key = NULL;
        uint8_t *kpart_data = NULL;
        uint64_t kpart_size = 0;
@@ -403,7 +403,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
                if (!signprivkey_file)
                        Fatal("Missing required signprivate file.\n");
 
-               signpriv_key = PrivateKeyRead(signprivkey_file);
+               signpriv_key = vb2_read_private_key(signprivkey_file);
                if (!signpriv_key)
                        Fatal("Error reading signing key.\n");
 
@@ -475,7 +475,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
                if (!signprivkey_file)
                        Fatal("Missing required signprivate file.\n");
 
-               signpriv_key = PrivateKeyRead(signprivkey_file);
+               signpriv_key = vb2_read_private_key(signprivkey_file);
                if (!signpriv_key)
                        Fatal("Error reading signing key.\n");
 
index e4e919e..7f61e0a 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+
 #include "cryptolib.h"
 #include "futility.h"
 #include "host_common.h"
+#include "host_key2.h"
 #include "util_misc.h"
 #include "vb1_helper.h"
 #include "vb2_common.h"
@@ -71,11 +73,10 @@ static void print_help(int argc, char *argv[])
 }
 
 /* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */
-static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
-               uint64_t version)
+static int do_pack(const char *infile, const char *outfile, uint32_t algorithm,
+                  uint32_t version)
 {
        VbPublicKey *pubkey;
-       VbPrivateKey *privkey;
 
        if (!infile || !outfile) {
                fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
@@ -92,9 +93,10 @@ static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
                return 0;
        }
 
-       privkey = PrivateKeyReadPem(infile, algorithm);
+       struct vb2_private_key *privkey =
+               vb2_read_private_key_pem(infile, algorithm);
        if (privkey) {
-               if (0 != PrivateKeyWrite(outfile, privkey)) {
+               if (VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) {
                        fprintf(stderr, "vbutil_key: Error writing key.\n");
                        return 1;
                }
@@ -107,10 +109,9 @@ static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
 }
 
 /* Unpack a .vbpubk or .vbprivk */
-static int Unpack(const char *infile, const char *outfile)
+static int do_unpack(const char *infile, const char *outfile)
 {
        VbPublicKey *pubkey;
-       VbPrivateKey *privkey;
 
        if (!infile) {
                fprintf(stderr, "Need file to unpack\n");
@@ -137,14 +138,17 @@ static int Unpack(const char *infile, const char *outfile)
                return 0;
        }
 
-       privkey = PrivateKeyRead(infile);
+       struct vb2_private_key *privkey = vb2_read_private_key(infile);
        if (privkey) {
                printf("Private Key file:  %s\n", infile);
-               printf("Algorithm:         %" PRIu64 " %s\n",
-                      privkey->algorithm,
-                      vb1_crypto_name(privkey->algorithm));
+
+               enum vb2_crypto_algorithm alg =
+                       vb2_get_crypto_algorithm(privkey->hash_alg,
+                                                privkey->sig_alg);
+               printf("Algorithm:         %u %s\n", alg, vb1_crypto_name(alg));
                if (outfile) {
-                       if (0 != PrivateKeyWrite(outfile, privkey)) {
+                       if (VB2_SUCCESS !=
+                           vb2_write_private_key(outfile, privkey)) {
                                fprintf(stderr,
                                        "vbutil_key: Error writing key copy\n");
                                free(privkey);
@@ -167,8 +171,8 @@ static int do_vbutil_key(int argc, char *argv[])
        char *outfile = NULL;
        int mode = 0;
        int parse_error = 0;
-       uint64_t version = 1;
-       uint64_t algorithm = kNumAlgorithms;
+       uint32_t version = 1;
+       uint32_t algorithm = VB2_ALG_COUNT;
        char *e;
        int i;
 
@@ -226,9 +230,9 @@ static int do_vbutil_key(int argc, char *argv[])
 
        switch (mode) {
        case OPT_MODE_PACK:
-               return Pack(infile, outfile, algorithm, version);
+               return do_pack(infile, outfile, algorithm, version);
        case OPT_MODE_UNPACK:
-               return Unpack(infile, outfile);
+               return do_unpack(infile, outfile);
        default:
                printf("Must specify a mode.\n");
                print_help(argc, argv);
index 788f7e8..9259f64 100644 (file)
@@ -39,11 +39,11 @@ FILE_TYPE(KEYBLOCK,         "keyblock",      "keyblock (signed public key)",
          R_(ft_recognize_vblock1),
          S_(ft_show_keyblock),
          NONE)
-FILE_TYPE(PUBKEY,           "pubkey",        "VbPublicKey (.vbpubk)",
+FILE_TYPE(PUBKEY,           "pubkey",        "vb1 packed public key (.vbpubk)",
          R_(ft_recognize_vb1_key),
          S_(ft_show_pubkey),
          S_(ft_sign_pubkey))
-FILE_TYPE(PRIVKEY,          "prikey",        "VbPrivateKey (.vbprivk)",
+FILE_TYPE(PRIVKEY,          "prikey",        "vb1 private key (.vbprivk)",
          R_(ft_recognize_vb1_key),
          S_(ft_show_privkey),
          NONE)
index 476898e..4739f04 100644 (file)
@@ -33,7 +33,6 @@ struct show_option_s {
 extern struct show_option_s show_option;
 
 struct sign_option_s {
-       VbPrivateKey *signprivate;
        struct vb2_private_key *signprivate2;
        struct vb2_keyblock *keyblock;
        VbPublicKey *kernel_subkey;
index b0f4fe8..2ec7750 100644 (file)
@@ -408,7 +408,7 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size,
                        uint64_t padding,
                        int version, uint64_t kernel_body_load_address,
                        struct vb2_keyblock *keyblock,
-                       VbPrivateKey *signpriv_key,
+                       struct vb2_private_key *signpriv_key,
                        uint32_t flags, uint64_t *vblock_size_ptr)
 {
        VbSignature *body_sig;
@@ -419,7 +419,9 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size,
        uint64_t outsize;
 
        /* Sign the kernel data */
-       body_sig = CalculateSignature(kernel_blob, kernel_size, signpriv_key);
+       body_sig = (VbSignature *)vb2_calculate_signature(kernel_blob,
+                                                         kernel_size,
+                                                         signpriv_key);
        if (!body_sig) {
                fprintf(stderr, "Error calculating body signature\n");
                return NULL;
@@ -797,25 +799,19 @@ enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len)
 
 enum futil_file_type ft_recognize_vb1_key(uint8_t *buf, uint32_t len)
 {
-       struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf;
-       VbPrivateKey key;
-       const unsigned char *start;
-
-       /* Maybe just a VbPublicKey? */
+       /* Maybe just a packed public key? */
+       const struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf;
        if (packed_key_looks_ok(pubkey, len))
                return FILE_TYPE_PUBKEY;
 
-       /* How about a VbPrivateKey? */
-       if (len < sizeof(key.algorithm))
+       /* How about a private key? */
+       if (len < sizeof(uint64_t))
                return FILE_TYPE_UNKNOWN;
-
-       key.algorithm = *(typeof(key.algorithm) *)buf;
-       start = buf + sizeof(key.algorithm);
-       key.rsa_private_key = d2i_RSAPrivateKey(NULL, &start,
-                                               len - sizeof(key.algorithm));
-
-       if (key.rsa_private_key) {
-               RSA_free(key.rsa_private_key);
+       const unsigned char *start = buf + sizeof(uint64_t);
+       struct rsa_st *rsa =
+               d2i_RSAPrivateKey(NULL, &start, len - sizeof(uint64_t));
+       if (rsa) {
+               RSA_free(rsa);
                return FILE_TYPE_PRIVKEY;
        }
 
index ec0f000..1c59da5 100644 (file)
@@ -35,7 +35,7 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size,
                        uint64_t padding,
                        int version, uint64_t kernel_body_load_address,
                        struct vb2_keyblock *keyblock,
-                       VbPrivateKey *signpriv_key,
+                       struct vb2_private_key *signpriv_key,
                        uint32_t flags, uint64_t *vblock_size_ptr);
 
 int WriteSomeParts(const char *outfile,
index a666e80..a8c1d97 100644 (file)
@@ -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 */
index e594b2c..a8b05b5 100644 (file)
 #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) {
index a100455..783ea5d 100644 (file)
 #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)
 {
index 33000f1..db810f3 100644 (file)
@@ -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,
index c9f9713..5068486 100644 (file)
@@ -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_ */
index d355e22..0d4641b 100644 (file)
 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. */
index 2c7f24a..df907d2 100644 (file)
@@ -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);
index e58b37d..e109cb1 100644 (file)
@@ -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;
index 5d56b89..b98e875 100644 (file)
@@ -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);
index e1199d8..32ee007 100644 (file)
@@ -330,17 +330,18 @@ static void test_verify_fw_preamble(const VbPublicKey *public_key,
 }
 
 static void resign_kernel_preamble(struct vb2_kernel_preamble *h,
-                                  const VbPrivateKey *key)
+                                  const struct vb2_private_key *key)
 {
-       VbSignature *sig = CalculateSignature(
+       struct vb2_signature *sig = vb2_calculate_signature(
                (const uint8_t *)h, h->preamble_signature.data_size, key);
 
-       SignatureCopy((VbSignature *)&h->preamble_signature, sig);
+       vb2_copy_signature(&h->preamble_signature, sig);
        free(sig);
 }
 
-static void test_verify_kernel_preamble(const VbPublicKey *public_key,
-                                       const VbPrivateKey *private_key)
+static void test_verify_kernel_preamble(
+               const VbPublicKey *public_key,
+               const struct vb2_private_key *private_key)
 {
        struct vb2_kernel_preamble *hdr;
        struct vb2_kernel_preamble *h;
@@ -511,7 +512,6 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
        int signing_rsa_len = siglen_map[signing_key_algorithm] * 8;
        int data_rsa_len = siglen_map[data_key_algorithm] * 8;
 
-       VbPrivateKey *signing_private_key = NULL;
        VbPublicKey *signing_public_key = NULL;
        VbPublicKey *data_public_key = NULL;
 
@@ -521,17 +521,9 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
               algo_strings[data_key_algorithm]);
 
        sprintf(filename, "%s/key_rsa%d.pem", keys_dir, signing_rsa_len);
-       signing_private_key = PrivateKeyReadPem(filename,
-                                               signing_key_algorithm);
-       if (!signing_private_key) {
-               fprintf(stderr, "Error reading signing_private_key: %s\n",
-                       filename);
-               return 1;
-       }
-
-       struct vb2_private_key *signing_private_key2 =
+       struct vb2_private_key *signing_private_key =
                vb2_read_private_key_pem(filename, signing_key_algorithm);
-       if (!signing_private_key2) {
+       if (!signing_private_key) {
                fprintf(stderr, "Error reading signing_private_key: %s\n",
                        filename);
                return 1;
@@ -567,11 +559,11 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
                return 1;
        }
 
-       test_check_keyblock(&signing_public_key2, signing_private_key2,
+       test_check_keyblock(&signing_public_key2, signing_private_key,
                            (struct vb2_packed_key *)data_public_key);
-       test_verify_keyblock(&signing_public_key2, signing_private_key2,
+       test_verify_keyblock(&signing_public_key2, signing_private_key,
                             (struct vb2_packed_key *)data_public_key);
-       test_verify_fw_preamble(signing_public_key, signing_private_key2,
+       test_verify_fw_preamble(signing_public_key, signing_private_key,
                                (struct vb2_packed_key *)data_public_key);
        test_verify_kernel_preamble(signing_public_key, signing_private_key);
 
@@ -579,8 +571,6 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
                free(signing_public_key);
        if (signing_private_key)
                free(signing_private_key);
-       if (signing_private_key2)
-               free(signing_private_key2);
        if (data_public_key)
                free(data_public_key);
 
index 8f662d3..5185deb 100644 (file)
@@ -44,14 +44,15 @@ static void VerifyPublicKeyToRSA(const VbPublicKey *orig_key)
 }
 
 static void VerifyDataTest(const VbPublicKey *public_key,
-                           const VbPrivateKey *private_key)
+                           const struct vb2_private_key *private_key)
 {
        const uint8_t test_data[] = "This is some test data to sign.";
        const uint64_t test_size = sizeof(test_data);
        VbSignature *sig;
        RSAPublicKey *rsa;
 
-       sig = CalculateSignature(test_data, test_size, private_key);
+       sig = (VbSignature *)vb2_calculate_signature(test_data, test_size,
+                                                    private_key);
        TEST_PTR_NEQ(sig, 0, "VerifyData() calculate signature");
 
        rsa = PublicKeyToRSA(public_key);
@@ -80,14 +81,16 @@ static void VerifyDataTest(const VbPublicKey *public_key,
 }
 
 static void VerifyDigestTest(const VbPublicKey *public_key,
-                             const VbPrivateKey *private_key)
+                             const struct vb2_private_key *private_key)
 {
        const uint8_t test_data[] = "This is some other test data to sign.";
        VbSignature *sig;
        RSAPublicKey *rsa;
        uint8_t digest[VB2_MAX_DIGEST_SIZE];
 
-       sig = CalculateSignature(test_data, sizeof(test_data), private_key);
+       sig = (VbSignature *)vb2_calculate_signature(test_data,
+                                                    sizeof(test_data),
+                                                    private_key);
        rsa = PublicKeyToRSA(public_key);
        TEST_SUCC(vb2_digest_buffer(test_data, sizeof(test_data),
                                    vb2_crypto_to_hash(public_key->algorithm),
@@ -111,17 +114,17 @@ static void VerifyDigestTest(const VbPublicKey *public_key,
 }
 
 static void ReSignKernelPreamble(VbKernelPreambleHeader *h,
-                                 const VbPrivateKey *key)
+                                 const struct vb2_private_key *key)
 {
-       VbSignature *sig = CalculateSignature((const uint8_t *)h,
-                       h->preamble_signature.data_size, key);
+       struct vb2_signature *sig = vb2_calculate_signature(
+               (const uint8_t *)h, h->preamble_signature.data_size, key);
 
-       SignatureCopy(&h->preamble_signature, sig);
+       SignatureCopy(&h->preamble_signature, (VbSignature *)sig);
        free(sig);
 }
 
 static void VerifyKernelPreambleTest(const VbPublicKey *public_key,
-                                     const VbPrivateKey *private_key)
+                                     const struct vb2_private_key *private_key)
 {
        VbKernelPreambleHeader *hdr;
        VbKernelPreambleHeader *h;
@@ -219,13 +222,13 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
        char filename[1024];
        int rsa_len = siglen_map[key_algorithm] * 8;
 
-       VbPrivateKey *private_key = NULL;
        VbPublicKey *public_key = NULL;
 
        printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]);
 
        sprintf(filename, "%s/key_rsa%d.pem", keys_dir, rsa_len);
-       private_key = PrivateKeyReadPem(filename, key_algorithm);
+       struct vb2_private_key *private_key =
+               vb2_read_private_key_pem(filename, key_algorithm);
        if (!private_key) {
                fprintf(stderr, "Error reading private_key: %s\n", filename);
                return 1;