futility: Create signatures using vboot 2.0 APIs

Refactor futility to use only vboot 2.0 APIs to create signatures.

BUG=chromium:611535
BRANCH=none
TEST=make runtests

Change-Id: I176e7f424fa556d34d8fe691df5681f1e43210ce
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/356128
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
Randall Spangler
2016-06-17 10:48:16 -07:00
committed by chrome-bot
parent 31f04ada58
commit 814aaf09ce
27 changed files with 505 additions and 319 deletions

View File

@@ -460,11 +460,14 @@ UTILLIB_SRCS = \
host/lib/file_keys.c \
host/lib/fmap.c \
host/lib/host_common.c \
host/lib/host_common2.c \
host/lib/host_key.c \
host/lib/host_key2.c \
host/lib/host_keyblock.c \
host/lib/host_misc.c \
host/lib/util_misc.c \
host/lib/host_signature.c \
host/lib/host_signature2.c \
host/lib/signature_digest.c \
host/lib21/host_fw_preamble.c \
host/lib21/host_key.c \

View File

@@ -91,94 +91,6 @@ typedef struct VbKeyBlockHeader {
/****************************************************************************/
#define FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR 2
#define FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR 1
/*
* Preamble block for rewritable firmware, version 2.0. All 2.x versions of
* this struct must start with the same data, to be compatible with version 2.0
* readers.
*/
typedef struct VbFirmwarePreambleHeader2_0 {
/*
* Size of this preamble, including keys, signatures, and padding, in
* bytes
*/
uint64_t preamble_size;
/*
* Signature for this preamble (header + kernel subkey + body
* signature)
*/
VbSignature preamble_signature;
/* Version of this header format (= 2) */
uint32_t header_version_major;
/* Version of this header format (= 0) */
uint32_t header_version_minor;
/* Firmware version */
uint64_t firmware_version;
/* Key to verify kernel key block */
VbPublicKey kernel_subkey;
/* Signature for the firmware body */
VbSignature body_signature;
} __attribute__((packed)) VbFirmwarePreambleHeader2_0;
#define EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE 104
/* Flags for VbFirmwarePreambleHeader.flags */
/*
* Use the normal/dev boot path from the read-only firmware, instead of
* verifying the body signature.
*/
#define VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL 0x00000001
/* Premable block for rewritable firmware, version 2.1.
*
* The firmware preamble header should be followed by:
* 1) The kernel_subkey key data, pointed to by kernel_subkey.key_offset.
* 2) The signature data for the firmware body, pointed to by
* body_signature.sig_offset.
* 3) The signature data for (header + kernel_subkey data + body signature
* data), pointed to by preamble_signature.sig_offset.
*/
typedef struct VbFirmwarePreambleHeader {
/*
* Size of this preamble, including keys, signatures, and padding, in
* bytes
*/
uint64_t preamble_size;
/*
* Signature for this preamble (header + kernel subkey + body
* signature)
*/
VbSignature preamble_signature;
/* Version of this header format */
uint32_t header_version_major;
/* Version of this header format */
uint32_t header_version_minor;
/* Firmware version */
uint64_t firmware_version;
/* Key to verify kernel key block */
VbPublicKey kernel_subkey;
/* Signature for the firmware body */
VbSignature body_signature;
/*
* Fields added in header version 2.1. You must verify the header
* version before reading these fields!
*/
/*
* Flags; see VB_FIRMWARE_PREAMBLE_*. Readers should return 0 for
* header version < 2.1.
*/
uint32_t flags;
} __attribute__((packed)) VbFirmwarePreambleHeader;
#define EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE 108
/****************************************************************************/
#define KERNEL_PREAMBLE_HEADER_VERSION_MAJOR 2
#define KERNEL_PREAMBLE_HEADER_VERSION_MINOR 2
@@ -187,7 +99,7 @@ typedef struct VbFirmwarePreambleHeader {
* This should be followed by:
* 1) The signature data for the kernel body, pointed to by
* body_signature.sig_offset.
* 2) The signature data for (VBFirmwarePreambleHeader + body signature
* 2) The signature data for (vb2_kernel_preamble + body signature
* data), pointed to by preamble_signature.sig_offset.
*/
typedef struct VbKernelPreambleHeader2_0 {
@@ -222,7 +134,7 @@ typedef struct VbKernelPreambleHeader2_0 {
* This should be followed by:
* 1) The signature data for the kernel body, pointed to by
* body_signature.sig_offset.
* 2) The signature data for (VBFirmwarePreambleHeader + body signature
* 2) The signature data for (vb2_fw_preamble + body signature
* data), pointed to by preamble_signature.sig_offset.
* 3) The 16-bit vmlinuz header, which is used for reconstruction of
* vmlinuz image.

View File

@@ -120,8 +120,8 @@ struct vb2_keyblock {
#define FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR 1
/* Flags for vb2_fw_preamble.flags */
/* Reserved; do not use */
#define VB2_FIRMWARE_PREAMBLE_RESERVED0 0x00000001
/* Use RO-normal firmware (deprecated; do not use) */
#define VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL 0x00000001
/* Do not allow use of any hardware crypto accelerators. */
#define VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO 0x00000002

View File

@@ -239,7 +239,7 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
printf(" Firmware body size: %d\n", pre2->body_signature.data_size);
printf(" Preamble flags: %d\n", flags);
if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
if (flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
printf("Preamble requests USE_RO_NORMAL;"
" skipping body verification.\n");
goto done;
@@ -269,7 +269,7 @@ done:
/* Can't trust the BIOS unless everything is signed (in which case
* we've already returned), but standalone files are okay. */
if (state || (sign_key && good_sig)) {
if (!(flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL))
if (!(flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL))
printf("Body verification succeeded.\n");
if (state)
state->area[state->c].is_valid = 1;

View File

@@ -27,6 +27,7 @@
#include "kernel_blob.h"
#include "util_misc.h"
#include "vb1_helper.h"
#include "vb2_struct.h"
#include "vb21_common.h"
#include "host_key2.h"
#include "vboot_common.h"
@@ -80,6 +81,15 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
strerror(errno));
return 1;
}
sign_option.signprivate2 = vb2_read_private_key_pem(
sign_option.pem_signpriv,
sign_option.pem_algo);
if (!sign_option.signprivate2) {
fprintf(stderr,
"Unable to read PEM signing key: %s\n",
strerror(errno));
return 1;
}
vblock = KeyBlockCreate(data_key,
sign_option.signprivate,
sign_option.flags);
@@ -244,21 +254,22 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
void *data)
{
VbSignature *body_sig;
VbFirmwarePreambleHeader *preamble;
struct vb2_signature *body_sig;
struct vb2_fw_preamble *preamble;
int rv;
body_sig = CalculateSignature(buf, len, sign_option.signprivate);
body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate2);
if (!body_sig) {
fprintf(stderr, "Error calculating body signature\n");
return 1;
}
preamble = CreateFirmwarePreamble(sign_option.version,
sign_option.kernel_subkey,
body_sig,
sign_option.signprivate,
sign_option.flags);
preamble = vb2_create_fw_preamble(
sign_option.version,
(struct vb2_packed_key *)sign_option.kernel_subkey,
body_sig,
sign_option.signprivate2,
sign_option.flags);
if (!preamble) {
fprintf(stderr, "Error creating firmware preamble.\n");
free(body_sig);
@@ -290,7 +301,7 @@ static const char usage_pubkey[] = "\n"
" --pem_signpriv FILE.pem Signing key in PEM format...\n"
" --pem_algo NUM AND the algorithm to use (0 - %d)\n"
"\n"
" If a signing key is not given, the keyblock will not be signed (duh)."
" If a signing key is not given, the keyblock will not be signed."
"\n\n"
"And these, too:\n\n"
" -f|--flags NUM Flags specifying use conditions\n"
@@ -363,7 +374,7 @@ static const char usage_new_kpart[] = "\n"
"Required PARAMS:\n"
" -s|--signprivate FILE.vbprivk"
" The private key to sign the kernel blob\n"
" -b|--keyblock FILE.keyblock The keyblock containing the public\n"
" -b|--keyblock FILE.keyblock Keyblock containing the public\n"
" key to verify the kernel blob\n"
" -v|--version NUM The kernel version number\n"
" --bootloader FILE Bootloader stub\n"
@@ -398,7 +409,7 @@ static const char usage_old_kpart[] = "\n"
" in place if no OUTFILE given)\n"
"\n"
"Optional PARAMS:\n"
" -b|--keyblock FILE.keyblock The keyblock containing the public\n"
" -b|--keyblock FILE.keyblock Keyblock containing the public\n"
" key to verify the kernel blob\n"
" -v|--version NUM The kernel version number\n"
" --config FILE The kernel commandline file\n"
@@ -651,6 +662,11 @@ static int do_sign(int argc, char *argv[])
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);
errorcnt++;
}
break;
case 'b':
sign_option.keyblock = KeyBlockRead(optarg);
@@ -667,7 +683,8 @@ static int do_sign(int argc, char *argv[])
}
break;
case 'S':
sign_option.devsignprivate = PrivateKeyRead(optarg);
sign_option.devsignprivate =
vb2_read_private_key(optarg);
if (!sign_option.devsignprivate) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
@@ -1037,6 +1054,8 @@ done:
if (sign_option.signprivate)
free(sign_option.signprivate);
if (sign_option.signprivate2)
free(sign_option.signprivate2);
if (sign_option.keyblock)
free(sign_option.keyblock);
if (sign_option.kernel_subkey)

View File

@@ -92,8 +92,6 @@ static int Vblock(const char *outfile, const char *keyblock_file,
VbPrivateKey *signing_key;
VbPublicKey *kernel_subkey;
VbSignature *body_sig;
VbFirmwarePreambleHeader *preamble;
VbKeyBlockHeader *key_block;
uint64_t key_block_size;
uint8_t *fv_data;
@@ -127,6 +125,12 @@ static int Vblock(const char *outfile, const char *keyblock_file,
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);
if (!kernel_subkey) {
@@ -142,7 +146,8 @@ static int Vblock(const char *outfile, const char *keyblock_file,
VbExError("Empty firmware volume file\n");
return 1;
}
body_sig = CalculateSignature(fv_data, fv_size, signing_key);
struct vb2_signature *body_sig =
vb2_calculate_signature(fv_data, fv_size, signing_key2);
if (!body_sig) {
VbExError("Error calculating body signature\n");
return 1;
@@ -150,10 +155,10 @@ static int Vblock(const char *outfile, const char *keyblock_file,
free(fv_data);
/* Create preamble */
preamble = CreateFirmwarePreamble(version,
kernel_subkey,
body_sig,
signing_key, preamble_flags);
struct vb2_fw_preamble *preamble =
vb2_create_fw_preamble(version,
(struct vb2_packed_key *)kernel_subkey,
body_sig, signing_key2, preamble_flags);
if (!preamble) {
VbExError("Error creating preamble.\n");
return 1;
@@ -284,7 +289,7 @@ static int Verify(const char *infile, const char *signpubkey,
/* TODO: verify body size same as signature size */
/* Verify body */
if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
if (flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
printf("Preamble requests USE_RO_NORMAL;"
" skipping body verification.\n");
} else if (VB2_SUCCESS ==

View File

@@ -27,7 +27,7 @@ FILE_TYPE(GBB, "gbb", "GBB",
R_(ft_recognize_gbb),
S_(ft_show_gbb),
NONE)
FILE_TYPE(FW_PREAMBLE, "fw_pre", "VbFirmwarePreamble (VBLOCK_A/B)",
FILE_TYPE(FW_PREAMBLE, "fw_pre", "firmware preamble (VBLOCK_A/B)",
R_(ft_recognize_vblock1),
S_(ft_show_fw_preamble),
NONE)

View File

@@ -285,8 +285,8 @@ static int fmap_sign_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
goto whatever;
}
uint32_t more = key_block->key_block_size;
VbFirmwarePreambleHeader *preamble =
(VbFirmwarePreambleHeader *)(buf + more);
struct vb2_fw_preamble *preamble =
(struct vb2_fw_preamble *)(buf + more);
uint32_t fw_size = preamble->body_signature.data_size;
struct bios_area_s *fw_body_area = 0;
@@ -322,23 +322,23 @@ whatever:
static int write_new_preamble(struct bios_area_s *vblock,
struct bios_area_s *fw_body,
VbPrivateKey *signkey,
struct vb2_private_key *signkey,
VbKeyBlockHeader *keyblock)
{
VbSignature *body_sig;
VbFirmwarePreambleHeader *preamble;
struct vb2_signature *body_sig;
struct vb2_fw_preamble *preamble;
body_sig = CalculateSignature(fw_body->buf, fw_body->len, signkey);
body_sig = vb2_calculate_signature(fw_body->buf, fw_body->len, signkey);
if (!body_sig) {
fprintf(stderr, "Error calculating body signature\n");
return 1;
}
preamble = CreateFirmwarePreamble(sign_option.version,
sign_option.kernel_subkey,
body_sig,
signkey,
sign_option.flags);
preamble = vb2_create_fw_preamble(sign_option.version,
(struct vb2_packed_key *)sign_option.kernel_subkey,
body_sig,
signkey,
sign_option.flags);
if (!preamble) {
fprintf(stderr, "Error creating firmware preamble.\n");
free(body_sig);
@@ -420,13 +420,13 @@ static int sign_bios_at_end(struct bios_state_s *state)
sign_option.devkeyblock);
} else {
retval |= write_new_preamble(vblock_a, fw_a,
sign_option.signprivate,
sign_option.signprivate2,
sign_option.keyblock);
}
/* FW B is always normal keys */
retval |= write_new_preamble(vblock_b, fw_b,
sign_option.signprivate,
sign_option.signprivate2,
sign_option.keyblock);

View File

@@ -34,9 +34,10 @@ extern struct show_option_s show_option;
struct sign_option_s {
VbPrivateKey *signprivate;
struct vb2_private_key *signprivate2;
VbKeyBlockHeader *keyblock;
VbPublicKey *kernel_subkey;
VbPrivateKey *devsignprivate;
struct vb2_private_key *devsignprivate;
VbKeyBlockHeader *devkeyblock;
uint32_t version;
int version_specified;

View File

@@ -14,62 +14,6 @@
#include "utility.h"
#include "vboot_common.h"
VbFirmwarePreambleHeader *CreateFirmwarePreamble(
uint64_t firmware_version,
const VbPublicKey *kernel_subkey,
const VbSignature *body_signature,
const VbPrivateKey *signing_key,
uint32_t flags)
{
VbFirmwarePreambleHeader *h;
uint64_t signed_size = (sizeof(VbFirmwarePreambleHeader) +
kernel_subkey->key_size +
body_signature->sig_size);
uint64_t block_size = signed_size + siglen_map[signing_key->algorithm];
uint8_t *kernel_subkey_dest;
uint8_t *body_sig_dest;
uint8_t *block_sig_dest;
VbSignature *sigtmp;
/* Allocate key block */
h = (VbFirmwarePreambleHeader *)malloc(block_size);
if (!h)
return NULL;
Memset(h, 0, block_size);
kernel_subkey_dest = (uint8_t *)(h + 1);
body_sig_dest = kernel_subkey_dest + kernel_subkey->key_size;
block_sig_dest = body_sig_dest + body_signature->sig_size;
h->header_version_major = FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR;
h->header_version_minor = FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR;
h->preamble_size = block_size;
h->firmware_version = firmware_version;
h->flags = flags;
/* Copy data key */
PublicKeyInit(&h->kernel_subkey, kernel_subkey_dest,
kernel_subkey->key_size);
PublicKeyCopy(&h->kernel_subkey, kernel_subkey);
/* Copy body signature */
SignatureInit(&h->body_signature, body_sig_dest,
body_signature->sig_size, 0);
SignatureCopy(&h->body_signature, body_signature);
/* Set up signature struct so we can calculate the signature */
SignatureInit(&h->preamble_signature, block_sig_dest,
siglen_map[signing_key->algorithm], signed_size);
/* Calculate signature */
sigtmp = CalculateSignature((uint8_t *)h, signed_size, signing_key);
SignatureCopy(&h->preamble_signature, sigtmp);
free(sigtmp);
/* Return the header */
return h;
}
VbKernelPreambleHeader *CreateKernelPreamble(
uint64_t kernel_version,
uint64_t body_load_address,

74
host/lib/host_common2.c Normal file
View File

@@ -0,0 +1,74 @@
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Host functions for verified boot.
*
* TODO: change all 'return 0', 'return 1' into meaningful return codes.
*/
#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 "vb2_common.h"
#include "vboot_common.h"
struct vb2_fw_preamble *vb2_create_fw_preamble(
uint32_t firmware_version,
const struct vb2_packed_key *kernel_subkey,
const struct vb2_signature *body_signature,
const struct vb2_private_key *signing_key,
uint32_t flags)
{
uint32_t signed_size = (sizeof(struct vb2_fw_preamble) +
kernel_subkey->key_size +
body_signature->sig_size);
uint32_t block_size = signed_size +
vb2_rsa_sig_size(signing_key->sig_alg);
/* Allocate preamble */
struct vb2_fw_preamble *h =
(struct vb2_fw_preamble *)calloc(block_size, 1);
if (!h)
return NULL;
uint8_t *kernel_subkey_dest = (uint8_t *)(h + 1);
uint8_t *body_sig_dest = kernel_subkey_dest + kernel_subkey->key_size;
uint8_t *block_sig_dest = body_sig_dest + body_signature->sig_size;
h->header_version_major = FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR;
h->header_version_minor = FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR;
h->preamble_size = block_size;
h->firmware_version = firmware_version;
h->flags = flags;
/* Copy data key */
PublicKeyInit((VbPublicKey *)&h->kernel_subkey, kernel_subkey_dest,
kernel_subkey->key_size);
PublicKeyCopy((VbPublicKey *)&h->kernel_subkey,
(VbPublicKey *)kernel_subkey);
/* Copy body signature */
vb2_init_signature(&h->body_signature,
body_sig_dest, body_signature->sig_size, 0);
vb2_copy_signature(&h->body_signature, body_signature);
/* Set up signature struct so we can calculate the signature */
vb2_init_signature(&h->preamble_signature, block_sig_dest,
vb2_rsa_sig_size(signing_key->sig_alg), signed_size);
/* Calculate signature */
struct vb2_signature *sig =
vb2_calculate_signature((uint8_t *)h, signed_size, signing_key);
vb2_copy_signature(&h->preamble_signature, sig);
free(sig);
/* Return the header */
return h;
}

105
host/lib/host_key2.c Normal file
View File

@@ -0,0 +1,105 @@
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Host functions for keys.
*/
/* TODO: change all 'return 0', 'return 1' into meaningful return codes */
#include <openssl/pem.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "2sysincludes.h"
#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "cryptolib.h"
#include "host_common.h"
#include "host_key.h"
#include "host_key2.h"
#include "host_misc.h"
#include "vb2_common.h"
#include "vboot_common.h"
struct vb2_private_key *vb2_read_private_key(const char *filename)
{
uint8_t *buf = NULL;
uint32_t bufsize = 0;
if (VB2_SUCCESS != vb2_read_file(filename, &buf, &bufsize)) {
VbExError("unable to read from file %s\n", filename);
return NULL;
}
struct vb2_private_key *key =
(struct vb2_private_key *)calloc(sizeof(*key), 1);
if (!key) {
VbExError("Unable to allocate private key\n");
free(buf);
return NULL;
}
uint64_t alg = *(uint64_t *)buf;
key->hash_alg = vb2_crypto_to_hash(alg);
key->sig_alg = vb2_crypto_to_signature(alg);
const unsigned char *start = buf + sizeof(alg);
key->rsa_private_key =
d2i_RSAPrivateKey(0, &start, bufsize - sizeof(alg));
if (!key->rsa_private_key) {
VbExError("Unable to parse RSA private key\n");
free(buf);
free(key);
return NULL;
}
free(buf);
return key;
}
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__);
return NULL;
}
/* Read private key */
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);
fclose(f);
if (!rsa_key) {
VB2_DEBUG("%s(): Couldn't read private key from file: %s\n",
__FUNCTION__, filename);
return NULL;
}
/* Store key and algorithm in our struct */
struct vb2_private_key *key =
(struct vb2_private_key *)calloc(sizeof(*key), 1);
if (!key) {
RSA_free(rsa_key);
return NULL;
}
key->rsa_private_key = rsa_key;
key->hash_alg = vb2_crypto_to_hash(algorithm);
key->sig_alg = vb2_crypto_to_signature(algorithm);
/* Return the key */
return key;
}

View File

@@ -57,9 +57,9 @@ VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key,
Memset(&h->key_block_signature, 0, sizeof(VbSignature));
/* Calculate checksum */
sigtmp = CalculateChecksum((uint8_t*)h, signed_size);
SignatureCopy(&h->key_block_checksum, sigtmp);
free(sigtmp);
struct vb2_signature *chk = vb2_sha512_signature((uint8_t*)h, signed_size);
SignatureCopy(&h->key_block_checksum, (VbSignature *)chk);
free(chk);
/* Calculate signature */
if (signing_key) {
@@ -117,9 +117,9 @@ VbKeyBlockHeader* KeyBlockCreate_external(const VbPublicKey* data_key,
siglen_map[algorithm], signed_size);
/* Calculate checksum */
sigtmp = CalculateChecksum((uint8_t*)h, signed_size);
SignatureCopy(&h->key_block_checksum, sigtmp);
free(sigtmp);
struct vb2_signature *chk = vb2_sha512_signature((uint8_t*)h, signed_size);
SignatureCopy(&h->key_block_checksum, (VbSignature *)chk);
free(chk);
/* Calculate signature */
sigtmp = CalculateSignature_external((uint8_t*)h, signed_size,

View File

@@ -54,54 +54,6 @@ int SignatureCopy(VbSignature* dest, const VbSignature* src) {
return 0;
}
VbSignature* CalculateChecksum(const uint8_t* data, uint64_t size) {
uint8_t header_checksum[VB2_SHA512_DIGEST_SIZE];
VbSignature* sig;
if (VB2_SUCCESS != vb2_digest_buffer(data, size, VB2_HASH_SHA512,
header_checksum,
sizeof(header_checksum)))
return NULL;
sig = SignatureAlloc(VB2_SHA512_DIGEST_SIZE, 0);
if (!sig)
return NULL;
sig->sig_offset = sizeof(VbSignature);
sig->sig_size = VB2_SHA512_DIGEST_SIZE;
sig->data_size = size;
/* Signature data immediately follows the header */
Memcpy(GetSignatureData(sig), header_checksum, VB2_SHA512_DIGEST_SIZE);
return sig;
}
VbSignature* CalculateHash(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);
VbSignature* sig = NULL;
/* Calculate the digest */
if (VB2_SUCCESS != vb2_digest_buffer(data, size, vb2_alg,
digest, sizeof(digest)))
return NULL;
/* Allocate output signature */
sig = SignatureAlloc(digest_size, size);
if (!sig)
return NULL;
/* The digest itself is the signature data */
Memcpy(GetSignatureData(sig), digest, digest_size);
/* Return the signature */
return sig;
}
VbSignature* CalculateSignature(const uint8_t* data, uint64_t size,
const VbPrivateKey* key) {
int vb2_alg = vb2_crypto_to_hash(key->algorithm);

135
host/lib/host_signature2.c Normal file
View File

@@ -0,0 +1,135 @@
/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Host functions for signature generation.
*/
#include <openssl/rsa.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "2sysincludes.h"
#include "2common.h"
#include "2rsa.h"
#include "2sha.h"
#include "cryptolib.h"
#include "file_keys.h"
#include "host_common.h"
#include "host_key2.h"
#include "host_signature2.h"
#include "vb2_common.h"
#include "vboot_common.h"
struct vb2_signature *vb2_alloc_signature(uint32_t sig_size,
uint32_t data_size)
{
struct vb2_signature *sig = (struct vb2_signature *)
calloc(sizeof(*sig) + sig_size, 1);
if (!sig)
return NULL;
sig->sig_offset = sizeof(*sig);
sig->sig_size = sig_size;
sig->data_size = data_size;
return sig;
}
void vb2_init_signature(struct vb2_signature *sig, uint8_t *sig_data,
uint32_t sig_size, uint32_t data_size)
{
sig->sig_offset = OffsetOf(sig, sig_data);
sig->sig_size = sig_size;
sig->data_size = data_size;
}
int vb2_copy_signature(struct vb2_signature *dest,
const struct vb2_signature *src)
{
if (dest->sig_size < src->sig_size)
return VB2_ERROR_SIG_SIZE;
dest->sig_size = src->sig_size;
dest->data_size = src->data_size;
memcpy(vb2_signature_data(dest),
vb2_signature_data((struct vb2_signature *)src),
src->sig_size);
return VB2_SUCCESS;
}
struct vb2_signature *vb2_sha512_signature(const uint8_t *data, uint32_t size)
{
uint8_t digest[VB2_SHA512_DIGEST_SIZE];
if (VB2_SUCCESS != vb2_digest_buffer(data, size, VB2_HASH_SHA512,
digest, sizeof(digest)))
return NULL;
struct vb2_signature *sig =
vb2_alloc_signature(VB2_SHA512_DIGEST_SIZE, size);
if (!sig)
return NULL;
memcpy(vb2_signature_data(sig), digest, VB2_SHA512_DIGEST_SIZE);
return sig;
}
struct vb2_signature *vb2_calculate_signature(
const uint8_t *data, uint32_t size,
const struct vb2_private_key *key)
{
uint8_t digest[VB2_MAX_DIGEST_SIZE];
uint32_t digest_size = vb2_digest_size(key->hash_alg);
uint32_t digest_info_size = 0;
const uint8_t *digest_info = NULL;
if (VB2_SUCCESS != vb2_digest_info(key->hash_alg,
&digest_info, &digest_info_size))
return NULL;
/* Calculate the digest */
if (VB2_SUCCESS != vb2_digest_buffer(data, size, key->hash_alg,
digest, digest_size))
return NULL;
/* Prepend the digest info to the digest */
int signature_digest_len = digest_size + digest_info_size;
uint8_t *signature_digest = malloc(signature_digest_len);
if (!signature_digest)
return NULL;
memcpy(signature_digest, digest_info, digest_info_size);
memcpy(signature_digest + digest_info_size, digest, digest_size);
/* Allocate output signature */
struct vb2_signature *sig = (struct vb2_signature *)
vb2_alloc_signature(vb2_rsa_sig_size(key->sig_alg), size);
if (!sig) {
free(signature_digest);
return NULL;
}
/* Sign the signature_digest into our output buffer */
int rv = RSA_private_encrypt(signature_digest_len, /* Input length */
signature_digest, /* Input data */
vb2_signature_data(sig), /* Output sig */
key->rsa_private_key, /* Key to use */
RSA_PKCS1_PADDING); /* Padding */
free(signature_digest);
if (-1 == rv) {
VB2_DEBUG("%s: RSA_private_encrypt() failed.\n", __func__);
free(sig);
return NULL;
}
/* Return the signature */
return sig;
}

View File

@@ -24,17 +24,21 @@
#include "vboot_struct.h"
/**
* Create a firmware preamble, signed with [signing_key].
* Create a firmware preamble.
*
* Caller owns the returned pointer, and must free it with Free().
* @param firmware_version Firmware version
* @param kernel_subkey Kernel subkey to store in preamble
* @param body_signature Signature of firmware body
* @param signing_key Private key to sign header with
* @param flags Firmware preamble flags
*
* Returns NULL if error.
* @return The preamble, or NULL if error. Caller must free() it.
*/
VbFirmwarePreambleHeader *CreateFirmwarePreamble(
uint64_t firmware_version,
const VbPublicKey *kernel_subkey,
const VbSignature *body_signature,
const VbPrivateKey *signing_key,
struct vb2_fw_preamble *vb2_create_fw_preamble(
uint32_t firmware_version,
const struct vb2_packed_key *kernel_subkey,
const struct vb2_signature *body_signature,
const struct vb2_private_key *signing_key,
uint32_t flags);
/**

View File

@@ -8,10 +8,12 @@
#ifndef VBOOT_REFERENCE_HOST_KEY_H_
#define VBOOT_REFERENCE_HOST_KEY_H_
#include "2crypto.h"
#include "cryptolib.h"
#include "vboot_struct.h"
struct vb2_packed_key;
struct vb2_private_key;
typedef struct rsa_st RSA;
@@ -23,9 +25,11 @@ typedef struct VbPrivateKey {
/* Read a private key from a .pem file. Caller owns the returned pointer,
* and must free it with PrivateKeyFree(). */
* and must free() it. */
VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm);
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);
@@ -33,13 +37,12 @@ void PrivateKeyFree(VbPrivateKey* key);
/* Write a private key to a file in .vbprivk format. */
int PrivateKeyWrite(const char* filename, const VbPrivateKey* key);
/* Read a privake key from a .vbprivk file. Caller owns the returned
* pointer, and must free it with PrivateKeyFree().
/* Read a private key from a .vbprivk file. Caller owns the returned
* pointer, and must free() it.
*
* Returns NULL if error. */
VbPrivateKey* PrivateKeyRead(const char* filename);
struct vb2_private_key *vb2_read_private_key(const char *filename);
/* Allocate a new public key with space for a [key_size] byte key. */
VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm,

View File

@@ -13,35 +13,57 @@
#include "utility.h"
#include "vboot_struct.h"
struct vb2_private_key;
struct vb2_signature;
/* Initialize a signature struct. */
/**
* Initialize a signature struct.
*
* @param sig Structure to initialize
* @param sig_data Pointer to signature data buffer (after sig)
* @param sig_size Size of signature data buffer in bytes
* @param data_size Amount of data signed in bytes
*/
void SignatureInit(VbSignature* sig, uint8_t* sig_data,
uint64_t sig_size, uint64_t data_size);
void vb2_init_signature(struct vb2_signature *sig, uint8_t *sig_data,
uint32_t sig_size, uint32_t data_size);
/* Allocate a new signature with space for a [sig_size] byte signature. */
/**
* Allocate a new signature.
*
* @param sig_size Size of signature in bytes
* @param data_size Amount of data signed in bytes
*
* @return The signature or NULL if error. Caller must free() it.
*/
VbSignature* SignatureAlloc(uint64_t sig_size, uint64_t data_size);
struct vb2_signature *vb2_alloc_signature(uint32_t sig_size,
uint32_t data_size);
/* Copy a signature key from [src] to [dest].
/**
* Copy a signature.
*
* Returns 0 if success, non-zero if error. */
* @param dest Destination signature
* @param src Source signature
*
* @return VB2_SUCCESS, or non-zero if error. */
int SignatureCopy(VbSignature* dest, const VbSignature* src);
int vb2_copy_signature(struct vb2_signature *dest,
const struct vb2_signature *src);
/* Calculates a SHA-512 checksum.
* Caller owns the returned pointer, and must free it with Free().
/**
* Calculate a SHA-512 digest-only signature.
*
* Returns NULL on error. */
VbSignature* CalculateChecksum(const uint8_t* data, uint64_t size);
/* Calculates a hash of the data using the algorithm from the specified key.
* Caller owns the returned pointer, and must free it with Free().
* Caller owns the returned pointer, and must free() it.
*
* Returns NULL on error. */
VbSignature* CalculateHash(const uint8_t* data, uint64_t size,
const VbPrivateKey* key);
* @param data Pointer to data to hash
* @param size Length of data in bytes
*
* @return The signature, or NULL if error.
*/
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().
@@ -49,6 +71,9 @@ VbSignature* CalculateHash(const uint8_t* data, uint64_t size,
* Returns NULL on error. */
VbSignature* CalculateSignature(const uint8_t* data, uint64_t size,
const VbPrivateKey* key);
struct vb2_signature *vb2_calculate_signature(
const uint8_t *data, uint32_t size,
const struct vb2_private_key *key);
/* Calculates a signature for the data using the specified key and
* an external program.

View File

@@ -17,17 +17,9 @@
#include "host_signature2.h"
#include "host_misc.h"
/**
* Get the digest info for a hash algorithm
*
* @param hash_alg Hash algorithm
* @param buf_ptr On success, points to the digest info
* @param size_ptr On success, contains the info size in bytes
* @return VB2_SUCCESS, or non-zero error code on failure.
*/
static int vb2_digest_info(enum vb2_hash_algorithm hash_alg,
const uint8_t **buf_ptr,
uint32_t *size_ptr)
int vb2_digest_info(enum vb2_hash_algorithm hash_alg,
const uint8_t **buf_ptr,
uint32_t *size_ptr)
{
*buf_ptr = NULL;
*size_ptr = 0;

View File

@@ -11,6 +11,19 @@
#include "2struct.h"
struct vb2_private_key;
struct vb21_signature;
/**
* Get the digest info for a hash algorithm
*
* @param hash_alg Hash algorithm
* @param buf_ptr On success, points to the digest info
* @param size_ptr On success, contains the info size in bytes
* @return VB2_SUCCESS, or non-zero error code on failure.
*/
int vb2_digest_info(enum vb2_hash_algorithm hash_alg,
const uint8_t **buf_ptr,
uint32_t *size_ptr);
/**
* Sign data buffer

View File

@@ -36,11 +36,9 @@ int main(void)
SignatureInit(0, 0, 0, 0);
SignatureAlloc(0, 0);
SignatureCopy(0, 0);
CalculateChecksum(0, 0);
CalculateSignature(0, 0, 0);
/* host_common.h */
CreateFirmwarePreamble(0, 0, 0, 0, 0);
CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
/* file_keys.h */

View File

@@ -4,11 +4,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This generates the pre-change test data used to ensure that modifications to
# VbFirmwarePreambleHeader and VbKernelPreambleHeader will not break the
# signing tools for older releases. This was run *before* any modifications, so
# be sure to revert the repo back to the correct point if you need to run it
# again.
# This generates the pre-change test data used to ensure that
# modifications to vb2_fw_preamble and VbKernelPreambleHeader will not
# break the signing tools for older releases. This was run *before*
# any modifications, so be sure to revert the repo back to the correct
# point if you need to run it again.
# Load common constants and variables for tests.

View File

@@ -4,10 +4,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This tests that vblocks using pre-3.0 versions of VbFirmwarePreambleHeader
# and VbKernelPreambleHeader will still verify (or not) correctly. We need to
# keep the old versions around to make sure that we can still sign images in
# the ways that existing devices can validate.
# This tests that vblocks using pre-3.0 versions of vb2_fw_preamble
# and VbKernelPreambleHeader will still verify (or not) correctly. We
# need to keep the old versions around to make sure that we can still
# sign images in the ways that existing devices can validate.
# Load common constants and variables for tests.
. "$(dirname "$0")/common.sh"

View File

@@ -140,14 +140,14 @@ 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;
struct vb2_private_key *private_key = NULL;
struct vb2_signature *sig = NULL;
struct vb2_packed_key *key1;
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);
private_key = vb2_read_private_key_pem(filename, key_algorithm);
if (!private_key) {
fprintf(stderr, "Error reading private_key: %s\n", filename);
return 1;
@@ -162,8 +162,8 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
}
/* Calculate good signatures */
sig = (struct vb2_signature *)
CalculateSignature(test_data, sizeof(test_data), private_key);
sig = vb2_calculate_signature(test_data, sizeof(test_data),
private_key);
TEST_PTR_NEQ(sig, 0, "Calculate signature");
if (!sig)
return 1;

View File

@@ -203,18 +203,18 @@ static void test_verify_keyblock(const VbPublicKey *public_key,
}
static void resign_fw_preamble(struct vb2_fw_preamble *h,
const VbPrivateKey *key)
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_fw_preamble(const VbPublicKey *public_key,
const VbPrivateKey *private_key,
const VbPublicKey *kernel_subkey)
struct vb2_private_key *private_key,
struct vb2_packed_key *kernel_subkey)
{
struct vb2_fw_preamble *hdr;
struct vb2_fw_preamble *h;
@@ -227,17 +227,16 @@ static void test_verify_fw_preamble(const VbPublicKey *public_key,
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
/* Create a dummy signature */
VbSignature *body_sig = SignatureAlloc(56, 78);
struct vb2_signature *body_sig = vb2_alloc_signature(56, 78);
TEST_SUCC(vb2_unpack_key(&rsa, (uint8_t *)public_key,
public_key->key_offset + public_key->key_size),
"vb2_verify_fw_preamble() prereq key");
hdr = (struct vb2_fw_preamble *)
CreateFirmwarePreamble(0x1234, kernel_subkey, body_sig,
private_key, 0x5678);
hdr = vb2_create_fw_preamble(0x1234, kernel_subkey, body_sig,
private_key, 0x5678);
TEST_PTR_NEQ(hdr, NULL,
"VerifyFirmwarePreamble() prereq test preamble");
"vb2_verify_fw_preamble() prereq test preamble");
if (!hdr)
return;
hsize = (uint32_t) hdr->preamble_size;
@@ -368,7 +367,7 @@ static void test_verify_kernel_preamble(const VbPublicKey *public_key,
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
/* Create a dummy signature */
VbSignature *body_sig = SignatureAlloc(56, 0x214000);
struct vb2_signature *body_sig = vb2_alloc_signature(56, 0x214000);
TEST_SUCC(vb2_unpack_key(&rsa, (uint8_t *)public_key,
public_key->key_offset + public_key->key_size),
@@ -376,7 +375,8 @@ static void test_verify_kernel_preamble(const VbPublicKey *public_key,
hdr = (struct vb2_kernel_preamble *)
CreateKernelPreamble(0x1234, 0x100000, 0x300000, 0x4000,
body_sig, 0x304000, 0x10000, 0, 0,
(VbSignature *)body_sig,
0x304000, 0x10000, 0, 0,
private_key);
TEST_PTR_NEQ(hdr, NULL,
"vb2_verify_kernel_preamble() prereq test preamble");
@@ -542,6 +542,14 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
return 1;
}
struct vb2_private_key *signing_private_key2 =
vb2_read_private_key_pem(filename, signing_key_algorithm);
if (!signing_private_key2) {
fprintf(stderr, "Error reading signing_private_key: %s\n",
filename);
return 1;
}
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
signing_public_key = PublicKeyReadKeyb(filename,
signing_key_algorithm, 1);
@@ -564,14 +572,16 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
data_public_key);
test_verify_keyblock(signing_public_key, signing_private_key,
data_public_key);
test_verify_fw_preamble(signing_public_key, signing_private_key,
data_public_key);
test_verify_fw_preamble(signing_public_key, signing_private_key2,
(struct vb2_packed_key *)data_public_key);
test_verify_kernel_preamble(signing_public_key, signing_private_key);
if (signing_public_key)
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);

View File

@@ -43,9 +43,6 @@ static void test_struct_packing(void)
TEST_EQ(EXPECTED_VB2_KEYBLOCK_SIZE,
EXPECTED_VBKEYBLOCKHEADER_SIZE,
"vboot1->2 keyblock sizes same");
TEST_EQ(EXPECTED_VB2_FW_PREAMBLE_SIZE,
EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE,
"vboot1->2 firmware preamble sizes same");
}
/**

View File

@@ -25,12 +25,6 @@ static void StructPackingTest(void)
"sizeof(VbSignature)");
TEST_EQ(EXPECTED_VBKEYBLOCKHEADER_SIZE, sizeof(VbKeyBlockHeader),
"sizeof(VbKeyBlockHeader)");
TEST_EQ(EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE,
sizeof(VbFirmwarePreambleHeader2_0),
"sizeof(VbFirmwarePreambleHeader2_0)");
TEST_EQ(EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE,
sizeof(VbFirmwarePreambleHeader),
"sizeof(VbFirmwarePreambleHeader)");
TEST_EQ(EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE,
sizeof(VbKernelPreambleHeader),
"sizeof(VbKernelPreambleHeader)");