rwsig: Add support for rwsig image types

usbpd1 futility image type is deprecated and should not be used for
new designs. This adds proper support for rwsig image type.

Key and signatures are added at linker stage step (futility cannot
directly create such signed images). Thanks to VB21 header, rwsig.c
can now tell how many bytes of the RW image need to be
cryptographically verified, and ensure that the rest is blank (0xff).

BRANCH=none
BUG=chromium:690773
TEST=make BOARD=hammer; flash, RW image is verified correctly.
TEST=make runtests -j
TEST=For the rest of the tests:
     Change config option to CONFIG_RWSIG_TYPE_RWSIG
TEST=make BOARD=hammer; flash, hammer still verifies correctly.
TEST=cp build/hammer/ec.RW.bin build/hammer/ec.RW.bin.orig;
     futility sign --type rwsig --prikey build/hammer/key.vbprik2 \
        build/hammer/ec.RW.bin
     diff build/hammer/ec.RW.bin build/hammer/ec.RW.bin.orig
     => Same file
TEST=Add CONFIG_CMD_FLASH, flashwrite 0x1e000, reboot, EC does
     not verify anymore.
TEST=dump_fmap build/hammer/ec.bin shows KEY_RO and SIG_RW at
     correct locations.

Change-Id: I50ec828284c2d1eca67fa8cbddaf6f3b06606c82
Reviewed-on: https://chromium-review.googlesource.com/441546
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Nicolas Boichat 2017-02-10 13:59:39 +08:00 committed by chrome-bot
parent cb6e3ec3a0
commit 07eccbb414
18 changed files with 590 additions and 27 deletions

View File

@ -91,8 +91,18 @@ cmd_sharedlib_elf = $(CC) $(libsharedobjs_deps) \
-o $(out)/$(SHOBJLIB)/$(SHOBJLIB).elf \
-Wl,-Map,$(out)/$(SHOBJLIB)/$(SHOBJLIB).map
# commands for RSA signature
cmd_rsasign = futility sign --type usbpd1 --pem $(PEM) $(out)/$*.bin.tmp
# commands for RSA signature: rwsig does not need to sign the whole image
# (it signs the RW part separately). usbpd1 type needs to sign the final image.
ifeq ($(CONFIG_RWSIG_TYPE_RWSIG),)
cmd_rsasign = futility sign --type usbpd1 --pem $(PEM) $(out)/$*.bin.tmp
else
cmd_rsasign =
endif
cmd_key_extract = futility create $(PEM) $(out)/$* $(silent)
cmd_rsasign_rwsig = futility sign --type rwsig \
--prikey $(out)/key.vbprik2 $< $@
# commands to build optional xref files
cmd_deps_to_list = cat $(deps) | tr -d ':\\' | tr ' ' '\012' \
@ -274,6 +284,9 @@ flat-$(CONFIG_FW_INCLUDE_RO) += $(out)/RO/$(PROJECT).RO.flat
deps += $(out)/firmware_image.lds.d $(flat-y:%.flat=%.lds.d)
flat-$(CONFIG_RWSIG_TYPE_RWSIG) += $(out)/key.vbpubk2
flat-$(CONFIG_RWSIG_TYPE_RWSIG) += $(out)/RW/$(PROJECT).RW.flat.sig
flat-$(CONFIG_SHAREDLIB) += $(libsharedobjs-y)
$(out)/$(PROJECT).obj: common/firmware_image.S $(out)/firmware_image.lds \
@ -305,6 +318,12 @@ endif
$(out)/$(PROJECT).hex: $(out)/$(PROJECT).bin
$(call quiet,bin_to_hex,OBJCOPY)
$(out)/%.vbprik2 $(out)/%.vbpubk2: $(PEM)
$(call quiet,key_extract,KEY )
$(out)/RW/%.flat.sig: $(out)/RW/%.flat $(out)/key.vbprik2
$(call quiet,rsasign_rwsig,SIGN )
$(out)/RW/%.elf: override BLD:=RW
$(out)/RW/%.elf: private objs := $(rw-objs)
$(out)/RW/%.elf: $(out)/RW/%.lds $(rw-objs) $(libsharedobjs_elf-y)

View File

@ -21,6 +21,7 @@
#define CONFIG_HW_CRC
#define CONFIG_RSA
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_USBPD1
#define CONFIG_SHA256
#define CONFIG_USB
#define CONFIG_USB_BOS

View File

@ -78,6 +78,7 @@
/* Sign and switch to RW partition on boot. */
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_USBPD1
#define CONFIG_RSA
#define CONFIG_SHA256
#define CONFIG_RSA_KEY_SIZE 2048

View File

@ -22,6 +22,7 @@
#define CONFIG_HW_CRC
#define CONFIG_RSA
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_USBPD1
#define CONFIG_SHA256
/* TODO(tbroch) Re-enable once STM spi master can be inhibited at boot so it
doesn't interfere with HDMI loading its f/w */

View File

@ -23,6 +23,7 @@
#undef CONFIG_LID_SWITCH
#define CONFIG_RSA
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_USBPD1
#define CONFIG_SHA256
#define CONFIG_STM_HWTIMER32
#undef CONFIG_TASK_PROFILING

View File

@ -53,6 +53,7 @@
#define CONFIG_LTO
#define CONFIG_RSA
#define CONFIG_RWSIG
#define CONFIG_RWSIG_TYPE_USBPD1
#define CONFIG_SHA256
#define CONFIG_STM_HWTIMER32
#define CONFIG_STM32_CHARGER_DETECT

View File

@ -49,6 +49,7 @@
#undef CONFIG_LID_SWITCH
#define CONFIG_LTO
#define CONFIG_RSA
#define CONFIG_RWSIG_TYPE_USBPD1
#define CONFIG_SHA256
#undef CONFIG_TASK_PROFILING
#define CONFIG_USB_POWER_DELIVERY

View File

@ -8,12 +8,15 @@
#include "config.h"
#define FW_FILE(builddir,proj,sect,suffix) \
builddir##/##sect##/##proj##.##sect##suffix##.flat
#define FW_FILE(builddir,proj,sect,suffix,ext) \
builddir##/##sect##/##proj##.##sect##suffix##.flat##ext
#define STRINGIFY0(name) #name
#define STRINGIFY(name) STRINGIFY0(name)
#define FW_IMAGE(sect,suffix) \
STRINGIFY(FW_FILE(FINAL_OUTDIR,PROJECT,sect,suffix))
STRINGIFY(FW_FILE(FINAL_OUTDIR,PROJECT,sect,suffix,))
#define FW_IMAGE_SIGN(sect,suffix) \
STRINGIFY(FW_FILE(FINAL_OUTDIR,PROJECT,sect,suffix,.sig))
/* Read Only firmware */
#ifdef CONFIG_FW_INCLUDE_RO
@ -21,6 +24,11 @@
.incbin FW_IMAGE(RO,)
#endif
#ifdef CONFIG_RWSIG_TYPE_RWSIG
.section .image.RO.key, "a"
.incbin STRINGIFY(FINAL_OUTDIR/key.vbpubk2)
#endif
/* Shared objects library */
#ifdef CONFIG_SHAREDLIB
.section .image.libsharedobjs, "ax"
@ -31,6 +39,11 @@
.section .image.RW, "ax"
.incbin FW_IMAGE(RW,)
#ifdef CONFIG_RWSIG_TYPE_RWSIG
.section .image.RW.sign, "a"
.incbin FW_IMAGE_SIGN(RW,)
#endif
#ifdef CONFIG_RW_B
.section .image.RW_B, "ax"
.incbin FW_IMAGE(RW,_B)

View File

@ -4,6 +4,7 @@
*/
#include "config.h"
#include "rsa.h"
OUTPUT_FORMAT(BFD_FORMAT, BFD_FORMAT, BFD_FORMAT)
OUTPUT_ARCH(BFD_ARCH)
@ -25,6 +26,13 @@ SECTIONS
*(.image.RO)
} > FLASH =0xff
. = ALIGN(CONFIG_FLASH_BANK_SIZE);
#ifdef CONFIG_RWSIG_TYPE_RWSIG
.image.RO.key : AT(CONFIG_RO_PUBKEY_ADDR) {
*(.image.RO.key)
} > FLASH =0xff
#endif
#ifdef CONFIG_SHAREDLIB
.image.libsharedobjs : AT(CONFIG_PROGRAM_MEMORY_BASE + \
CONFIG_SHAREDLIB_MEM_OFF) {
@ -48,6 +56,11 @@ and RW images at different Flash offset */
#endif
*(.image.RW)
} > FLASH =0xff
#ifdef CONFIG_RWSIG_TYPE_RWSIG
.image.RW.sign : AT(CONFIG_RW_SIG_ADDR) {
*(.image.RW.sign)
} > FLASH =0xff
#endif
#ifdef CONFIG_RW_B_MEM_OFF
.image.RW_B : AT(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_B_MEM_OFF) {
*(.image.RW_B)

View File

@ -7,6 +7,7 @@
#include <stddef.h>
#include "common.h"
#include "rsa.h"
#include "util.h"
#include "version.h"
@ -61,7 +62,11 @@ struct fmap_area_header {
uint16_t area_flags;
} __packed;
#ifdef CONFIG_RWSIG_TYPE_RWSIG
#define NUM_EC_FMAP_AREAS 9
#else
#define NUM_EC_FMAP_AREAS 7
#endif
const struct _ec_fmap {
struct fmap_header header;
@ -136,6 +141,17 @@ const struct _ec_fmap {
.area_size = CONFIG_WP_STORAGE_SIZE,
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
},
#ifdef CONFIG_RWSIG_TYPE_RWSIG
{
/* RO public key address, for RW verification */
.area_name = "KEY_RO",
.area_offset = CONFIG_EC_PROTECTED_STORAGE_OFF -
FMAP_REGION_START + CONFIG_RO_PUBKEY_ADDR -
CONFIG_PROGRAM_MEMORY_BASE,
.area_size = CONFIG_RO_PUBKEY_SIZE,
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
},
#endif
/* RW Firmware */
{
@ -162,5 +178,16 @@ const struct _ec_fmap {
.area_size = sizeof(version_data.version),
.area_flags = FMAP_AREA_STATIC,
},
#ifdef CONFIG_RWSIG_TYPE_RWSIG
{
/* RW image signature */
.area_name = "SIG_RW",
.area_offset = CONFIG_EC_PROTECTED_STORAGE_OFF -
FMAP_REGION_START + CONFIG_RW_SIG_ADDR -
CONFIG_PROGRAM_MEMORY_BASE,
.area_size = CONFIG_RW_SIG_SIZE,
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
},
#endif
}
};

View File

@ -15,6 +15,7 @@
#include "system.h"
#include "usb_pd.h"
#include "util.h"
#include "vb21_struct.h"
/* Console output macros */
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
@ -24,12 +25,44 @@
static uint32_t * const rw_rst =
(uint32_t *)(CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RW_MEM_OFF + 4);
/*
* Check that memory between rwdata[start] and rwdata[len-1] is filled
* with ones. data, start and len must be aligned on 4-byte boundary.
*/
static int check_padding(const uint8_t *data,
unsigned int start, unsigned int len)
{
unsigned int i;
const uint32_t *data32 = (const uint32_t *)data;
if ((start % 4) != 0 || (len % 4) != 0)
return 0;
for (i = start/4; i < len/4; i++) {
if (data32[i] != 0xffffffff)
return 0;
}
return 1;
}
void check_rw_signature(void)
{
struct sha256_ctx ctx;
int good, res;
int res;
const struct rsa_public_key *key;
const uint8_t *sig;
uint8_t *hash;
uint32_t *rsa_workbuf;
const uint8_t *rwdata = (uint8_t *)CONFIG_PROGRAM_MEMORY_BASE
+ CONFIG_RW_MEM_OFF;
int good = 0;
unsigned int rwlen;
#ifdef CONFIG_RWSIG_TYPE_RWSIG
const struct vb21_packed_key *vb21_key;
const struct vb21_signature *vb21_sig;
#endif
/* Only the Read-Only firmware needs to do the signature check */
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
@ -48,17 +81,60 @@ void check_rw_signature(void)
return;
}
#ifdef CONFIG_RWSIG_TYPE_USBPD1
key = (const struct rsa_public_key *)CONFIG_RO_PUBKEY_ADDR;
sig = (const uint8_t *)CONFIG_RW_SIG_ADDR;
rwlen = CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE;
#elif defined(CONFIG_RWSIG_TYPE_RWSIG)
vb21_key = (const struct vb21_packed_key *)CONFIG_RO_PUBKEY_ADDR;
vb21_sig = (const struct vb21_signature *)CONFIG_RW_SIG_ADDR;
if (vb21_key->c.magic != VB21_MAGIC_PACKED_KEY ||
vb21_key->key_size != sizeof(struct rsa_public_key)) {
CPRINTS("Invalid key.");
goto out;
}
key = (const struct rsa_public_key *)
((const uint8_t *)vb21_key + vb21_key->key_offset);
/*
* TODO(crbug.com/690773): We could verify other parameters such
* as sig_alg/hash_alg actually matches what we build for.
*/
if (vb21_sig->c.magic != VB21_MAGIC_SIGNATURE ||
vb21_sig->sig_size != RSANUMBYTES ||
vb21_key->sig_alg != vb21_sig->sig_alg ||
vb21_key->hash_alg != vb21_sig->hash_alg ||
/* Sanity check signature offset and data size. */
vb21_sig->sig_offset < sizeof(vb21_sig) ||
(vb21_sig->sig_offset + RSANUMBYTES) > CONFIG_RW_SIG_SIZE ||
vb21_sig->data_size > (CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE)) {
CPRINTS("Invalid signature.");
goto out;
}
sig = (const uint8_t *)vb21_sig + vb21_sig->sig_offset;
rwlen = vb21_sig->data_size;
#endif
/*
* Check that unverified RW region is actually filled with ones.
*/
good = check_padding(rwdata, rwlen,
CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
if (!good) {
CPRINTS("Invalid padding.");
goto out;
}
/* SHA-256 Hash of the RW firmware */
/* TODO(crosbug.com/p/44803): Do we have to hash the whole region? */
SHA256_init(&ctx);
SHA256_update(&ctx, (void *)CONFIG_PROGRAM_MEMORY_BASE
+ CONFIG_RW_MEM_OFF,
CONFIG_RW_SIZE - CONFIG_RW_SIG_SIZE);
SHA256_update(&ctx, rwdata, rwlen);
hash = SHA256_final(&ctx);
good = rsa_verify((const struct rsa_public_key *)CONFIG_RO_PUBKEY_ADDR,
(const uint8_t *)CONFIG_RW_SIG_ADDR,
hash, rsa_workbuf);
good = rsa_verify(key, sig, hash, rsa_workbuf);
out:
if (good) {
CPRINTS("RW image verified");
/* Jump to the RW firmware */

32
include/2id.h Normal file
View File

@ -0,0 +1,32 @@
/* Copyright 2015 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.
*
* Key ID, used to quickly match keys with signatures. There's not a standard
* fingerprint for private keys, so we're using the sha1sum of the public key
* in our keyb format. Pretty much anything would work as long as it's
* resistant to collisions and easy to compare.
*
* Note: This file is copied from
* src/platform/vboot_reference/firmware/2lib/include/2id.h
* and should be updated if necessary.
*/
#ifndef VBOOT_REFERENCE_VBOOT_2ID_H_
#define VBOOT_REFERENCE_VBOOT_2ID_H_
#include <stdint.h>
#define VB2_ID_NUM_BYTES 20
struct vb2_id {
uint8_t raw[VB2_ID_NUM_BYTES];
} __attribute__((packed));
#define EXPECTED_ID_SIZE VB2_ID_NUM_BYTES
/* IDs to use for "keys" with sig_alg==VB2_SIG_NONE */
#define VB2_ID_NONE_SHA1 {{0x00, 0x01,}}
#define VB2_ID_NONE_SHA256 {{0x02, 0x56,}}
#define VB2_ID_NONE_SHA512 {{0x05, 0x12,}}
#endif /* VBOOT_REFERENCE_VBOOT_2ID_H_ */

View File

@ -1755,6 +1755,15 @@
* (for accessories without software sync)
*/
#undef CONFIG_RWSIG
/*
* Defines what type of futility signature type should be used.
* RWSIG should be used for new designs.
* Old adapters use the USBPD1 futility signature type.
*/
#undef CONFIG_RWSIG_TYPE_RWSIG
#undef CONFIG_RWSIG_TYPE_USBPD1
/*
* By default the pubkey and sig are put at the end of the first and second
* half of the total flash, and take up the minimum space possible. You can

View File

@ -22,6 +22,8 @@
* plus 4 for n0inv, aligned on a multiple of 16
* Put numerical constants here to please the linker script.
*/
#ifndef CONFIG_RWSIG_TYPE_RWSIG
/* vboot2 public keys are packed in a slightly different way. */
#if CONFIG_RSA_KEY_SIZE == 2048
#define RSA_PUBLIC_KEY_SIZE 528
#elif CONFIG_RSA_KEY_SIZE == 4096
@ -31,18 +33,29 @@
#else
#error Unsupported RSA key size
#endif
#endif /* ! CONFIG_RWSIG_TYPE_RWSIG */
#endif /* CONFIG_RSA */
#ifndef __ASSEMBLER__
#include "common.h"
#ifdef CONFIG_RWSIG_TYPE_RWSIG
/* RSA public key definition, VBoot2 packing */
struct rsa_public_key {
uint32_t size;
uint32_t n0inv; /* -1 / n[0] mod 2^32 */
uint32_t n[RSANUMWORDS]; /* modulus as little endian array */
uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */
};
#else
/* RSA public key definition */
struct rsa_public_key {
uint32_t n[RSANUMWORDS]; /* modulus as little endian array */
uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */
uint32_t n0inv; /* -1 / n[0] mod 2^32 */
};
#endif
int rsa_verify(const struct rsa_public_key *key,
const uint8_t *signature,
@ -63,8 +76,19 @@ void check_rw_signature(void);
/* The pubkey goes at the end of the first half of flash */
#ifndef CONFIG_RO_PUBKEY_SIZE
#ifdef CONFIG_RWSIG_TYPE_RWSIG
/*
* rwsig type: 1024 bytes is enough to fit RSA-3072 public key.
*
* TODO(crosbug.com/p/62321): This still wastes space. We could pack the key at
* any arbitrary location, but we need proper signer support to make sure it
* can overwrite the key correctly.
*/
#define CONFIG_RO_PUBKEY_SIZE 1024
#else
#define CONFIG_RO_PUBKEY_SIZE RSA_PUBLIC_KEY_SIZE
#endif
#endif /* ! CONFIG_RO_PUBKEY_SIZE */
#ifndef CONFIG_RO_PUBKEY_ADDR
#define CONFIG_RO_PUBKEY_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
+ (CONFIG_FLASH_SIZE / 2) \
@ -73,8 +97,16 @@ void check_rw_signature(void);
/* The signature goes at the end of the second half of flash */
#ifndef CONFIG_RW_SIG_SIZE
#ifdef CONFIG_RWSIG_TYPE_RWSIG
/*
* rwsig type: futility expects signature to be 1024 bytes from the end of
* the file.
*/
#define CONFIG_RW_SIG_SIZE 1024
#else
#define CONFIG_RW_SIG_SIZE RSANUMBYTES
#endif
#endif /* ! CONFIG_RW_SIG_SIZE */
#ifndef CONFIG_RW_SIG_ADDR
#define CONFIG_RW_SIG_ADDR (CONFIG_PROGRAM_MEMORY_BASE \
+ CONFIG_FLASH_SIZE \

346
include/vb21_struct.h Normal file
View File

@ -0,0 +1,346 @@
/* Copyright (c) 2014 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.
*
* Vboot 2.1 data structures
*
* Offsets should be padded to 32-bit boundaries, since some architectures
* have trouble with accessing unaligned integers.
*
* Note: This file is copied from
* src/platform/vboot_reference/firmware/lib21/include/vb21_struct.h
* and should be updated if necessary.
*/
#ifndef VBOOT_REFERENCE_VB21_STRUCT_H_
#define VBOOT_REFERENCE_VB21_STRUCT_H_
#include <stdint.h>
#include "2id.h"
/*
* Magic numbers used by vb21_struct_common.magic.
*
* All valid numbers should be listed here to avoid accidental overlap.
* Numbers start at a large value, so that previous parsers (which stored
* things like lengths and offsets at that field) will detect and reject new
* structs as invalid.
*/
enum vb21_struct_common_magic {
/* "Vb2B" = vb21_keyblock.c.magic */
VB21_MAGIC_KEYBLOCK = 0x42326256,
/* "Vb2F" = vb21_fw_preamble.c.magic */
VB21_MAGIC_FW_PREAMBLE = 0x46326256,
/* "Vb2I" = vb21_packed_private_key.c.magic */
VB21_MAGIC_PACKED_PRIVATE_KEY = 0x49326256,
/* "Vb2K" = vb2_kernel_preamble.c.magic */
VB21_MAGIC_KERNEL_PREAMBLE = 0x4b326256,
/* "Vb2P" = vb21_packed_key.c.magic */
VB21_MAGIC_PACKED_KEY = 0x50326256,
/* "Vb2S" = vb21_signature.c.magic */
VB21_MAGIC_SIGNATURE = 0x53326256,
};
/*
* Generic struct header for all vboot2.1 structs. This makes it easy to
* automatically parse and identify vboot structs (e.g., in futility). This
* must be the first member of the parent vboot2.1 struct.
*/
struct vb21_struct_common {
/* Magic number; see vb21_struct_common_magic for expected values */
uint32_t magic;
/*
* Parent struct version; see each struct for the expected value.
*
* How to handle struct version mismatches, if the parser is version
* A.b and the data is version C.d:
* 1) If A.b == C.d, we're good.
* 2) If A != C, the data cannot be parsed at all.
* 3) If b < d, C.d is a newer version of data which is backwards-
* compatible to old parsers. We're good.
* 4) If b > d, C.d is an older version of data. The parser should
* use default values for fields added after version d. We're
* good.
*
* Struct versions start at 3.0, since the highest version of the old
* structures was 2.1. This way, there is no possibility of collision
* for old code which depends on the version number.
*/
uint16_t struct_version_major;
uint16_t struct_version_minor;
/*
* Size of the parent structure and all its data, including the
* description and any necessary padding. That is, all data must lie
* in a contiguous region of <total_size> bytes starting at the first
* byte of this header.
*/
uint32_t total_size;
/*
* Size of the fixed portion of the parent structure. If a description
* is present, it must start at this offset.
*/
uint32_t fixed_size;
/*
* The object may contain an ASCII description following the fixed
* portion of the structure. If it is present, it must be
* null-terminated, and padded with 0 (null) bytes to a multiple of 32
* bits.
*
* Size of ASCII description in bytes, counting null terminator and
* padding (if any). Set 0 if no description is present. If non-zero,
* there must be a null terminator (0) at offset (fixed_size +
* desc_size - 1).
*/
uint32_t desc_size;
} __attribute__((packed));
#define EXPECTED_VB21_STRUCT_COMMON_SIZE 20
/* Current version of vb21_packed_key struct */
#define VB21_PACKED_KEY_VERSION_MAJOR 3
#define VB21_PACKED_KEY_VERSION_MINOR 0
/*
* Packed public key data
*
* The key data must be arranged like this:
* 1) vb21_packed_key header struct h
* 2) Key description (pointed to by h.c.fixed_size)
* 3) Key data key (pointed to by h.key_offset)
*/
struct vb21_packed_key {
/* Common header fields */
struct vb21_struct_common c;
/* Offset of key data from start of this struct */
uint32_t key_offset;
/* Size of key data in bytes (NOT strength of key in bits) */
uint32_t key_size;
/* Signature algorithm used by the key (enum vb2_signature_algorithm) */
uint16_t sig_alg;
/*
* Hash digest algorithm used with the key (enum vb2_hash_algorithm).
* This is explicitly specified as part of the key to prevent use of a
* strong key with a weak hash.
*/
uint16_t hash_alg;
/* Key version */
uint32_t key_version;
/* Key ID */
struct vb2_id id;
} __attribute__((packed));
#define EXPECTED_VB21_PACKED_KEY_SIZE \
(EXPECTED_VB21_STRUCT_COMMON_SIZE + 16 + EXPECTED_ID_SIZE)
/* Current version of vb21_packed_private_key struct */
#define VB21_PACKED_PRIVATE_KEY_VERSION_MAJOR 3
#define VB21_PACKED_PRIVATE_KEY_VERSION_MINOR 0
/*
* Packed private key data
*
* The key data must be arranged like this:
* 1) vb21_packed_private_key header struct h
* 2) Key description (pointed to by h.c.fixed_size)
* 3) Key data key (pointed to by h.key_offset)
*/
struct vb21_packed_private_key {
/* Common header fields */
struct vb21_struct_common c;
/* Offset of key data from start of this struct */
uint32_t key_offset;
/* Size of key data in bytes (NOT strength of key in bits) */
uint32_t key_size;
/* Signature algorithm used by the key (enum vb2_signature_algorithm) */
uint16_t sig_alg;
/*
* Hash digest algorithm used with the key (enum vb2_hash_algorithm).
* This is explicitly specified as part of the key to prevent use of a
* strong key with a weak hash.
*/
uint16_t hash_alg;
/* Key ID */
struct vb2_id id;
} __attribute__((packed));
#define EXPECTED_VB21_PACKED_PRIVATE_KEY_SIZE \
(EXPECTED_VB21_STRUCT_COMMON_SIZE + 12 + EXPECTED_ID_SIZE)
/* Current version of vb21_signature struct */
#define VB21_SIGNATURE_VERSION_MAJOR 3
#define VB21_SIGNATURE_VERSION_MINOR 0
/*
* Signature data
*
* The signature data must be arranged like this:
* 1) vb21_signature header struct h
* 2) Signature description (pointed to by h.c.fixed_size)
* 3) Signature data (pointed to by h.sig_offset)
*/
struct vb21_signature {
/* Common header fields */
struct vb21_struct_common c;
/* Offset of signature data from start of this struct */
uint32_t sig_offset;
/* Size of signature data in bytes */
uint32_t sig_size;
/* Size of the data block which was signed in bytes */
uint32_t data_size;
/* Signature algorithm used (enum vb2_signature_algorithm) */
uint16_t sig_alg;
/* Hash digest algorithm used (enum vb2_hash_algorithm) */
uint16_t hash_alg;
/*
* ID for the signature.
*
* If this is a keyblock signature entry, this is the ID of the key
* used to generate this signature. This allows the firmware to
* quickly determine which signature block (if any) goes with the key
* being used by the firmware.
*
* If this is a preamble hash entry, this is the ID of the data type
* being hashed. There is no key ID, because sig_alg=VB2_ALG_NONE.
*/
struct vb2_id id;
} __attribute__((packed));
#define EXPECTED_VB21_SIGNATURE_SIZE \
(EXPECTED_VB21_STRUCT_COMMON_SIZE + 16 + EXPECTED_ID_SIZE)
/* Current version of vb21_keyblock struct */
#define VB21_KEYBLOCK_VERSION_MAJOR 3
#define VB21_KEYBLOCK_VERSION_MINOR 0
/*
* Key block. This contains a signed, versioned key for use in the next stage
* of verified boot.
*
* The key block data must be arranged like this:
* 1) vb21_keyblock header struct h
* 2) Keyblock description (pointed to by h.c.fixed_size)
* 3) Data key (pointed to by h.data_key_offset)
* 4) Signatures (first signature pointed to by h.sig_offset)
*
* The signatures from 4) must cover all the data from 1), 2), 3). That is,
* signatures must sign all data up to sig_offset.
*/
struct vb21_keyblock {
/* Common header fields */
struct vb21_struct_common c;
/* Flags (VB2_KEY_BLOCK_FLAG_*) */
uint32_t flags;
/*
* Offset of key (struct vb21_packed_key) to use in next stage of
* verification, from start of the keyblock.
*/
uint32_t key_offset;
/* Number of keyblock signatures which follow */
uint32_t sig_count;
/*
* Offset of the first signature (struct vb21_signature) from the start
* of the keyblock.
*
* Signatures sign the contents of this struct and the data pointed to
* by data_key_offset, but not themselves or other signatures.
*
* For the firmware, there may be only one signature.
*
* Kernels often have at least two signatures - one using the kernel
* subkey from the RW firmware (for signed kernels) and one which is
* simply a SHA-512 hash (for unsigned developer kernels).
*
* The ID for each signature indicates which key was used to generate
* the signature.
*/
uint32_t sig_offset;
} __attribute__((packed));
#define EXPECTED_VB21_KEYBLOCK_SIZE (EXPECTED_VB21_STRUCT_COMMON_SIZE + 16)
/* Current version of vb21_fw_preamble struct */
#define VB21_FW_PREAMBLE_VERSION_MAJOR 3
#define VB21_FW_PREAMBLE_VERSION_MINOR 0
/* Flags for vb21_fw_preamble.flags */
/* Reserved; do not use */
#define VB21_FIRMWARE_PREAMBLE_RESERVED0 0x00000001
/* Do not allow use of any hardware crypto accelerators. */
#define VB21_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO 0x00000002
/*
* Firmware preamble
*
* The preamble data must be arranged like this:
* 1) vb21_fw_preamble header struct h
* 2) Preamble description (pointed to by h.c.fixed_size)
* 3) Hashes (pointed to by h.hash_offset)
* 4) Signature (pointed to by h.sig_offset)
*
* The signature 4) must cover all the data from 1), 2), 3).
*/
struct vb21_fw_preamble {
/* Common header fields */
struct vb21_struct_common c;
/* Flags; see VB21_FIRMWARE_PREAMBLE_* */
uint32_t flags;
/* Firmware version */
uint32_t fw_version;
/* Offset of signature (struct vb21_signature) for this preamble */
uint32_t sig_offset;
/*
* The preamble contains a list of hashes (struct vb21_signature) for
* the various firmware components. These have sig_alg=VB2_SIG_NONE,
* and the ID for each hash identifies the component being hashed.
* The calling firmware is responsible for knowing where to find those
* components, which may be on a different storage device than this
* preamble.
*/
/* Number of hash entries */
uint32_t hash_count;
/* Offset of first hash entry from start of preamble */
uint32_t hash_offset;
} __attribute__((packed));
#define EXPECTED_VB21_FW_PREAMBLE_SIZE (EXPECTED_VB21_STRUCT_COMMON_SIZE + 20)
#endif /* VBOOT_REFERENCE_VB21_STRUCT_H_ */

View File

@ -11,13 +11,9 @@
* # openssl rsa -in key.pem -pubout > key.pub
* Then dump the key:
* # dumpRSAPublicKey -pub key.pub | xxd -i
* That's a slightly different format, so comment out the 1st 4 bytes (length),
* and move the next 4 to the end (n0inv).
*/
const uint8_t rsa_data[] = {
/* Length */
/* 0x40, 0x00, 0x00, 0x00, */
0x11, 0x17, 0x38, 0xfd,
0x40, 0x00, 0x00, 0x00, 0x0f, 0x46, 0xe8, 0x2c, 0x11, 0x17, 0x38, 0xfd,
0xef, 0xa2, 0xb5, 0x2d, 0x6d, 0x76, 0xe1, 0x70, 0x7d, 0x67, 0xb1, 0x9a,
0x18, 0x78, 0x90, 0xe2, 0xce, 0xa6, 0x81, 0xa0, 0x13, 0x37, 0xf2, 0x71,
0xf0, 0x44, 0x96, 0xaf, 0x52, 0x53, 0xd4, 0x23, 0x51, 0x19, 0xe5, 0xb0,
@ -61,8 +57,6 @@ const uint8_t rsa_data[] = {
0x23, 0xa1, 0x21, 0x4e, 0x1f, 0x6e, 0xdd, 0xac, 0xa6, 0x2c, 0x83, 0x61,
0xdf, 0x8f, 0x9a, 0xfb, 0x55, 0x0a, 0x88, 0x0b, 0x0b, 0x34, 0xbd, 0x35,
0x43, 0x2d, 0xe4, 0x49,
/* n0inv */
0x0f, 0x46, 0xe8, 0x2c
};
const struct rsa_public_key *rsa_key = (struct rsa_public_key *)rsa_data;

View File

@ -11,13 +11,9 @@
* # openssl rsa -in key.pem -pubout > key.pub
* Then dump the key:
* # dumpRSAPublicKey -pub key.pub | xxd -i
* That's a slightly different format, so comment out the 1st 4 bytes (length),
* and move the next 4 to the end (n0inv).
*/
const uint8_t rsa_data[] = {
/* Length */
/* 0x40, 0x00, 0x00, 0x00, */
0x3d, 0xbe, 0xa2, 0xde,
0x40, 0x00, 0x00, 0x00, 0xeb, 0xb6, 0x8c, 0xb4, 0x3d, 0xbe, 0xa2, 0xde,
0x0c, 0xa8, 0x6b, 0xcc, 0x1b, 0x58, 0x2e, 0x1b, 0x44, 0x3f, 0xda, 0xdb,
0x1d, 0xe1, 0xe4, 0xfd, 0x4b, 0xc5, 0x34, 0xc9, 0x7e, 0x58, 0xfc, 0x82,
0x6d, 0x95, 0x9f, 0x46, 0x01, 0xaf, 0x7c, 0xa1, 0x50, 0xd5, 0x9c, 0x22,
@ -61,8 +57,6 @@ const uint8_t rsa_data[] = {
0xcf, 0x5a, 0xa2, 0x66, 0x7a, 0xa2, 0x0e, 0x02, 0x56, 0x87, 0x98, 0x67,
0x90, 0xf4, 0x9f, 0x3b, 0xf7, 0xaa, 0x1c, 0xd9, 0xda, 0x0d, 0x49, 0x12,
0x50, 0xa3, 0x70, 0x62,
/* n0inv */
0xeb, 0xb6, 0x8c, 0xb4
};
const struct rsa_public_key *rsa_key = (struct rsa_public_key *)rsa_data;

View File

@ -57,12 +57,14 @@
#ifdef TEST_RSA
#define CONFIG_RSA
#define CONFIG_RSA_KEY_SIZE 2048
#define CONFIG_RWSIG_TYPE_RWSIG
#endif
#ifdef TEST_RSA3
#define CONFIG_RSA
#define CONFIG_RSA_KEY_SIZE 2048
#define CONFIG_RSA_EXPONENT_3
#define CONFIG_RWSIG_TYPE_RWSIG
#endif
#ifdef TEST_SHMALLOC