mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
futility: Use vboot 2.0 APIs for public keys
This replaces calls to the old vboot 1 APIs with their vboot 2.0 equivalents. BUG=chromium:611535 BRANCH=none TEST=make runtests Change-Id: Ieb1a127577c6428c47ac088c3aaa0d0dad6275a8 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/356541 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
df2bd9b1e7
commit
f7559e4b46
@@ -676,6 +676,12 @@ enum vb2_return_code {
|
|||||||
/* Unable to convert back to vb1 crypto algorithm */
|
/* Unable to convert back to vb1 crypto algorithm */
|
||||||
VB2_ERROR_VB1_CRYPTO_ALGORITHM,
|
VB2_ERROR_VB1_CRYPTO_ALGORITHM,
|
||||||
|
|
||||||
|
/* Unable to allocate packed key */
|
||||||
|
VB2_ERROR_PACKED_KEY_ALLOC,
|
||||||
|
|
||||||
|
/* Unable to copy packed key */
|
||||||
|
VB2_ERROR_PACKED_KEY_COPY,
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Errors generated by host library signature functions
|
* Errors generated by host library signature functions
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,6 +17,15 @@
|
|||||||
#define VBOOT_REFERENCE_VB2_STRUCT_H_
|
#define VBOOT_REFERENCE_VB2_STRUCT_H_
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rollback protection currently uses a 32-bit value comprised of the bottom 16
|
||||||
|
* bits of the (firmware or kernel) preamble version and the bottom 16 bits of
|
||||||
|
* the key version. So each of those versions is effectively limited to 16
|
||||||
|
* bits even though they get stored in 32-bit fields.
|
||||||
|
*/
|
||||||
|
#define VB2_MAX_KEY_VERSION 0xffff
|
||||||
|
#define VB2_MAX_PREAMBLE_VERSION 0xffff
|
||||||
|
|
||||||
/* Packed public key data */
|
/* Packed public key data */
|
||||||
struct vb2_packed_key {
|
struct vb2_packed_key {
|
||||||
/* Offset of key data from start of this struct */
|
/* Offset of key data from start of this struct */
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ int vb2_load_kernel_keyblock(struct vb2_context *ctx)
|
|||||||
|
|
||||||
/* Check for keyblock rollback if not in recovery mode */
|
/* Check for keyblock rollback if not in recovery mode */
|
||||||
/* Key version is the upper 16 bits of the composite version */
|
/* Key version is the upper 16 bits of the composite version */
|
||||||
if (!rec_switch && kb->data_key.key_version > 0xffff) {
|
if (!rec_switch && kb->data_key.key_version > VB2_MAX_KEY_VERSION) {
|
||||||
keyblock_is_valid = 0;
|
keyblock_is_valid = 0;
|
||||||
if (need_keyblock_valid)
|
if (need_keyblock_valid)
|
||||||
return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_RANGE;
|
return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_RANGE;
|
||||||
@@ -419,7 +419,7 @@ int vb2_load_kernel_preamble(struct vb2_context *ctx)
|
|||||||
* Kernel preamble version is the lower 16 bits of the composite kernel
|
* Kernel preamble version is the lower 16 bits of the composite kernel
|
||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
if (pre->kernel_version > 0xffff)
|
if (pre->kernel_version > VB2_MAX_PREAMBLE_VERSION)
|
||||||
return VB2_ERROR_KERNEL_PREAMBLE_VERSION_RANGE;
|
return VB2_ERROR_KERNEL_PREAMBLE_VERSION_RANGE;
|
||||||
|
|
||||||
/* Combine with the key version from vb2_load_kernel_keyblock() */
|
/* Combine with the key version from vb2_load_kernel_keyblock() */
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Key version is the upper 16 bits of the composite firmware version */
|
/* Key version is the upper 16 bits of the composite firmware version */
|
||||||
if (kb->data_key.key_version > 0xffff)
|
if (kb->data_key.key_version > VB2_MAX_KEY_VERSION)
|
||||||
rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
|
rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
|
||||||
if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16)) {
|
if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16)) {
|
||||||
if (sd->gbb_flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
|
if (sd->gbb_flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
|
||||||
@@ -253,7 +253,7 @@ int vb2_load_fw_preamble(struct vb2_context *ctx)
|
|||||||
* Firmware version is the lower 16 bits of the composite firmware
|
* Firmware version is the lower 16 bits of the composite firmware
|
||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
if (pre->firmware_version > 0xffff)
|
if (pre->firmware_version > VB2_MAX_PREAMBLE_VERSION)
|
||||||
rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
|
rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
|
||||||
/* Combine with the key version from vb2_load_fw_keyblock() */
|
/* Combine with the key version from vb2_load_fw_keyblock() */
|
||||||
sd->fw_version |= pre->firmware_version;
|
sd->fw_version |= pre->firmware_version;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "2rsa.h"
|
#include "2rsa.h"
|
||||||
#include "2sha.h"
|
#include "2sha.h"
|
||||||
#include "util_misc.h"
|
#include "util_misc.h"
|
||||||
|
#include "vb2_common.h"
|
||||||
#include "vb21_common.h"
|
#include "vb21_common.h"
|
||||||
|
|
||||||
#include "host_key.h"
|
#include "host_key.h"
|
||||||
@@ -81,7 +82,7 @@ static void print_help(int argc, char *argv[])
|
|||||||
static int vb1_make_keypair()
|
static int vb1_make_keypair()
|
||||||
{
|
{
|
||||||
struct vb2_private_key *privkey = NULL;
|
struct vb2_private_key *privkey = NULL;
|
||||||
VbPublicKey *pubkey = 0;
|
struct vb2_packed_key *pubkey = NULL;
|
||||||
struct rsa_st *rsa_key = NULL;
|
struct rsa_st *rsa_key = NULL;
|
||||||
uint8_t *keyb_data = 0;
|
uint8_t *keyb_data = 0;
|
||||||
uint32_t keyb_size;
|
uint32_t keyb_size;
|
||||||
@@ -136,14 +137,14 @@ static int vb1_make_keypair()
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey = PublicKeyAlloc(keyb_size, vb1_algorithm, opt_version);
|
pubkey = vb2_alloc_packed_key(keyb_size, vb1_algorithm, opt_version);
|
||||||
if (!pubkey)
|
if (!pubkey)
|
||||||
goto done;
|
goto done;
|
||||||
memcpy(GetPublicKeyData(pubkey), keyb_data, keyb_size);
|
memcpy((uint8_t *)vb2_packed_key_data(pubkey), keyb_data, keyb_size);
|
||||||
|
|
||||||
/* Write it out */
|
/* Write it out */
|
||||||
strcpy(outext, ".vbpubk");
|
strcpy(outext, ".vbpubk");
|
||||||
if (0 != PublicKeyWrite(outfile, pubkey)) {
|
if (VB2_SUCCESS != vb2_write_packed_key(outfile, pubkey)) {
|
||||||
fprintf(stderr, "unable to write public key\n");
|
fprintf(stderr, "unable to write public key\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -214,7 +215,8 @@ static int vb2_make_keypair()
|
|||||||
privkey->sig_alg = sig_alg;
|
privkey->sig_alg = sig_alg;
|
||||||
privkey->hash_alg = opt_hash_alg;
|
privkey->hash_alg = opt_hash_alg;
|
||||||
if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) {
|
if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) {
|
||||||
fprintf(stderr, "Unable to set the private key description\n");
|
fprintf(stderr,
|
||||||
|
"Unable to set the private key description\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,22 +78,22 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
|
|||||||
sign_option.flags,
|
sign_option.flags,
|
||||||
sign_option.pem_external);
|
sign_option.pem_external);
|
||||||
} else {
|
} else {
|
||||||
sign_option.signprivate2 = vb2_read_private_key_pem(
|
sign_option.signprivate = vb2_read_private_key_pem(
|
||||||
sign_option.pem_signpriv,
|
sign_option.pem_signpriv,
|
||||||
sign_option.pem_algo);
|
sign_option.pem_algo);
|
||||||
if (!sign_option.signprivate2) {
|
if (!sign_option.signprivate) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Unable to read PEM signing key: %s\n",
|
"Unable to read PEM signing key: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
block = vb2_create_keyblock(data_key,
|
block = vb2_create_keyblock(data_key,
|
||||||
sign_option.signprivate2,
|
sign_option.signprivate,
|
||||||
sign_option.flags);
|
sign_option.flags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Not PEM. Should already have a signing key. */
|
/* Not PEM. Should already have a signing key. */
|
||||||
block = vb2_create_keyblock(data_key, sign_option.signprivate2,
|
block = vb2_create_keyblock(data_key, sign_option.signprivate,
|
||||||
sign_option.flags);
|
sign_option.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
|
|||||||
sign_option.version,
|
sign_option.version,
|
||||||
sign_option.kloadaddr,
|
sign_option.kloadaddr,
|
||||||
sign_option.keyblock,
|
sign_option.keyblock,
|
||||||
sign_option.signprivate2,
|
sign_option.signprivate,
|
||||||
sign_option.flags, &vblock_size);
|
sign_option.flags, &vblock_size);
|
||||||
if (!vblock_data) {
|
if (!vblock_data) {
|
||||||
fprintf(stderr, "Unable to sign kernel blob\n");
|
fprintf(stderr, "Unable to sign kernel blob\n");
|
||||||
@@ -217,7 +217,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
|
|||||||
sign_option.version,
|
sign_option.version,
|
||||||
sign_option.kloadaddr,
|
sign_option.kloadaddr,
|
||||||
keyblock,
|
keyblock,
|
||||||
sign_option.signprivate2,
|
sign_option.signprivate,
|
||||||
sign_option.flags,
|
sign_option.flags,
|
||||||
&vblock_size);
|
&vblock_size);
|
||||||
if (!vblock_data) {
|
if (!vblock_data) {
|
||||||
@@ -255,7 +255,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
|
|||||||
struct vb2_fw_preamble *preamble;
|
struct vb2_fw_preamble *preamble;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate2);
|
body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate);
|
||||||
if (!body_sig) {
|
if (!body_sig) {
|
||||||
fprintf(stderr, "Error calculating body signature\n");
|
fprintf(stderr, "Error calculating body signature\n");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -265,7 +265,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
|
|||||||
sign_option.version,
|
sign_option.version,
|
||||||
(struct vb2_packed_key *)sign_option.kernel_subkey,
|
(struct vb2_packed_key *)sign_option.kernel_subkey,
|
||||||
body_sig,
|
body_sig,
|
||||||
sign_option.signprivate2,
|
sign_option.signprivate,
|
||||||
sign_option.flags);
|
sign_option.flags);
|
||||||
if (!preamble) {
|
if (!preamble) {
|
||||||
fprintf(stderr, "Error creating firmware preamble.\n");
|
fprintf(stderr, "Error creating firmware preamble.\n");
|
||||||
@@ -654,8 +654,8 @@ static int do_sign(int argc, char *argv[])
|
|||||||
&longindex)) != -1) {
|
&longindex)) != -1) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 's':
|
case 's':
|
||||||
sign_option.signprivate2 = vb2_read_private_key(optarg);
|
sign_option.signprivate = vb2_read_private_key(optarg);
|
||||||
if (!sign_option.signprivate2) {
|
if (!sign_option.signprivate) {
|
||||||
fprintf(stderr, "Error reading %s\n", optarg);
|
fprintf(stderr, "Error reading %s\n", optarg);
|
||||||
errorcnt++;
|
errorcnt++;
|
||||||
}
|
}
|
||||||
@@ -668,7 +668,7 @@ static int do_sign(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
sign_option.kernel_subkey = PublicKeyRead(optarg);
|
sign_option.kernel_subkey = vb2_read_packed_key(optarg);
|
||||||
if (!sign_option.kernel_subkey) {
|
if (!sign_option.kernel_subkey) {
|
||||||
fprintf(stderr, "Error reading %s\n", optarg);
|
fprintf(stderr, "Error reading %s\n", optarg);
|
||||||
errorcnt++;
|
errorcnt++;
|
||||||
@@ -908,13 +908,13 @@ static int do_sign(int argc, char *argv[])
|
|||||||
switch (sign_option.type) {
|
switch (sign_option.type) {
|
||||||
case FILE_TYPE_PUBKEY:
|
case FILE_TYPE_PUBKEY:
|
||||||
sign_option.create_new_outfile = 1;
|
sign_option.create_new_outfile = 1;
|
||||||
if (sign_option.signprivate2 && sign_option.pem_signpriv) {
|
if (sign_option.signprivate && sign_option.pem_signpriv) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Only one of --signprivate and --pem_signpriv"
|
"Only one of --signprivate and --pem_signpriv"
|
||||||
" can be specified\n");
|
" can be specified\n");
|
||||||
errorcnt++;
|
errorcnt++;
|
||||||
}
|
}
|
||||||
if ((sign_option.signprivate2 &&
|
if ((sign_option.signprivate &&
|
||||||
sign_option.pem_algo_specified) ||
|
sign_option.pem_algo_specified) ||
|
||||||
(sign_option.pem_signpriv &&
|
(sign_option.pem_signpriv &&
|
||||||
!sign_option.pem_algo_specified)) {
|
!sign_option.pem_algo_specified)) {
|
||||||
@@ -932,18 +932,18 @@ static int do_sign(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case FILE_TYPE_BIOS_IMAGE:
|
case FILE_TYPE_BIOS_IMAGE:
|
||||||
case FILE_TYPE_OLD_BIOS_IMAGE:
|
case FILE_TYPE_OLD_BIOS_IMAGE:
|
||||||
errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
|
errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
|
||||||
errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
|
errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
|
||||||
errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
|
errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
|
||||||
break;
|
break;
|
||||||
case FILE_TYPE_KERN_PREAMBLE:
|
case FILE_TYPE_KERN_PREAMBLE:
|
||||||
errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
|
errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
|
||||||
if (sign_option.vblockonly || sign_option.inout_file_count > 1)
|
if (sign_option.vblockonly || sign_option.inout_file_count > 1)
|
||||||
sign_option.create_new_outfile = 1;
|
sign_option.create_new_outfile = 1;
|
||||||
break;
|
break;
|
||||||
case FILE_TYPE_RAW_FIRMWARE:
|
case FILE_TYPE_RAW_FIRMWARE:
|
||||||
sign_option.create_new_outfile = 1;
|
sign_option.create_new_outfile = 1;
|
||||||
errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
|
errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
|
||||||
errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
|
errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
|
||||||
errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
|
errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
|
||||||
errorcnt += no_opt_if(!sign_option.version_specified,
|
errorcnt += no_opt_if(!sign_option.version_specified,
|
||||||
@@ -951,7 +951,7 @@ static int do_sign(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case FILE_TYPE_RAW_KERNEL:
|
case FILE_TYPE_RAW_KERNEL:
|
||||||
sign_option.create_new_outfile = 1;
|
sign_option.create_new_outfile = 1;
|
||||||
errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate");
|
errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
|
||||||
errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
|
errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
|
||||||
errorcnt += no_opt_if(!sign_option.version_specified,
|
errorcnt += no_opt_if(!sign_option.version_specified,
|
||||||
"version");
|
"version");
|
||||||
@@ -1044,8 +1044,8 @@ done:
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sign_option.signprivate2)
|
if (sign_option.signprivate)
|
||||||
free(sign_option.signprivate2);
|
free(sign_option.signprivate);
|
||||||
if (sign_option.keyblock)
|
if (sign_option.keyblock)
|
||||||
free(sign_option.keyblock);
|
free(sign_option.keyblock);
|
||||||
if (sign_option.kernel_subkey)
|
if (sign_option.kernel_subkey)
|
||||||
|
|||||||
@@ -285,12 +285,11 @@ static int do_verify(const char *infile, const char *signpubkey,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kernelkey_file) {
|
if (kernelkey_file &&
|
||||||
if (0 != PublicKeyWrite(kernelkey_file,
|
VB2_SUCCESS != vb2_write_packed_key(kernelkey_file,
|
||||||
(struct VbPublicKey *)kernel_subkey)) {
|
kernel_subkey)) {
|
||||||
VbExError("Unable to write kernel subkey\n");
|
VbExError("Unable to write kernel subkey\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
|
|||||||
struct vb2_keyblock *keyblock = NULL;
|
struct vb2_keyblock *keyblock = NULL;
|
||||||
struct vb2_keyblock *t_keyblock = NULL;
|
struct vb2_keyblock *t_keyblock = NULL;
|
||||||
struct vb2_private_key *signpriv_key = NULL;
|
struct vb2_private_key *signpriv_key = NULL;
|
||||||
VbPublicKey *signpub_key = NULL;
|
struct vb2_packed_key *signpub_key = NULL;
|
||||||
uint8_t *kpart_data = NULL;
|
uint8_t *kpart_data = NULL;
|
||||||
uint64_t kpart_size = 0;
|
uint64_t kpart_size = 0;
|
||||||
uint8_t *vmlinuz_buf = NULL;
|
uint8_t *vmlinuz_buf = NULL;
|
||||||
@@ -547,7 +547,7 @@ static int do_vbutil_kernel(int argc, char *argv[])
|
|||||||
/* Optional */
|
/* Optional */
|
||||||
|
|
||||||
if (signpubkey_file) {
|
if (signpubkey_file) {
|
||||||
signpub_key = PublicKeyRead(signpubkey_file);
|
signpub_key = vb2_read_packed_key(signpubkey_file);
|
||||||
if (!signpub_key)
|
if (!signpub_key)
|
||||||
Fatal("Error reading public key.\n");
|
Fatal("Error reading public key.\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,16 +76,15 @@ static void print_help(int argc, char *argv[])
|
|||||||
static int do_pack(const char *infile, const char *outfile, uint32_t algorithm,
|
static int do_pack(const char *infile, const char *outfile, uint32_t algorithm,
|
||||||
uint32_t version)
|
uint32_t version)
|
||||||
{
|
{
|
||||||
VbPublicKey *pubkey;
|
|
||||||
|
|
||||||
if (!infile || !outfile) {
|
if (!infile || !outfile) {
|
||||||
fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
|
fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey = PublicKeyReadKeyb(infile, algorithm, version);
|
struct vb2_packed_key *pubkey =
|
||||||
|
vb2_read_packed_keyb(infile, algorithm, version);
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
if (0 != PublicKeyWrite(outfile, pubkey)) {
|
if (0 != vb2_write_packed_key(outfile, pubkey)) {
|
||||||
fprintf(stderr, "vbutil_key: Error writing key.\n");
|
fprintf(stderr, "vbutil_key: Error writing key.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -111,28 +110,26 @@ static int do_pack(const char *infile, const char *outfile, uint32_t algorithm,
|
|||||||
/* Unpack a .vbpubk or .vbprivk */
|
/* Unpack a .vbpubk or .vbprivk */
|
||||||
static int do_unpack(const char *infile, const char *outfile)
|
static int do_unpack(const char *infile, const char *outfile)
|
||||||
{
|
{
|
||||||
VbPublicKey *pubkey;
|
struct vb2_packed_key *pubkey;
|
||||||
|
|
||||||
if (!infile) {
|
if (!infile) {
|
||||||
fprintf(stderr, "Need file to unpack\n");
|
fprintf(stderr, "Need file to unpack\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkey = PublicKeyRead(infile);
|
pubkey = vb2_read_packed_key(infile);
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
printf("Public Key file: %s\n", infile);
|
printf("Public Key file: %s\n", infile);
|
||||||
printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm,
|
printf("Algorithm: %u %s\n", pubkey->algorithm,
|
||||||
vb1_crypto_name(pubkey->algorithm));
|
vb1_crypto_name(pubkey->algorithm));
|
||||||
printf("Key Version: %" PRIu64 "\n", pubkey->key_version);
|
printf("Key Version: %u\n", pubkey->key_version);
|
||||||
printf("Key sha1sum: %s\n",
|
printf("Key sha1sum: %s\n",
|
||||||
packed_key_sha1_string((struct vb2_packed_key *)pubkey));
|
packed_key_sha1_string(pubkey));
|
||||||
if (outfile) {
|
if (outfile &&
|
||||||
if (0 != PublicKeyWrite(outfile, pubkey)) {
|
VB2_SUCCESS != vb2_write_packed_key(outfile, pubkey)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "butil_key: Error writing key copy\n");
|
||||||
"vbutil_key: Error writing key copy\n");
|
free(pubkey);
|
||||||
free(pubkey);
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(pubkey);
|
free(pubkey);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -146,14 +143,11 @@ static int do_unpack(const char *infile, const char *outfile)
|
|||||||
vb2_get_crypto_algorithm(privkey->hash_alg,
|
vb2_get_crypto_algorithm(privkey->hash_alg,
|
||||||
privkey->sig_alg);
|
privkey->sig_alg);
|
||||||
printf("Algorithm: %u %s\n", alg, vb1_crypto_name(alg));
|
printf("Algorithm: %u %s\n", alg, vb1_crypto_name(alg));
|
||||||
if (outfile) {
|
if (outfile &&
|
||||||
if (VB2_SUCCESS !=
|
VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) {
|
||||||
vb2_write_private_key(outfile, privkey)) {
|
fprintf(stderr,"vbutil_key: Error writing key copy\n");
|
||||||
fprintf(stderr,
|
free(privkey);
|
||||||
"vbutil_key: Error writing key copy\n");
|
return 1;
|
||||||
free(privkey);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(privkey);
|
free(privkey);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -225,14 +225,12 @@ static int Unpack(const char *infile, const char *datapubkey,
|
|||||||
vb1_crypto_name(data_key->algorithm));
|
vb1_crypto_name(data_key->algorithm));
|
||||||
printf("Data key version: %u\n", data_key->key_version);
|
printf("Data key version: %u\n", data_key->key_version);
|
||||||
printf("Data key sha1sum: %s\n",
|
printf("Data key sha1sum: %s\n",
|
||||||
packed_key_sha1_string((struct vb2_packed_key *)data_key));
|
packed_key_sha1_string(data_key));
|
||||||
|
|
||||||
if (datapubkey) {
|
if (datapubkey &&
|
||||||
if (0 != PublicKeyWrite(datapubkey, (VbPublicKey *)data_key)) {
|
VB2_SUCCESS != vb2_write_packed_key(datapubkey, data_key)) {
|
||||||
fprintf(stderr, "vbutil_keyblock:"
|
fprintf(stderr, "vbutil_keyblock: error writing public key\n");
|
||||||
" unable to write public key\n");
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(block);
|
free(block);
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
|
|||||||
{
|
{
|
||||||
GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)buf;
|
GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)buf;
|
||||||
struct bios_state_s *state = (struct bios_state_s *)data;
|
struct bios_state_s *state = (struct bios_state_s *)data;
|
||||||
struct vb2_packed_key *pubkey;
|
|
||||||
BmpBlockHeader *bmp;
|
BmpBlockHeader *bmp;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
uint32_t maxlen = 0;
|
uint32_t maxlen = 0;
|
||||||
@@ -96,7 +95,8 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
|
|||||||
printf(" HWID: %s\n", buf + gbb->hwid_offset);
|
printf(" HWID: %s\n", buf + gbb->hwid_offset);
|
||||||
print_hwid_digest(gbb, " digest: ", "\n");
|
print_hwid_digest(gbb, " digest: ", "\n");
|
||||||
|
|
||||||
pubkey = (struct vb2_packed_key *)(buf + gbb->rootkey_offset);
|
struct vb2_packed_key *pubkey =
|
||||||
|
(struct vb2_packed_key *)(buf + gbb->rootkey_offset);
|
||||||
if (packed_key_looks_ok(pubkey, gbb->rootkey_size)) {
|
if (packed_key_looks_ok(pubkey, gbb->rootkey_size)) {
|
||||||
if (state) {
|
if (state) {
|
||||||
state->rootkey.offset =
|
state->rootkey.offset =
|
||||||
@@ -282,8 +282,9 @@ static int fmap_sign_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
|
|||||||
goto whatever;
|
goto whatever;
|
||||||
}
|
}
|
||||||
|
|
||||||
RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key);
|
if (!packed_key_looks_ok(&keyblock->data_key,
|
||||||
if (!rsa) {
|
keyblock->data_key.key_offset +
|
||||||
|
keyblock->data_key.key_size)) {
|
||||||
fprintf(stderr, "Warning: %s public key is invalid. "
|
fprintf(stderr, "Warning: %s public key is invalid. "
|
||||||
"Signing the entire FW FMAP region...\n", name);
|
"Signing the entire FW FMAP region...\n", name);
|
||||||
goto whatever;
|
goto whatever;
|
||||||
@@ -424,13 +425,13 @@ static int sign_bios_at_end(struct bios_state_s *state)
|
|||||||
sign_option.devkeyblock);
|
sign_option.devkeyblock);
|
||||||
} else {
|
} else {
|
||||||
retval |= write_new_preamble(vblock_a, fw_a,
|
retval |= write_new_preamble(vblock_a, fw_a,
|
||||||
sign_option.signprivate2,
|
sign_option.signprivate,
|
||||||
sign_option.keyblock);
|
sign_option.keyblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FW B is always normal keys */
|
/* FW B is always normal keys */
|
||||||
retval |= write_new_preamble(vblock_b, fw_b,
|
retval |= write_new_preamble(vblock_b, fw_b,
|
||||||
sign_option.signprivate2,
|
sign_option.signprivate,
|
||||||
sign_option.keyblock);
|
sign_option.keyblock);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ struct show_option_s {
|
|||||||
extern struct show_option_s show_option;
|
extern struct show_option_s show_option;
|
||||||
|
|
||||||
struct sign_option_s {
|
struct sign_option_s {
|
||||||
struct vb2_private_key *signprivate2;
|
struct vb2_private_key *signprivate;
|
||||||
struct vb2_keyblock *keyblock;
|
struct vb2_keyblock *keyblock;
|
||||||
VbPublicKey *kernel_subkey;
|
struct vb2_packed_key *kernel_subkey;
|
||||||
struct vb2_private_key *devsignprivate;
|
struct vb2_private_key *devsignprivate;
|
||||||
struct vb2_keyblock *devkeyblock;
|
struct vb2_keyblock *devkeyblock;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|||||||
@@ -502,17 +502,16 @@ int WriteSomeParts(const char *outfile,
|
|||||||
/* Returns 0 on success */
|
/* Returns 0 on success */
|
||||||
int VerifyKernelBlob(uint8_t *kernel_blob,
|
int VerifyKernelBlob(uint8_t *kernel_blob,
|
||||||
uint64_t kernel_size,
|
uint64_t kernel_size,
|
||||||
VbPublicKey *signpub_key,
|
struct vb2_packed_key *signpub_key,
|
||||||
const char *keyblock_outfile,
|
const char *keyblock_outfile,
|
||||||
uint64_t min_version)
|
uint64_t min_version)
|
||||||
{
|
{
|
||||||
RSAPublicKey *rsa;
|
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
uint64_t vmlinuz_header_size = 0;
|
uint64_t vmlinuz_header_size = 0;
|
||||||
uint64_t vmlinuz_header_address = 0;
|
uint64_t vmlinuz_header_address = 0;
|
||||||
|
|
||||||
static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
|
uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE];
|
||||||
static struct vb2_workbuf wb;
|
struct vb2_workbuf wb;
|
||||||
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
|
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
|
||||||
|
|
||||||
if (signpub_key) {
|
if (signpub_key) {
|
||||||
@@ -585,15 +584,18 @@ int VerifyKernelBlob(uint8_t *kernel_blob,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsa = PublicKeyToRSA((VbPublicKey *)data_key);
|
struct vb2_public_key pubkey;
|
||||||
if (!rsa) {
|
if (VB2_SUCCESS !=
|
||||||
|
vb2_unpack_key(&pubkey, (uint8_t *)data_key,
|
||||||
|
data_key->key_offset + data_key->key_size)) {
|
||||||
fprintf(stderr, "Error parsing data key.\n");
|
fprintf(stderr, "Error parsing data key.\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify preamble */
|
/* Verify preamble */
|
||||||
if (0 != VerifyKernelPreamble(g_preamble,
|
if (VB2_SUCCESS != vb2_verify_kernel_preamble(
|
||||||
g_preamble->preamble_size, rsa)) {
|
(struct vb2_kernel_preamble *)g_preamble,
|
||||||
|
g_preamble->preamble_size, &pubkey, &wb)) {
|
||||||
fprintf(stderr, "Error verifying preamble.\n");
|
fprintf(stderr, "Error verifying preamble.\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -642,8 +644,10 @@ int VerifyKernelBlob(uint8_t *kernel_blob,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Verify body */
|
/* Verify body */
|
||||||
if (0 != VerifyData(kernel_blob, kernel_size,
|
if (VB2_SUCCESS !=
|
||||||
&g_preamble->body_signature, rsa)) {
|
vb2_verify_data(kernel_blob, kernel_size,
|
||||||
|
(struct vb2_signature *)&g_preamble->body_signature,
|
||||||
|
&pubkey, &wb)) {
|
||||||
fprintf(stderr, "Error verifying kernel body.\n");
|
fprintf(stderr, "Error verifying kernel body.\n");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -749,17 +753,14 @@ uint8_t *CreateKernelBlob(uint8_t *vmlinuz_buf, uint64_t vmlinuz_size,
|
|||||||
|
|
||||||
enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len)
|
enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
int rv;
|
uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE];
|
||||||
|
|
||||||
uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
|
|
||||||
struct vb2_workbuf wb;
|
struct vb2_workbuf wb;
|
||||||
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
|
vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
|
||||||
|
|
||||||
/* Vboot 2.0 signature checks destroy the buffer, so make a copy */
|
/* Vboot 2.0 signature checks destroy the buffer, so make a copy */
|
||||||
uint8_t *buf2 = malloc(len);
|
uint8_t *buf2 = malloc(len);
|
||||||
memcpy(buf2, buf, len);
|
memcpy(buf2, buf, len);
|
||||||
|
struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf2;
|
||||||
struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
|
|
||||||
if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
|
if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
|
||||||
free(buf2);
|
free(buf2);
|
||||||
return FILE_TYPE_UNKNOWN;
|
return FILE_TYPE_UNKNOWN;
|
||||||
@@ -780,18 +781,26 @@ enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len)
|
|||||||
|
|
||||||
/* Followed by firmware preamble too? */
|
/* Followed by firmware preamble too? */
|
||||||
struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(buf2 + more);
|
struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(buf2 + more);
|
||||||
rv = vb2_verify_fw_preamble(pre2, len - more, &data_key, &wb);
|
if (VB2_SUCCESS ==
|
||||||
free(buf2);
|
vb2_verify_fw_preamble(pre2, len - more, &data_key, &wb)) {
|
||||||
if (VB2_SUCCESS == rv)
|
free(buf2);
|
||||||
return FILE_TYPE_FW_PREAMBLE;
|
return FILE_TYPE_FW_PREAMBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recopy since firmware preamble check destroyed the buffer */
|
||||||
|
memcpy(buf2, buf, len);
|
||||||
|
|
||||||
/* Or maybe kernel preamble? */
|
/* Or maybe kernel preamble? */
|
||||||
RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key);
|
struct vb2_kernel_preamble *kern_preamble =
|
||||||
VbKernelPreambleHeader *kern_preamble =
|
(struct vb2_kernel_preamble *)(buf2 + more);
|
||||||
(VbKernelPreambleHeader *)(buf + more);
|
if (VB2_SUCCESS ==
|
||||||
if (VBOOT_SUCCESS ==
|
vb2_verify_kernel_preamble(kern_preamble, len - more,
|
||||||
VerifyKernelPreamble(kern_preamble, len - more, rsa))
|
&data_key, &wb)) {
|
||||||
|
free(buf2);
|
||||||
return FILE_TYPE_KERN_PREAMBLE;
|
return FILE_TYPE_KERN_PREAMBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf2);
|
||||||
|
|
||||||
/* No, just keyblock */
|
/* No, just keyblock */
|
||||||
return FILE_TYPE_KEYBLOCK;
|
return FILE_TYPE_KEYBLOCK;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ int UpdateKernelBlobConfig(uint8_t *kblob_data, uint64_t kblob_size,
|
|||||||
|
|
||||||
int VerifyKernelBlob(uint8_t *kernel_blob,
|
int VerifyKernelBlob(uint8_t *kernel_blob,
|
||||||
uint64_t kernel_size,
|
uint64_t kernel_size,
|
||||||
VbPublicKey *signpub_key,
|
struct vb2_packed_key *signpub_key,
|
||||||
const char *keyblock_outfile,
|
const char *keyblock_outfile,
|
||||||
uint64_t min_version);
|
uint64_t min_version);
|
||||||
|
|
||||||
|
|||||||
@@ -49,15 +49,22 @@ struct vb2_fw_preamble *vb2_create_fw_preamble(
|
|||||||
h->flags = flags;
|
h->flags = flags;
|
||||||
|
|
||||||
/* Copy data key */
|
/* Copy data key */
|
||||||
PublicKeyInit((VbPublicKey *)&h->kernel_subkey, kernel_subkey_dest,
|
vb2_init_packed_key(&h->kernel_subkey, kernel_subkey_dest,
|
||||||
kernel_subkey->key_size);
|
kernel_subkey->key_size);
|
||||||
PublicKeyCopy((VbPublicKey *)&h->kernel_subkey,
|
if (VB2_SUCCESS !=
|
||||||
(VbPublicKey *)kernel_subkey);
|
vb2_copy_packed_key(&h->kernel_subkey, kernel_subkey)) {
|
||||||
|
free(h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy body signature */
|
/* Copy body signature */
|
||||||
vb2_init_signature(&h->body_signature,
|
vb2_init_signature(&h->body_signature,
|
||||||
body_sig_dest, body_signature->sig_size, 0);
|
body_sig_dest, body_signature->sig_size, 0);
|
||||||
vb2_copy_signature(&h->body_signature, body_signature);
|
if (VB2_SUCCESS !=
|
||||||
|
vb2_copy_signature(&h->body_signature, body_signature)) {
|
||||||
|
free(h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up signature struct so we can calculate the signature */
|
/* Set up signature struct so we can calculate the signature */
|
||||||
vb2_init_signature(&h->preamble_signature, block_sig_dest,
|
vb2_init_signature(&h->preamble_signature, block_sig_dest,
|
||||||
|
|||||||
@@ -13,6 +13,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "2sysincludes.h"
|
||||||
|
#include "2common.h"
|
||||||
|
#include "2rsa.h"
|
||||||
|
#include "2sha.h"
|
||||||
#include "cryptolib.h"
|
#include "cryptolib.h"
|
||||||
#include "host_common.h"
|
#include "host_common.h"
|
||||||
#include "host_key.h"
|
#include "host_key.h"
|
||||||
@@ -20,82 +24,15 @@
|
|||||||
#include "vb2_common.h"
|
#include "vb2_common.h"
|
||||||
#include "vboot_common.h"
|
#include "vboot_common.h"
|
||||||
|
|
||||||
/* 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) {
|
|
||||||
VbPublicKey* key = (VbPublicKey*)malloc(sizeof(VbPublicKey) + key_size);
|
|
||||||
if (!key)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
key->algorithm = algorithm;
|
|
||||||
key->key_version = version;
|
|
||||||
key->key_size = key_size;
|
|
||||||
key->key_offset = sizeof(VbPublicKey);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
|
|
||||||
uint64_t version) {
|
|
||||||
VbPublicKey* key;
|
|
||||||
uint8_t* key_data;
|
|
||||||
uint64_t key_size;
|
|
||||||
uint64_t expected_key_size;
|
|
||||||
|
|
||||||
if (algorithm >= kNumAlgorithms) {
|
|
||||||
VBDEBUG(("PublicKeyReadKeyb() called with invalid algorithm!\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (version > 0xFFFF) {
|
|
||||||
/* Currently, TPM only supports 16-bit version */
|
|
||||||
VBDEBUG(("PublicKeyReadKeyb() called with invalid version!\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
key_data = ReadFile(filename, &key_size);
|
|
||||||
if (!key_data)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!RSAProcessedKeySize(algorithm, &expected_key_size) ||
|
|
||||||
expected_key_size != key_size) {
|
|
||||||
VBDEBUG(("PublicKeyReadKeyb() wrong key size for algorithm\n"));
|
|
||||||
free(key_data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
key = PublicKeyAlloc(key_size, algorithm, version);
|
|
||||||
if (!key) {
|
|
||||||
free(key_data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Memcpy(GetPublicKeyData(key), key_data, key_size);
|
|
||||||
|
|
||||||
free(key_data);
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size)
|
int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size)
|
||||||
{
|
{
|
||||||
uint64_t key_size;
|
struct vb2_public_key pubkey;
|
||||||
|
if (VB2_SUCCESS != vb2_unpack_key(&pubkey, (const uint8_t *)key, size))
|
||||||
if (size < sizeof(*key))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Sanity-check key data */
|
if (key->key_version > VB2_MAX_KEY_VERSION) {
|
||||||
if (0 != VerifyPublicKeyInside(key, size, (VbPublicKey *)key)) {
|
/* Currently, TPM only supports 16-bit version */
|
||||||
VBDEBUG(("PublicKeyRead() not a VbPublicKey\n"));
|
VB2_DEBUG("%s() - packed key invalid version\n", __func__);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (key->algorithm >= kNumAlgorithms) {
|
|
||||||
VBDEBUG(("PublicKeyRead() invalid algorithm\n"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (key->key_version > 0xFFFF) {
|
|
||||||
VBDEBUG(("PublicKeyRead() invalid version\n"));
|
|
||||||
return 0; /* Currently, TPM only supports 16-bit version */
|
|
||||||
}
|
|
||||||
if (!RSAProcessedKeySize(key->algorithm, &key_size) ||
|
|
||||||
key_size != key->key_size) {
|
|
||||||
VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n"));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,37 +40,20 @@ int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VbPublicKey* PublicKeyRead(const char* filename) {
|
/* TODO: the host code just uses this to check the embedded key length in
|
||||||
struct vb2_packed_key *key;
|
* uint32_t's. It should get folded into packed_key_looks_ok. */
|
||||||
uint64_t file_size;
|
|
||||||
|
|
||||||
key = (struct vb2_packed_key *)ReadFile(filename, &file_size);
|
RSAPublicKey *vb2_packed_key_to_rsa(const struct vb2_packed_key *key)
|
||||||
if (!key)
|
{
|
||||||
|
RSAPublicKey *rsa;
|
||||||
|
|
||||||
|
if (!packed_key_looks_ok(key, key->key_size))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rsa = RSAPublicKeyFromBuf(vb2_packed_key_data(key), key->key_size);
|
||||||
|
if (!rsa)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (packed_key_looks_ok(key, file_size))
|
rsa->algorithm = (unsigned int)key->algorithm;
|
||||||
return (VbPublicKey *)key;
|
return rsa;
|
||||||
|
|
||||||
/* Error */
|
|
||||||
free(key);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PublicKeyWrite(const char* filename, const VbPublicKey* key) {
|
|
||||||
VbPublicKey* kcopy;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/* Copy the key, so its data is contiguous with the header */
|
|
||||||
kcopy = PublicKeyAlloc(key->key_size, 0, 0);
|
|
||||||
if (!kcopy)
|
|
||||||
return 1;
|
|
||||||
if (0 != PublicKeyCopy(kcopy, key)) {
|
|
||||||
free(kcopy);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write the copy, then free it */
|
|
||||||
rv = WriteFile(filename, kcopy, kcopy->key_offset + kcopy->key_size);
|
|
||||||
free(kcopy);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,6 +170,22 @@ void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data,
|
|||||||
key->algorithm = VB2_ALG_COUNT; /* Key not present yet */
|
key->algorithm = VB2_ALG_COUNT; /* Key not present yet */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vb2_packed_key *vb2_alloc_packed_key(uint32_t key_size,
|
||||||
|
uint32_t algorithm,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
struct vb2_packed_key *key =
|
||||||
|
(struct vb2_packed_key *)calloc(sizeof(*key) + key_size, 1);
|
||||||
|
if (!key)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
key->algorithm = algorithm;
|
||||||
|
key->key_version = version;
|
||||||
|
key->key_size = key_size;
|
||||||
|
key->key_offset = sizeof(*key);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
int vb2_copy_packed_key(struct vb2_packed_key *dest,
|
int vb2_copy_packed_key(struct vb2_packed_key *dest,
|
||||||
const struct vb2_packed_key *src)
|
const struct vb2_packed_key *src)
|
||||||
{
|
{
|
||||||
@@ -201,3 +217,64 @@ struct vb2_packed_key *vb2_read_packed_key(const char *filename)
|
|||||||
free(key);
|
free(key);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vb2_packed_key *vb2_read_packed_keyb(const char *filename,
|
||||||
|
uint32_t algorithm,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
if (algorithm >= VB2_ALG_COUNT) {
|
||||||
|
fprintf(stderr, "%s() - invalid algorithm\n", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (version > VB2_MAX_KEY_VERSION) {
|
||||||
|
/* Currently, TPM only supports 16-bit version */
|
||||||
|
fprintf(stderr, "%s() - invalid version 0x%x\n", __func__,
|
||||||
|
version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *key_data = NULL;
|
||||||
|
uint32_t key_size = 0;
|
||||||
|
if (VB2_SUCCESS != vb2_read_file(filename, &key_data, &key_size))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
uint64_t expected_key_size;
|
||||||
|
if (!RSAProcessedKeySize(algorithm, &expected_key_size) ||
|
||||||
|
expected_key_size != key_size) {
|
||||||
|
fprintf(stderr, "%s() - wrong key size %u for algorithm %u\n",
|
||||||
|
__func__, key_size, algorithm);
|
||||||
|
free(key_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vb2_packed_key *key =
|
||||||
|
vb2_alloc_packed_key(key_size, algorithm, version);
|
||||||
|
if (!key) {
|
||||||
|
free(key_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy((uint8_t *)vb2_packed_key_data(key), key_data, key_size);
|
||||||
|
|
||||||
|
free(key_data);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vb2_write_packed_key(const char *filename,
|
||||||
|
const struct vb2_packed_key *key)
|
||||||
|
{
|
||||||
|
/* Copy the key, so its data is contiguous with the header */
|
||||||
|
struct vb2_packed_key *kcopy =
|
||||||
|
vb2_alloc_packed_key(key->key_size, 0, 0);
|
||||||
|
if (!kcopy)
|
||||||
|
return VB2_ERROR_PACKED_KEY_ALLOC;
|
||||||
|
if (VB2_SUCCESS != vb2_copy_packed_key(kcopy, key)) {
|
||||||
|
free(kcopy);
|
||||||
|
return VB2_ERROR_PACKED_KEY_COPY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the copy, then free it */
|
||||||
|
int rv = vb2_write_file(filename, kcopy,
|
||||||
|
kcopy->key_offset + kcopy->key_size);
|
||||||
|
free(kcopy);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
#define VBOOT_REFERENCE_HOST_KEY_H_
|
#define VBOOT_REFERENCE_HOST_KEY_H_
|
||||||
|
|
||||||
#include "2crypto.h"
|
#include "2crypto.h"
|
||||||
#include "cryptolib.h"
|
|
||||||
#include "vboot_struct.h"
|
|
||||||
|
|
||||||
struct vb2_packed_key;
|
struct vb2_packed_key;
|
||||||
struct vb2_private_key;
|
struct vb2_private_key;
|
||||||
@@ -68,9 +66,17 @@ int vb2_write_private_key(const char *filename,
|
|||||||
*/
|
*/
|
||||||
struct vb2_private_key *vb2_read_private_key(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,
|
* Allocate a new public key.
|
||||||
uint64_t version);
|
* @param key_size Size of key data the key can hold
|
||||||
|
* @param algorithm Algorithm to store in key header
|
||||||
|
* @param version Version to store in key header
|
||||||
|
*
|
||||||
|
* @return The public key or NULL if error. Caller must free() it.
|
||||||
|
*/
|
||||||
|
struct vb2_packed_key *vb2_alloc_packed_key(uint32_t key_size,
|
||||||
|
uint32_t algorithm,
|
||||||
|
uint32_t version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a packed key structure.
|
* Initialize a packed key structure.
|
||||||
@@ -93,26 +99,49 @@ void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data,
|
|||||||
int vb2_copy_packed_key(struct vb2_packed_key *dest,
|
int vb2_copy_packed_key(struct vb2_packed_key *dest,
|
||||||
const struct vb2_packed_key *src);
|
const struct vb2_packed_key *src);
|
||||||
|
|
||||||
/* Read a public key from a .vbpubk file. Caller owns the returned
|
/**
|
||||||
* pointer, and must free it with Free().
|
* Read a packed key from a .vbpubk file.
|
||||||
*
|
*
|
||||||
* Returns NULL if error. */
|
* @param filename Name of file to read
|
||||||
VbPublicKey* PublicKeyRead(const char* filename);
|
* @param algorithm Crypto algorithm to associate with key
|
||||||
|
* @param version Version to store in key
|
||||||
|
*
|
||||||
|
* @return The packed key, or NULL if error. Caller must free() it.
|
||||||
|
*/
|
||||||
struct vb2_packed_key *vb2_read_packed_key(const char *filename);
|
struct vb2_packed_key *vb2_read_packed_key(const char *filename);
|
||||||
|
|
||||||
/* Return true if the packed (public) key struct appears correct. */
|
/**
|
||||||
|
* Sanity-check a packed key structure.
|
||||||
|
*
|
||||||
|
* @param key Key to check
|
||||||
|
* @param size Size of key buffer in bytes
|
||||||
|
*
|
||||||
|
* @return True if the key struct appears valid.
|
||||||
|
*/
|
||||||
int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size);
|
int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size);
|
||||||
|
|
||||||
/* Read a public key from a .keyb file. Caller owns the returned
|
/**
|
||||||
* pointer, and must free it with Free().
|
* Read a packed key from a .keyb file.
|
||||||
*
|
*
|
||||||
* Returns NULL if error. */
|
* @param filename Name of file to read
|
||||||
VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm,
|
* @param algorithm Crypto algorithm to associate with key
|
||||||
uint64_t version);
|
* @param version Version to store in key
|
||||||
|
*
|
||||||
|
* @return The packed key, or NULL if error. Caller must free() it.
|
||||||
/* Write a public key to a file in .vbpubk format. */
|
*/
|
||||||
int PublicKeyWrite(const char* filename, const VbPublicKey* key);
|
struct vb2_packed_key *vb2_read_packed_keyb(const char *filename,
|
||||||
|
uint32_t algorithm,
|
||||||
|
uint32_t version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a packed key in .vbpubk format.
|
||||||
|
*
|
||||||
|
* @param filename Name of file to write
|
||||||
|
* @param key Key to write
|
||||||
|
*
|
||||||
|
* @return VB2_SUCCESS, or non-zero if error.
|
||||||
|
*/
|
||||||
|
int vb2_write_packed_key(const char *filename,
|
||||||
|
const struct vb2_packed_key *key);
|
||||||
|
|
||||||
#endif /* VBOOT_REFERENCE_HOST_KEY_H_ */
|
#endif /* VBOOT_REFERENCE_HOST_KEY_H_ */
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ const char *private_key_sha1_string(const struct vb2_private_key *key);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Our packed RSBPublicKey buffer (historically in files ending with ".keyb",
|
* Our packed RSBPublicKey buffer (historically in files ending with ".keyb",
|
||||||
* but also the part of VbPublicKey and struct vb21_packed_key that is
|
* but also the part of struct vb2_packed_key and struct vb21_packed_key that
|
||||||
* referenced by .key_offset) has this binary format:
|
* is referenced by .key_offset) has this binary format:
|
||||||
*
|
*
|
||||||
* struct {
|
* struct {
|
||||||
* uint32_t nwords; // size of RSA key in 32-bit words
|
* uint32_t nwords; // size of RSA key in 32-bit words
|
||||||
|
|||||||
@@ -15,12 +15,6 @@
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* host_key.h */
|
|
||||||
PublicKeyAlloc(0, 0, 0);
|
|
||||||
PublicKeyRead(0);
|
|
||||||
PublicKeyReadKeyb(0, 0, 0);
|
|
||||||
PublicKeyWrite(0, 0);
|
|
||||||
|
|
||||||
/* host_misc.h */
|
/* host_misc.h */
|
||||||
ReadFile(0, 0);
|
ReadFile(0, 0);
|
||||||
WriteFile(0, 0, 0);
|
WriteFile(0, 0, 0);
|
||||||
|
|||||||
@@ -154,8 +154,7 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len);
|
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len);
|
||||||
key1 = (struct vb2_packed_key *)
|
key1 = vb2_read_packed_keyb(filename, key_algorithm, 1);
|
||||||
PublicKeyReadKeyb(filename, key_algorithm, 1);
|
|
||||||
if (!key1) {
|
if (!key1) {
|
||||||
fprintf(stderr, "Error reading public_key: %s\n", filename);
|
fprintf(stderr, "Error reading public_key: %s\n", filename);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ static void resign_fw_preamble(struct vb2_fw_preamble *h,
|
|||||||
free(sig);
|
free(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_verify_fw_preamble(const VbPublicKey *public_key,
|
static void test_verify_fw_preamble(struct vb2_packed_key *public_key,
|
||||||
struct vb2_private_key *private_key,
|
struct vb2_private_key *private_key,
|
||||||
struct vb2_packed_key *kernel_subkey)
|
struct vb2_packed_key *kernel_subkey)
|
||||||
{
|
{
|
||||||
@@ -340,7 +340,7 @@ static void resign_kernel_preamble(struct vb2_kernel_preamble *h,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void test_verify_kernel_preamble(
|
static void test_verify_kernel_preamble(
|
||||||
const VbPublicKey *public_key,
|
const struct vb2_packed_key *public_key,
|
||||||
const struct vb2_private_key *private_key)
|
const struct vb2_private_key *private_key)
|
||||||
{
|
{
|
||||||
struct vb2_kernel_preamble *hdr;
|
struct vb2_kernel_preamble *hdr;
|
||||||
@@ -512,9 +512,6 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
|
|||||||
int signing_rsa_len = siglen_map[signing_key_algorithm] * 8;
|
int signing_rsa_len = siglen_map[signing_key_algorithm] * 8;
|
||||||
int data_rsa_len = siglen_map[data_key_algorithm] * 8;
|
int data_rsa_len = siglen_map[data_key_algorithm] * 8;
|
||||||
|
|
||||||
VbPublicKey *signing_public_key = NULL;
|
|
||||||
VbPublicKey *data_public_key = NULL;
|
|
||||||
|
|
||||||
printf("***Testing signing algorithm: %s\n",
|
printf("***Testing signing algorithm: %s\n",
|
||||||
algo_strings[signing_key_algorithm]);
|
algo_strings[signing_key_algorithm]);
|
||||||
printf("***With data key algorithm: %s\n",
|
printf("***With data key algorithm: %s\n",
|
||||||
@@ -530,8 +527,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
|
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
|
||||||
signing_public_key = PublicKeyReadKeyb(filename,
|
struct vb2_packed_key *signing_public_key =
|
||||||
signing_key_algorithm, 1);
|
vb2_read_packed_keyb(filename, signing_key_algorithm, 1);
|
||||||
if (!signing_public_key) {
|
if (!signing_public_key) {
|
||||||
fprintf(stderr, "Error reading signing_public_key: %s\n",
|
fprintf(stderr, "Error reading signing_public_key: %s\n",
|
||||||
filename);
|
filename);
|
||||||
@@ -539,8 +536,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
|
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
|
||||||
data_public_key = PublicKeyReadKeyb(filename,
|
struct vb2_packed_key *data_public_key =
|
||||||
data_key_algorithm, 1);
|
vb2_read_packed_keyb(filename, data_key_algorithm, 1);
|
||||||
if (!data_public_key) {
|
if (!data_public_key) {
|
||||||
fprintf(stderr, "Error reading data_public_key: %s\n",
|
fprintf(stderr, "Error reading data_public_key: %s\n",
|
||||||
filename);
|
filename);
|
||||||
@@ -560,11 +557,11 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
test_check_keyblock(&signing_public_key2, signing_private_key,
|
test_check_keyblock(&signing_public_key2, signing_private_key,
|
||||||
(struct vb2_packed_key *)data_public_key);
|
data_public_key);
|
||||||
test_verify_keyblock(&signing_public_key2, signing_private_key,
|
test_verify_keyblock(&signing_public_key2, signing_private_key,
|
||||||
(struct vb2_packed_key *)data_public_key);
|
data_public_key);
|
||||||
test_verify_fw_preamble(signing_public_key, signing_private_key,
|
test_verify_fw_preamble(signing_public_key, signing_private_key,
|
||||||
(struct vb2_packed_key *)data_public_key);
|
data_public_key);
|
||||||
test_verify_kernel_preamble(signing_public_key, signing_private_key);
|
test_verify_kernel_preamble(signing_public_key, signing_private_key);
|
||||||
|
|
||||||
if (signing_public_key)
|
if (signing_public_key)
|
||||||
|
|||||||
@@ -22,7 +22,8 @@
|
|||||||
static void VerifyPublicKeyToRSA(const VbPublicKey *orig_key)
|
static void VerifyPublicKeyToRSA(const VbPublicKey *orig_key)
|
||||||
{
|
{
|
||||||
RSAPublicKey *rsa;
|
RSAPublicKey *rsa;
|
||||||
VbPublicKey *key = PublicKeyAlloc(orig_key->key_size, 0, 0);
|
VbPublicKey *key =
|
||||||
|
(VbPublicKey *)vb2_alloc_packed_key(orig_key->key_size, 0, 0);
|
||||||
|
|
||||||
PublicKeyCopy(key, orig_key);
|
PublicKeyCopy(key, orig_key);
|
||||||
key->algorithm = kNumAlgorithms;
|
key->algorithm = kNumAlgorithms;
|
||||||
@@ -235,7 +236,8 @@ int test_algorithm(int key_algorithm, const char *keys_dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len);
|
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len);
|
||||||
public_key = PublicKeyReadKeyb(filename, key_algorithm, 1);
|
public_key = (VbPublicKey *)vb2_read_packed_keyb(filename,
|
||||||
|
key_algorithm, 1);
|
||||||
if (!public_key) {
|
if (!public_key) {
|
||||||
fprintf(stderr, "Error reading public_key: %s\n", filename);
|
fprintf(stderr, "Error reading public_key: %s\n", filename);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -182,8 +182,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
|
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
|
||||||
signing_public_key = PublicKeyReadKeyb(filename,
|
signing_public_key = (VbPublicKey *)
|
||||||
signing_key_algorithm, 1);
|
vb2_read_packed_keyb(filename, signing_key_algorithm, 1);
|
||||||
if (!signing_public_key) {
|
if (!signing_public_key) {
|
||||||
fprintf(stderr, "Error reading signing_public_key: %s\n",
|
fprintf(stderr, "Error reading signing_public_key: %s\n",
|
||||||
filename);
|
filename);
|
||||||
@@ -191,8 +191,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
|
sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
|
||||||
struct vb2_packed_key *data_public_key = (struct vb2_packed_key *)
|
struct vb2_packed_key *data_public_key =
|
||||||
PublicKeyReadKeyb(filename, data_key_algorithm, 1);
|
vb2_read_packed_keyb(filename, data_key_algorithm, 1);
|
||||||
if (!data_public_key) {
|
if (!data_public_key) {
|
||||||
fprintf(stderr, "Error reading data_public_key: %s\n",
|
fprintf(stderr, "Error reading data_public_key: %s\n",
|
||||||
filename);
|
filename);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read public key */
|
/* Read public key */
|
||||||
kernkey = PublicKeyRead(argv[2]);
|
kernkey = (VbPublicKey *)vb2_read_packed_key(argv[2]);
|
||||||
if (!kernkey) {
|
if (!kernkey) {
|
||||||
fprintf(stderr, "Can't read key file %s\n", argv[2]);
|
fprintf(stderr, "Can't read key file %s\n", argv[2]);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user