summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.rules23
-rw-r--r--board/dingdong/board.h1
-rw-r--r--board/hammer/board.h1
-rw-r--r--board/hoho/board.h1
-rw-r--r--board/honeybuns/board.h1
-rw-r--r--board/lucid/board.h1
-rw-r--r--board/zinger/board.h1
-rw-r--r--common/firmware_image.S19
-rw-r--r--common/firmware_image.lds.S13
-rw-r--r--common/fmap.c27
-rw-r--r--common/rwsig.c92
-rw-r--r--include/2id.h32
-rw-r--r--include/config.h9
-rw-r--r--include/rsa.h32
-rw-r--r--include/vb21_struct.h346
-rw-r--r--test/rsa2048-3.h8
-rw-r--r--test/rsa2048-F4.h8
-rw-r--r--test/test_config.h2
18 files changed, 590 insertions, 27 deletions
diff --git a/Makefile.rules b/Makefile.rules
index b9364d1b56..d8bfd68bc7 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -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)
diff --git a/board/dingdong/board.h b/board/dingdong/board.h
index 4c33b4ba45..5f22ef5b08 100644
--- a/board/dingdong/board.h
+++ b/board/dingdong/board.h
@@ -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
diff --git a/board/hammer/board.h b/board/hammer/board.h
index bc613ec920..a9c60a0807 100644
--- a/board/hammer/board.h
+++ b/board/hammer/board.h
@@ -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
diff --git a/board/hoho/board.h b/board/hoho/board.h
index d0c72f18b9..79f769ae0e 100644
--- a/board/hoho/board.h
+++ b/board/hoho/board.h
@@ -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 */
diff --git a/board/honeybuns/board.h b/board/honeybuns/board.h
index ad60fdb680..9cb147f87a 100644
--- a/board/honeybuns/board.h
+++ b/board/honeybuns/board.h
@@ -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
diff --git a/board/lucid/board.h b/board/lucid/board.h
index cfae5c3bf3..0a7b759dfb 100644
--- a/board/lucid/board.h
+++ b/board/lucid/board.h
@@ -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
diff --git a/board/zinger/board.h b/board/zinger/board.h
index 9a2a40afe8..1b11447614 100644
--- a/board/zinger/board.h
+++ b/board/zinger/board.h
@@ -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
diff --git a/common/firmware_image.S b/common/firmware_image.S
index 1fa4f25f71..97a7123f49 100644
--- a/common/firmware_image.S
+++ b/common/firmware_image.S
@@ -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)
diff --git a/common/firmware_image.lds.S b/common/firmware_image.lds.S
index 1b846bd045..85d4a56aa1 100644
--- a/common/firmware_image.lds.S
+++ b/common/firmware_image.lds.S
@@ -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)
diff --git a/common/fmap.c b/common/fmap.c
index 6f84c37b63..f46b29b68e 100644
--- a/common/fmap.c
+++ b/common/fmap.c
@@ -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
}
};
diff --git a/common/rwsig.c b/common/rwsig.c
index ee1bd6c9fc..1ad3ed37f9 100644
--- a/common/rwsig.c
+++ b/common/rwsig.c
@@ -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 */
diff --git a/include/2id.h b/include/2id.h
new file mode 100644
index 0000000000..8daa4d27db
--- /dev/null
+++ b/include/2id.h
@@ -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_ */
diff --git a/include/config.h b/include/config.h
index 3b2e6f3906..ef65989c6b 100644
--- a/include/config.h
+++ b/include/config.h
@@ -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
diff --git a/include/rsa.h b/include/rsa.h
index 2fb896c652..ca3b227aae 100644
--- a/include/rsa.h
+++ b/include/rsa.h
@@ -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 \
diff --git a/include/vb21_struct.h b/include/vb21_struct.h
new file mode 100644
index 0000000000..30adf84d04
--- /dev/null
+++ b/include/vb21_struct.h
@@ -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_ */
diff --git a/test/rsa2048-3.h b/test/rsa2048-3.h
index 37119ffb70..d1b15c15a4 100644
--- a/test/rsa2048-3.h
+++ b/test/rsa2048-3.h
@@ -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;
diff --git a/test/rsa2048-F4.h b/test/rsa2048-F4.h
index a145d756ac..afe66a198f 100644
--- a/test/rsa2048-F4.h
+++ b/test/rsa2048-F4.h
@@ -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;
diff --git a/test/test_config.h b/test/test_config.h
index 5314dd5ebc..36bebe8a01 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -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