diff options
author | Joel Kitching <kitching@google.com> | 2019-07-22 10:23:06 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-07-24 06:53:40 +0000 |
commit | 34abb32ed2e48ccad95320c37fb001df8e3442fd (patch) | |
tree | f545be6d773fc5b8b0c1a1a65b506117b36ce6c3 | |
parent | 38f135e83e1d213fde64ac32bd366339f32f29fa (diff) | |
download | vboot-34abb32ed2e48ccad95320c37fb001df8e3442fd.tar.gz |
vboot: remove Boot Descriptor Block (BDB) library and utilities
Remove unused BDB code, previously created for a cancelled SoC
project.
BUG=b:124141368, chromium:986177
TEST=make clean && make runtests
BRANCH=none
Change-Id: I91faf97d9850f8afb816fa324ad9a4d9f3842888
Signed-off-by: Joel Kitching <kitching@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1710336
Tested-by: Joel Kitching <kitching@chromium.org>
Reviewed-by: Joel Kitching <kitching@chromium.org>
Commit-Queue: Joel Kitching <kitching@chromium.org>
62 files changed, 7 insertions, 9222 deletions
@@ -325,9 +325,6 @@ FWLIB20 = ${BUILD}/vboot_fw20.a # Vboot 2.1 (not yet ready - see firmware/README) FWLIB21 = ${BUILD}/vboot_fw21.a -# Static library containing firmware APIs for common boot flow -BDBLIB = ${BUILD}/bdb.a - # Firmware library sources needed by VbInit() call VBINIT_SRCS = \ firmware/lib/vboot_common_init.c \ @@ -386,16 +383,6 @@ FWLIB21_SRCS = \ firmware/lib21/misc.c \ firmware/lib21/packed_key.c -BDBLIB_SRCS = \ - firmware/bdb/bdb.c \ - firmware/bdb/ecdsa.c \ - firmware/bdb/misc.c \ - firmware/bdb/rsa.c \ - firmware/bdb/secrets.c \ - firmware/bdb/sha.c \ - firmware/bdb/stub.c \ - firmware/bdb/nvm.c - # TPM lightweight command library ifeq (${TPM2_MODE},) TLCL_SRCS = \ @@ -453,16 +440,11 @@ FWLIB_OBJS = ${FWLIB_SRCS:%.c=${BUILD}/%.o} FWLIB2X_OBJS = ${FWLIB2X_SRCS:%.c=${BUILD}/%.o} FWLIB20_OBJS = ${FWLIB20_SRCS:%.c=${BUILD}/%.o} FWLIB21_OBJS = ${FWLIB21_SRCS:%.c=${BUILD}/%.o} -BDBLIB_OBJS = ${BDBLIB_SRCS:%.c=${BUILD}/%.o} -ALL_OBJS += ${FWLIB_OBJS} ${FWLIB2X_OBJS} ${FWLIB20_OBJS} ${FWLIB21_OBJS} \ - $(BDBLIB_OBJS} +ALL_OBJS += ${FWLIB_OBJS} ${FWLIB2X_OBJS} ${FWLIB20_OBJS} ${FWLIB21_OBJS} # Intermediate library for the vboot_reference utilities to link against. UTILLIB = ${BUILD}/libvboot_util.a -# Static library containing both host and firmware APIs -UTILBDB = ${BUILD}/libvboot_utilbdb.a - UTILLIB_SRCS = \ cgpt/cgpt_create.c \ cgpt/cgpt_add.c \ @@ -495,13 +477,6 @@ UTILLIB_SRCS = \ UTILLIB_OBJS = ${UTILLIB_SRCS:%.c=${BUILD}/%.o} ALL_OBJS += ${UTILLIB_OBJS} -# Source files containing host side APIs for common boot flow -UTILBDB_SRCS += \ - firmware/bdb/host.c - -UTILBDB_OBJS = ${UTILBDB_SRCS:%.c=${BUILD}/%.o} -ALL_OBJS += ${UTILBDB_OBJS} - # Externally exported library for some target userspace apps to link with # (cryptohome, updater, etc.) HOSTLIB = ${BUILD}/libvboot_host.a @@ -614,7 +589,6 @@ endif ifeq (${MINIMAL},) UTIL_NAMES += \ - utility/bdb_extend \ utility/load_kernel_test \ utility/pad_digest_utility \ utility/signature_digest_utility \ @@ -663,8 +637,6 @@ FUTIL_SYMLINKS = \ FUTIL_SRCS = \ futility/futility.c \ - futility/bdb_helper.c \ - futility/cmd_bdb.c \ futility/cmd_create.c \ futility/cmd_dump_fmap.c \ futility/cmd_dump_kernel_config.c \ @@ -698,8 +670,7 @@ FUTIL_CMD_LIST = ${BUILD}/gen/futility_cmds.c FUTIL_OBJS = ${FUTIL_SRCS:%.c=${BUILD}/%.o} ${FUTIL_CMD_LIST:%.c=%.o} -${FUTIL_OBJS}: INCLUDES += -Ihost/lib21/include -Ifirmware/lib21/include \ - -Ifirmware/bdb +${FUTIL_OBJS}: INCLUDES += -Ihost/lib21/include -Ifirmware/lib21/include ALL_OBJS += ${FUTIL_OBJS} @@ -784,12 +755,7 @@ TEST21_NAMES = \ tests/vb21_host_misc_tests \ tests/vb21_host_sig_tests -TESTBDB_NAMES = \ - tests/bdb_test \ - tests/bdb_nvm_test \ - tests/bdb_sprw_test - -TEST_NAMES += ${TEST2X_NAMES} ${TEST20_NAMES} ${TEST21_NAMES} ${TESTBDB_NAMES} +TEST_NAMES += ${TEST2X_NAMES} ${TEST20_NAMES} ${TEST21_NAMES} # And a few more... ifeq (${TPM2_MODE},) @@ -820,7 +786,6 @@ TEST_FUTIL_BINS = $(addprefix ${BUILD}/,${TEST_FUTIL_NAMES}) TEST2X_BINS = $(addprefix ${BUILD}/,${TEST2X_NAMES}) TEST20_BINS = $(addprefix ${BUILD}/,${TEST20_NAMES}) TEST21_BINS = $(addprefix ${BUILD}/,${TEST21_NAMES}) -TESTBDB_BINS = $(addprefix ${BUILD}/,${TESTBDB_NAMES}) # Directory containing test keys TEST_KEYS = ${SRC_RUN}/tests/testkeys @@ -893,7 +858,6 @@ ${FWLIB_OBJS}: CFLAGS += -DUNROLL_LOOPS ${FWLIB2X_OBJS}: CFLAGS += -DUNROLL_LOOPS ${FWLIB20_OBJS}: CFLAGS += -DUNROLL_LOOPS ${FWLIB21_OBJS}: CFLAGS += -DUNROLL_LOOPS -${BDBLIB_OBJS}: CFLAGS += -DUNROLL_LOOPS # Workaround for coreboot on x86, which will power off asynchronously # without giving us a chance to react. This is not an example of the Right @@ -914,7 +878,6 @@ ${FWLIB_OBJS}: CFLAGS += -DDISABLE_ROLLBACK_TPM endif ${FWLIB21_OBJS}: INCLUDES += -Ifirmware/lib21/include -${BDBLIB_OBJS}: INCLUDES += -Ifirmware/bdb # Linktest ensures firmware lib doesn't rely on outside libraries ${BUILD}/firmware/linktest/main: ${FWLIB} @@ -960,15 +923,6 @@ ${FWLIB21}: ${FWLIB2X_OBJS} ${FWLIB21_OBJS} @${PRINTF} " AR $(subst ${BUILD}/,,$@)\n" ${Q}ar qc $@ $^ -.PHONY: bdblib -bdblib: ${BDBLIB} - -${BDBLIB}: ${FWLIB2X_OBJS} ${BDBLIB_OBJS} - @${PRINTF} " RM $(subst ${BUILD}/,,$@)\n" - ${Q}rm -f $@ - @${PRINTF} " AR $(subst ${BUILD}/,,$@)\n" - ${Q}ar qc $@ $^ - # ---------------------------------------------------------------------------- # Host library(s) @@ -989,12 +943,6 @@ ${UTILLIB}: ${UTILLIB_OBJS} ${FWLIB_OBJS} ${FWLIB2X_OBJS} ${FWLIB20_OBJS} \ @${PRINTF} " AR $(subst ${BUILD}/,,$@)\n" ${Q}ar qc $@ $^ -${UTILBDB}: ${UTILBDB_OBJS} ${BDBLIB_OBJS} - @${PRINTF} " RM $(subst ${BUILD}/,,$@)\n" - ${Q}rm -f $@ - @${PRINTF} " AR $(subst ${BUILD}/,,$@)\n" - ${Q}ar qc $@ $^ - # Link tests for external repos ${BUILD}/host/linktest/extern: ${HOSTLIB} ${BUILD}/host/linktest/extern: LIBS = ${HOSTLIB} @@ -1113,7 +1061,7 @@ futil: ${FUTIL_BIN} FUTIL_LIBS = ${CRYPTO_LIBS} ${LIBZIP_LIBS} ${FUTIL_BIN}: LDLIBS += ${FUTIL_LIBS} -${FUTIL_BIN}: ${FUTIL_OBJS} ${UTILLIB} ${FWLIB20} ${UTILBDB} +${FUTIL_BIN}: ${FUTIL_OBJS} ${UTILLIB} ${FWLIB20} @${PRINTF} " LD $(subst ${BUILD}/,,$@)\n" ${Q}${LD} -o $@ ${CFLAGS} ${LDFLAGS} $^ ${LDLIBS} @@ -1152,9 +1100,9 @@ ${TEST_BINS}: INCLUDES += -Itests ${TEST_BINS}: LIBS = ${TESTLIB} ${UTILLIB} # Futility tests need almost everything that futility needs. -${TEST_FUTIL_BINS}: ${FUTIL_OBJS} ${UTILLIB} ${UTILBDB} +${TEST_FUTIL_BINS}: ${FUTIL_OBJS} ${UTILLIB} ${TEST_FUTIL_BINS}: INCLUDES += -Ifutility -${TEST_FUTIL_BINS}: OBJS += ${FUTIL_OBJS} ${UTILLIB} ${UTILBDB} +${TEST_FUTIL_BINS}: OBJS += ${FUTIL_OBJS} ${UTILLIB} ${TEST_FUTIL_BINS}: LDLIBS += ${FUTIL_LIBS} ${TEST2X_BINS}: ${FWLIB2X} @@ -1164,10 +1112,6 @@ ${TEST20_BINS}: ${FWLIB20} ${TEST20_BINS}: LIBS += ${FWLIB20} ${TEST20_BINS}: LDLIBS += ${CRYPTO_LIBS} -${TESTBDB_BINS}: ${FWLIB2X} ${UTILBDB} -${TESTBDB_BINS}: INCLUDES += -Ifirmware/bdb -${TESTBDB_BINS}: LIBS += ${UTILBDB} ${FWLIB2X} - ${TESTLIB}: ${TESTLIB_OBJS} @${PRINTF} " RM $(subst ${BUILD}/,,$@)\n" ${Q}rm -f $@ @@ -1234,18 +1178,10 @@ ${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/verify_data: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/utility/bdb_extend: ${FWLIB2X} ${UTILBDB} -${BUILD}/utility/bdb_extend.o: INCLUDES += -Ifirmware/bdb -${BUILD}/utility/bdb_extend: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/utility/bdb_extend: LIBS += ${UTILBDB} ${FWLIB2X} - ${BUILD}/host/linktest/main: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/vb20_common2_tests: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/vb20_common3_tests: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/verify_kernel: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/tests/bdb_test: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/tests/bdb_nvm_test: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/tests/bdb_sprw_test: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/hmac_test: LDLIBS += ${CRYPTO_LIBS} ${TEST21_BINS}: LDLIBS += ${CRYPTO_LIBS} @@ -1302,7 +1238,7 @@ ${FUTIL_CMD_LIST}: ${FUTIL_SRCS} # Frequently-run tests .PHONY: test_targets -test_targets:: runcgpttests runmisctests run2tests runbdbtests +test_targets:: runcgpttests runmisctests run2tests ifeq (${MINIMAL},) # Bitmap utility isn't compiled for minimal variant @@ -1414,11 +1350,6 @@ run2tests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/vb21_host_sig_tests ${TEST_KEYS} ${RUNTEST} ${BUILD_RUN}/tests/hmac_test -.PHONY: runbdbtests -runbdbtests: test_setup - ${RUNTEST} ${BUILD_RUN}/tests/bdb_test ${TEST_KEYS} - ${RUNTEST} ${BUILD_RUN}/tests/bdb_sprw_test ${TEST_KEYS} - .PHONY: runfutiltests runfutiltests: test_setup tests/futility/run_test_scripts.sh ${TEST_INSTALL_DIR}/bin diff --git a/bdb/LICENSE b/bdb/LICENSE deleted file mode 100644 index d2514965..00000000 --- a/bdb/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/bdb/Makefile b/bdb/Makefile deleted file mode 100644 index 2140b679..00000000 --- a/bdb/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -# 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. - -# This Makefile normally builds in a 'build' subdir, but use -# -# make BUILD=<dir> -# -# to put the output somewhere else. - -############################################################################## -# Configuration variables come first. - -# Verbose? Use V=1 -ifeq (${V},) -Q := @ -endif - -# Quiet? Use QUIET=1 -ifeq (${QUIET},) -PRINTF := printf -else -PRINTF := : -endif - -CC ?= gcc -LD = ${CC} -PKG_CONFIG ?= pkg-config - -SRCDIR := $(shell pwd) -export SRCDIR -BUILD = ${SRCDIR}/build -export BUILD -KEYDIR = ${SRCDIR}/testkeys - -CFLAGS = -Wall -Werror - -# Create / use dependency files -CFLAGS += -MMD -MF $@.d - -############################################################################## -# Create output directories if necessary. Do this via explicit shell commands -# so it happens before trying to generate/include dependencies. -_dir_create := $(shell [ -d ${BUILD} ] || mkdir -p ${BUILD})) -_keydir_create := $(shell [ -d ${KEYDIR} ] || mkdir -p ${KEYDIR})) - -INC_PATH := $(shell ${PKG_CONFIG} --cflags libcrypto) -CFLAGS += ${INC_PATH} - -CRYPTO_LIBS := $(shell ${PKG_CONFIG} --libs libcrypto) -LDLIBS += ${CRYPTO_LIBS} - -############################################################################## -# Sources - -LIBSRC = bdb.c host.c sha.c rsa.c -LIBOBJ = ${LIBSRC:%.c=${BUILD}/%.o} - -BDBTESTSRC = bdb_test.c -BDBTESTOBJ = ${BDBTESTSRC:%.c=${BUILD}/%.o} -BDBTEST = ${BUILD}/bdb_test - -BDBCREATESRC = bdb_create.c -BDBCREATEOBJ = ${BDBCREATESRC:%.c=${BUILD}/%.o} -BDBCREATE = ${BUILD}/bdb_create - -DUMPRSASRC = dump_rsa.c -DUMPRSAOBJ = ${DUMPRSASRC:%.c=${BUILD}/%.o} -DUMPRSA = ${BUILD}/dump_rsa - -ALL_OBJS = ${LIBOBJ} ${BDBTESTOBJ} ${BDBCREATEOBJ} -ALL_EXES = ${BDBTEST} ${BDBCREATE} ${DUMPRSA} - -############################################################################## -# Targets - -.PHONY: all -all: ${ALL_EXES} - -.PHONY: clean -clean: - ${Q}/bin/rm -rf ${BUILD} - -.PHONY: bdb -bdb: ${BDBCREATE} - ${Q}${BDBCREATE} - -.PHONY: runtests -runtests: ${BDBTEST} - ${Q}${BDBTEST} - -.PHONY: testkeys -testkeys: ${DUMPRSA} - ${Q}openssl genrsa -F4 -out ${KEYDIR}/bdbkey.pem 4096 - ${Q}openssl req -batch -new -x509 -key ${KEYDIR}/bdbkey.pem \ - -out ${KEYDIR}/bdbkey.crt - ${Q}${DUMPRSA} -cert ${KEYDIR}/bdbkey.crt > ${KEYDIR}/bdbkey.keyb - - ${Q}openssl genrsa -3 -out ${KEYDIR}/subkey.pem 3072 - ${Q}openssl req -batch -new -x509 -key ${KEYDIR}/subkey.pem \ - -out ${KEYDIR}/subkey.crt - ${Q}${DUMPRSA} -cert ${KEYDIR}/subkey.crt > ${KEYDIR}/subkey.keyb - -${BDBTEST}: ${BDBTESTOBJ} ${LIBOBJ} - @$(PRINTF) " LD $(subst ${BUILD}/,,$@)\n" - ${Q}${LD} -o ${BDBTEST} ${CFLAGS} $^ ${LIBS} ${LDLIBS} - -${BDBCREATE}: ${BDBCREATEOBJ} ${LIBOBJ} - @$(PRINTF) " LD $(subst ${BUILD}/,,$@)\n" - ${Q}${LD} -o ${BDBCREATE} ${CFLAGS} $^ ${LIBS} ${LDLIBS} - -${DUMPRSA}: ${DUMPRSAOBJ} ${LIBOBJ} - @$(PRINTF) " LD $(subst ${BUILD}/,,$@)\n" - ${Q}${LD} -o ${DUMPRSA} ${CFLAGS} $^ ${LIBS} ${LDLIBS} - -############################################################################## -# Generic build rules. LIBS and OBJS can be overridden to tweak the generic -# rules for specific targets. - -${BUILD}/%: ${BUILD}/%.o ${OBJS} ${LIBS} - @${PRINTF} " LD $(subst ${BUILD}/,,$@)\n" - ${Q}${LD} -o $@ ${CFLAGS} ${LDFLAGS} $< ${OBJS} ${LIBS} ${LDLIBS} - -${BUILD}/%.o: %.c - @${PRINTF} " CC $(subst ${BUILD}/,,$@)\n" - ${Q}${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< - -# Include generated dependencies -ALL_DEPS += ${ALL_OBJS:%.o=%.o.d} --include ${ALL_DEPS} diff --git a/bdb/README b/bdb/README deleted file mode 100644 index 82fb715b..00000000 --- a/bdb/README +++ /dev/null @@ -1,30 +0,0 @@ -Boot Descriptor Block (BDB) library and utilities - -Building: ---------- -The host-side library and utilities requires OpenSSL. - -Do 'make runtests' to ensure everything is working. - -Generating a BDB: ------------------ -Edit the options in bdb_create.c. Then 'make bdb'. - -In the next release, this will take a config file rather than -requiring recompilation each time. Also, the BDB header and data will -be signed in two separate steps, so that the private BDB key is not -required each time. - -Revision History: ------------------ -v0.1.2 24-Nov-2015 Add support for RSA-3072B keys and signatures. - Add dump_rsa utility and 'make testkeys' to create - new keys. - Use a RSA-3072B (exponent 3) key for the subkey so - the exponent 3 code gets tested. - -v0.1.1 17-Nov-2015 Add support for ECDSA-521 data types. Note that - only the data types are supported; there is not a - C implementation for ECDSA. - -v0.1.0 15-Sep-2015 Initial version. diff --git a/bdb/bdb.c b/bdb/bdb.c deleted file mode 100644 index d3327a51..00000000 --- a/bdb/bdb.c +++ /dev/null @@ -1,398 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block firmware functions - */ - -#include <string.h> -#include "bdb.h" - -/*****************************************************************************/ - -/** - * Check if string contains a null terminator. - * - * Bytes after the null terminator do not need to be null. - * - * @param s String to check - * @param size Size of string buffer in characters - * @return 1 if string has a null terminator, 0 if not - */ -int string_has_null(const char *s, size_t size) -{ - for (; size; size--) { - if (*s++ == 0) - return 1; - } - return 0; -} - -int bdb_check_header(const struct bdb_header *p, size_t size) -{ - if (size < sizeof(*p) || size < p->struct_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_HEADER_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_HEADER_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (p->struct_size < sizeof(*p)) - return BDB_ERROR_STRUCT_SIZE; - - if (p->oem_area_0_size & 3) - return BDB_ERROR_OEM_AREA_SIZE; /* Not 32-bit aligned */ - - /* - * Make sure the BDB is at least big enough for us. At this point, all - * the caller may have loaded is this header We'll check if there's - * space for everything else after we load it. - */ - if (p->bdb_size < sizeof(*p)) - return BDB_ERROR_BDB_SIZE; - - /* - * The rest of the fields don't matter yet; we'll check them when we - * check the BDB itself. - */ - return BDB_SUCCESS; -} - -int bdb_check_key(const struct bdb_key *p, size_t size) -{ - size_t expect_key_size = 0; - - if (size < sizeof(*p) || size < p->struct_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_KEY_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_KEY_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (!string_has_null(p->description, sizeof(p->description))) - return BDB_ERROR_DESCRIPTION; - - /* We currently only support SHA-256 */ - if (p->hash_alg != BDB_HASH_ALG_SHA256) - return BDB_ERROR_HASH_ALG; - - /* Make sure signature algorithm and size are correct */ - switch (p->sig_alg) { - case BDB_SIG_ALG_RSA4096: - expect_key_size = BDB_RSA4096_KEY_DATA_SIZE; - break; - case BDB_SIG_ALG_ECSDSA521: - expect_key_size = BDB_ECDSA521_KEY_DATA_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - expect_key_size = BDB_RSA3072B_KEY_DATA_SIZE; - break; - default: - return BDB_ERROR_SIG_ALG; - } - - if (p->struct_size < sizeof(*p) + expect_key_size) - return BDB_ERROR_STRUCT_SIZE; - - return BDB_SUCCESS; -} - -int bdb_check_sig(const struct bdb_sig *p, size_t size) -{ - size_t expect_sig_size = 0; - - if (size < sizeof(*p) || size < p->struct_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_SIG_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_SIG_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (!string_has_null(p->description, sizeof(p->description))) - return BDB_ERROR_DESCRIPTION; - - /* We currently only support SHA-256 */ - if (p->hash_alg != BDB_HASH_ALG_SHA256) - return BDB_ERROR_HASH_ALG; - - /* Make sure signature algorithm and size are correct */ - switch (p->sig_alg) { - case BDB_SIG_ALG_RSA4096: - expect_sig_size = BDB_RSA4096_SIG_SIZE; - break; - case BDB_SIG_ALG_ECSDSA521: - expect_sig_size = BDB_ECDSA521_SIG_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - expect_sig_size = BDB_RSA3072B_SIG_SIZE; - break; - default: - return BDB_ERROR_SIG_ALG; - } - - if (p->struct_size < sizeof(*p) + expect_sig_size) - return BDB_ERROR_STRUCT_SIZE; - - return BDB_SUCCESS; -} - -int bdb_check_data(const struct bdb_data *p, size_t size) -{ - size_t need_size; - - if (size < sizeof(*p) || size < p->signed_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_DATA_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_DATA_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (!string_has_null(p->description, sizeof(p->description))) - return BDB_ERROR_DESCRIPTION; - - if (p->struct_size < sizeof(*p)) - return BDB_ERROR_STRUCT_SIZE; - - if (p->hash_entry_size < sizeof(struct bdb_hash)) - return BDB_ERROR_HASH_ENTRY_SIZE; - - /* Calculate expected size */ - need_size = p->struct_size + p->num_hashes * p->hash_entry_size; - - /* Make sure OEM area size doesn't cause wraparound */ - if (need_size + p->oem_area_1_size < need_size) - return BDB_ERROR_OEM_AREA_SIZE; - if (p->oem_area_1_size & 3) - return BDB_ERROR_OEM_AREA_SIZE; /* Not 32-bit aligned */ - need_size += p->oem_area_1_size; - - if (p->signed_size < need_size) - return BDB_ERROR_SIGNED_SIZE; - - return BDB_SUCCESS; -} - -/*****************************************************************************/ - -const struct bdb_header *bdb_get_header(const void *buf) -{ - return buf; -} - -const struct bdb_key *bdb_get_bdbkey(const void *buf) -{ - const struct bdb_header *h = bdb_get_header(buf); - const uint8_t *b8 = buf; - - /* BDB key follows header */ - return (const struct bdb_key *)(b8 + h->struct_size); -} - -const void *bdb_get_oem_area_0(const void *buf) -{ - const struct bdb_key *k = bdb_get_bdbkey(buf); - const uint8_t *b8 = (const uint8_t *)k; - - /* OEM area 0 follows BDB key */ - return b8 + k->struct_size; -} - -const struct bdb_key *bdb_get_subkey(const void *buf) -{ - const struct bdb_header *h = bdb_get_header(buf); - const uint8_t *b8 = bdb_get_oem_area_0(buf); - - /* Subkey follows OEM area 0 */ - return (const struct bdb_key *)(b8 + h->oem_area_0_size); -} - -const struct bdb_sig *bdb_get_header_sig(const void *buf) -{ - const struct bdb_header *h = bdb_get_header(buf); - const uint8_t *b8 = bdb_get_oem_area_0(buf); - - /* Header signature starts after signed data */ - return (const struct bdb_sig *)(b8 + h->signed_size); -} - -const struct bdb_data *bdb_get_data(const void *buf) -{ - const struct bdb_sig *s = bdb_get_header_sig(buf); - const uint8_t *b8 = (const uint8_t *)s; - - /* Data follows header signature */ - return (const struct bdb_data *)(b8 + s->struct_size); -} - -const void *bdb_get_oem_area_1(const void *buf) -{ - const struct bdb_data *p = bdb_get_data(buf); - const uint8_t *b8 = (const uint8_t *)p; - - /* OEM area 1 follows BDB data */ - return b8 + p->struct_size; -} - -const struct bdb_hash *bdb_get_hash(const void *buf, enum bdb_data_type type) -{ - const struct bdb_data *data = bdb_get_data(buf); - const uint8_t *b8 = bdb_get_oem_area_1(buf); - int i; - - /* Hashes follow OEM area 0 */ - b8 += data->oem_area_1_size; - - /* Search for a matching hash */ - for (i = 0; i < data->num_hashes; i++, b8 += data->hash_entry_size) { - const struct bdb_hash *h = (const struct bdb_hash *)b8; - - if (h->type == type) - return h; - } - - return NULL; -} - -const struct bdb_sig *bdb_get_data_sig(const void *buf) -{ - const struct bdb_data *data = bdb_get_data(buf); - const uint8_t *b8 = (const uint8_t *)data; - - /* Data signature starts after signed data */ - return (const struct bdb_sig *)(b8 + data->signed_size); -} - -/*****************************************************************************/ - -int bdb_verify_sig(const struct bdb_key *key, - const struct bdb_sig *sig, - const uint8_t *digest) -{ - /* Key and signature algorithms must match */ - if (key->sig_alg != sig->sig_alg) - return BDB_ERROR_SIG_ALG; - - switch (key->sig_alg) { - case BDB_SIG_ALG_RSA4096: - if (bdb_rsa4096_verify(key->key_data, sig->sig_data, digest)) - return BDB_ERROR_VERIFY_SIG; - break; - case BDB_SIG_ALG_ECSDSA521: - if (bdb_ecdsa521_verify(key->key_data, sig->sig_data, digest)) - return BDB_ERROR_VERIFY_SIG; - break; - case BDB_SIG_ALG_RSA3072B: - if (bdb_rsa3072b_verify(key->key_data, sig->sig_data, digest)) - return BDB_ERROR_VERIFY_SIG; - break; - default: - return BDB_ERROR_VERIFY_SIG; - } - - return BDB_SUCCESS; -} - -int bdb_verify(const void *buf, size_t size, const uint8_t *bdb_key_digest) -{ - const uint8_t *end = (const uint8_t *)buf + size; - const struct bdb_header *h; - const struct bdb_key *bdbkey, *subkey; - const struct bdb_sig *sig; - const struct bdb_data *data; - const void *oem; - uint8_t digest[BDB_SHA256_DIGEST_SIZE]; - int bdb_digest_mismatch; - - /* Make sure buffer doesn't wrap around address space */ - if (end < (const uint8_t *)buf) - return BDB_ERROR_BUF_SIZE; - - /* - * Check header now that we've actually loaded it. We can't guarantee - * this is the same header which was checked before. - */ - h = bdb_get_header(buf); - if (bdb_check_header(h, size)) - return BDB_ERROR_HEADER; - - /* Sanity-check BDB key */ - bdbkey = bdb_get_bdbkey(buf); - if (bdb_check_key(bdbkey, end - (const uint8_t *)bdbkey)) - return BDB_ERROR_BDBKEY; - - /* Calculate BDB key digest and compare with expected */ - if (bdb_sha256(digest, bdbkey, bdbkey->struct_size)) - return BDB_ERROR_DIGEST; - - bdb_digest_mismatch = memcmp(digest, bdb_key_digest, sizeof(digest)); - - /* Make sure OEM area 0 fits */ - oem = bdb_get_oem_area_0(buf); - if (h->oem_area_0_size > end - (const uint8_t *)oem) - return BDB_ERROR_OEM_AREA_0; - - /* Sanity-check subkey */ - subkey = bdb_get_subkey(buf); - if (bdb_check_key(subkey, end - (const uint8_t *)subkey)) - return BDB_ERROR_SUBKEY; - - /* Make sure enough data was signed, and the signed data fits */ - if (h->oem_area_0_size + subkey->struct_size > h->signed_size || - h->signed_size > end - (const uint8_t *)oem) - return BDB_ERROR_BDB_SIGNED_SIZE; - - /* Sanity-check header signature */ - sig = bdb_get_header_sig(buf); - if (bdb_check_sig(sig, end - (const uint8_t *)sig)) - return BDB_ERROR_HEADER_SIG; - - /* Make sure it signed the right amount of data */ - if (sig->signed_size != h->signed_size) - return BDB_ERROR_HEADER_SIG; - - /* Calculate header digest and compare with expected signature */ - if (bdb_sha256(digest, oem, h->signed_size)) - return BDB_ERROR_DIGEST; - if (bdb_verify_sig(bdbkey, sig, digest)) - return BDB_ERROR_HEADER_SIG; - - /* - * Sanity-check data struct. This also checks that OEM area 1 and the - * hashes fit in the remaining buffer. - */ - data = bdb_get_data(buf); - if (bdb_check_data(data, end - (const uint8_t *)data)) - return BDB_ERROR_DATA; - - /* Sanity-check data signature */ - sig = bdb_get_data_sig(buf); - if (bdb_check_sig(sig, end - (const uint8_t *)sig)) - return BDB_ERROR_DATA_SIG; - if (sig->signed_size != data->signed_size) - return BDB_ERROR_DATA_SIG; - - /* Calculate data digest and compare with expected signature */ - if (bdb_sha256(digest, data, data->signed_size)) - return BDB_ERROR_DIGEST; - if (bdb_verify_sig(subkey, sig, digest)) - return BDB_ERROR_DATA_SIG; - - /* Return success or success-other-than-BDB-key-mismatch */ - return bdb_digest_mismatch ? BDB_GOOD_OTHER_THAN_KEY : BDB_SUCCESS; -} diff --git a/bdb/bdb.h b/bdb/bdb.h deleted file mode 100644 index 177deeae..00000000 --- a/bdb/bdb.h +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block firmware functions - */ - -#ifndef VBOOT_REFERENCE_BDB_H_ -#define VBOOT_REFERENCE_BDB_H_ - -#include <stdlib.h> -#include "bdb_struct.h" - -/*****************************************************************************/ -/* -Expected calling sequence: - -Load and check just the header -bdb_check_header(buf, size); - -Load and verify the entire BDB -bdb_verify(buf, size, bdb_key_hash, dev_mode_flag); - -Check RW subkey version. If normal boot from primary BDB, roll forward - -Check data version. If normal boot from primary BDB, roll forward -*/ - -/*****************************************************************************/ -/* Codes for functions returning numeric error codes */ - -enum bdb_return_code { - /* Success */ - BDB_SUCCESS = 0, - - /* BDB key did not match hash, but other than that the BDB was - * fully verified. */ - BDB_GOOD_OTHER_THAN_KEY = 1, - - /* Other errors */ - BDB_ERROR_UNKNOWN = 100, - - /* Buffer size too small or wraps around */ - BDB_ERROR_BUF_SIZE, - - /* Bad fields in structures */ - BDB_ERROR_STRUCT_MAGIC, - BDB_ERROR_STRUCT_VERSION, - BDB_ERROR_STRUCT_SIZE, - BDB_ERROR_SIGNED_SIZE, - BDB_ERROR_BDB_SIZE, - BDB_ERROR_OEM_AREA_SIZE, - BDB_ERROR_HASH_ENTRY_SIZE, - BDB_ERROR_HASH_ALG, - BDB_ERROR_SIG_ALG, - BDB_ERROR_DESCRIPTION, - - /* Bad components of BDB in bdb_verify() */ - BDB_ERROR_HEADER, - BDB_ERROR_BDBKEY, - BDB_ERROR_OEM_AREA_0, - BDB_ERROR_SUBKEY, - BDB_ERROR_BDB_SIGNED_SIZE, - BDB_ERROR_HEADER_SIG, - BDB_ERROR_DATA, - BDB_ERROR_DATA_SIG, - - /* Other errors in bdb_verify() */ - BDB_ERROR_DIGEST, /* Error calculating digest */ - BDB_ERROR_VERIFY_SIG, /* Error verifying signature */ -}; - -/*****************************************************************************/ -/* Functions */ - -/** - * Sanity-check BDB structures. - * - * This checks for known version numbers, magic numbers, algorithms, etc. and - * ensures the sizes are consistent with those parameters. - * - * @param p Pointer to structure to check - * @param size Size of structure buffer - * @return 0 if success, non-zero error code if error. - */ -int bdb_check_header(const struct bdb_header *p, size_t size); -int bdb_check_key(const struct bdb_key *p, size_t size); -int bdb_check_sig(const struct bdb_sig *p, size_t size); -int bdb_check_data(const struct bdb_data *p, size_t size); - -/** - * Verify the entire BDB - * - * @param buf Data to hash - * @param size Size of data in bytes - * @param bdb_key_digest Pointer to expected digest for BDB key. - * Must be BDB_SHA256_DIGEST_SIZE bytes long. - * - * @return 0 if success, non-zero error code if error. Note that error code - * BDB_GOOD_OTHER_THAN_KEY may still indicate an acceptable BDB if the Boot - * Verified fuse has not been set, or in developer mode. - */ -int bdb_verify(const void *buf, size_t size, const uint8_t *bdb_key_digest); - -/** - * Functions to extract things from a verified BDB buffer. - * - * Do not call these externally until after bdb_verify()! These methods - * assume data structures have already been verified. - * - * @param buf Pointer to BDB buffer - * @param type Data type, for bdb_get_hash() - * @return A pointer to the requested data, or NULL if error / not present. - */ -const struct bdb_header *bdb_get_header(const void *buf); -const struct bdb_key *bdb_get_bdbkey(const void *buf); -const void *bdb_get_oem_area_0(const void *buf); -const struct bdb_key *bdb_get_subkey(const void *buf); -const struct bdb_sig *bdb_get_header_sig(const void *buf); -const struct bdb_data *bdb_get_data(const void *buf); -const void *bdb_get_oem_area_1(const void *buf); -const struct bdb_hash *bdb_get_hash(const void *buf, enum bdb_data_type type); -const struct bdb_sig *bdb_get_data_sig(const void *buf); - -/*****************************************************************************/ -/* Functions probably provided by the caller */ - -/** - * Calculate a SHA-256 digest of a buffer. - * - * @param digest Pointer to the digest buffer. Must be - * BDB_SHA256_DIGEST_SIZE bytes long. - * @param buf Data to hash - * @param size Size of data in bytes - * @return 0 if success, non-zero error code if error. - */ -__attribute__((weak)) -int bdb_sha256(void *digest, const void *buf, size_t size); - -/** - * Verify a RSA-4096 signed digest - * - * @param key_data Key data to use (BDB_RSA4096_KEY_DATA_SIZE bytes) - * @param sig_data Signature to verify (BDB_RSA4096_SIG_SIZE bytes) - * @param digest Digest of signed data (BDB_SHA256_DIGEST bytes) - * @return 0 if success, non-zero error code if error. - */ -__attribute__((weak)) -int bdb_rsa4096_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest); - -/** - * Verify a RSA-3072B signed digest - * - * @param key_data Key data to use (BDB_RSA3072B_KEY_DATA_SIZE bytes) - * @param sig_data Signature to verify (BDB_RSA3072B_SIG_SIZE bytes) - * @param digest Digest of signed data (BDB_SHA256_DIGEST bytes) - * @return 0 if success, non-zero error code if error. - */ -__attribute__((weak)) -int bdb_rsa3072b_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest); - -/** - * Verify a ECDSA-521 signed digest - * - * @param key_data Key data to use (BDB_ECDSA521_KEY_DATA_SIZE bytes) - * @param sig_data Signature to verify (BDB_ECDSA521_SIG_SIZE bytes) - * @param digest Digest of signed data (BDB_SHA256_DIGEST bytes) - * @return 0 if success, non-zero error code if error. - */ -__attribute__((weak)) -int bdb_ecdsa521_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest); - -/*****************************************************************************/ - -#endif /* VBOOT_REFERENCE_BDB_H_ */ diff --git a/bdb/bdb_create.c b/bdb/bdb_create.c deleted file mode 100644 index fdbf71d9..00000000 --- a/bdb/bdb_create.c +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright (c) 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. - * - * Create a BDB - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "bdb.h" -#include "host.h" - -/* Parameters for creating a BDB hash entry */ -struct create_hash { - /* File containing data */ - const char *filename; - - /* Type of data; enum bdb_data_type */ - uint8_t type; - - /* Address in RAM to load data. -1 means use default. */ - uint64_t load_address; - - /* Partition number containing data, or -1 to use the same partition as - * the BDB. */ - uint8_t partition; - - /* - * Offset of data from start of partition. - * - * TODO: if -1, append after BDB. But need to know how big the BDB - * is, and need to round up offset to 32-bit boundary. - */ - uint64_t offset; -}; - -/* Parameters for a key */ -struct create_key { - /* Description */ - const char *description; - - /* Key version (not meaningful for BDB key) */ - uint32_t key_version; - - /* Public key filename (.keyb) */ - const char *public_filename; - - /* Private key filename (.pem) */ - const char *private_filename; -}; - -struct create_params_2 { - /* Destination filename */ - const char *filename; - - /* Partition to contain the BDB */ - uint8_t partition; - - /* OEM area files. NULL means there is no data for that area. */ - const char *oem_area_0_filename; - const char *oem_area_1_filename; - - /* BDB key and subkey */ - struct create_key bdbkey; - struct create_key subkey; -}; - -/*****************************************************************************/ -/* FILL THIS IN WITH YOUR SOURCE DATA */ - -/* - * Creation parameters. Hash and num_hashes will be filled in automatically - * by create(). - */ -struct bdb_create_params p = { - .bdb_load_address = 0x11223344, - .header_sig_description = "The header sig", - .data_sig_description = "The data sig", - .data_description = "Test BDB data", - .data_version = 3, -}; - -/* Additional parameters */ -struct create_params_2 p2 = { - .filename = "build/bdb.bin", - .partition = 1, - .oem_area_0_filename = "testdata/oem0.bin", - .oem_area_1_filename = "testdata/oem1.bin", - .bdbkey = { - .description = "Test BDB key", - .key_version = 3, - .public_filename = "testkeys/bdbkey.keyb", - .private_filename = "testkeys/bdbkey.pem", - }, - .subkey = { - .description = "Test Subkey", - .key_version = 4, - .public_filename = "testkeys/subkey.keyb", - .private_filename = "testkeys/subkey.pem", - }, -}; - -/* List of hash entries, terminated by one with a NULL filename */ -struct create_hash hash_entries[] = { - { - .filename = "testdata/sp-rw.bin", - .type = BDB_DATA_SP_RW, - .load_address = -1, - .partition = -1, - .offset = 0x10000, - }, - { - .filename = "testdata/ap-rw.bin", - .type = BDB_DATA_AP_RW, - .load_address = 0x200000, - .partition = -1, - .offset = 0x28000, - }, - { - .filename = NULL - }, -}; - -/*****************************************************************************/ - -int create(void) -{ - struct bdb_hash *hash; - struct bdb_header *h; - int i; - - /* Count the number of hash entries */ - for (p.num_hashes = 0; hash_entries[p.num_hashes].filename; - p.num_hashes++) - ; - printf("Found %d hash entries\n", p.num_hashes); - - /* Calculate hashes */ - p.hash = hash = calloc(sizeof(struct bdb_hash), p.num_hashes); - for (i = 0; i < p.num_hashes; i++, hash++) { - const struct create_hash *he = hash_entries + i; - - /* Read file and calculate size and hash */ - uint8_t *buf = read_file(he->filename, &hash->size); - if (!buf) - return 1; - if (bdb_sha256(hash->digest, buf, hash->size)) { - fprintf(stderr, "Unable to calculate hash\n"); - return 1; - } - free(buf); - - hash->type = he->type; - hash->load_address = he->load_address; - - hash->partition = he->partition == -1 ? p2.partition : - he->partition; - - hash->offset = he->offset; - } - - /* Read OEM data */ - if (p2.oem_area_0_filename) { - p.oem_area_0 = read_file(p2.oem_area_0_filename, - &p.oem_area_0_size); - if (!p.oem_area_0) - return 1; - - if (p.oem_area_0_size & 3) { - fprintf(stderr, - "OEM area 0 size isn't 32-bit aligned\n"); - return 1; - } - } - - if (p2.oem_area_1_filename) { - p.oem_area_1 = read_file(p2.oem_area_1_filename, - &p.oem_area_1_size); - if (!p.oem_area_1) - return 1; - - if (p.oem_area_1_size & 3) { - fprintf(stderr, - "OEM area 1 size isn't 32-bit aligned\n"); - return 1; - } - } - - /* Load keys */ - p.bdbkey = bdb_create_key(p2.bdbkey.public_filename, - p2.bdbkey.key_version, - p2.bdbkey.description); - p.subkey = bdb_create_key(p2.subkey.public_filename, - p2.subkey.key_version, - p2.subkey.description); - p.private_bdbkey = read_pem(p2.bdbkey.private_filename); - p.private_subkey = read_pem(p2.subkey.private_filename); - if (!p.bdbkey || !p.subkey || !p.private_bdbkey || !p.private_subkey) { - fprintf(stderr, "Unable to load keys\n"); - return 1; - } - - /* Create the BDB */ - h = bdb_create(&p); - if (!h) { - fprintf(stderr, "Unable to create BDB\n"); - return 1; - } - - /* Write it */ - if (write_file(p2.filename, h, h->bdb_size)) - return 1; - - /* Free keys and buffers */ - free(p.bdbkey); - free(p.subkey); - RSA_free(p.private_bdbkey); - RSA_free(p.private_subkey); - free(h); - free(p.hash); - - return 0; -} - -/*****************************************************************************/ - -int main(void) -{ - return create(); -} diff --git a/bdb/bdb_struct.h b/bdb/bdb_struct.h deleted file mode 100644 index b4ffb50d..00000000 --- a/bdb/bdb_struct.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block structures - */ - -#ifndef VBOOT_REFERENCE_BDB_STRUCT_H_ -#define VBOOT_REFERENCE_BDB_STRUCT_H_ - -#include <stdint.h> - -/* Size of SHA256 digest in bytes */ -#define BDB_SHA256_DIGEST_SIZE 32 - -/* Size of RSA4096 key data in bytes */ -#define BDB_RSA4096_KEY_DATA_SIZE 1032 - -/* Size of RSA4096 signature in bytes */ -#define BDB_RSA4096_SIG_SIZE 512 - -/* Size of ECDSA521 key data in bytes = ceil(521/8) * 2 */ -#define BDB_ECDSA521_KEY_DATA_SIZE 132 - -/* Size of ECDSA521 signature in bytes = ceil(521/8) * 2 */ -#define BDB_ECDSA521_SIG_SIZE 132 - -/* Size of RSA3072B key data in bytes */ -#define BDB_RSA3072B_KEY_DATA_SIZE 776 - -/* Size of RSA3072B signature in bytes */ -#define BDB_RSA3072B_SIG_SIZE 384 - -/*****************************************************************************/ -/* Header for BDB */ - -/* Magic number for bdb_header.struct_magic */ -#define BDB_HEADER_MAGIC 0x30426442 - -/* Current version of bdb_header struct */ -#define BDB_HEADER_VERSION_MAJOR 1 -#define BDB_HEADER_VERSION_MINOR 0 - -/* Expected size of bdb_header struct in bytes */ -#define BDB_HEADER_EXPECTED_SIZE 32 - -struct bdb_header { - /* Magic number to identify struct = BDB_HEADER_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_HEADER_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes */ - uint16_t struct_size; - - /* Recommended address in SP SRAM to load BDB. Set to -1 to use - * default address. */ - uint64_t bdb_load_address; - - /* Size of the entire BDB in bytes */ - uint32_t bdb_size; - - /* Number of bytes following the BDB key which are signed by the BDB - * header signature. */ - uint32_t signed_size; - - /* Size of OEM area 0 in bytes, or 0 if not present */ - uint32_t oem_area_0_size; - - /* Reserved; set 0 */ - uint8_t reserved0[8]; -} __attribute__((packed)); - -/*****************************************************************************/ -/* Public key structure for BDB */ - -/* Magic number for bdb_key.struct_magic */ -#define BDB_KEY_MAGIC 0x73334256 - -/* Current version of bdb_key struct */ -#define BDB_KEY_VERSION_MAJOR 1 -#define BDB_KEY_VERSION_MINOR 0 - -/* Supported hash algorithms */ -enum bdb_hash_alg { - BDB_HASH_ALG_INVALID = 0, /* Not used; invalid */ - BDB_HASH_ALG_SHA256 = 2, /* SHA-256 */ -}; - -/* Supported signature algorithms */ -enum bdb_sig_alg { - BDB_SIG_ALG_INVALID = 0, /* Not used; invalid */ - BDB_SIG_ALG_RSA4096 = 3, /* RSA-4096, exponent 65537 */ - BDB_SIG_ALG_ECSDSA521 = 5, /* ECDSA-521 */ - BDB_SIG_ALG_RSA3072B = 7, /* RSA_3072, exponent 3 */ -}; - -/* - * Expected size of bdb_key struct in bytes, not counting variable-length key - * data at end. - */ -#define BDB_KEY_EXPECTED_SIZE 80 - -struct bdb_key { - /* Magic number to identify struct = BDB_KEY_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_KEY_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes, including variable-length key data */ - uint16_t struct_size; - - /* Hash algorithm (enum bdb_hash_alg) */ - uint8_t hash_alg; - - /* Signature algorithm (enum bdb_sig_alg) */ - uint8_t sig_alg; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Key version */ - uint32_t key_version; - - /* Description; null-terminated ASCII */ - char description[128]; - - /* - * Key data. Variable-length; size is struct_size - - * offset_of(bdb_key, key_data). - */ - uint8_t key_data[0]; -} __attribute__((packed)); - -/*****************************************************************************/ -/* Signature structure for BDB */ - -/* Magic number for bdb_sig.struct_magic */ -#define BDB_SIG_MAGIC 0x6b334256 - -/* Current version of bdb_sig struct */ -#define BDB_SIG_VERSION_MAJOR 1 -#define BDB_SIG_VERSION_MINOR 0 - -struct bdb_sig { - /* Magic number to identify struct = BDB_SIG_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_SIG_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes, including variable-length signature - * data. */ - uint16_t struct_size; - - /* Hash algorithm used for this signature (enum bdb_hash_alg) */ - uint8_t hash_alg; - - /* Signature algorithm (enum bdb_sig_alg) */ - uint8_t sig_alg; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Number of bytes of data signed by this signature */ - uint32_t signed_size; - - /* Description; null-terminated ASCII */ - char description[128]; - - /* Signature data. Variable-length; size is struct_size - - * offset_of(bdb_sig, sig_data). */ - uint8_t sig_data[0]; -} __attribute__((packed)); - -/*****************************************************************************/ -/* Data structure for BDB */ - -/* Magic number for bdb_data.struct_magic */ -#define BDB_DATA_MAGIC 0x31426442 - -/* Current version of bdb_sig struct */ -#define BDB_DATA_VERSION_MAJOR 1 -#define BDB_DATA_VERSION_MINOR 0 - -struct bdb_data { - /* Magic number to identify struct = BDB_DATA_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_DATA_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes, NOT including hashes which follow. */ - uint16_t struct_size; - - /* Version of data (RW firmware) contained */ - uint32_t data_version; - - /* Size of OEM area 1 in bytes, or 0 if not present */ - uint32_t oem_area_1_size; - - /* Number of hashes which follow */ - uint8_t num_hashes; - - /* Size of each hash entry in bytes */ - uint8_t hash_entry_size; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Number of bytes of data signed by the subkey, including this - * header */ - uint32_t signed_size; - - /* Reserved; set 0 */ - uint8_t reserved1[8]; - - /* Description; null-terminated ASCII */ - char description[128]; -} __attribute__((packed)); - -/* Type of data for bdb_hash.type */ -enum bdb_data_type { - /* Types of data for boot descriptor blocks */ - BDB_DATA_SP_RW = 1, /* SP-RW firmware */ - BDB_DATA_AP_RW = 2, /* AP-RW firmware */ - BDB_DATA_MCU = 3, /* MCU firmware */ - - /* Types of data for kernel descriptor blocks */ - BDB_DATA_KERNEL = 128, /* Kernel */ - BDB_DATA_CMD_LINE = 129, /* Command line */ - BDB_DATA_HEADER16 = 130, /* 16-bit vmlinuz header */ -}; - -/* Hash entries which follow the structure */ -struct bdb_hash { - /* Offset of data from start of partition */ - uint64_t offset; - - /* Size of data in bytes */ - uint32_t size; - - /* Partition number containing data */ - uint8_t partition; - - /* Type of data; enum bdb_data_type */ - uint8_t type; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Address in RAM to load data. -1 means use default. */ - uint64_t load_address; - - /* SHA-256 hash digest */ - uint8_t digest[BDB_SHA256_DIGEST_SIZE]; -} __attribute__((packed)); - -/*****************************************************************************/ - -#endif /* VBOOT_REFERENCE_BDB_STRUCT_H_ */ - diff --git a/bdb/bdb_test.c b/bdb/bdb_test.c deleted file mode 100644 index 6c9022dc..00000000 --- a/bdb/bdb_test.c +++ /dev/null @@ -1,492 +0,0 @@ -/* Copyright (c) 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. - * - * Unit tests - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "bdb.h" -#include "host.h" - -#define TEST_EQ(got, want) test_eq(got, want, #got, #want, __LINE__) - -void test_eq(int got, int want, const char *gotstr, const char *wantstr, - int line) -{ - if (got == want) - return; - - fprintf(stderr, "Fail(%d): %s != %s\n" - "got: 0x%08x (%d)\n" - "wanted: 0x%08x (%d)\n", - line, gotstr, wantstr, got, got, want, want); - exit(1); -} - -void check_header_tests(void) -{ - struct bdb_header sgood = { - .struct_magic = BDB_HEADER_MAGIC, - .struct_major_version = BDB_HEADER_VERSION_MAJOR, - .struct_minor_version = BDB_HEADER_VERSION_MINOR, - .struct_size = sizeof(struct bdb_header), - .bdb_load_address = -1, - .bdb_size = 1024, - .signed_size = 512, - .oem_area_0_size = 256, - }; - const size_t ssize = sgood.struct_size; - struct bdb_header s; - - s = sgood; - TEST_EQ(bdb_check_header(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_header(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - s = sgood; - s.oem_area_0_size++; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_OEM_AREA_SIZE); - - s = sgood; - s.bdb_size = ssize - 1; - TEST_EQ(bdb_check_header(&s, ssize), BDB_ERROR_BDB_SIZE); -} - -void check_key_tests(void) -{ - struct bdb_key sgood = { - .struct_magic = BDB_KEY_MAGIC, - .struct_major_version = BDB_KEY_VERSION_MAJOR, - .struct_minor_version = BDB_KEY_VERSION_MINOR, - .struct_size = (sizeof(struct bdb_key) + - BDB_RSA4096_KEY_DATA_SIZE), - .hash_alg = BDB_HASH_ALG_SHA256, - .sig_alg = BDB_SIG_ALG_RSA4096, - .key_version = 1, - .description = "Test key", - }; - const size_t ssize = sgood.struct_size; - struct bdb_key s; - - s = sgood; - TEST_EQ(bdb_check_key(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_key(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ(bdb_check_key(&s, ssize), BDB_SUCCESS); - - /* Limited algorithm choices at present */ - s = sgood; - s.hash_alg = BDB_HASH_ALG_INVALID; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_HASH_ALG); - - /* This works because ECDSA521 signatures are smaller than RSA4096 */ - s = sgood; - s.sig_alg = BDB_SIG_ALG_ECSDSA521; - TEST_EQ(bdb_check_key(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.sig_alg = BDB_SIG_ALG_INVALID; - TEST_EQ(bdb_check_key(&s, ssize), BDB_ERROR_SIG_ALG); -} - -void check_sig_tests(void) -{ - struct bdb_sig sgood = { - .struct_magic = BDB_SIG_MAGIC, - .struct_major_version = BDB_SIG_VERSION_MAJOR, - .struct_minor_version = BDB_SIG_VERSION_MINOR, - .struct_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE, - .hash_alg = BDB_HASH_ALG_SHA256, - .sig_alg = BDB_SIG_ALG_RSA4096, - .signed_size = 123, - .description = "Test sig", - }; - const size_t ssize = sgood.struct_size; - struct bdb_sig s; - - s = sgood; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_sig(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_SUCCESS); - - /* Limited algorithm choices at present */ - s = sgood; - s.hash_alg = BDB_HASH_ALG_INVALID; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_HASH_ALG); - - /* This works because ECDSA521 signatures are smaller than RSA4096 */ - s = sgood; - s.sig_alg = BDB_SIG_ALG_ECSDSA521; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.sig_alg = BDB_SIG_ALG_INVALID; - TEST_EQ(bdb_check_sig(&s, ssize), BDB_ERROR_SIG_ALG); -} - -void check_data_tests(void) -{ - struct bdb_data sgood = { - .struct_magic = BDB_DATA_MAGIC, - .struct_major_version = BDB_DATA_VERSION_MAJOR, - .struct_minor_version = BDB_DATA_VERSION_MINOR, - .struct_size = sizeof(struct bdb_data), - .data_version = 1, - .oem_area_1_size = 256, - .num_hashes = 3, - .hash_entry_size = sizeof(struct bdb_hash), - .signed_size = 2048, - .description = "Test data", - }; - const size_t ssize = sgood.signed_size; - struct bdb_data s; - - s = sgood; - TEST_EQ(bdb_check_data(&s, ssize), BDB_SUCCESS); - TEST_EQ(bdb_check_data(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ(bdb_check_data(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.hash_entry_size--; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_HASH_ENTRY_SIZE); - - s = sgood; - s.oem_area_1_size++; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_OEM_AREA_SIZE); - - /* Check exact size needed */ - s = sgood; - s.signed_size = sizeof(s) + s.num_hashes * sizeof(struct bdb_hash) + - s.oem_area_1_size; - TEST_EQ(bdb_check_data(&s, ssize), BDB_SUCCESS); - s.signed_size--; - TEST_EQ(bdb_check_data(&s, ssize), BDB_ERROR_SIGNED_SIZE); - - /* - * TODO: Verify wraparound check works. That can only be tested on a - * platform where size_t is uint32_t, because otherwise a 32-bit - * oem_area_1_size can't cause wraparound. - */ -} - -/** - * Test bdb_verify() and bdb_create() - */ -void check_bdb_verify(void) -{ - uint8_t oem_area_0[32] = "Some OEM area."; - uint8_t oem_area_1[64] = "Some other OEM area."; - - struct bdb_hash hash[2] = { - { - .offset = 0x10000, - .size = 0x18000, - .partition = 1, - .type = BDB_DATA_SP_RW, - .load_address = 0x100000, - .digest = {0x11, 0x11, 0x11, 0x10}, - }, - { - .offset = 0x28000, - .size = 0x20000, - .partition = 1, - .type = BDB_DATA_AP_RW, - .load_address = 0x200000, - .digest = {0x22, 0x22, 0x22, 0x20}, - }, - }; - - struct bdb_create_params p = { - .bdb_load_address = 0x11223344, - .oem_area_0 = oem_area_0, - .oem_area_0_size = sizeof(oem_area_0), - .oem_area_1 = oem_area_1, - .oem_area_1_size = sizeof(oem_area_1), - .header_sig_description = "The header sig", - .data_sig_description = "The data sig", - .data_description = "Test BDB data", - .data_version = 3, - .hash = hash, - .num_hashes = 2, - }; - - uint8_t bdbkey_digest[BDB_SHA256_DIGEST_SIZE]; - struct bdb_header *hgood, *h; - size_t hsize; - - /* Load keys */ - p.bdbkey = bdb_create_key("testkeys/bdbkey.keyb", 100, "BDB key"); - p.subkey = bdb_create_key("testkeys/subkey.keyb", 200, "Subkey"); - p.private_bdbkey = read_pem("testkeys/bdbkey.pem"); - p.private_subkey = read_pem("testkeys/subkey.pem"); - if (!p.bdbkey || !p.subkey || !p.private_bdbkey || !p.private_subkey) { - fprintf(stderr, "Unable to load test keys\n"); - exit(2); - } - - bdb_sha256(bdbkey_digest, p.bdbkey, p.bdbkey->struct_size); - - /* Create the test BDB */ - hgood = bdb_create(&p); - if (!hgood) { - fprintf(stderr, "Unable to create test BDB\n"); - exit(2); - } - hsize = hgood->bdb_size; - - /* Allocate a copy we can mangle */ - h = calloc(hsize, 1); - - /* As created, it should pass */ - memcpy(h, hgood, hsize); - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_SUCCESS); - - /* Mangle each component in turn */ - memcpy(h, hgood, hsize); - h->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_bdbkey(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_BDBKEY); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_bdbkey(h))->key_version++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_GOOD_OTHER_THAN_KEY); - - memcpy(h, hgood, hsize); - h->oem_area_0_size += hsize; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_OEM_AREA_0); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_subkey(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_SUBKEY); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_subkey(h))->struct_size += 4; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_BDB_SIGNED_SIZE); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->signed_size--; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->sig_data[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - /* Also make sure the header sig really covers all the fields */ - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_subkey(h))->key_version++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_0(h))[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_0(h))[p.oem_area_0_size - 1] ^= 0x24; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - /* Check data header */ - memcpy(h, hgood, hsize); - ((struct bdb_data *)bdb_get_data(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->struct_magic++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->signed_size--; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->sig_data[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - /* Also make sure the data sig really covers all the fields */ - memcpy(h, hgood, hsize); - ((struct bdb_data *)bdb_get_data(h))->data_version--; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_1(h))[0] ^= 0x42; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_1(h))[p.oem_area_1_size - 1] ^= 0x24; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_hash *)bdb_get_hash(h, BDB_DATA_SP_RW))->offset++; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_hash *)bdb_get_hash(h, BDB_DATA_AP_RW))->digest[0] ^= 0x96; - TEST_EQ(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - /* - * This is also a convenient place to test that all the parameters we - * fed into bdb_create() also worked. That also tests all the - * bdb_get_*() functions. - */ - memcpy(h, hgood, hsize); - TEST_EQ(h->bdb_load_address, p.bdb_load_address); - - TEST_EQ(strcmp(bdb_get_bdbkey(h)->description, - p.bdbkey->description), 0); - TEST_EQ(bdb_get_bdbkey(h)->key_version, p.bdbkey->key_version); - - TEST_EQ(h->oem_area_0_size, p.oem_area_0_size); - TEST_EQ(memcmp(bdb_get_oem_area_0(h), oem_area_0, sizeof(oem_area_0)), - 0); - - TEST_EQ(strcmp(bdb_get_subkey(h)->description, p.subkey->description), - 0); - TEST_EQ(bdb_get_subkey(h)->key_version, p.subkey->key_version); - - TEST_EQ(strcmp(bdb_get_header_sig(h)->description, - p.header_sig_description), 0); - - TEST_EQ(strcmp(bdb_get_data(h)->description, p.data_description), 0); - TEST_EQ(bdb_get_data(h)->data_version, p.data_version); - TEST_EQ(bdb_get_data(h)->num_hashes, p.num_hashes); - - TEST_EQ(bdb_get_data(h)->oem_area_1_size, p.oem_area_1_size); - TEST_EQ(memcmp(bdb_get_oem_area_1(h), oem_area_1, sizeof(oem_area_1)), - 0); - - TEST_EQ(strcmp(bdb_get_data_sig(h)->description, - p.data_sig_description), 0); - - /* Test getting hash entries */ - memcpy(h, hgood, hsize); - TEST_EQ(bdb_get_hash(h, BDB_DATA_SP_RW)->offset, hash[0].offset); - TEST_EQ(bdb_get_hash(h, BDB_DATA_AP_RW)->offset, hash[1].offset); - /* And a non-existent one */ - TEST_EQ(bdb_get_hash(h, BDB_DATA_MCU)!=NULL, 0); - - /* - * TODO: Verify wraparound checks works. That can only be tested on a - * platform where size_t is uint32_t, because otherwise a 32-bit - * oem_area_1_size can't cause wraparound. - */ - - /* Free keys and buffers */ - free(p.bdbkey); - free(p.subkey); - RSA_free(p.private_bdbkey); - RSA_free(p.private_subkey); - free(hgood); - free(h); -} - -/*****************************************************************************/ - -int main(void) -{ - printf("Running tests...\n"); - - check_header_tests(); - check_key_tests(); - check_sig_tests(); - check_data_tests(); - check_bdb_verify(); - - printf("All tests passed!\n"); - - return 0; -} diff --git a/bdb/dump_rsa.c b/bdb/dump_rsa.c deleted file mode 100644 index c40f803a..00000000 --- a/bdb/dump_rsa.c +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright (c) 2010 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. - */ - -/* - * C port of DumpPublicKey.java from the Android Open source project with - * support for additional RSA key sizes. (platform/system/core,git/libmincrypt - * /tools/DumpPublicKey.java). Uses the OpenSSL X509 and BIGNUM library. - */ - -#include <openssl/pem.h> - -#include <stdint.h> -#include <string.h> -#include <unistd.h> - -/* - * Command line tool to extract RSA public keys from X.509 certificates and - * output a pre-processed version of keys for use by RSA verification routines. - */ - -int check(RSA *key) -{ - int public_exponent = BN_get_word(key->e); - int modulus = BN_num_bits(key->n); - - if (public_exponent != 65537 && public_exponent != 3) { - fprintf(stderr, "WARNING: Non-standard public exponent %d.\n", - public_exponent); - } - - if (modulus != 1024 && modulus != 2048 && modulus != 3072 && - modulus != 4096 && modulus != 8192) { - fprintf(stderr, "WARNING: Non-standard modulus length = %d.\n", - modulus); - } - return 1; -} - -/** - * Pre-processes and outputs RSA public key to standard output. - */ -void output(RSA *key) -{ - BIGNUM *N; - BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL; - BIGNUM *B = NULL; - BIGNUM *N0inv= NULL, *R = NULL, *RR = NULL, *RRTemp = NULL; - BIGNUM *NnumBits = NULL; - BIGNUM *n = NULL, *rr = NULL; - BN_CTX *bn_ctx = BN_CTX_new(); - uint32_t n0invout; - int nwords, i; - - N = key->n; - /* Output size of RSA key in 32-bit words */ - nwords = BN_num_bits(N) / 32; - if (-1 == write(1, &nwords, sizeof(nwords))) - goto failure; - - /* Initialize BIGNUMs */ - Big1 = BN_new(); - Big2 = BN_new(); - Big32 = BN_new(); - BigMinus1 = BN_new(); - N0inv= BN_new(); - R = BN_new(); - RR = BN_new(); - RRTemp = BN_new(); - NnumBits = BN_new(); - n = BN_new(); - rr = BN_new(); - - BN_set_word(Big1, 1L); - BN_set_word(Big2, 2L); - BN_set_word(Big32, 32L); - BN_sub(BigMinus1, Big1, Big2); - - B = BN_new(); - BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */ - - /* Calculate and output N0inv = -1 / N[0] mod 2^32 */ - BN_mod_inverse(N0inv, N, B, bn_ctx); - BN_sub(N0inv, B, N0inv); - n0invout = BN_get_word(N0inv); - if (-1 == write(1, &n0invout, sizeof(n0invout))) - goto failure; - - /* Calculate R = 2^(# of key bits) */ - BN_set_word(NnumBits, BN_num_bits(N)); - BN_exp(R, Big2, NnumBits, bn_ctx); - - /* Calculate RR = R^2 mod N */ - BN_copy(RR, R); - BN_mul(RRTemp, RR, R, bn_ctx); - BN_mod(RR, RRTemp, N, bn_ctx); - - /* Write out modulus as little endian array of integers. */ - for (i = 0; i < nwords; ++i) { - uint32_t nout; - - BN_mod(n, N, B, bn_ctx); /* n = N mod B */ - nout = BN_get_word(n); - if (-1 == write(1, &nout, sizeof(nout))) - goto failure; - - BN_rshift(N, N, 32); /* N = N/B */ - } - - /* Write R^2 as little endian array of integers. */ - for (i = 0; i < nwords; ++i) { - uint32_t rrout; - - BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */ - rrout = BN_get_word(rr); - if (-1 == write(1, &rrout, sizeof(rrout))) - goto failure; - - BN_rshift(RR, RR, 32); /* RR = RR/B */ - } - - failure: - /* Free BIGNUMs. */ - BN_free(Big1); - BN_free(Big2); - BN_free(Big32); - BN_free(BigMinus1); - BN_free(N0inv); - BN_free(R); - BN_free(RRTemp); - BN_free(NnumBits); - BN_free(n); - BN_free(rr); - -} - -int main(int argc, char* argv[]) { - int cert_mode = 0; - FILE* fp; - X509* cert = NULL; - RSA* pubkey = NULL; - EVP_PKEY* key; - char *progname; - - if (argc != 3 || - (strcmp(argv[1], "-cert") && strcmp(argv[1], "-pub"))) { - progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - fprintf(stderr, "Usage: %s <-cert | -pub> <file>\n", progname); - return -1; - } - - if (!strcmp(argv[1], "-cert")) - cert_mode = 1; - - fp = fopen(argv[2], "r"); - - if (!fp) { - fprintf(stderr, "Couldn't open file %s!\n", argv[2]); - return -1; - } - - if (cert_mode) { - /* Read the certificate */ - if (!PEM_read_X509(fp, &cert, NULL, NULL)) { - fprintf(stderr, "Couldn't read certificate.\n"); - goto fail; - } - - /* Get the public key from the certificate. */ - key = X509_get_pubkey(cert); - - /* Convert to a RSA_style key. */ - if (!(pubkey = EVP_PKEY_get1_RSA(key))) { - fprintf(stderr, "Couldn't convert to RSA style key.\n"); - goto fail; - } - } else { - /* Read the pubkey in .PEM format. */ - if (!(pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL))) { - fprintf(stderr, "Couldn't read public key file.\n"); - goto fail; - } - } - - if (check(pubkey)) { - output(pubkey); - } - - fail: - X509_free(cert); - RSA_free(pubkey); - fclose(fp); - - return 0; -} diff --git a/bdb/ecdsa.c b/bdb/ecdsa.c deleted file mode 100644 index f4d17287..00000000 --- a/bdb/ecdsa.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block firmware ECDSA stub - */ - -#include <string.h> -#include "bdb.h" - -int bdb_ecdsa521_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest) -{ - /* This is just a stub */ - return BDB_ERROR_DIGEST; -} diff --git a/bdb/host.c b/bdb/host.c deleted file mode 100644 index 24d94652..00000000 --- a/bdb/host.c +++ /dev/null @@ -1,347 +0,0 @@ -/* Copyright (c) 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. - * - * Host functions for signing - */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "bdb.h" -#include "host.h" - -char *strzcpy(char *dest, const char *src, size_t size) -{ - strncpy(dest, src, size); - dest[size - 1] = 0; - return dest; -} - -uint8_t *read_file(const char *filename, uint32_t *size_ptr) -{ - FILE *f; - uint8_t *buf; - long size; - - *size_ptr = 0; - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "Unable to open file %s\n", filename); - return NULL; - } - - fseek(f, 0, SEEK_END); - size = ftell(f); - rewind(f); - - if (size < 0 || size > UINT32_MAX) { - fclose(f); - return NULL; - } - - buf = malloc(size); - if (!buf) { - fclose(f); - return NULL; - } - - if (1 != fread(buf, size, 1, f)) { - fprintf(stderr, "Unable to read file %s\n", filename); - fclose(f); - free(buf); - return NULL; - } - - fclose(f); - - *size_ptr = size; - return buf; -} - -int write_file(const char *filename, const void *buf, uint32_t size) -{ - FILE *f = fopen(filename, "wb"); - - if (!f) { - fprintf(stderr, "Unable to open file %s\n", filename); - return 1; - } - - if (1 != fwrite(buf, size, 1, f)) { - fprintf(stderr, "Unable to write to file %s\n", filename); - fclose(f); - unlink(filename); /* Delete any partial file */ - return 1; - } - - fclose(f); - return 0; -} - -struct rsa_st *read_pem(const char *filename) -{ - struct rsa_st *pem; - FILE *f; - - /* Read private key */ - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "%s: unable to read key from %s\n", - __func__, filename); - return NULL; - } - - pem = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); - fclose(f); - - return pem; -} - -struct bdb_key *bdb_create_key(const char *filename, - uint32_t key_version, - const char *desc) -{ - uint32_t sig_alg; - size_t key_size = sizeof(struct bdb_key); - struct bdb_key *k; - uint8_t *kdata; - uint32_t kdata_size = 0; - - /* - * Read key data. Somewhat lame assumption that we can determine the - * signature algorithm from the key size, but it's true right now. - */ - kdata = read_file(filename, &kdata_size); - if (kdata_size == BDB_RSA4096_KEY_DATA_SIZE) { - sig_alg = BDB_SIG_ALG_RSA4096; - } else if (kdata_size == BDB_RSA3072B_KEY_DATA_SIZE) { - sig_alg = BDB_SIG_ALG_RSA3072B; - } else { - fprintf(stderr, "%s: bad key size from %s\n", - __func__, filename); - return NULL; - } - key_size += kdata_size; - - /* Allocate buffer */ - k = (struct bdb_key *)calloc(key_size, 1); - if (!k) { - free(kdata); - return NULL; - } - - k->struct_magic = BDB_KEY_MAGIC; - k->struct_major_version = BDB_KEY_VERSION_MAJOR; - k->struct_minor_version = BDB_KEY_VERSION_MINOR; - k->struct_size = key_size; - k->hash_alg = BDB_HASH_ALG_SHA256; - k->sig_alg = sig_alg; - k->key_version = key_version; - - /* Copy description, if any */ - if (desc) - strzcpy(k->description, desc, sizeof(k->description)); - - /* Copy key data */ - memcpy(k->key_data, kdata, kdata_size); - free(kdata); - - return k; -} - -struct bdb_sig *bdb_create_sig(const void *data, - size_t size, - struct rsa_st *key, - uint32_t sig_alg, - const char *desc) -{ - static const uint8_t info[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, - 0x00, 0x04, 0x20 - }; - - size_t sig_size = sizeof(struct bdb_sig); - uint8_t digest[sizeof(info) + BDB_SHA256_DIGEST_SIZE]; - struct bdb_sig *sig; - - if (size >= UINT32_MAX) - return NULL; - - switch(sig_alg) { - case BDB_SIG_ALG_RSA4096: - sig_size += BDB_RSA4096_SIG_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - sig_size += BDB_RSA3072B_SIG_SIZE; - break; - default: - fprintf(stderr, "%s: bad signature algorithm %d\n", - __func__, sig_alg); - return NULL; - } - - /* Allocate buffer */ - sig = (struct bdb_sig *)calloc(sig_size, 1); - if (!sig) - return NULL; - - sig->struct_magic = BDB_SIG_MAGIC; - sig->struct_major_version = BDB_SIG_VERSION_MAJOR; - sig->struct_minor_version = BDB_SIG_VERSION_MINOR; - sig->struct_size = sig_size; - sig->hash_alg = BDB_HASH_ALG_SHA256; - sig->sig_alg = sig_alg; - sig->signed_size = size; - - /* Copy description, if any */ - if (desc) - strzcpy(sig->description, desc, sizeof(sig->description)); - - /* Calculate info-padded digest */ - memcpy(digest, info, sizeof(info)); - if (bdb_sha256(digest + sizeof(info), data, size)) { - free(sig); - return NULL; - } - - /* RSA-encrypt the signature */ - if (RSA_private_encrypt(sizeof(digest), - digest, - sig->sig_data, - key, - RSA_PKCS1_PADDING) == -1) { - free(sig); - return NULL; - } - return sig; -} - -struct bdb_header *bdb_create(struct bdb_create_params *p) -{ - size_t bdb_size = 0; - size_t sig_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE; - size_t hashes_size = sizeof(struct bdb_hash) * p->num_hashes; - uint8_t *buf, *bnext; - struct bdb_header *h; - struct bdb_sig *sig; - struct bdb_data *data; - const void *oem; - - /* We can do some checks before we even allocate the buffer */ - - /* Make sure OEM sizes are aligned */ - if ((p->oem_area_0_size & 3) || (p->oem_area_1_size & 3)) { - fprintf(stderr, "%s: OEM areas not 32-bit aligned\n", - __func__); - return NULL; - } - - /* Hash count must fit in uint8_t */ - if (p->num_hashes > 255) { - fprintf(stderr, "%s: too many hashes\n", __func__); - return NULL; - } - - /* Calculate BDB size */ - bdb_size = sizeof(struct bdb_header); - bdb_size += p->bdbkey->struct_size; - bdb_size += p->oem_area_0_size; - bdb_size += p->subkey->struct_size; - bdb_size += sig_size; - bdb_size += sizeof(struct bdb_data); - bdb_size += p->oem_area_1_size; - bdb_size += sizeof(struct bdb_hash) * p->num_hashes; - bdb_size += sig_size; - - /* Make sure it fits */ - if (bdb_size > UINT32_MAX) { - fprintf(stderr, "%s: BDB size > UINT32_MAX\n", __func__); - return NULL; - } - - /* Allocate a buffer */ - bnext = buf = calloc(bdb_size, 1); - if (!buf) { - fprintf(stderr, "%s: can't allocate buffer\n", __func__); - return NULL; - } - - /* Fill in the header */ - h = (struct bdb_header *)bnext; - h->struct_magic = BDB_HEADER_MAGIC; - h->struct_major_version = BDB_HEADER_VERSION_MAJOR; - h->struct_minor_version = BDB_HEADER_VERSION_MINOR; - h->struct_size = sizeof(*h); - h->bdb_load_address = p->bdb_load_address; - h->bdb_size = bdb_size; - h->signed_size = p->oem_area_0_size + p->subkey->struct_size; - h->oem_area_0_size = p->oem_area_0_size; - bnext += h->struct_size; - - /* Copy BDB key */ - memcpy(bnext, p->bdbkey, p->bdbkey->struct_size); - bnext += p->bdbkey->struct_size; - - /* Copy OEM area 0 */ - oem = bnext; - if (p->oem_area_0_size) { - memcpy(bnext, p->oem_area_0, p->oem_area_0_size); - bnext += p->oem_area_0_size; - } - - /* Copy subkey */ - memcpy(bnext, p->subkey, p->subkey->struct_size); - bnext += p->subkey->struct_size; - - /* - * Create header signature using private BDB key. - * - * TODO: create the header signature in a totally separate step. That - * way, the private BDB key is not required each time a BDB is created. - */ - sig = bdb_create_sig(oem, h->signed_size, p->private_bdbkey, - p->bdbkey->sig_alg, p->header_sig_description); - memcpy(bnext, sig, sig->struct_size); - bnext += sig->struct_size; - - /* Fill in the data */ - data = (struct bdb_data *)bnext; - data->struct_magic = BDB_DATA_MAGIC; - data->struct_major_version = BDB_DATA_VERSION_MAJOR; - data->struct_minor_version = BDB_DATA_VERSION_MINOR; - data->struct_size = sizeof(struct bdb_data); - data->data_version = p->data_version; - data->oem_area_1_size = p->oem_area_1_size; - data->num_hashes = p->num_hashes; - data->hash_entry_size = sizeof(struct bdb_hash); - data->signed_size = data->struct_size + data->oem_area_1_size + - hashes_size; - if (p->data_description) { - strzcpy(data->description, p->data_description, - sizeof(data->description)); - } - bnext += data->struct_size; - - /* Copy OEM area 1 */ - oem = bnext; - if (p->oem_area_1_size) { - memcpy(bnext, p->oem_area_1, p->oem_area_1_size); - bnext += p->oem_area_1_size; - } - - /* Copy hashes */ - memcpy(bnext, p->hash, hashes_size); - bnext += hashes_size; - - /* Create data signature using private subkey */ - sig = bdb_create_sig(data, data->signed_size, p->private_subkey, - p->subkey->sig_alg, p->data_sig_description); - memcpy(bnext, sig, sig->struct_size); - - /* Return the BDB */ - return h; -} diff --git a/bdb/host.h b/bdb/host.h deleted file mode 100644 index 9334680b..00000000 --- a/bdb/host.h +++ /dev/null @@ -1,171 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block host functions - */ - -#ifndef VBOOT_REFERENCE_BDB_HOST_H_ -#define VBOOT_REFERENCE_BDB_HOST_H_ - -#include <stdlib.h> -#include <openssl/pem.h> -#include "bdb_struct.h" - -/*****************************************************************************/ -/* -Expected calling sequence: - -Load and check just the header -bdb_check_header(buf, size); - -Load and verify the entire BDB -bdb_verify(buf, size, bdb_key_hash, dev_mode_flag); - - bdb_check_header() again - paranoia against bad storage devices - - bdb_check_key() on BDB key - bdb_sha256() on BDB key - Compare with appropriate root key hash - If dev_mode_flag(), mismatch is not fatal - - bdb_check_sig() on BDB header sig - bdb_sha256() on OEM area 1, RW subkey - bdb_rsa_verify() on digest using BDB key - - bdb_check_key() on RW subkey - - bdb_check_data() on RW data - bdb_check_sig() on data sig - bdb_sha256() on data, OEM area 1, hashes - bdb_rsa_verify() on digest using RW subkey - -Check RW subkey version. If normal boot from primary BDB, roll forward -Check data version. If normal boot from primary BDB, roll forward -*/ - -/*****************************************************************************/ -/* Codes for functions returning numeric error codes */ - -enum bdb_host_return_code { - /* All/any of bdb_return_code, and the following... */ - - /* Other errors */ - BDB_ERROR_HOST = 200, -}; - -/*****************************************************************************/ -/* Functions */ - -/** - * Like strncpy, but guaranteeing null termination - */ -char *strzcpy(char *dest, const char *src, size_t size); - -/** - * Read a file. - * - * Caller must free() the returned buffer. - * - * @param filename Path to file - * @param size_ptr Destination for size of buffer - * @return A newly allocated buffer containing the data, or NULL if error. - */ -uint8_t *read_file(const char *filename, uint32_t *size_ptr); - -/** - * Write a file. - * - * @param buf Data to write - * @param size Size of data in bytes - * @return 0 if success, non-zero error code if error. - */ -int write_file(const char *filename, const void *buf, uint32_t size); - -/** - * Read a PEM from a file. - * - * Caller must free the PEM with RSA_free(). - * - * @param filename Path to file - * @return A newly allocated PEM object, or NULL if error. - */ -struct rsa_st *read_pem(const char *filename); - -/** - * Create a BDB public key object. - * - * Caller must free() the returned key. - * - * @param filename Path to file containing public key (.keyb) - * @param key_version Version for key - * @param desc Description. Optional; may be NULL. - * @return A newly allocated public key, or NULL if error. - */ -struct bdb_key *bdb_create_key(const char *filename, - uint32_t key_version, - const char *desc); - -/** - * Create a BDB signature object. - * - * Caller must free() the returned signature. - * - * @param data Data to sign - * @param size Size of data in bytes - * @param key PEM key - * @param sig_alg Signature algorithm - * @param desc Description. Optional; may be NULL. - * @return A newly allocated signature, or NULL if error. - */ -struct bdb_sig *bdb_create_sig(const void *data, - size_t size, - struct rsa_st *key, - uint32_t sig_alg, - const char *desc); - -struct bdb_create_params -{ - /* Load address */ - uint64_t bdb_load_address; - - /* OEM areas. Size may be 0, in which case the buffer is ignored */ - uint8_t *oem_area_0; - uint32_t oem_area_0_size; - uint8_t *oem_area_1; - uint32_t oem_area_1_size; - - /* Public BDB key and subkey */ - struct bdb_key *bdbkey; - struct bdb_key *subkey; - - /* Private BDB key and subkey */ - struct rsa_st *private_bdbkey; - struct rsa_st *private_subkey; - - /* Descriptions for header and data signatures */ - char *header_sig_description; - char *data_sig_description; - - /* Data description and version */ - char *data_description; - uint32_t data_version; - - /* Data hashes and count */ - struct bdb_hash *hash; - uint32_t num_hashes; -}; - -/** - * Create a new BDB - * - * Caller must free() returned object. - * - * @param p Creation parameters - * @return A newly allocated BDB, or NULL if error. - */ -struct bdb_header *bdb_create(struct bdb_create_params *p); - -/*****************************************************************************/ - -#endif /* VBOOT_REFERENCE_BDB_HOST_H_ */ diff --git a/bdb/rsa.c b/bdb/rsa.c deleted file mode 100644 index 134bd512..00000000 --- a/bdb/rsa.c +++ /dev/null @@ -1,339 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block firmware RSA - */ - -#include <string.h> -#include "bdb.h" - -/* Public key structure in RAM */ -struct public_key { - uint32_t arrsize; /* Size of n[] and rr[] arrays in elements */ - uint32_t n0inv; /* -1 / n[0] mod 2^32 */ - const uint32_t *n; /* Modulus as little endian array */ - const uint32_t *rr; /* R^2 as little endian array */ -}; - -/** - * a[] -= mod - */ -static void subM(const struct public_key *key, uint32_t *a) -{ - int64_t A = 0; - uint32_t i; - for (i = 0; i < key->arrsize; ++i) { - A += (uint64_t)a[i] - key->n[i]; - a[i] = (uint32_t)A; - A >>= 32; - } -} - -/** - * Return a[] >= mod - */ -int vb2_mont_ge(const struct public_key *key, uint32_t *a) -{ - uint32_t i; - for (i = key->arrsize; i;) { - --i; - if (a[i] < key->n[i]) - return 0; - if (a[i] > key->n[i]) - return 1; - } - return 1; /* equal */ -} - -/** - * Montgomery c[] += a * b[] / R % mod - */ -static void montMulAdd(const struct public_key *key, - uint32_t *c, - const uint32_t a, - const uint32_t *b) -{ - uint64_t A = (uint64_t)a * b[0] + c[0]; - uint32_t d0 = (uint32_t)A * key->n0inv; - uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A; - uint32_t i; - - for (i = 1; i < key->arrsize; ++i) { - A = (A >> 32) + (uint64_t)a * b[i] + c[i]; - B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A; - c[i - 1] = (uint32_t)B; - } - - A = (A >> 32) + (B >> 32); - - c[i - 1] = (uint32_t)A; - - if (A >> 32) { - subM(key, c); - } -} - -/** - * Montgomery c[] = a[] * b[] / R % mod - */ -static void montMul(const struct public_key *key, - uint32_t *c, - const uint32_t *a, - const uint32_t *b) -{ - uint32_t i; - for (i = 0; i < key->arrsize; ++i) { - c[i] = 0; - } - for (i = 0; i < key->arrsize; ++i) { - montMulAdd(key, c, a[i], b); - } -} - -int vb2_safe_memcmp(const void *s1, const void *s2, size_t size) -{ - const unsigned char *us1 = s1; - const unsigned char *us2 = s2; - int result = 0; - - if (0 == size) - return 0; - - /* - * Code snippet without data-dependent branch due to Nate Lawson - * (nate@root.org) of Root Labs. - */ - while (size--) - result |= *us1++ ^ *us2++; - - return result != 0; -} - -/* - * PKCS 1.5 padding (from the RSA PKCS#1 v2.1 standard) - * - * Depending on the RSA key size and hash function, the padding is calculated - * as follows: - * - * 0x00 || 0x01 || PS || 0x00 || T - * - * T: DER Encoded DigestInfo value which depends on the hash function used. - * - * SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H. - * - * Length(T) = 51 octets for SHA-256 - * - * PS: octet string consisting of {Length(RSA Key) - Length(T) - 3} 0xFF - */ -static const uint8_t sha256_tail[] = { - 0x00,0x30,0x31,0x30,0x0d,0x06,0x09,0x60, - 0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, - 0x05,0x00,0x04,0x20 -}; - -int vb2_check_padding(const uint8_t *sig, const struct public_key *key, - uint32_t pad_size) -{ - /* Determine padding to use depending on the signature type */ - const uint32_t tail_size = sizeof(sha256_tail); - int result = 0; - int i; - - /* First 2 bytes are always 0x00 0x01 */ - result |= *sig++ ^ 0x00; - result |= *sig++ ^ 0x01; - - /* Then 0xff bytes until the tail */ - for (i = 0; i < pad_size - tail_size - 2; i++) - result |= *sig++ ^ 0xff; - - /* - * Then the tail. Even though there are probably no timing issues - * here, we use vb2_safe_memcmp() just to be on the safe side. - */ - result |= vb2_safe_memcmp(sig, sha256_tail, tail_size); - - return result ? BDB_ERROR_DIGEST : BDB_SUCCESS; -} - -/* Array size for RSA4096 */ -#define ARRSIZE4096 (4096 / 32) - -/** - * In-place public exponentiation. (exponent 65537, key size 4096 bits) - * - * @param key Key to use in signing - * @param inout Input and output big-endian byte array - */ -static void modpowF4(const struct public_key *key, uint8_t *inout) -{ - uint32_t a[ARRSIZE4096]; - uint32_t aR[ARRSIZE4096]; - uint32_t aaR[ARRSIZE4096]; - uint32_t *aaa = aaR; /* Re-use location. */ - int i; - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0; i < ARRSIZE4096; ++i) { - uint32_t tmp = - (inout[((ARRSIZE4096 - 1 - i) * 4) + 0] << 24) | - (inout[((ARRSIZE4096 - 1 - i) * 4) + 1] << 16) | - (inout[((ARRSIZE4096 - 1 - i) * 4) + 2] << 8) | - (inout[((ARRSIZE4096 - 1 - i) * 4) + 3] << 0); - a[i] = tmp; - } - - montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ - for (i = 0; i < 16; i+=2) { - montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ - montMul(key, aR, aaR, aaR); /* aR = aaR * aaR / R mod M */ - } - montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */ - - /* Make sure aaa < mod; aaa is at most 1x mod too large. */ - if (vb2_mont_ge(key, aaa)) { - subM(key, aaa); - } - - /* Convert to bigendian byte array */ - for (i = ARRSIZE4096 - 1; i >= 0; --i) { - uint32_t tmp = aaa[i]; - *inout++ = (uint8_t)(tmp >> 24); - *inout++ = (uint8_t)(tmp >> 16); - *inout++ = (uint8_t)(tmp >> 8); - *inout++ = (uint8_t)(tmp >> 0); - } -} - -int bdb_rsa4096_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest) -{ - const uint32_t *kdata32 = (const uint32_t *)key_data; - struct public_key key; - uint8_t sig_work[BDB_RSA4096_SIG_SIZE]; - uint32_t pad_size; - int rv; - - /* Unpack key */ - if (kdata32[0] != ARRSIZE4096) - return BDB_ERROR_DIGEST; /* Wrong key size */ - - key.arrsize = kdata32[0]; - key.n0inv = kdata32[1]; - key.n = kdata32 + 2; - key.rr = kdata32 + 2 + key.arrsize; - - /* Copy signature to work buffer */ - memcpy(sig_work, sig, sizeof(sig_work)); - - modpowF4(&key, sig_work); - - /* - * Check padding. Continue on to check the digest even if error to - * reduce the risk of timing based attacks. - */ - pad_size = key.arrsize * sizeof(uint32_t) - BDB_SHA256_DIGEST_SIZE; - rv = vb2_check_padding(sig_work, &key, pad_size); - - /* - * Check digest. Even though there are probably no timing issues here, - * use vb2_safe_memcmp() just to be on the safe side. (That's also why - * we don't return before this check if the padding check failed.) - */ - if (vb2_safe_memcmp(sig_work + pad_size, digest, - BDB_SHA256_DIGEST_SIZE)) - rv = BDB_ERROR_DIGEST; - - return rv; -} - -/* Array size for RSA3072B */ -#define ARRSIZE3072B (3072 / 32) - -/** - * In-place public exponentiation. (exponent 3, key size 3072 bits) - * - * @param key Key to use in signing - * @param inout Input and output big-endian byte array - */ -static void modpow3(const struct public_key *key, uint8_t *inout) -{ - uint32_t a[ARRSIZE3072B]; - uint32_t aR[ARRSIZE3072B]; - uint32_t aaR[ARRSIZE3072B]; - uint32_t *aaa = aR; /* Re-use location */ - int i; - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0; i < ARRSIZE3072B; ++i) { - uint32_t tmp = - (inout[((ARRSIZE3072B - 1 - i) * 4) + 0] << 24) | - (inout[((ARRSIZE3072B - 1 - i) * 4) + 1] << 16) | - (inout[((ARRSIZE3072B - 1 - i) * 4) + 2] << 8) | - (inout[((ARRSIZE3072B - 1 - i) * 4) + 3] << 0); - a[i] = tmp; - } - - montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ - montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ - montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */ - - /* Make sure aaa < mod; aaa is at most 1x mod too large. */ - if (vb2_mont_ge(key, aaa)) { - subM(key, aaa); - } - - /* Convert to bigendian byte array */ - for (i = ARRSIZE3072B - 1; i >= 0; --i) { - uint32_t tmp = aaa[i]; - *inout++ = (uint8_t)(tmp >> 24); - *inout++ = (uint8_t)(tmp >> 16); - *inout++ = (uint8_t)(tmp >> 8); - *inout++ = (uint8_t)(tmp >> 0); - } -} - -int bdb_rsa3072b_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest) -{ - const uint32_t *kdata32 = (const uint32_t *)key_data; - struct public_key key; - uint8_t sig_work[BDB_RSA3072B_SIG_SIZE]; - uint32_t pad_size; - int rv; - - /* Unpack key */ - if (kdata32[0] != ARRSIZE3072B) - return BDB_ERROR_DIGEST; /* Wrong key size */ - - key.arrsize = kdata32[0]; - key.n0inv = kdata32[1]; - key.n = kdata32 + 2; - key.rr = kdata32 + 2 + key.arrsize; - - /* Copy signature to work buffer */ - memcpy(sig_work, sig, sizeof(sig_work)); - - modpow3(&key, sig_work); - - /* - * Check padding. Continue on to check the digest even if error to - * reduce the risk of timing based attacks. - */ - pad_size = key.arrsize * sizeof(uint32_t) - BDB_SHA256_DIGEST_SIZE; - rv = vb2_check_padding(sig_work, &key, pad_size); - - /* - * Check digest. Even though there are probably no timing issues here, - * use vb2_safe_memcmp() just to be on the safe side. (That's also why - * we don't return before this check if the padding check failed.) - */ - if (vb2_safe_memcmp(sig_work + pad_size, digest, - BDB_SHA256_DIGEST_SIZE)) - rv = BDB_ERROR_DIGEST; - - return rv; -} diff --git a/bdb/sha.c b/bdb/sha.c deleted file mode 100644 index 1e83662d..00000000 --- a/bdb/sha.c +++ /dev/null @@ -1,210 +0,0 @@ -/* SHA-256 and SHA-512 implementation based on code by Oliver Gay - * <olivier.gay@a3.epfl.ch> under a BSD-style license. See below. - */ -/* - * FIPS 180-2 SHA-224/256/384/512 implementation - * Last update: 02/02/2007 - * Issue date: 04/30/2005 - * - * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <string.h> - -#include "bdb.h" - -#define VB2_SHA256_DIGEST_SIZE 32 -#define VB2_SHA256_BLOCK_SIZE 64 - -struct vb2_sha256_context { - uint32_t h[8]; - uint32_t total_size; - uint32_t size; - uint8_t block[2 * VB2_SHA256_BLOCK_SIZE]; -}; - -#define SHFR(x, n) (x >> n) -#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) -#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) -#define CH(x, y, z) ((x & y) ^ (~x & z)) -#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) -#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) -#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) -#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) -#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) -#define UNPACK32(x, str) \ - { \ - *((str) + 3) = (uint8_t) ((x) ); \ - *((str) + 2) = (uint8_t) ((x) >> 8); \ - *((str) + 1) = (uint8_t) ((x) >> 16); \ - *((str) + 0) = (uint8_t) ((x) >> 24); \ - } -#define PACK32(str, x) \ - { \ - *(x) = ((uint32_t) *((str) + 3) ) \ - | ((uint32_t) *((str) + 2) << 8) \ - | ((uint32_t) *((str) + 1) << 16) \ - | ((uint32_t) *((str) + 0) << 24); \ - } -#define SHA256_SCR(i) \ - { \ - w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \ - + SHA256_F3(w[i - 15]) + w[i - 16]; \ - } - -static const uint32_t sha256_h0[8] = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -}; - -static const uint32_t sha256_k[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -/* SHA-256 implementation from verified boot library */ -void vb2_sha256_init(struct vb2_sha256_context *ctx) -{ - int i; - for (i = 0; i < 8; i++) { - ctx->h[i] = sha256_h0[i]; - } - ctx->size = 0; - ctx->total_size = 0; -} - -static void vb2_sha256_transform(struct vb2_sha256_context *ctx, - const uint8_t *message, - unsigned int block_nb) -{ - /* Note that these arrays use 72*4=288 bytes of stack */ - uint32_t w[64]; - uint32_t wv[8]; - uint32_t t1, t2; - const unsigned char *sub_block; - int i; - int j; - for (i = 0; i < (int) block_nb; i++) { - sub_block = message + (i << 6); - for (j = 0; j < 16; j++) { - PACK32(&sub_block[j << 2], &w[j]); - } - for (j = 16; j < 64; j++) { - SHA256_SCR(j); - } - for (j = 0; j < 8; j++) { - wv[j] = ctx->h[j]; - } - for (j = 0; j < 64; j++) { - t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) - + sha256_k[j] + w[j]; - t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); - wv[7] = wv[6]; - wv[6] = wv[5]; - wv[5] = wv[4]; - wv[4] = wv[3] + t1; - wv[3] = wv[2]; - wv[2] = wv[1]; - wv[1] = wv[0]; - wv[0] = t1 + t2; - } - for (j = 0; j < 8; j++) { - ctx->h[j] += wv[j]; - } - } -} - -void vb2_sha256_update(struct vb2_sha256_context *ctx, - const uint8_t *data, - uint32_t size) -{ - unsigned int block_nb; - unsigned int new_size, rem_size, tmp_size; - const uint8_t *shifted_data; - tmp_size = VB2_SHA256_BLOCK_SIZE - ctx->size; - rem_size = size < tmp_size ? size : tmp_size; - memcpy(&ctx->block[ctx->size], data, rem_size); - if (ctx->size + size < VB2_SHA256_BLOCK_SIZE) { - ctx->size += size; - return; - } - new_size = size - rem_size; - block_nb = new_size / VB2_SHA256_BLOCK_SIZE; - shifted_data = data + rem_size; - vb2_sha256_transform(ctx, ctx->block, 1); - vb2_sha256_transform(ctx, shifted_data, block_nb); - rem_size = new_size % VB2_SHA256_BLOCK_SIZE; - memcpy(ctx->block, &shifted_data[block_nb << 6], - rem_size); - ctx->size = rem_size; - ctx->total_size += (block_nb + 1) << 6; -} - -void vb2_sha256_finalize(struct vb2_sha256_context *ctx, uint8_t *digest) -{ - unsigned int block_nb; - unsigned int pm_size; - unsigned int size_b; - int i; - block_nb = (1 + ((VB2_SHA256_BLOCK_SIZE - 9) - < (ctx->size % VB2_SHA256_BLOCK_SIZE))); - size_b = (ctx->total_size + ctx->size) << 3; - pm_size = block_nb << 6; - memset(ctx->block + ctx->size, 0, pm_size - ctx->size); - ctx->block[ctx->size] = 0x80; - UNPACK32(size_b, ctx->block + pm_size - 4); - vb2_sha256_transform(ctx, ctx->block, block_nb); - for (i = 0 ; i < 8; i++) { - UNPACK32(ctx->h[i], &digest[i << 2]); - } -} - -int bdb_sha256(void *digest, const void *buf, size_t size) -{ - struct vb2_sha256_context ctx; - - vb2_sha256_init(&ctx); - vb2_sha256_update(&ctx, buf, size); - vb2_sha256_finalize(&ctx, digest); - - return BDB_SUCCESS; -} diff --git a/bdb/testdata/ap-rw.bin b/bdb/testdata/ap-rw.bin deleted file mode 100644 index ed74f8e8..00000000 --- a/bdb/testdata/ap-rw.bin +++ /dev/null @@ -1 +0,0 @@ -This is a pretend ap-rw.bin image. Exciting. diff --git a/bdb/testdata/oem0.bin b/bdb/testdata/oem0.bin deleted file mode 100644 index 0b35ed69..00000000 --- a/bdb/testdata/oem0.bin +++ /dev/null @@ -1 +0,0 @@ -This is some OEM0 data. diff --git a/bdb/testdata/oem1.bin b/bdb/testdata/oem1.bin deleted file mode 100644 index a65fc5b7..00000000 --- a/bdb/testdata/oem1.bin +++ /dev/null @@ -1 +0,0 @@ -This is some OEM1 data of some sort diff --git a/bdb/testdata/sp-rw.bin b/bdb/testdata/sp-rw.bin deleted file mode 100644 index df31026f..00000000 --- a/bdb/testdata/sp-rw.bin +++ /dev/null @@ -1 +0,0 @@ -This is a pretend sp-rw.bin image. diff --git a/bdb/testkeys/bdbkey.crt b/bdb/testkeys/bdbkey.crt deleted file mode 100644 index 383216a3..00000000 --- a/bdb/testkeys/bdbkey.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFtTCCA52gAwIBAgIJANitnQKymb5VMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTAwOTI5MTgxNjM4WhcNMTAxMDI5MTgxNjM4WjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAm5v71oqFynujT4FVq5lKaYxpmKfXdeBNKDmLzgu7fXLUKaEqTGEDsseE -5qyaaP+dmTnQKfne7G31zgf46//YEl+u5Gt/S4oAgYyvs3rjymzD5kVOLEAzgrIX -AwyhDFARRzAFWos43hypunHGvu4fDBAzZ3zGVulhjgAzD/gNjToVYCP7bj6kTaDx -1u9siCKdYN09vGwSUt9WuV+yort7kns/B8ArVxt3bFSjsAxuWel/dJyLwCMQ9XAx -dgWpg3RBUsK/KgekQybPLrhLYJn1AeOApwzJ4HoJSqU/1jCEaGrKA/KtCRXiurZz -6lBi7sElsigjBvEZH0iCmmRgH3Oi/cbpHIs1C6YHvCCbO90ntwgtDf0+2WJtFtbG -t5Do3CXri0tcsXBWqISSK3VzzjHH691BVwLuoBvF1XICMEjmq9aJ+MdbEe4E+GU8 -TV9NnRnuYyOUoxeisyXiArUUI9+1qL6pIgulTlY2Ch51QZY5n2aYY97PtosNotbS -ylMrLvWXGiiQWxux12eOnB3c/3wNYWey8Km4cmOhEOYz7hLz2r1uIoC/SzM5wLnn -TEQmaiUDNV9R3Gj3E3xkpTq3UNSSPsV7k8lInMtWqzps6aTvBw1k6i6CUvWbEZqm -t/0bimQHOEdg3OrJjQpwTKSp4ouSyVu0IphDwy1yjKCfNWKRzrUCAwEAAaOBpzCB -pDAdBgNVHQ4EFgQUyBKBgFg+vONV1sbup7QtFa7DR78wdQYDVR0jBG4wbIAUyBKB -gFg+vONV1sbup7QtFa7DR7+hSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT -b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDY -rZ0Cspm+VTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQA0wtlLEAKR -ctB41x/V10SMFIg5eLbDrUKQQT33BddrhFu0blc7U5jgXjqTYS80xIlOC0hXtN7D -Z478st3NAxjtvBKxNMWB9Ppz6+15UENnXNGLElhRPaeAbxBs7zVB64b8fY69EJRe -JOJNp6+c4WJsHWzxrmfHD0Wx18pJ877ThRi/ZH0QP2TjPc0gZT4szP1taoOJ7SXy -gO10WfPoF1GgI/VXhPLnk2zXpTlFdp+qyKOtDFxOOK/cVKdXAxDDDO9DAw6cvrEn -mPS2Zml9HI25/CrE00y+k4w7bqzNeGNzhSGPBvq5Yqnefc1dJSdDQZ3XLG9Fis4a -nVfuSTvP1MUrFEGEvuxRcA0rWPwQtYSHHs8ZnpT6eayTPcpDvWSihe4xUywirXTT -kbWgeABGQGaoAnFJYhjqBROGdVb4V3vbsjbCi8k2r4IIcqOzp6OIJxha2LvkZ+iu -f+OlMVAO/C1LbRsVQkfJp7NxEt6PVewQV5Kgnwlf+x7Q2tUfZfdpLd/EMtojv3BD -Ewx5X2yHGXcYZG/C1kNzyGTfg97/+55mtNlkTmo8elcPxlpnEuMXEv4JthnRy90x -ZLflcR9q0pOiV+n//KyQvfjH99JmRtVJGG8xlDEtRbJWjFQD/uSEBxeS0T6INrza -0WTaiIOZB1vMPe6CDYDWDzrFdQrD6HoWDQ== ------END CERTIFICATE----- diff --git a/bdb/testkeys/bdbkey.keyb b/bdb/testkeys/bdbkey.keyb Binary files differdeleted file mode 100644 index 515aaa98..00000000 --- a/bdb/testkeys/bdbkey.keyb +++ /dev/null diff --git a/bdb/testkeys/bdbkey.pem b/bdb/testkeys/bdbkey.pem deleted file mode 100644 index 204b440f..00000000 --- a/bdb/testkeys/bdbkey.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIJKQIBAAKCAgEAm5v71oqFynujT4FVq5lKaYxpmKfXdeBNKDmLzgu7fXLUKaEq -TGEDsseE5qyaaP+dmTnQKfne7G31zgf46//YEl+u5Gt/S4oAgYyvs3rjymzD5kVO -LEAzgrIXAwyhDFARRzAFWos43hypunHGvu4fDBAzZ3zGVulhjgAzD/gNjToVYCP7 -bj6kTaDx1u9siCKdYN09vGwSUt9WuV+yort7kns/B8ArVxt3bFSjsAxuWel/dJyL -wCMQ9XAxdgWpg3RBUsK/KgekQybPLrhLYJn1AeOApwzJ4HoJSqU/1jCEaGrKA/Kt -CRXiurZz6lBi7sElsigjBvEZH0iCmmRgH3Oi/cbpHIs1C6YHvCCbO90ntwgtDf0+ -2WJtFtbGt5Do3CXri0tcsXBWqISSK3VzzjHH691BVwLuoBvF1XICMEjmq9aJ+Mdb -Ee4E+GU8TV9NnRnuYyOUoxeisyXiArUUI9+1qL6pIgulTlY2Ch51QZY5n2aYY97P -tosNotbSylMrLvWXGiiQWxux12eOnB3c/3wNYWey8Km4cmOhEOYz7hLz2r1uIoC/ -SzM5wLnnTEQmaiUDNV9R3Gj3E3xkpTq3UNSSPsV7k8lInMtWqzps6aTvBw1k6i6C -UvWbEZqmt/0bimQHOEdg3OrJjQpwTKSp4ouSyVu0IphDwy1yjKCfNWKRzrUCAwEA -AQKCAgEAlbfvBu0g7UEoUEbQdtp2jjdbIlXbKL83fYxgx07ihkEFgUhfuj1doZX2 -eTt5Fa1bpSHK95hCtJjX9/QTvH3dF1CYpY4IXFXbRspmAvoqUYl0swnbvRfId+eB -3J06Fu6ysRuzCvsJLCvH4mu2Hd5eYOz1iIy1CMpj4oyulJ7F6ywHhQkZ0WjUDRzd -kz+p3RHw+lHkJHaW6sWYW6OH7KsWqkmKy5pKGPWEYebN14UeZ8QRrdExZRxYJM5d -yICKKMCiWU6nP3k6wqGElh8b50Y6RibukcvsMN86MWftk9f6jbyxwjqr4iH8lEkY -HkpZ5f5QlqmnifZPhZnujz4kfh50oteC2QPQ0hrNYCDG75wuiNX/vINVfrKG0ddg -iQDFqyQyQirxCGQgy7Wto08KAzKt146ST28N+kdF/kY14ou5f5+GlWQJcnqdHd2p -R25MueXUsY3I63dULR6k02Y6M7Tzo39lYe0LV82+G0A3iGpI+eM7xw/sQDNb2sQs -jCcz7XPrfTomrVJaW1FkM8vM6eWhuhAyDFP+unz0aMnKrkUrarh4t9QpriiCjm3E -HV2Hc7t/Do/w+B3rywKy3PE2yO49eGz20um0JqWcAbGDZY2vDnyV+/xibxqaIZUo -saI/btlyvCv00812momkX/qWwS+1GHvyYYcpIg0XQbZY1TvEi8ECggEBAM6LTfVu -MKNwW/QdZ6pxKl/Oy8zlb1o8HET5hKCdhoMvpwlvpO2qSvlCxH3VZTmcXIXd+Mkd -e4OZrzeMLVxMd64xP10k2ui/O2/8G38xmpMGqZihc+LnY6JgajujfAQHljOgrAJL -xzO2Gk4oWX72oA6jqP8LZkRp/9acTWqBTKs6MOdrfn6I3k0urBB29+jcbqFAfgMx -hfcTKAOHYmg/SeEZDvKP6fRDJGMGXqJ4TaBXjsnhNGCjGmuCqJhxxIGCI/AVK10B -CjEboo9vACzNE1/JMxH8aT5up7e+7R/WoiJ5e3jlvSKmcO7KiR27JVsAlZeIddKd -LzG9KKZ8Yla0U3MCggEBAMDefKVTqSPaG7cmAQGtXrbBDLdCWIaT08v+kMw/drlq -NqLD+1ct098iFwRtKaYPERPKqNtxfJdkUMqWELBWV2Sq4Fi+JVXjGOUctP7Atd2x -6NJ9xHqQKQwKUv0/9jN5Oie9sFvsLwPAJNOJej1BrmvPZvc0CoMyOjkmxEhYu3qG -i26ZTSZSCTrbE8eAL0EJdH0gB7Ryuks8O+jEF7eXuZLZyN3AromISJtmLVlMFZ7m -+0sQnZQqwNF+BIrOgO+3R61jjNzCJbFo7frvRIlDSnrbmWp6sYns1cjhZiKCnO78 -RgDiaJcuceqsalgBZi8/Fmam2IPeqhvTNg+5alCuWzcCggEAXFjglFmeGZVFJ9J1 -5TkPzyJw8L2smdXCdfxyFjYYTFNkBc4LGdBIEUaPAAwHZEjK/XePoqwx61cthlKA -fYIbCKEwSX8O+X13H8zCpo4RJKeX8IxPeiYm4BTnqp6f9lVGDPNLtQMYn8BN5qAX -07KFQcZe6xm3seMK5nOgEXyaQPyVnQLs3bpoWm4BtKLcmRrlw+dH8DmWQjAoddt0 -XlPdvm0rx7wcyH+0pynT6iSL4KMFTrIIbyS9zU/v/ajwSU9crh1o8/5hBi/q8OKa -W22dufgFg4ctryJejsMo1lFq0KssT5O4iuOMHtgjkk14mEWcnNIAjBiHX1/J6xY2 -Cbo6jQKCAQBtvmt4e1kz8Ehy92n9NVQ+cyy0HklXEkiiu9BSmA4LRPefuBqNKaN0 -ROaJ+z+GoO4br+ZTL4kwb8FU9Py8CfUib+TGOjPuYhFpVONcTfVuF2yeUTf6cYsZ -sco1Fi8WbPV9ZX8zXvoFjVCnGYP31SbVa6dwJCmTK4JbwMZRUEQlXOd74Dk5A9cC -qWPg0fyRajrhc9dOgzWj17tTIDlKm0fZ2phkLd5inayK2CIXvKZUy6PTu7medJFQ -4v7cqNJPFJ/xdkLR3psqDsXTUlBSNnrr24a5QuVA0QV4j2DZZC6+Acgneqz+0Uu6 -t66vMuSdH620bV2n84wh1xXc7qkjDYMTAoIBAQC6DsTyBGNNI0/DGwAsae5Zri8w -T/SOER7Tc/PCgQyFUNsJJc/OmSy66PPiH2HzqLjl6/jeiJP++oCnfO6pNTq1Fjz4 -Le2iS1szlcuJ9QLdtn2LTqORzdQVpka42X+o+NqJEdzkZb/N6eBA4PPQdTxHIiu1 -WGBpDc5vGkpuzLm9SVCw/4SD84z+Nhs0pqOvwWhmQWCtl28fgqU4LMeOX1Wz5P8E -IledlgbCZh2KwXuv3BJdkawuwrSPsahnZmoJapx2dE+FkNl4equaBwImfLf5Qifj -IhIN5GueO9k/D2/7/XvW2qJ3Vy0z0xMMNiTVYufVpbh77Kn2ebKfROlkzMEU ------END RSA PRIVATE KEY----- diff --git a/bdb/testkeys/subkey.crt b/bdb/testkeys/subkey.crt deleted file mode 100644 index fad23f48..00000000 --- a/bdb/testkeys/subkey.crt +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEWzCCAsOgAwIBAgIJAKOPQrNCNRSqMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTUxMTIzMjA1MTI4WhcNMTUxMjIzMjA1MTI4WjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBoDANBgkqhkiG9w0BAQEFAAOCAY0AMIIB -iAKCAYEA1/JAfpirBAFZdm+m6AcX5QQt7vWDV6OAN4T5nWxAtedRb0XLeV9ICJJI -4CwxWKhvM4pe8pUwwldjoIHIs7viDjBnFVO6+41Gwdsp54AO9qpd//izjarwrOFq -QcZIn7KVOaYxTlMWlfIDOS3K0rr2adBuR/Yq4Nj61XevNsxRelojDLAQeamRia8t -hB3vR1LHQJlMT7R8VXy3AOHx+YcYKUFCgf5A7J+pdAaOIgkFKuakZZNDC+7D0Ykq -jPHadHKzT1SCJxILD/YkCUCOn5bdh7oQekCnhJgf3bwPRDaGEsJL3nnxhc8hx3tI -7DHwKmz9naz63S41Zqd+VvWam7Jttyb6lQjj7Y8TauXGAL3vEiI/u0iiVyw6b3c3 -77/W4RWuRIiMAn6FAkUY6oxKB+67ZA1PoRLfiIxFGot1KEpTeLzdsyYx7fB1Scj+ -DDzx3EaHQAz12E4anTozljvdAPMoZ6i9Dar3eZvA0KFsM5sdNy0Hp96PBeBNiw1O -XZYUrYgVAgEDo1AwTjAdBgNVHQ4EFgQUiwtVmJWqyIBZWV1xvn7iMbLeE30wHwYD -VR0jBBgwFoAUiwtVmJWqyIBZWV1xvn7iMbLeE30wDAYDVR0TBAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAYEAJXgsYoQ7QDNf1GF0bQQKnSqIKMssecD8x66rrJQr1Yon -biJeUfN9N/pAca7CI/vjeTC1w6BlXEbUDNNwLKQYVfTOBdmbW1qDANMUP05PaiAG -cZHVKMZZrR/5+z+LWG157cP7HzHPGfw78LopVXUDZmd5fRD2d7MnqYCrswp/dORM -brHTwzpPhH75uNQmq6w2RowjrntDnKhGT0tSY57/OI+Gke3ch3XPPg3juhREaVUm -4ZXSCwajKmPBju+7adT46gY/LjAYv/rAEiUN5YHOBVHxHdoMOIqsf6VfPVc8USpg -5fsV7NWGNSuvpiA7xBIBKai3dZl8nztFHvjn7z4x6XrqQ1KTMBvnGONHAHopeUtj -a3WPd3GpBmLMpSfDWtcaSSuwOAgZro6vGqcHN4FybKASbtS0RynPRL42DBbLiarn -nA0hhR1YR03Kqc6hexrsg7zrjcNL6b8dzu6o+VxD30ecj68D7IliORtouJahvk5/ -F8MyzvHvAa+K7Hb/IcJv ------END CERTIFICATE----- diff --git a/bdb/testkeys/subkey.keyb b/bdb/testkeys/subkey.keyb Binary files differdeleted file mode 100644 index 33ed4ace..00000000 --- a/bdb/testkeys/subkey.keyb +++ /dev/null diff --git a/bdb/testkeys/subkey.pem b/bdb/testkeys/subkey.pem deleted file mode 100644 index 2a8885e0..00000000 --- a/bdb/testkeys/subkey.pem +++ /dev/null @@ -1,39 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIG4wIBAAKCAYEA1/JAfpirBAFZdm+m6AcX5QQt7vWDV6OAN4T5nWxAtedRb0XL -eV9ICJJI4CwxWKhvM4pe8pUwwldjoIHIs7viDjBnFVO6+41Gwdsp54AO9qpd//iz -jarwrOFqQcZIn7KVOaYxTlMWlfIDOS3K0rr2adBuR/Yq4Nj61XevNsxRelojDLAQ -eamRia8thB3vR1LHQJlMT7R8VXy3AOHx+YcYKUFCgf5A7J+pdAaOIgkFKuakZZND -C+7D0YkqjPHadHKzT1SCJxILD/YkCUCOn5bdh7oQekCnhJgf3bwPRDaGEsJL3nnx -hc8hx3tI7DHwKmz9naz63S41Zqd+VvWam7Jttyb6lQjj7Y8TauXGAL3vEiI/u0ii -Vyw6b3c377/W4RWuRIiMAn6FAkUY6oxKB+67ZA1PoRLfiIxFGot1KEpTeLzdsyYx -7fB1Scj+DDzx3EaHQAz12E4anTozljvdAPMoZ6i9Dar3eZvA0KFsM5sdNy0Hp96P -BeBNiw1OXZYUrYgVAgEDAoIBgQCP9tWpuxytVjukSm9FWg/uAslJ+QI6bQAlA1ET -nYB5ROD02TJQ6jAFtttAHXY7GvTNBun3DiCBj5fAVoXNJ+wJdZoON9H9CNnWkhvv -qrSkcZP/+yJecfXIlkbWhDBqdw4mbsuJjLm5TAImHoc3J07xNZ7apByV5fyOT8ok -iDZRkWyzIAr7xmEGdMkCvp+E4dorEN2KeFLjqHoAlqFRBLrGK4Gr/tXzFRuirwls -BgNx7xhDt4IH9IKLsMcIoTxNocul86msFzeUDFXM/ruLFa34DBtT935WhGn+18+/ -bYA+qM4GoC8N/4sSQtENQ8bX21aUHRs1MIOa82rJEmkCWW+Tgw8kYSSi8gVmd7Ly -QFp4XN17ReaIZZKBYJt/3XamcV2tcapxwqBNiGOLPQM4wnnuinkiZD7rXf1u/NFV -rHiVFu1+ORZaTX34+Vq9/wdj18E3cm1ghQsN3BQNzCE1qtulDcs5w2O1iZlP29wq -mtgeU7YHK7CzqNuUiPJWJardCWsCgcEA8VAXoPMSAJByCk3l92eDTOe8n5IMZ307 -qXpGMlSUT+SctpgVdoN9iV+7bUQE636Hn37E5czANNpERIoVjFJRm0ioYW/9jOEN -B8zPnvwtLN1vVD1u5XNlumDGWGU1bQCdjgA07DtCM0S5xfhWOACCUJ4l4TDE3DAz -eNfnaXXP8UNfpL6gaWb/xZZwwTesS+hcX8zw14Gzn/GHkyGEtSMA+lezI5C37bzk -ao2pWr+W26HeDPwdG/38gBQceUujidJ9AoHBAOUW7AP8JbFTMUt0j1eO1UbAKty7 -XZtURTX+EXK9sWTgeh3xlXpMU6K3U+sIQPsldCACjSeYr8lgGeTP54vZ9L6Zu30H -L2xC/kllafZhOjC5hC4iWaUgePMFiFeOb3prBDJd12ufUlqzydO4bvrKgi2fdAxL -vEtPFXs4U75RzqfXGdER7/0VOI68hS4GunqaiQ0UYPAE1mh+je5oJntP3fW8WRN1 -KfuQdm5J+JjzQi4NmJAg6NxlB6wrxmMR8NgneQKBwQCg4A/AogwAYEwG3plPmleI -mn2/trLvqNJw/C7MOGLf7b3PEA5PAlOw6nzzgq3yVFpqVIND3dV4kYLYXA5djDZn -hcWWSqkIlgiv3d+/UsjIk5+NfknuTO58QIQ67iOeAGkJVXidfNbM2HvZUDl6qwGL -FBlAyy3oICJQj++bo9/2LOpt1Grw71UuZEsrenLdRZLqiKCPq80VS6+3a63OF1X8 -OndtCyVJKJhHCRuR1Q89FpQIqBNn/qhVYr2mMm0GjFMCgcEAmLnyrVLDy4zLh6MK -Ol842dVx6HzpEjguI/62TH52Q0BRaUu4/DLibHo38gWAp25NaqxeGmXKhkARQzVF -B+ajKbvSU1ofnYH+25jxTut8IHutdBbmbhWl91kFj7RKUZytduk6R7+MPHfb4nr0 -pzGsHmpNXYfS3N9jp3rifuE0b+S74Laf/g4ltH2uHq8m/GcGCLhAoAM5mv8JSZrE -UjU+o9LmDPjGp7WkSYalu0zWyV5ltWtF6ENacsfZl2FLOsT7AoHARP9ZNA7JMYMs -dbx2l7eLaTtdOeeSE9AxssmzXBsNHWklEx8DTI3MAFcIXPNesqnm++D/T5sXsIy6 -kd3srldHGYHoh1IT5mOO7S8SlKLdYTIlsVIg+I4jpqmHTgk7DWDDpjYzkmJz3A29 -q4HHmNx92SXNZD+mX0GnDdP9XDbT3tbt3ANuR1LoTcI3wAUMTN/NQiF8qj2NHzb1 -CFOpBOJ9cuUgkWcntjqLJ6mUAMcQ8kF7Pyuhn46qDhY5ceVhrPt9 ------END RSA PRIVATE KEY----- diff --git a/firmware/README b/firmware/README index 3d174f7b..754edf1b 100644 --- a/firmware/README +++ b/firmware/README @@ -1,10 +1,6 @@ Here's what's what in the firmware/ directory. -bdb/ - - Code for managing Boot Descriptor Blocks (BDB). - include/ lib/ diff --git a/firmware/bdb/LICENSE b/firmware/bdb/LICENSE deleted file mode 100644 index d2514965..00000000 --- a/firmware/bdb/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/firmware/bdb/README b/firmware/bdb/README deleted file mode 100644 index 82fb715b..00000000 --- a/firmware/bdb/README +++ /dev/null @@ -1,30 +0,0 @@ -Boot Descriptor Block (BDB) library and utilities - -Building: ---------- -The host-side library and utilities requires OpenSSL. - -Do 'make runtests' to ensure everything is working. - -Generating a BDB: ------------------ -Edit the options in bdb_create.c. Then 'make bdb'. - -In the next release, this will take a config file rather than -requiring recompilation each time. Also, the BDB header and data will -be signed in two separate steps, so that the private BDB key is not -required each time. - -Revision History: ------------------ -v0.1.2 24-Nov-2015 Add support for RSA-3072B keys and signatures. - Add dump_rsa utility and 'make testkeys' to create - new keys. - Use a RSA-3072B (exponent 3) key for the subkey so - the exponent 3 code gets tested. - -v0.1.1 17-Nov-2015 Add support for ECDSA-521 data types. Note that - only the data types are supported; there is not a - C implementation for ECDSA. - -v0.1.0 15-Sep-2015 Initial version. diff --git a/firmware/bdb/bdb.c b/firmware/bdb/bdb.c deleted file mode 100644 index 30d10586..00000000 --- a/firmware/bdb/bdb.c +++ /dev/null @@ -1,450 +0,0 @@ -/* 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. - * - * Boot descriptor block firmware functions - */ - -#include "2sysincludes.h" -#include "2common.h" -#include "2sha.h" -#include "bdb.h" - -/*****************************************************************************/ - -/** - * Check if string contains a null terminator. - * - * Bytes after the null terminator do not need to be null. - * - * @param s String to check - * @param size Size of string buffer in characters - * @return 1 if string has a null terminator, 0 if not - */ -static int string_has_null(const char *s, size_t size) -{ - for (; size; size--) { - if (*s++ == 0) - return 1; - } - return 0; -} - -int bdb_check_header(const struct bdb_header *p, size_t size) -{ - if (size < sizeof(*p) || size < p->struct_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_HEADER_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_HEADER_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (p->struct_size < sizeof(*p)) - return BDB_ERROR_STRUCT_SIZE; - - if (p->oem_area_0_size & 3) - return BDB_ERROR_OEM_AREA_SIZE; /* Not 32-bit aligned */ - - /* - * Make sure the BDB is at least big enough for us. At this point, all - * the caller may have loaded is this header We'll check if there's - * space for everything else after we load it. - */ - if (p->bdb_size < sizeof(*p)) - return BDB_ERROR_BDB_SIZE; - - /* - * The rest of the fields don't matter yet; we'll check them when we - * check the BDB itself. - */ - return BDB_SUCCESS; -} - -int bdb_check_key(const struct bdb_key *p, size_t size) -{ - size_t expect_key_size = 0; - - if (size < sizeof(*p) || size < p->struct_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_KEY_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_KEY_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (!string_has_null(p->description, sizeof(p->description))) - return BDB_ERROR_DESCRIPTION; - - /* We currently only support SHA-256 */ - if (p->hash_alg != BDB_HASH_ALG_SHA256) - return BDB_ERROR_HASH_ALG; - - /* Make sure signature algorithm and size are correct */ - switch (p->sig_alg) { - case BDB_SIG_ALG_RSA4096: - expect_key_size = BDB_RSA4096_KEY_DATA_SIZE; - break; - case BDB_SIG_ALG_ECSDSA521: - expect_key_size = BDB_ECDSA521_KEY_DATA_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - expect_key_size = BDB_RSA3072B_KEY_DATA_SIZE; - break; - default: - return BDB_ERROR_SIG_ALG; - } - - if (p->struct_size < sizeof(*p) + expect_key_size) - return BDB_ERROR_STRUCT_SIZE; - - return BDB_SUCCESS; -} - -int bdb_check_sig(const struct bdb_sig *p, size_t size) -{ - size_t expect_sig_size = 0; - - if (size < sizeof(*p) || size < p->struct_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_SIG_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_SIG_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (!string_has_null(p->description, sizeof(p->description))) - return BDB_ERROR_DESCRIPTION; - - /* We currently only support SHA-256 */ - if (p->hash_alg != BDB_HASH_ALG_SHA256) - return BDB_ERROR_HASH_ALG; - - /* Make sure signature algorithm and size are correct */ - switch (p->sig_alg) { - case BDB_SIG_ALG_RSA4096: - expect_sig_size = BDB_RSA4096_SIG_SIZE; - break; - case BDB_SIG_ALG_ECSDSA521: - expect_sig_size = BDB_ECDSA521_SIG_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - expect_sig_size = BDB_RSA3072B_SIG_SIZE; - break; - default: - return BDB_ERROR_SIG_ALG; - } - - if (p->struct_size < sizeof(*p) + expect_sig_size) - return BDB_ERROR_STRUCT_SIZE; - - return BDB_SUCCESS; -} - -int bdb_check_data(const struct bdb_data *p, size_t size) -{ - size_t need_size; - - if (size < sizeof(*p) || size < p->signed_size) - return BDB_ERROR_BUF_SIZE; - - if (p->struct_magic != BDB_DATA_MAGIC) - return BDB_ERROR_STRUCT_MAGIC; - - if (p->struct_major_version != BDB_DATA_VERSION_MAJOR) - return BDB_ERROR_STRUCT_VERSION; - - /* Note that minor version doesn't matter yet */ - - if (!string_has_null(p->description, sizeof(p->description))) - return BDB_ERROR_DESCRIPTION; - - if (p->struct_size < sizeof(*p)) - return BDB_ERROR_STRUCT_SIZE; - - if (p->hash_entry_size < sizeof(struct bdb_hash)) - return BDB_ERROR_HASH_ENTRY_SIZE; - - /* Calculate expected size */ - need_size = p->struct_size + p->num_hashes * p->hash_entry_size; - - /* Make sure OEM area size doesn't cause wraparound */ - if (need_size + p->oem_area_1_size < need_size) - return BDB_ERROR_OEM_AREA_SIZE; - if (p->oem_area_1_size & 3) - return BDB_ERROR_OEM_AREA_SIZE; /* Not 32-bit aligned */ - need_size += p->oem_area_1_size; - - if (p->signed_size < need_size) - return BDB_ERROR_SIGNED_SIZE; - - return BDB_SUCCESS; -} - -/*****************************************************************************/ - -const struct bdb_header *bdb_get_header(const void *buf) -{ - return buf; -} - -uint32_t bdb_size_of(const void *buf) -{ - return bdb_get_header(buf)->bdb_size; -} - -const struct bdb_key *bdb_get_bdbkey(const void *buf) -{ - const struct bdb_header *h = bdb_get_header(buf); - const uint8_t *b8 = buf; - - /* BDB key follows header */ - return (const struct bdb_key *)(b8 + h->struct_size); -} - -const void *bdb_get_oem_area_0(const void *buf) -{ - const struct bdb_key *k = bdb_get_bdbkey(buf); - const uint8_t *b8 = (const uint8_t *)k; - - /* OEM area 0 follows BDB key */ - return b8 + k->struct_size; -} - -const struct bdb_key *bdb_get_datakey(const void *buf) -{ - const struct bdb_header *h = bdb_get_header(buf); - const uint8_t *b8 = bdb_get_oem_area_0(buf); - - /* datakey follows OEM area 0 */ - return (const struct bdb_key *)(b8 + h->oem_area_0_size); -} - -ptrdiff_t bdb_offset_of_datakey(const void *buf) -{ - return vb2_offset_of(buf, bdb_get_datakey(buf)); -} - -const struct bdb_sig *bdb_get_header_sig(const void *buf) -{ - const struct bdb_header *h = bdb_get_header(buf); - const uint8_t *b8 = bdb_get_oem_area_0(buf); - - /* Header signature starts after signed data */ - return (const struct bdb_sig *)(b8 + h->signed_size); -} - -ptrdiff_t bdb_offset_of_header_sig(const void *buf) -{ - return vb2_offset_of(buf, bdb_get_header_sig(buf)); -} - -const struct bdb_data *bdb_get_data(const void *buf) -{ - const struct bdb_sig *s = bdb_get_header_sig(buf); - const uint8_t *b8 = (const uint8_t *)s; - - /* Data follows header signature */ - return (const struct bdb_data *)(b8 + s->struct_size); -} - -ptrdiff_t bdb_offset_of_data(const void *buf) -{ - return vb2_offset_of(buf, bdb_get_data(buf)); -} - -const void *bdb_get_oem_area_1(const void *buf) -{ - const struct bdb_data *p = bdb_get_data(buf); - const uint8_t *b8 = (const uint8_t *)p; - - /* OEM area 1 follows BDB data */ - return b8 + p->struct_size; -} - -static const void *bdb_get_hash(const void *buf) -{ - const struct bdb_data *data = bdb_get_data(buf); - const uint8_t *b8 = bdb_get_oem_area_1(buf); - - /* Hashes follow OEM area 0 */ - return b8 + data->oem_area_1_size; -} - -const struct bdb_hash *bdb_get_hash_by_type(const void *buf, - enum bdb_data_type type) -{ - const struct bdb_data *data = bdb_get_data(buf); - const uint8_t *b8 = bdb_get_hash(buf); - int i; - - /* Search for a matching hash */ - for (i = 0; i < data->num_hashes; i++, b8 += data->hash_entry_size) { - const struct bdb_hash *h = (const struct bdb_hash *)b8; - - if (h->type == type) - return h; - } - - return NULL; -} - -const struct bdb_hash *bdb_get_hash_by_index(const void *buf, int index) -{ - const struct bdb_data *data = bdb_get_data(buf); - const uint8_t *p = bdb_get_hash(buf); - const struct bdb_hash *h = NULL; - int i; - - /* Search for a matching hash */ - for (i = 0; i < data->num_hashes; i++, p += data->hash_entry_size) { - if (i == index) { - h = (const struct bdb_hash *)p; - break; - } - } - - return h; -} - -const struct bdb_sig *bdb_get_data_sig(const void *buf) -{ - const struct bdb_data *data = bdb_get_data(buf); - const uint8_t *b8 = (const uint8_t *)data; - - /* Data signature starts after signed data */ - return (const struct bdb_sig *)(b8 + data->signed_size); -} - -/*****************************************************************************/ - -static int bdb_verify_sig(const struct bdb_key *key, - const struct bdb_sig *sig, - const uint8_t *digest) -{ - /* Key and signature algorithms must match */ - if (key->sig_alg != sig->sig_alg) - return BDB_ERROR_SIG_ALG; - - switch (key->sig_alg) { - case BDB_SIG_ALG_RSA4096: - if (bdb_rsa4096_verify(key->key_data, sig->sig_data, digest)) - return BDB_ERROR_VERIFY_SIG; - break; - case BDB_SIG_ALG_ECSDSA521: - if (bdb_ecdsa521_verify(key->key_data, sig->sig_data, digest)) - return BDB_ERROR_VERIFY_SIG; - break; - case BDB_SIG_ALG_RSA3072B: - if (bdb_rsa3072b_verify(key->key_data, sig->sig_data, digest)) - return BDB_ERROR_VERIFY_SIG; - break; - default: - return BDB_ERROR_VERIFY_SIG; - } - - return BDB_SUCCESS; -} - -int bdb_verify(const void *buf, size_t size, const uint8_t *bdb_key_digest) -{ - const uint8_t *end = (const uint8_t *)buf + size; - const struct bdb_header *h; - const struct bdb_key *bdbkey, *datakey; - const struct bdb_sig *sig; - const struct bdb_data *data; - const void *oem; - uint8_t digest[BDB_SHA256_DIGEST_SIZE]; - int bdb_digest_mismatch = -1; - - /* Make sure buffer doesn't wrap around address space */ - if (end < (const uint8_t *)buf) - return BDB_ERROR_BUF_SIZE; - - /* - * Check header now that we've actually loaded it. We can't guarantee - * this is the same header which was checked before. - */ - h = bdb_get_header(buf); - if (bdb_check_header(h, size)) - return BDB_ERROR_HEADER; - - /* Sanity-check BDB key */ - bdbkey = bdb_get_bdbkey(buf); - if (bdb_check_key(bdbkey, end - (const uint8_t *)bdbkey)) - return BDB_ERROR_BDBKEY; - - /* Calculate BDB key digest and compare with expected */ - if (vb2_digest_buffer((uint8_t *)bdbkey, bdbkey->struct_size, - VB2_HASH_SHA256, digest, BDB_SHA256_DIGEST_SIZE)) - return BDB_ERROR_DIGEST; - - if (bdb_key_digest) - bdb_digest_mismatch = memcmp(digest, - bdb_key_digest, sizeof(digest)); - - /* Make sure OEM area 0 fits */ - oem = bdb_get_oem_area_0(buf); - if (h->oem_area_0_size > end - (const uint8_t *)oem) - return BDB_ERROR_OEM_AREA_0; - - /* Sanity-check datakey */ - datakey = bdb_get_datakey(buf); - if (bdb_check_key(datakey, end - (const uint8_t *)datakey)) - return BDB_ERROR_DATAKEY; - - /* Make sure enough data was signed, and the signed data fits */ - if (h->oem_area_0_size + datakey->struct_size > h->signed_size || - h->signed_size > end - (const uint8_t *)oem) - return BDB_ERROR_BDB_SIGNED_SIZE; - - /* Sanity-check header signature */ - sig = bdb_get_header_sig(buf); - if (bdb_check_sig(sig, end - (const uint8_t *)sig)) - return BDB_ERROR_HEADER_SIG; - - /* Make sure it signed the right amount of data */ - if (sig->signed_size != h->signed_size) - return BDB_ERROR_HEADER_SIG; - - /* Calculate header digest and compare with expected signature */ - if (vb2_digest_buffer((uint8_t *)oem, h->signed_size, - VB2_HASH_SHA256, digest, BDB_SHA256_DIGEST_SIZE)) - return BDB_ERROR_DIGEST; - if (bdb_verify_sig(bdbkey, sig, digest)) - return BDB_ERROR_HEADER_SIG; - - /* - * Sanity-check data struct. This also checks that OEM area 1 and the - * hashes fit in the remaining buffer. - */ - data = bdb_get_data(buf); - if (bdb_check_data(data, end - (const uint8_t *)data)) - return BDB_ERROR_DATA; - - /* Sanity-check data signature */ - sig = bdb_get_data_sig(buf); - if (bdb_check_sig(sig, end - (const uint8_t *)sig)) - return BDB_ERROR_DATA_CHECK_SIG; - if (sig->signed_size != data->signed_size) - return BDB_ERROR_DATA_SIGNED_SIZE; - - /* Calculate data digest and compare with expected signature */ - if (vb2_digest_buffer((uint8_t *)data, data->signed_size, - VB2_HASH_SHA256, digest, BDB_SHA256_DIGEST_SIZE)) - return BDB_ERROR_DIGEST; - if (bdb_verify_sig(datakey, sig, digest)) - return BDB_ERROR_DATA_SIG; - - /* Return success or success-other-than-BDB-key-mismatch */ - return bdb_digest_mismatch ? BDB_GOOD_OTHER_THAN_KEY : BDB_SUCCESS; -} diff --git a/firmware/bdb/bdb.h b/firmware/bdb/bdb.h deleted file mode 100644 index 9e13696c..00000000 --- a/firmware/bdb/bdb.h +++ /dev/null @@ -1,232 +0,0 @@ -/* 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. - * - * Boot descriptor block firmware functions - */ - -#ifndef VBOOT_REFERENCE_BDB_H_ -#define VBOOT_REFERENCE_BDB_H_ - -#include <stdlib.h> -#include <stddef.h> - -#include "bdb_struct.h" - -/*****************************************************************************/ -/* -Expected calling sequence: - -Load and check just the header -bdb_check_header(buf, size); - -Load and verify the entire BDB -bdb_verify(buf, size, bdb_key_hash, dev_mode_flag); - -Check RW datakey version. If normal boot from primary BDB, roll forward - -Check data version. If normal boot from primary BDB, roll forward -*/ - -/*****************************************************************************/ -/* Codes for functions returning numeric error codes */ - -enum bdb_return_code { - /* Success */ - BDB_SUCCESS = 0, - - /* BDB key did not match hash, but other than that the BDB was - * fully verified. */ - BDB_GOOD_OTHER_THAN_KEY = 1, - - /* Function is not implemented, thus supposed to be not called */ - BDB_ERROR_NOT_IMPLEMENTED, - - /* Other errors */ - BDB_ERROR_UNKNOWN = 100, - - /* Buffer size too small or wraps around */ - BDB_ERROR_BUF_SIZE, - - /* Bad fields in structures */ - BDB_ERROR_STRUCT_MAGIC, - BDB_ERROR_STRUCT_VERSION, - BDB_ERROR_STRUCT_SIZE, - BDB_ERROR_SIGNED_SIZE, - BDB_ERROR_BDB_SIZE, - BDB_ERROR_OEM_AREA_SIZE, - BDB_ERROR_HASH_ENTRY_SIZE, - BDB_ERROR_HASH_ALG, - BDB_ERROR_SIG_ALG, - BDB_ERROR_DESCRIPTION, - - /* Bad components of BDB in bdb_verify() */ - BDB_ERROR_HEADER, - BDB_ERROR_BDBKEY, - BDB_ERROR_OEM_AREA_0, - BDB_ERROR_DATAKEY, - BDB_ERROR_BDB_SIGNED_SIZE, - BDB_ERROR_HEADER_SIG, - BDB_ERROR_DATA, - BDB_ERROR_DATA_SIG, - BDB_ERROR_DATA_CHECK_SIG, - BDB_ERROR_DATA_SIGNED_SIZE, - - /* Other errors in bdb_verify() */ - BDB_ERROR_DIGEST, /* Error calculating digest */ - BDB_ERROR_VERIFY_SIG, /* Error verifying signature */ - - /* Errors in vba_bdb_init */ - BDB_ERROR_TRY_OTHER_SLOT, - BDB_ERROR_RECOVERY_REQUEST, - - BDB_ERROR_NVM_INIT, - BDB_ERROR_NVM_WRITE, - BDB_ERROR_NVM_RW_HMAC, - BDB_ERROR_NVM_RW_INVALID_HMAC, - BDB_ERROR_NVM_INVALID_PARAMETER, - BDB_ERROR_NVM_INVALID_SECRET, - BDB_ERROR_NVM_RW_MAGIC, - BDB_ERROR_NVM_STRUCT_SIZE, - BDB_ERROR_NVM_WRITE_VERIFY, - BDB_ERROR_NVM_STRUCT_VERSION, - BDB_ERROR_NVM_VBE_READ, - BDB_ERROR_NVM_RW_BUFFER_SMALL, - BDB_ERROR_DECRYPT_BUC, - BDB_ERROR_ENCRYPT_BUC, - BDB_ERROR_WRITE_BUC, - - BDB_ERROR_SECRET_TYPE, - BDB_ERROR_SECRET_BUC, - BDB_ERROR_SECRET_BOOT_VERIFIED, - BDB_ERROR_SECRET_BOOT_PATH, - BDB_ERROR_SECRET_BDB, -}; - -/*****************************************************************************/ -/* Functions */ - -/** - * Sanity-check BDB structures. - * - * This checks for known version numbers, magic numbers, algorithms, etc. and - * ensures the sizes are consistent with those parameters. - * - * @param p Pointer to structure to check - * @param size Size of structure buffer - * @return 0 if success, non-zero error code if error. - */ -int bdb_check_header(const struct bdb_header *p, size_t size); -int bdb_check_key(const struct bdb_key *p, size_t size); -int bdb_check_sig(const struct bdb_sig *p, size_t size); -int bdb_check_data(const struct bdb_data *p, size_t size); - -/** - * Verify the entire BDB - * - * @param buf Data to hash - * @param size Size of data in bytes - * @param bdb_key_digest Pointer to expected digest for BDB key. - * Must be BDB_SHA256_DIGEST_SIZE bytes long. - * If it's NULL, digest match will be skipped - * (and it'll be treated as 'mismatch'). - * - * @return 0 if success, non-zero error code if error. Note that error code - * BDB_GOOD_OTHER_THAN_KEY may still indicate an acceptable BDB if the Boot - * Verified fuse has not been set, or in developer mode. - */ -int bdb_verify(const void *buf, size_t size, const uint8_t *bdb_key_digest); - -/** - * Functions to extract things from a verified BDB buffer. - * - * Do not call these externally until after bdb_verify()! These methods - * assume data structures have already been verified. - * - * @param buf Pointer to BDB buffer - * @param type Data type, for bdb_get_hash() - * @return A pointer to the requested data, or NULL if error / not present. - */ -const struct bdb_header *bdb_get_header(const void *buf); -const struct bdb_key *bdb_get_bdbkey(const void *buf); -const void *bdb_get_oem_area_0(const void *buf); -const struct bdb_key *bdb_get_datakey(const void *buf); -const struct bdb_sig *bdb_get_header_sig(const void *buf); -const struct bdb_data *bdb_get_data(const void *buf); -const void *bdb_get_oem_area_1(const void *buf); -const struct bdb_hash *bdb_get_hash_by_type(const void *buf, - enum bdb_data_type type); -const struct bdb_hash *bdb_get_hash_by_index(const void *buf, int index); -const struct bdb_sig *bdb_get_data_sig(const void *buf); - -/** - * Functions to calculate size of BDB components - * - * @param buf Pointer to BDB buffer - * @return Size of the component - */ -uint32_t bdb_size_of(const void *buf); - -/** - * Functions to calculate offset of BDB components - * - * @param buf Pointer to BDB buffer - * @return Offset of the component - */ -ptrdiff_t bdb_offset_of_datakey(const void *buf); -ptrdiff_t bdb_offset_of_header_sig(const void *buf); -ptrdiff_t bdb_offset_of_data(const void *buf); - -/*****************************************************************************/ -/* Functions probably provided by the caller */ - -/** - * Calculate a SHA-256 digest of a buffer. - * - * @param digest Pointer to the digest buffer. Must be - * BDB_SHA256_DIGEST_SIZE bytes long. - * @param buf Data to hash - * @param size Size of data in bytes - * @return 0 if success, non-zero error code if error. - */ -int bdb_sha256(void *digest, const void *buf, size_t size); - -/** - * Verify a RSA-4096 signed digest - * - * @param key_data Key data to use (BDB_RSA4096_KEY_DATA_SIZE bytes) - * @param sig_data Signature to verify (BDB_RSA4096_SIG_SIZE bytes) - * @param digest Digest of signed data (BDB_SHA256_DIGEST bytes) - * @return 0 if success, non-zero error code if error. - */ -int bdb_rsa4096_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest); - -/** - * Verify a RSA-3072B signed digest - * - * @param key_data Key data to use (BDB_RSA3072B_KEY_DATA_SIZE bytes) - * @param sig_data Signature to verify (BDB_RSA3072B_SIG_SIZE bytes) - * @param digest Digest of signed data (BDB_SHA256_DIGEST bytes) - * @return 0 if success, non-zero error code if error. - */ -int bdb_rsa3072b_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest); - -/** - * Verify a ECDSA-521 signed digest - * - * @param key_data Key data to use (BDB_ECDSA521_KEY_DATA_SIZE bytes) - * @param sig_data Signature to verify (BDB_ECDSA521_SIG_SIZE bytes) - * @param digest Digest of signed data (BDB_SHA256_DIGEST bytes) - * @return 0 if success, non-zero error code if error. - */ -int bdb_ecdsa521_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest); - -/*****************************************************************************/ - -#endif /* VBOOT_REFERENCE_BDB_H_ */ diff --git a/firmware/bdb/bdb_api.h b/firmware/bdb/bdb_api.h deleted file mode 100644 index c0e850f9..00000000 --- a/firmware/bdb/bdb_api.h +++ /dev/null @@ -1,194 +0,0 @@ -/* Copyright 2016 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. - */ - -#ifndef VBOOT_REFERENCE_FIRMWARE_BDB_BDB_API_H -#define VBOOT_REFERENCE_FIRMWARE_BDB_BDB_API_H - -#include <stdint.h> -#include "vboot_register.h" -#include "nvm.h" -#include "secrets.h" -#include "bdb_flag.h" - -struct vba_context { - /* Indicate which slot is being tried: 0 - primary, 1 - secondary */ - uint8_t slot; - - /* Defined by VBA_CONTEXT_FLAG_* in bdb_flag.h */ - uint32_t flags; - - /* BDB */ - uint8_t *bdb; - - /* Secrets */ - struct bdb_secrets *secrets; - - /* NVM-RW buffer */ - struct nvmrw nvmrw; -}; - -/** - * Initialize vboot process - * - * @param ctx - * @return enum bdb_return_code - */ -int vba_bdb_init(struct vba_context *ctx); - -/** - * Finalize vboot process - * - * @param ctx - * @return enum bdb_return_code - */ -int vba_bdb_finalize(struct vba_context *ctx); - -/** - * Log failed boot attempt and reset the chip - * - * @param ctx - */ -void vba_bdb_fail(struct vba_context *ctx); - -/** - * Update kernel and its data key version in NVM - * - * This is the function called from SP-RW, which receives a kernel version - * from an AP-RW after successful verification of a kernel. - * - * It checks whether the version in NVM-RW is older than the reported version - * or not. If so, it updates the version in NVM-RW. - * - * @param ctx - * @param kernel_data_key_version - * @param kernel_version - * @return BDB_SUCCESS or BDB_ERROR_* - */ -int vba_update_kernel_version(struct vba_context *ctx, - uint32_t kernel_data_key_version, - uint32_t kernel_version); - -/** - * Write new boot unlock code to NVM-RW - * - * @param ctx - * @param new_buc New BUC to be written - * @return BDB_SUCCESS or BDB_ERROR_* - */ -int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc); - -/** - * Derive a secret - * - * This derives a new secret from a secret passed from SP-RO. - * - * @param ctx - * @param type Type of secret to derive - * @param buf Buffer containing data to derive secret from - * @param buf_size Size of <buf> - * @return BDB_SUCCESS or BDB_ERROR_* - */ -int vba_derive_secret(struct vba_context *ctx, enum bdb_secret_type type, - uint8_t *wsr, const uint8_t *buf, uint32_t buf_size); - -/** - * Clear a secret - * - * @param ctx - * @param type Type of secret to clear - * @return BDB_SUCCESS or BDB_ERROR_* - */ -int vba_clear_secret(struct vba_context *ctx, enum bdb_secret_type type); - -/** - * Extend secrets for SP-RO - * - * @param ctx struct vba_context - * @param bdb BDB - * @param wsr Pointer to working secret register contents - * @param extend Function to be called for extending a secret - * @return BDB_SUCCESS or BDB_ERROR_* - */ -typedef void (*f_extend)(const uint8_t *from, const uint8_t *by, uint8_t *to); -int vba_extend_secrets_ro(struct vba_context *ctx, const uint8_t *bdb, - uint8_t *wsr, f_extend extend); - -/** - * Get vboot register value - * - * Implemented by each chip - * - * @param type Type of register to get - * @return Register value - */ -uint32_t vbe_get_vboot_register(enum vboot_register type); - -/** - * Set vboot register value - * - * Implemented by each chip - * - * @param type Type of register to set - * @param val Value to set - */ -void vbe_set_vboot_register(enum vboot_register type, uint32_t val); - -/** - * Reset the SoC - * - * Implemented by each chip. This is different from reboot (a.k.a. board reset, - * cold reset). - */ -void vbe_reset(void); - -/** - * Read contents from Non-Volatile Memory - * - * Implemented by each chip. - * - * @param type Type of NVM - * @param buf Buffer where the data will be read to - * @param size Size of data to read - * @return Zero if success or non-zero otherwise - */ -int vbe_read_nvm(enum nvm_type type, uint8_t *buf, uint32_t size); - -/** - * Write contents to Non-Volatile Memory - * - * Implemented by each chip. - * - * @param type Type of NVM - * @param buf Buffer where the data will be written from - * @param size Size of data to write - * @return Zero if success or non-zero otherwise - */ -int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size); - -/** - * Encrypt data by AES-256 - * - * @param msg Message to be encrypted - * @param len Length of <msg> in bytes - * @param key Key used for encryption - * @param out Buffer where encrypted message is stored - * @return BDB_SUCCESS or BDB_ERROR_* - */ -int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key, - uint8_t *out); - -/** - * Decrypt data by AES-256 - * - * @param msg Message to be decrypted - * @param len Length of <msg> in bytes - * @param key Key used for decryption - * @param out Buffer where decrypted message is stored - * @return BDB_SUCCESS or BDB_ERROR_* - */ -int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key, - uint8_t *out); - -#endif diff --git a/firmware/bdb/bdb_flag.h b/firmware/bdb/bdb_flag.h deleted file mode 100644 index a7bd8574..00000000 --- a/firmware/bdb/bdb_flag.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright 2016 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. - */ - -#ifndef VBOOT_REFERENCE_FIRMWARE_BDB_BDB_FLAG_H -#define VBOOT_REFERENCE_FIRMWARE_BDB_BDB_FLAG_H - -/* Indicate whether BDB key is verified */ -#define VBA_CONTEXT_FLAG_BDB_KEY_EFUSED (1 << 0) - -/* Indicate whether kernel data key is verified */ -#define VBA_CONTEXT_FLAG_KERNEL_DATA_KEY_VERIFIED (1 << 1) - -#endif diff --git a/firmware/bdb/bdb_struct.h b/firmware/bdb/bdb_struct.h deleted file mode 100644 index b9b4b852..00000000 --- a/firmware/bdb/bdb_struct.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block structures - */ - -#ifndef VBOOT_REFERENCE_BDB_STRUCT_H_ -#define VBOOT_REFERENCE_BDB_STRUCT_H_ - -#include <stdint.h> - -/* Size of SHA256 digest in bytes */ -#define BDB_SHA256_DIGEST_SIZE 32 - -/* Size of RSA4096 key data in bytes */ -#define BDB_RSA4096_KEY_DATA_SIZE 1032 - -/* Size of RSA4096 signature in bytes */ -#define BDB_RSA4096_SIG_SIZE 512 - -/* Size of ECDSA521 key data in bytes = ceil(521/8) * 2 */ -#define BDB_ECDSA521_KEY_DATA_SIZE 132 - -/* Size of ECDSA521 signature in bytes = ceil(521/8) * 2 */ -#define BDB_ECDSA521_SIG_SIZE 132 - -/* Size of RSA3072B key data in bytes */ -#define BDB_RSA3072B_KEY_DATA_SIZE 776 - -/* Size of RSA3072B signature in bytes */ -#define BDB_RSA3072B_SIG_SIZE 384 - -/*****************************************************************************/ -/* Header for BDB */ - -/* Magic number for bdb_header.struct_magic */ -#define BDB_HEADER_MAGIC 0x30426442 - -/* Current version of bdb_header struct */ -#define BDB_HEADER_VERSION_MAJOR 1 -#define BDB_HEADER_VERSION_MINOR 0 - -/* Expected size of bdb_header struct in bytes */ -#define BDB_HEADER_EXPECTED_SIZE 32 - -struct bdb_header { - /* Magic number to identify struct = BDB_HEADER_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_HEADER_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes */ - uint16_t struct_size; - - /* Recommended address in SP SRAM to load BDB. Set to -1 to use - * default address. */ - uint64_t bdb_load_address; - - /* Size of the entire BDB in bytes */ - uint32_t bdb_size; - - /* Number of bytes following the BDB key which are signed by the BDB - * header signature. */ - uint32_t signed_size; - - /* Size of OEM area 0 in bytes, or 0 if not present */ - uint32_t oem_area_0_size; - - /* Reserved; set 0 */ - uint8_t reserved0[8]; -} __attribute__((packed)); - -/*****************************************************************************/ -/* Public key structure for BDB */ - -/* Magic number for bdb_key.struct_magic */ -#define BDB_KEY_MAGIC 0x73334256 - -/* Current version of bdb_key struct */ -#define BDB_KEY_VERSION_MAJOR 1 -#define BDB_KEY_VERSION_MINOR 0 - -/* Supported hash algorithms */ -enum bdb_hash_alg { - BDB_HASH_ALG_INVALID = 0, /* Not used; invalid */ - BDB_HASH_ALG_SHA256 = 2, /* SHA-256 */ -}; - -/* Supported signature algorithms */ -enum bdb_sig_alg { - BDB_SIG_ALG_INVALID = 0, /* Not used; invalid */ - BDB_SIG_ALG_RSA4096 = 3, /* RSA-4096, exponent 65537 */ - BDB_SIG_ALG_ECSDSA521 = 5, /* ECDSA-521 */ - BDB_SIG_ALG_RSA3072B = 7, /* RSA_3072, exponent 3 */ -}; - -/* - * Expected size of bdb_key struct in bytes, not counting variable-length key - * data at end. - */ -#define BDB_KEY_EXPECTED_SIZE 80 - -struct bdb_key { - /* Magic number to identify struct = BDB_KEY_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_KEY_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes, including variable-length key data */ - uint16_t struct_size; - - /* Hash algorithm (enum bdb_hash_alg) */ - uint8_t hash_alg; - - /* Signature algorithm (enum bdb_sig_alg) */ - uint8_t sig_alg; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Key version */ - uint32_t key_version; - - /* Description; null-terminated ASCII */ - char description[128]; - - /* - * Key data. Variable-length; size is struct_size - - * offset_of(bdb_key, key_data). - */ - uint8_t key_data[0]; -} __attribute__((packed)); - -/*****************************************************************************/ -/* Signature structure for BDB */ - -/* Magic number for bdb_sig.struct_magic */ -#define BDB_SIG_MAGIC 0x6b334256 - -/* Current version of bdb_sig struct */ -#define BDB_SIG_VERSION_MAJOR 1 -#define BDB_SIG_VERSION_MINOR 0 - -struct bdb_sig { - /* Magic number to identify struct = BDB_SIG_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_SIG_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes, including variable-length signature - * data. */ - uint16_t struct_size; - - /* Hash algorithm used for this signature (enum bdb_hash_alg) */ - uint8_t hash_alg; - - /* Signature algorithm (enum bdb_sig_alg) */ - uint8_t sig_alg; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Number of bytes of data signed by this signature */ - uint32_t signed_size; - - /* Description; null-terminated ASCII */ - char description[128]; - - /* Signature data. Variable-length; size is struct_size - - * offset_of(bdb_sig, sig_data). */ - uint8_t sig_data[0]; -} __attribute__((packed)); - -/*****************************************************************************/ -/* Data structure for BDB */ - -/* Magic number for bdb_data.struct_magic */ -#define BDB_DATA_MAGIC 0x31426442 - -/* Current version of bdb_sig struct */ -#define BDB_DATA_VERSION_MAJOR 1 -#define BDB_DATA_VERSION_MINOR 0 - -struct bdb_data { - /* Magic number to identify struct = BDB_DATA_MAGIC. */ - uint32_t struct_magic; - - /* Structure version = BDB_DATA_VERSION{MAJOR,MINOR} */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of structure in bytes, NOT including hashes which follow. */ - uint16_t struct_size; - - /* Version of data (RW firmware) contained */ - uint32_t data_version; - - /* Size of OEM area 1 in bytes, or 0 if not present */ - uint32_t oem_area_1_size; - - /* Number of hashes which follow */ - uint8_t num_hashes; - - /* Size of each hash entry in bytes */ - uint8_t hash_entry_size; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Number of bytes of data signed by the datakey, including this - * header */ - uint32_t signed_size; - - /* Reserved; set 0 */ - uint8_t reserved1[8]; - - /* Description; null-terminated ASCII */ - char description[128]; -} __attribute__((packed)); - -/* Type of data for bdb_hash.type */ -enum bdb_data_type { - /* Types of data for boot descriptor blocks */ - BDB_DATA_SP_RW = 1, /* SP-RW firmware */ - BDB_DATA_AP_RW = 2, /* AP-RW firmware */ - BDB_DATA_MCU = 3, /* MCU firmware */ - - /* Types of data for kernel descriptor blocks */ - BDB_DATA_KERNEL = 128, /* Kernel */ - BDB_DATA_CMD_LINE = 129, /* Command line */ - BDB_DATA_HEADER16 = 130, /* 16-bit vmlinuz header */ -}; - -/* Hash entries which follow the structure */ -struct bdb_hash { - /* Offset of data from start of partition */ - uint64_t offset; - - /* Size of data in bytes */ - uint32_t size; - - /* Partition number containing data */ - uint8_t partition; - - /* Type of data; enum bdb_data_type */ - uint8_t type; - - /* Reserved; set 0 */ - uint8_t reserved0[2]; - - /* Address in RAM to load data. -1 means use default. */ - uint64_t load_address; - - /* SHA-256 hash digest */ - uint8_t digest[BDB_SHA256_DIGEST_SIZE]; -} __attribute__((packed)); - -/*****************************************************************************/ - -#endif /* VBOOT_REFERENCE_BDB_STRUCT_H_ */ - diff --git a/firmware/bdb/dump_rsa.c b/firmware/bdb/dump_rsa.c deleted file mode 100644 index c40f803a..00000000 --- a/firmware/bdb/dump_rsa.c +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright (c) 2010 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. - */ - -/* - * C port of DumpPublicKey.java from the Android Open source project with - * support for additional RSA key sizes. (platform/system/core,git/libmincrypt - * /tools/DumpPublicKey.java). Uses the OpenSSL X509 and BIGNUM library. - */ - -#include <openssl/pem.h> - -#include <stdint.h> -#include <string.h> -#include <unistd.h> - -/* - * Command line tool to extract RSA public keys from X.509 certificates and - * output a pre-processed version of keys for use by RSA verification routines. - */ - -int check(RSA *key) -{ - int public_exponent = BN_get_word(key->e); - int modulus = BN_num_bits(key->n); - - if (public_exponent != 65537 && public_exponent != 3) { - fprintf(stderr, "WARNING: Non-standard public exponent %d.\n", - public_exponent); - } - - if (modulus != 1024 && modulus != 2048 && modulus != 3072 && - modulus != 4096 && modulus != 8192) { - fprintf(stderr, "WARNING: Non-standard modulus length = %d.\n", - modulus); - } - return 1; -} - -/** - * Pre-processes and outputs RSA public key to standard output. - */ -void output(RSA *key) -{ - BIGNUM *N; - BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL; - BIGNUM *B = NULL; - BIGNUM *N0inv= NULL, *R = NULL, *RR = NULL, *RRTemp = NULL; - BIGNUM *NnumBits = NULL; - BIGNUM *n = NULL, *rr = NULL; - BN_CTX *bn_ctx = BN_CTX_new(); - uint32_t n0invout; - int nwords, i; - - N = key->n; - /* Output size of RSA key in 32-bit words */ - nwords = BN_num_bits(N) / 32; - if (-1 == write(1, &nwords, sizeof(nwords))) - goto failure; - - /* Initialize BIGNUMs */ - Big1 = BN_new(); - Big2 = BN_new(); - Big32 = BN_new(); - BigMinus1 = BN_new(); - N0inv= BN_new(); - R = BN_new(); - RR = BN_new(); - RRTemp = BN_new(); - NnumBits = BN_new(); - n = BN_new(); - rr = BN_new(); - - BN_set_word(Big1, 1L); - BN_set_word(Big2, 2L); - BN_set_word(Big32, 32L); - BN_sub(BigMinus1, Big1, Big2); - - B = BN_new(); - BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */ - - /* Calculate and output N0inv = -1 / N[0] mod 2^32 */ - BN_mod_inverse(N0inv, N, B, bn_ctx); - BN_sub(N0inv, B, N0inv); - n0invout = BN_get_word(N0inv); - if (-1 == write(1, &n0invout, sizeof(n0invout))) - goto failure; - - /* Calculate R = 2^(# of key bits) */ - BN_set_word(NnumBits, BN_num_bits(N)); - BN_exp(R, Big2, NnumBits, bn_ctx); - - /* Calculate RR = R^2 mod N */ - BN_copy(RR, R); - BN_mul(RRTemp, RR, R, bn_ctx); - BN_mod(RR, RRTemp, N, bn_ctx); - - /* Write out modulus as little endian array of integers. */ - for (i = 0; i < nwords; ++i) { - uint32_t nout; - - BN_mod(n, N, B, bn_ctx); /* n = N mod B */ - nout = BN_get_word(n); - if (-1 == write(1, &nout, sizeof(nout))) - goto failure; - - BN_rshift(N, N, 32); /* N = N/B */ - } - - /* Write R^2 as little endian array of integers. */ - for (i = 0; i < nwords; ++i) { - uint32_t rrout; - - BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */ - rrout = BN_get_word(rr); - if (-1 == write(1, &rrout, sizeof(rrout))) - goto failure; - - BN_rshift(RR, RR, 32); /* RR = RR/B */ - } - - failure: - /* Free BIGNUMs. */ - BN_free(Big1); - BN_free(Big2); - BN_free(Big32); - BN_free(BigMinus1); - BN_free(N0inv); - BN_free(R); - BN_free(RRTemp); - BN_free(NnumBits); - BN_free(n); - BN_free(rr); - -} - -int main(int argc, char* argv[]) { - int cert_mode = 0; - FILE* fp; - X509* cert = NULL; - RSA* pubkey = NULL; - EVP_PKEY* key; - char *progname; - - if (argc != 3 || - (strcmp(argv[1], "-cert") && strcmp(argv[1], "-pub"))) { - progname = strrchr(argv[0], '/'); - if (progname) - progname++; - else - progname = argv[0]; - fprintf(stderr, "Usage: %s <-cert | -pub> <file>\n", progname); - return -1; - } - - if (!strcmp(argv[1], "-cert")) - cert_mode = 1; - - fp = fopen(argv[2], "r"); - - if (!fp) { - fprintf(stderr, "Couldn't open file %s!\n", argv[2]); - return -1; - } - - if (cert_mode) { - /* Read the certificate */ - if (!PEM_read_X509(fp, &cert, NULL, NULL)) { - fprintf(stderr, "Couldn't read certificate.\n"); - goto fail; - } - - /* Get the public key from the certificate. */ - key = X509_get_pubkey(cert); - - /* Convert to a RSA_style key. */ - if (!(pubkey = EVP_PKEY_get1_RSA(key))) { - fprintf(stderr, "Couldn't convert to RSA style key.\n"); - goto fail; - } - } else { - /* Read the pubkey in .PEM format. */ - if (!(pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL))) { - fprintf(stderr, "Couldn't read public key file.\n"); - goto fail; - } - } - - if (check(pubkey)) { - output(pubkey); - } - - fail: - X509_free(cert); - RSA_free(pubkey); - fclose(fp); - - return 0; -} diff --git a/firmware/bdb/ecdsa.c b/firmware/bdb/ecdsa.c deleted file mode 100644 index f4d17287..00000000 --- a/firmware/bdb/ecdsa.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 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. - * - * Boot descriptor block firmware ECDSA stub - */ - -#include <string.h> -#include "bdb.h" - -int bdb_ecdsa521_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest) -{ - /* This is just a stub */ - return BDB_ERROR_DIGEST; -} diff --git a/firmware/bdb/host.c b/firmware/bdb/host.c deleted file mode 100644 index 730d17d9..00000000 --- a/firmware/bdb/host.c +++ /dev/null @@ -1,419 +0,0 @@ -/* 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. - * - * Host functions for signing - */ - -#include <unistd.h> - -#include "2sysincludes.h" -#include "2common.h" -#include "2sha.h" -#include "bdb.h" -#include "host.h" - -char *strzcpy(char *dest, const char *src, size_t size) -{ - strncpy(dest, src, size); - dest[size - 1] = 0; - return dest; -} - -uint8_t *read_file(const char *filename, uint32_t *size_ptr) -{ - FILE *f; - uint8_t *buf; - long size; - - *size_ptr = 0; - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "Unable to open file %s\n", filename); - return NULL; - } - - fseek(f, 0, SEEK_END); - size = ftell(f); - rewind(f); - - if (size < 0 || size > UINT32_MAX) { - fclose(f); - return NULL; - } - - buf = malloc(size); - if (!buf) { - fclose(f); - return NULL; - } - - if (1 != fread(buf, size, 1, f)) { - fprintf(stderr, "Unable to read file %s\n", filename); - fclose(f); - free(buf); - return NULL; - } - - fclose(f); - - *size_ptr = size; - return buf; -} - -int write_file(const char *filename, const void *buf, uint32_t size) -{ - FILE *f = fopen(filename, "wb"); - - if (!f) { - fprintf(stderr, "Unable to open file %s\n", filename); - return 1; - } - - if (1 != fwrite(buf, size, 1, f)) { - fprintf(stderr, "Unable to write to file %s\n", filename); - fclose(f); - unlink(filename); /* Delete any partial file */ - return 1; - } - - fclose(f); - return 0; -} - -struct rsa_st *read_pem(const char *filename) -{ - struct rsa_st *pem; - FILE *f; - - /* Read private key */ - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "%s: unable to read key from %s\n", - __func__, filename); - return NULL; - } - - pem = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); - fclose(f); - - return pem; -} - -struct bdb_key *bdb_create_key(const char *filename, - uint32_t key_version, - const char *desc) -{ - uint32_t sig_alg; - size_t key_size = sizeof(struct bdb_key); - struct bdb_key *k; - uint8_t *kdata; - uint32_t kdata_size = 0; - - /* - * Read key data. Somewhat lame assumption that we can determine the - * signature algorithm from the key size, but it's true right now. - */ - kdata = read_file(filename, &kdata_size); - if (kdata_size == BDB_RSA4096_KEY_DATA_SIZE) { - sig_alg = BDB_SIG_ALG_RSA4096; - } else if (kdata_size == BDB_RSA3072B_KEY_DATA_SIZE) { - sig_alg = BDB_SIG_ALG_RSA3072B; - } else { - fprintf(stderr, "%s: bad key size from %s\n", - __func__, filename); - free(kdata); - return NULL; - } - key_size += kdata_size; - - /* Allocate buffer */ - k = (struct bdb_key *)calloc(key_size, 1); - if (!k) { - free(kdata); - return NULL; - } - - k->struct_magic = BDB_KEY_MAGIC; - k->struct_major_version = BDB_KEY_VERSION_MAJOR; - k->struct_minor_version = BDB_KEY_VERSION_MINOR; - k->struct_size = key_size; - k->hash_alg = BDB_HASH_ALG_SHA256; - k->sig_alg = sig_alg; - k->key_version = key_version; - - /* Copy description, if any */ - if (desc) - strzcpy(k->description, desc, sizeof(k->description)); - - /* Copy key data */ - memcpy(k->key_data, kdata, kdata_size); - free(kdata); - - return k; -} - -struct bdb_sig *bdb_create_sig(const void *data, - size_t size, - struct rsa_st *key, - uint32_t sig_alg, - const char *desc) -{ - static const uint8_t info[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, - 0x00, 0x04, 0x20 - }; - - size_t sig_size = sizeof(struct bdb_sig); - uint8_t digest[sizeof(info) + BDB_SHA256_DIGEST_SIZE]; - struct bdb_sig *sig; - - if (size >= UINT32_MAX) - return NULL; - - switch(sig_alg) { - case BDB_SIG_ALG_RSA4096: - sig_size += BDB_RSA4096_SIG_SIZE; - break; - case BDB_SIG_ALG_RSA3072B: - sig_size += BDB_RSA3072B_SIG_SIZE; - break; - default: - fprintf(stderr, "%s: bad signature algorithm %d\n", - __func__, sig_alg); - return NULL; - } - - /* Allocate buffer */ - sig = (struct bdb_sig *)calloc(sig_size, 1); - if (!sig) - return NULL; - - sig->struct_magic = BDB_SIG_MAGIC; - sig->struct_major_version = BDB_SIG_VERSION_MAJOR; - sig->struct_minor_version = BDB_SIG_VERSION_MINOR; - sig->struct_size = sig_size; - sig->hash_alg = BDB_HASH_ALG_SHA256; - sig->sig_alg = sig_alg; - sig->signed_size = size; - - /* Copy description, if any */ - if (desc) - strzcpy(sig->description, desc, sizeof(sig->description)); - - /* Calculate info-padded digest */ - memcpy(digest, info, sizeof(info)); - if (vb2_digest_buffer((uint8_t *)data, size, - VB2_HASH_SHA256, - digest + sizeof(info), BDB_SHA256_DIGEST_SIZE)) { - free(sig); - return NULL; - } - - /* RSA-encrypt the signature */ - if (RSA_private_encrypt(sizeof(digest), - digest, - sig->sig_data, - key, - RSA_PKCS1_PADDING) == -1) { - free(sig); - return NULL; - } - return sig; -} - -int bdb_sign_datakey(uint8_t **bdb, struct rsa_st *key) -{ - const struct bdb_header *header = bdb_get_header(*bdb); - const struct bdb_key *bdbkey = bdb_get_bdbkey(*bdb); - const void *oem = bdb_get_oem_area_0(*bdb); - const struct bdb_sig *sig = bdb_get_header_sig(*bdb); - struct bdb_sig *new_sig; - uint8_t *new_bdb, *src, *dst; - size_t len; - - new_sig = bdb_create_sig(oem, header->signed_size, - key, bdbkey->sig_alg, NULL); - new_bdb = calloc(1, header->bdb_size - + (new_sig->struct_size - sig->struct_size)); - if (!new_bdb) - return BDB_ERROR_UNKNOWN; - - /* copy up to sig */ - src = *bdb; - dst = new_bdb; - len = bdb_offset_of_header_sig(*bdb); - memcpy(dst, src, len); - - /* copy new sig */ - src += len; - dst += len; - memcpy(dst, new_sig, new_sig->struct_size); - - /* copy the rest */ - src += sig->struct_size; - dst += new_sig->struct_size; - len = bdb_size_of(*bdb) - vb2_offset_of(*bdb, src); - memcpy(dst, src, len); - - free(*bdb); - free(new_sig); - *bdb = new_bdb; - - return BDB_SUCCESS; -} - -int bdb_sign_data(uint8_t **bdb, struct rsa_st *key) -{ - const struct bdb_key *datakey = bdb_get_datakey(*bdb); - const struct bdb_data *data = bdb_get_data(*bdb); - const uint64_t sig_offset = vb2_offset_of(*bdb, bdb_get_data_sig(*bdb)); - struct bdb_sig *new_sig; - uint8_t *new_bdb; - - new_sig = bdb_create_sig(data, data->signed_size, - key, datakey->sig_alg, NULL); - new_bdb = calloc(1, sig_offset + new_sig->struct_size); - if (!new_bdb) - return BDB_ERROR_UNKNOWN; - - /* copy all data up to the data sig */ - memcpy(new_bdb, *bdb, sig_offset); - - /* copy the new signature */ - memcpy(new_bdb + sig_offset, new_sig, new_sig->struct_size); - - free(*bdb); - free(new_sig); - *bdb = new_bdb; - - return BDB_SUCCESS; -} - -struct bdb_header *bdb_create(struct bdb_create_params *p) -{ - size_t bdb_size = 0; - size_t sig_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE; - size_t hashes_size = sizeof(struct bdb_hash) * p->num_hashes; - uint8_t *buf, *bnext; - struct bdb_header *h; - struct bdb_sig *sig; - struct bdb_data *data; - const void *oem; - - /* We can do some checks before we even allocate the buffer */ - - /* Make sure OEM sizes are aligned */ - if ((p->oem_area_0_size & 3) || (p->oem_area_1_size & 3)) { - fprintf(stderr, "%s: OEM areas not 32-bit aligned\n", - __func__); - return NULL; - } - - /* Hash count must fit in uint8_t */ - if (p->num_hashes > 255) { - fprintf(stderr, "%s: too many hashes\n", __func__); - return NULL; - } - - /* Calculate BDB size */ - bdb_size = sizeof(struct bdb_header); - bdb_size += p->bdbkey->struct_size; - bdb_size += p->oem_area_0_size; - bdb_size += p->datakey->struct_size; - bdb_size += sig_size; - bdb_size += sizeof(struct bdb_data); - bdb_size += p->oem_area_1_size; - bdb_size += sizeof(struct bdb_hash) * p->num_hashes; - bdb_size += sig_size; - - /* Make sure it fits */ - if (bdb_size > UINT32_MAX) { - fprintf(stderr, "%s: BDB size > UINT32_MAX\n", __func__); - return NULL; - } - - /* Allocate a buffer */ - bnext = buf = calloc(bdb_size, 1); - if (!buf) { - fprintf(stderr, "%s: can't allocate buffer\n", __func__); - return NULL; - } - - /* Fill in the header */ - h = (struct bdb_header *)bnext; - h->struct_magic = BDB_HEADER_MAGIC; - h->struct_major_version = BDB_HEADER_VERSION_MAJOR; - h->struct_minor_version = BDB_HEADER_VERSION_MINOR; - h->struct_size = sizeof(*h); - h->bdb_load_address = p->bdb_load_address; - h->bdb_size = bdb_size; - h->signed_size = p->oem_area_0_size + p->datakey->struct_size; - h->oem_area_0_size = p->oem_area_0_size; - bnext += h->struct_size; - - /* Copy BDB key */ - memcpy(bnext, p->bdbkey, p->bdbkey->struct_size); - bnext += p->bdbkey->struct_size; - - /* Copy OEM area 0 */ - oem = bnext; - if (p->oem_area_0_size) { - memcpy(bnext, p->oem_area_0, p->oem_area_0_size); - bnext += p->oem_area_0_size; - } - - /* Copy datakey */ - memcpy(bnext, p->datakey, p->datakey->struct_size); - bnext += p->datakey->struct_size; - - /* - * Create header signature using private BDB key. - * - * TODO: create the header signature in a totally separate step. That - * way, the private BDB key is not required each time a BDB is created. - */ - sig = bdb_create_sig(oem, h->signed_size, p->private_bdbkey, - p->bdbkey->sig_alg, p->header_sig_description); - memcpy(bnext, sig, sig->struct_size); - bnext += sig->struct_size; - - /* Fill in the data */ - data = (struct bdb_data *)bnext; - data->struct_magic = BDB_DATA_MAGIC; - data->struct_major_version = BDB_DATA_VERSION_MAJOR; - data->struct_minor_version = BDB_DATA_VERSION_MINOR; - data->struct_size = sizeof(struct bdb_data); - data->data_version = p->data_version; - data->oem_area_1_size = p->oem_area_1_size; - data->num_hashes = p->num_hashes; - data->hash_entry_size = sizeof(struct bdb_hash); - data->signed_size = data->struct_size + data->oem_area_1_size + - hashes_size; - if (p->data_description) { - strzcpy(data->description, p->data_description, - sizeof(data->description)); - } - bnext += data->struct_size; - - /* Copy OEM area 1 */ - oem = bnext; - if (p->oem_area_1_size) { - memcpy(bnext, p->oem_area_1, p->oem_area_1_size); - bnext += p->oem_area_1_size; - } - - /* Copy hashes */ - memcpy(bnext, p->hash, hashes_size); - bnext += hashes_size; - - /* Create data signature using private datakey */ - sig = bdb_create_sig(data, data->signed_size, p->private_datakey, - p->datakey->sig_alg, p->data_sig_description); - memcpy(bnext, sig, sig->struct_size); - - /* Return the BDB */ - return h; -} diff --git a/firmware/bdb/host.h b/firmware/bdb/host.h deleted file mode 100644 index 105d668c..00000000 --- a/firmware/bdb/host.h +++ /dev/null @@ -1,191 +0,0 @@ -/* 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. - * - * Boot descriptor block host functions - */ - -#ifndef VBOOT_REFERENCE_BDB_HOST_H_ -#define VBOOT_REFERENCE_BDB_HOST_H_ - -#include <stdlib.h> -#include <openssl/pem.h> -#include "bdb_struct.h" - -/*****************************************************************************/ -/* -Expected calling sequence: - -Load and check just the header -bdb_check_header(buf, size); - -Load and verify the entire BDB -bdb_verify(buf, size, bdb_key_hash, dev_mode_flag); - - bdb_check_header() again - paranoia against bad storage devices - - bdb_check_key() on BDB key - bdb_sha256() on BDB key - Compare with appropriate root key hash - If dev_mode_flag(), mismatch is not fatal - - bdb_check_sig() on BDB header sig - bdb_sha256() on OEM area 1, RW datakey - bdb_rsa_verify() on digest using BDB key - - bdb_check_key() on RW datakey - - bdb_check_data() on RW data - bdb_check_sig() on data sig - bdb_sha256() on data, OEM area 1, hashes - bdb_rsa_verify() on digest using RW datakey - -Check RW datakey version. If normal boot from primary BDB, roll forward -Check data version. If normal boot from primary BDB, roll forward -*/ - -/*****************************************************************************/ -/* Codes for functions returning numeric error codes */ - -enum bdb_host_return_code { - /* All/any of bdb_return_code, and the following... */ - - /* Other errors */ - BDB_ERROR_HOST = 200, -}; - -/*****************************************************************************/ -/* Functions */ - -/** - * Like strncpy, but guaranteeing null termination - */ -char *strzcpy(char *dest, const char *src, size_t size); - -/** - * Read a file. - * - * Caller must free() the returned buffer. - * - * @param filename Path to file - * @param size_ptr Destination for size of buffer - * @return A newly allocated buffer containing the data, or NULL if error. - */ -uint8_t *read_file(const char *filename, uint32_t *size_ptr); - -/** - * Write a file. - * - * @param buf Data to write - * @param size Size of data in bytes - * @return 0 if success, non-zero error code if error. - */ -int write_file(const char *filename, const void *buf, uint32_t size); - -/** - * Read a PEM from a file. - * - * Caller must free the PEM with RSA_free(). - * - * @param filename Path to file - * @return A newly allocated PEM object, or NULL if error. - */ -struct rsa_st *read_pem(const char *filename); - -/** - * Create a BDB public key object. - * - * Caller must free() the returned key. - * - * @param filename Path to file containing public key (.keyb) - * @param key_version Version for key - * @param desc Description. Optional; may be NULL. - * @return A newly allocated public key, or NULL if error. - */ -struct bdb_key *bdb_create_key(const char *filename, - uint32_t key_version, - const char *desc); - -/** - * Create a BDB signature object. - * - * Caller must free() the returned signature. - * - * @param data Data to sign - * @param size Size of data in bytes - * @param key PEM key - * @param sig_alg Signature algorithm - * @param desc Description. Optional; may be NULL. - * @return A newly allocated signature, or NULL if error. - */ -struct bdb_sig *bdb_create_sig(const void *data, - size_t size, - struct rsa_st *key, - uint32_t sig_alg, - const char *desc); - -struct bdb_create_params -{ - /* Load address */ - uint64_t bdb_load_address; - - /* OEM areas. Size may be 0, in which case the buffer is ignored */ - uint8_t *oem_area_0; - uint32_t oem_area_0_size; - uint8_t *oem_area_1; - uint32_t oem_area_1_size; - - /* Public BDB key and datakey */ - struct bdb_key *bdbkey; - struct bdb_key *datakey; - - /* Private BDB key and datakey */ - struct rsa_st *private_bdbkey; - struct rsa_st *private_datakey; - - /* Descriptions for header and data signatures */ - char *header_sig_description; - char *data_sig_description; - - /* Data description and version */ - char *data_description; - uint32_t data_version; - - /* Data hashes and count */ - struct bdb_hash *hash; - uint32_t num_hashes; -}; - -/** - * Sign data key in BDB - * - * @param bdb (IN/OUT) Buffer is freed upon successful call. Caller is - * responsible for freeing the newly allocated buffer. - * @param key Private BDB key to be signed with - * @return BDB_SUCCESS on success or BDB_ERROR_* otherwise. - */ -int bdb_sign_datakey(uint8_t **bdb, struct rsa_st *key); - -/** - * Sign data section of BDB - * - * @param bdb (IN/OUT) Buffer is freed upon successful call. Caller is - * responsible for freeing the newly allocated buffer. - * @param key Private data key to be signed with - * @return BDB_SUCCESS on success or BDB_ERROR_* otherwise. - */ -int bdb_sign_data(uint8_t **bdb, struct rsa_st *key); - -/** - * Create a new BDB - * - * Caller must free() returned object. - * - * @param p Creation parameters - * @return A newly allocated BDB, or NULL if error. - */ -struct bdb_header *bdb_create(struct bdb_create_params *p); - -/*****************************************************************************/ - -#endif /* VBOOT_REFERENCE_BDB_HOST_H_ */ diff --git a/firmware/bdb/misc.c b/firmware/bdb/misc.c deleted file mode 100644 index fd3e0c9b..00000000 --- a/firmware/bdb/misc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright 2016 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. - */ - -#include <stdint.h> -#include "bdb.h" -#include "bdb_api.h" -#include "vboot_register.h" - -static int did_current_slot_fail(struct vba_context *ctx) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - if (ctx->slot) - return val & VBOOT_REGISTER_FAILED_RW_SECONDARY; - else - return val & VBOOT_REGISTER_FAILED_RW_PRIMARY; -} - -static int did_other_slot_fail(struct vba_context *ctx) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - if (ctx->slot) - return val & VBOOT_REGISTER_FAILED_RW_PRIMARY; - else - return val & VBOOT_REGISTER_FAILED_RW_SECONDARY; -} - -static void set_try_other_slot(struct vba_context *ctx) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - if (ctx->slot) - val &= ~VBOOT_REGISTER_TRY_SECONDARY_BDB; - else - val |= VBOOT_REGISTER_TRY_SECONDARY_BDB; - - vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val); -} - -static void set_recovery_request(struct vba_context *ctx) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - val |= VBOOT_REGISTER_RECOVERY_REQUEST; - - vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val); -} - -static void get_current_slot(struct vba_context *ctx) -{ - /* Assume SP-RO selects slot this way */ - ctx->slot = (vbe_get_vboot_register(VBOOT_REGISTER_PERSIST) - & VBOOT_REGISTER_TRY_SECONDARY_BDB) ? 1 : 0; -} - -static void set_current_slot_failed(struct vba_context *ctx) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - if (ctx->slot) - val |= VBOOT_REGISTER_FAILED_RW_SECONDARY; - else - val |= VBOOT_REGISTER_FAILED_RW_PRIMARY; - - vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val); -} - -static void unset_current_slot_failed(struct vba_context *ctx) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - if (ctx->slot) - val &= ~VBOOT_REGISTER_FAILED_RW_SECONDARY; - else - val &= ~VBOOT_REGISTER_FAILED_RW_PRIMARY; - - vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val); -} - -int vba_bdb_init(struct vba_context *ctx) -{ - /* Get current slot */ - get_current_slot(ctx); - - /* Check current slot failed or not at the last boot */ - if (!did_current_slot_fail(ctx)) { - /* If not, we try this slot. Prepare for any accidents */ - set_current_slot_failed(ctx); - return BDB_SUCCESS; - } - - /* Check other slot failed or not at the previous boot */ - if (!did_other_slot_fail(ctx)) { - /* If not, we try the other slot after reboot. */ - set_try_other_slot(ctx); - return BDB_ERROR_TRY_OTHER_SLOT; - } else { - /* Otherwise, both slots are bad. Reboot to recovery */ - set_recovery_request(ctx); - return BDB_ERROR_RECOVERY_REQUEST; - } -} - -int vba_bdb_finalize(struct vba_context *ctx) -{ - /* Mark the current slot good */ - unset_current_slot_failed(ctx); - - /* Disable NVM bus */ - - return BDB_SUCCESS; -} - -void vba_bdb_fail(struct vba_context *ctx) -{ - /* We can do some logging here if we want */ - - /* Unconditionally reboot. FailedRW flag is already set. - * At the next boot, bdb_init will decide what to do. */ - vbe_reset(); -} diff --git a/firmware/bdb/nvm.c b/firmware/bdb/nvm.c deleted file mode 100644 index 85c301a2..00000000 --- a/firmware/bdb/nvm.c +++ /dev/null @@ -1,346 +0,0 @@ -/* Copyright 2016 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. - */ - -#include "2sysincludes.h" -#include "2hmac.h" -#include "2sha.h" -#include "bdb_api.h" -#include "bdb_struct.h" -#include "bdb.h" -#include "nvm.h" -#include "secrets.h" - -static int nvmrw_validate(const void *buf, uint32_t size) -{ - const struct nvmrw *nvm = buf; - - if (nvm->struct_magic != NVM_RW_MAGIC) - return BDB_ERROR_NVM_RW_MAGIC; - - if (nvm->struct_major_version != NVM_HEADER_VERSION_MAJOR) - return BDB_ERROR_NVM_STRUCT_VERSION; - - if (size < nvm->struct_size) - return BDB_ERROR_NVM_STRUCT_SIZE; - - /* - * We allow any sizes between min and max so that we can handle minor - * version mismatches. Reader can be older than data or the other way - * around. FW in slot B can upgrade NVM-RW but fails to qualify as a - * stable boot path. Then, FW in slot A is invoked which is older than - * the NVM-RW written by FW in slot B. - */ - if (nvm->struct_size < NVM_RW_MIN_STRUCT_SIZE || - NVM_RW_MAX_STRUCT_SIZE < nvm->struct_size) - return BDB_ERROR_NVM_STRUCT_SIZE; - - return BDB_SUCCESS; -} - -static int nvmrw_verify(const struct bdb_secrets *secrets, - const struct nvmrw *nvm, uint32_t size) -{ - uint8_t mac[NVM_HMAC_SIZE]; - int rv; - - if (!secrets || !nvm) - return BDB_ERROR_NVM_INVALID_PARAMETER; - - rv = nvmrw_validate(nvm, size); - if (rv) - return rv; - - /* Compute and verify HMAC */ - if (hmac(VB2_HASH_SHA256, secrets->nvm_rw, BDB_SECRET_SIZE, - nvm, nvm->struct_size - sizeof(mac), mac, sizeof(mac))) - return BDB_ERROR_NVM_RW_HMAC; - /* TODO: Use safe_memcmp */ - if (memcmp(mac, nvm->hmac, sizeof(mac))) - return BDB_ERROR_NVM_RW_INVALID_HMAC; - - return BDB_SUCCESS; -} - -int nvmrw_write(struct vba_context *ctx, enum nvm_type type) -{ - struct nvmrw *nvm = &ctx->nvmrw; - int retry = NVM_MAX_WRITE_RETRY; - int rv; - - if (!ctx) - return BDB_ERROR_NVM_INVALID_PARAMETER; - - if (!ctx->secrets) - return BDB_ERROR_NVM_INVALID_SECRET; - - rv = nvmrw_validate(nvm, sizeof(*nvm)); - if (rv) - return rv; - - /* Update HMAC */ - hmac(VB2_HASH_SHA256, ctx->secrets->nvm_rw, BDB_SECRET_SIZE, - nvm, nvm->struct_size - sizeof(nvm->hmac), - nvm->hmac, sizeof(nvm->hmac)); - - while (retry--) { - uint8_t buf[sizeof(struct nvmrw)]; - if (vbe_write_nvm(type, nvm, nvm->struct_size)) - continue; - if (vbe_read_nvm(type, buf, sizeof(buf))) - continue; - if (memcmp(buf, nvm, sizeof(buf))) - continue; - /* Write success */ - return BDB_SUCCESS; - } - - /* NVM seems corrupted. Go to chip recovery mode */ - return BDB_ERROR_NVM_WRITE; -} - -static int read_verify_nvmrw(enum nvm_type type, - const struct bdb_secrets *secrets, - uint8_t *buf, uint32_t buf_size) -{ - struct nvmrw *nvm = (struct nvmrw *)buf; - int rv; - - /* Read minimum amount */ - if (vbe_read_nvm(type, buf, NVM_MIN_STRUCT_SIZE)) - return BDB_ERROR_NVM_VBE_READ; - - /* Validate the content */ - rv = nvmrw_validate(buf, buf_size); - if (rv) - return rv; - - /* Read full body */ - if (vbe_read_nvm(type, buf, nvm->struct_size)) - return BDB_ERROR_NVM_VBE_READ; - - /* Verify the content */ - rv = nvmrw_verify(secrets, nvm, sizeof(*nvm)); - return rv; - - return BDB_SUCCESS; -} - -int nvmrw_read(struct vba_context *ctx) -{ - uint8_t buf1[NVM_RW_MAX_STRUCT_SIZE]; - uint8_t buf2[NVM_RW_MAX_STRUCT_SIZE]; - struct nvmrw *nvm1 = (struct nvmrw *)buf1; - struct nvmrw *nvm2 = (struct nvmrw *)buf2; - int rv1, rv2; - - /* Read and verify the 1st copy */ - rv1 = read_verify_nvmrw(NVM_TYPE_RW_PRIMARY, ctx->secrets, - buf1, sizeof(buf1)); - - /* Read and verify the 2nd copy */ - rv2 = read_verify_nvmrw(NVM_TYPE_RW_SECONDARY, ctx->secrets, - buf2, sizeof(buf2)); - - if (rv1 == BDB_SUCCESS && rv2 == BDB_SUCCESS) { - /* Sync primary and secondary based on update_count. */ - if (nvm1->update_count > nvm2->update_count) - rv2 = !BDB_SUCCESS; - else if (nvm1->update_count < nvm2->update_count) - rv1 = !BDB_SUCCESS; - } else if (rv1 != BDB_SUCCESS && rv2 != BDB_SUCCESS){ - /* Abort. Neither was successful. */ - return rv1; - } - - if (rv1 == BDB_SUCCESS) - /* both copies are good. use primary copy */ - memcpy(&ctx->nvmrw, buf1, sizeof(ctx->nvmrw)); - else - /* primary is bad but secondary is good. */ - memcpy(&ctx->nvmrw, buf2, sizeof(ctx->nvmrw)); - - if (ctx->nvmrw.struct_minor_version != NVM_HEADER_VERSION_MINOR) { - /* - * Upgrade or downgrade is required. So, we need to write both. - * When upgrading, this is the place where new fields should be - * initialized. We don't increment update_count. - */ - ctx->nvmrw.struct_minor_version = NVM_HEADER_VERSION_MINOR; - ctx->nvmrw.struct_size = sizeof(ctx->nvmrw); - /* We don't worry about calculating hmac twice because - * this is a corner case. */ - rv1 = nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY); - rv2 = nvmrw_write(ctx, NVM_TYPE_RW_SECONDARY); - } else if (rv1 != BDB_SUCCESS) { - /* primary copy is bad. sync it with secondary copy */ - rv1 = nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY); - } else if (rv2 != BDB_SUCCESS){ - /* secondary copy is bad. sync it with primary copy */ - rv2 = nvmrw_write(ctx, NVM_TYPE_RW_SECONDARY); - } else { - /* Both copies are good and versions are same as the reader. - * Skip writing. This should be the common case. */ - } - - if (rv1 || rv2) - return rv1 ? rv1 : rv2; - - return BDB_SUCCESS; -} - -static int nvmrw_init(struct vba_context *ctx) -{ - if (nvmrw_read(ctx)) - return BDB_ERROR_NVM_INIT; - - return BDB_SUCCESS; -} - -int vba_update_kernel_version(struct vba_context *ctx, - uint32_t kernel_data_key_version, - uint32_t kernel_version) -{ - struct nvmrw *nvm = &ctx->nvmrw; - - if (nvmrw_verify(ctx->secrets, nvm, sizeof(*nvm))) { - if (nvmrw_init(ctx)) - return BDB_ERROR_NVM_INIT; - } - - if (nvm->min_kernel_data_key_version < kernel_data_key_version || - nvm->min_kernel_version < kernel_version) { - int rv1, rv2; - - /* Roll forward versions */ - nvm->min_kernel_data_key_version = kernel_data_key_version; - nvm->min_kernel_version = kernel_version; - - /* Increment update counter */ - nvm->update_count++; - - /* Update both copies */ - rv1 = nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY); - rv2 = nvmrw_write(ctx, NVM_TYPE_RW_SECONDARY); - if (rv1 || rv2) - return BDB_ERROR_RECOVERY_REQUEST; - } - - return BDB_SUCCESS; -} - -int vba_update_buc(struct vba_context *ctx, uint8_t *new_buc) -{ - struct nvmrw *nvm = &ctx->nvmrw; - uint8_t buc[BUC_ENC_DIGEST_SIZE]; - int rv1, rv2; - - if (nvmrw_verify(ctx->secrets, nvm, sizeof(*nvm))) { - if (nvmrw_init(ctx)) - return BDB_ERROR_NVM_INIT; - } - - /* Encrypt new BUC - * Note that we do not need to decide whether we should use hardware - * crypto or not because this is supposed to be running in RW code. */ - if (vbe_aes256_encrypt(new_buc, BUC_ENC_DIGEST_SIZE, - ctx->secrets->buc, buc)) - return BDB_ERROR_ENCRYPT_BUC; - - /* Return if new BUC is same as current one. */ - if (!memcmp(buc, nvm->buc_enc_digest, sizeof(buc))) - return BDB_SUCCESS; - - memcpy(nvm->buc_enc_digest, buc, sizeof(buc)); - - /* Increment update counter */ - nvm->update_count++; - - /* Write new BUC */ - rv1 = nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY); - rv2 = nvmrw_write(ctx, NVM_TYPE_RW_SECONDARY); - if (rv1 || rv2) - return BDB_ERROR_WRITE_BUC; - - return BDB_SUCCESS; -} - -int nvmrw_get(struct vba_context *ctx, enum nvmrw_var var, uint32_t *val) -{ - struct nvmrw *nvm = &ctx->nvmrw; - - /* No init or verify so that this can be called from futility. - * Callers are responsible for init and verify. */ - - switch (var) { - case NVMRW_VAR_UPDATE_COUNT: - *val = nvm->update_count; - break; - case NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION: - *val = nvm->min_kernel_data_key_version; - break; - case NVMRW_VAR_MIN_KERNEL_VERSION: - *val = nvm->min_kernel_version; - break; - case NVMRW_VAR_BUC_TYPE: - *val = nvm->buc_type; - break; - case NVMRW_VAR_FLAG_BUC_PRESENT: - *val = nvm->flags & NVM_RW_FLAG_BUC_PRESENT; - break; - case NVMRW_VAR_FLAG_DFM_DISABLE: - *val = nvm->flags & NVM_RW_FLAG_DFM_DISABLE; - break; - case NVMRW_VAR_FLAG_DOSM: - *val = nvm->flags & NVM_RW_FLAG_DOSM; - break; - default: - return BDB_ERROR_NVM_INVALID_PARAMETER; - } - - return BDB_SUCCESS; -} - -#define MAX_8BIT_UINT ((((uint64_t)1) << 8) - 1) - -int nvmrw_set(struct vba_context *ctx, enum nvmrw_var var, uint32_t val) -{ - struct nvmrw *nvm = &ctx->nvmrw; - - /* No init or verify so that this can be called from futility. - * Callers are responsible for init and verify. */ - - switch (var) { - case NVMRW_VAR_UPDATE_COUNT: - nvm->update_count = val; - break; - case NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION: - nvm->min_kernel_data_key_version = val; - break; - case NVMRW_VAR_MIN_KERNEL_VERSION: - nvm->min_kernel_version = val; - break; - case NVMRW_VAR_BUC_TYPE: - if (val > MAX_8BIT_UINT) - return BDB_ERROR_NVM_INVALID_PARAMETER; - nvm->buc_type = val; - break; - case NVMRW_VAR_FLAG_BUC_PRESENT: - nvm->flags &= ~NVM_RW_FLAG_BUC_PRESENT; - nvm->flags |= val ? NVM_RW_FLAG_BUC_PRESENT : 0; - break; - case NVMRW_VAR_FLAG_DFM_DISABLE: - nvm->flags &= ~NVM_RW_FLAG_DFM_DISABLE; - nvm->flags |= val ? NVM_RW_FLAG_DFM_DISABLE : 0; - break; - case NVMRW_VAR_FLAG_DOSM: - nvm->flags &= ~NVM_RW_FLAG_DOSM; - nvm->flags |= val ? NVM_RW_FLAG_DOSM : 0; - break; - default: - return BDB_ERROR_NVM_INVALID_PARAMETER; - } - - return BDB_SUCCESS; -} diff --git a/firmware/bdb/nvm.h b/firmware/bdb/nvm.h deleted file mode 100644 index c0a55402..00000000 --- a/firmware/bdb/nvm.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2016 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. - */ - -#ifndef VBOOT_REFERENCE_BDB_NVM_H_ -#define VBOOT_REFERENCE_BDB_NVM_H_ - -#include <stdint.h> -#include "bdb_struct.h" -#include "bdb_api.h" - -enum nvm_type { - NVM_TYPE_WP_PRIMARY, - NVM_TYPE_WP_SECONDARY, - NVM_TYPE_RW_PRIMARY, - NVM_TYPE_RW_SECONDARY, -}; - -#define NVM_RW_MAGIC 0x3052766e - -/* Size in bytes of encrypted BUC (Boot Unlock Code) */ -#define BUC_ENC_DIGEST_SIZE 32 -/* Size in bytes of HMAC of struct NVM-RW */ -#define NVM_HMAC_SIZE BDB_SHA256_DIGEST_SIZE - -#define NVM_RW_FLAG_BUC_PRESENT (1 << 0) -#define NVM_RW_FLAG_DFM_DISABLE (1 << 1) -#define NVM_RW_FLAG_DOSM (1 << 2) - -/* This is the minimum size of the data needed to learn the actual size */ -#define NVM_MIN_STRUCT_SIZE 8 - -#define NVM_HEADER_VERSION_MAJOR 1 -#define NVM_HEADER_VERSION_MINOR 1 - -/* Maximum number of retries for writing NVM */ -#define NVM_MAX_WRITE_RETRY 2 - -struct nvmrw { - /* Magic number to identify struct */ - uint32_t struct_magic; - - /* Structure version */ - uint8_t struct_major_version; - uint8_t struct_minor_version; - - /* Size of struct in bytes. 96 for version 1.0 */ - uint16_t struct_size; - - /* Number of updates to structure contents */ - uint32_t update_count; - - /* Flags: NVM_RW_FLAG_* */ - uint32_t flags; - - /* Minimum valid kernel data key version */ - uint32_t min_kernel_data_key_version; - - /* Minimum valid kernel version */ - uint32_t min_kernel_version; - - /* Type of BUC */ - uint8_t buc_type; - - uint8_t reserved0[7]; - - /* Encrypted BUC */ - uint8_t buc_enc_digest[BUC_ENC_DIGEST_SIZE]; - - /* SHA-256 HMAC of the struct contents. Add new fields before this. */ - uint8_t hmac[NVM_HMAC_SIZE]; -} __attribute__((packed)); - -/* - * List of variables stored in NVM-RW. This should be exported and used by - * firmware and futility to access data in NVM-RW. - */ -enum nvmrw_var { - NVMRW_VAR_UPDATE_COUNT, - NVMRW_VAR_FLAGS, - NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION, - NVMRW_VAR_MIN_KERNEL_VERSION, - NVMRW_VAR_BUC_TYPE, - NVMRW_VAR_FLAG_BUC_PRESENT, - NVMRW_VAR_FLAG_DFM_DISABLE, - NVMRW_VAR_FLAG_DOSM, -}; - -/* Size of the version 1.0 */ -#define NVM_RW_MIN_STRUCT_SIZE 96 -/* 4 Kbit EEPROM divided by 4 regions (RO,RW) x (1st,2nd) = 128 KB */ -#define NVM_RW_MAX_STRUCT_SIZE 128 - -/* For nvm_rw_read and nvm_write */ -struct vba_context; - -/** - * Read NVM-RW contents into the context - * - * @param ctx struct vba_context - * @return BDB_SUCCESS or BDB_ERROR_NVM_* - */ -int nvmrw_read(struct vba_context *ctx); - -/** - * Write to NVM-RW from the context - * - * @param ctx struct vba_context - * @param type NVM_TYPE_RW_* - * @return BDB_SUCCESS or BDB_ERROR_NVM_* - */ -int nvmrw_write(struct vba_context *ctx, enum nvm_type type); - -/** - * Get a value of NVM-RW variable - * - * Callers are responsible for init and verify of ctx->nvmrw. - * - * @param ctx struct vba_context - * @param var Index of the variable - * @param val Destination where the value is stored - * @return BDB_SUCCESS or BDB_ERROR_NVM_* - */ -int nvmrw_get(struct vba_context *ctx, enum nvmrw_var var, uint32_t *val); - -/** - * Set a value in NVM-RW variable - * - * Callers are responsible for init and verify of ctx->nvmrw. - * - * @param ctx struct vba_context - * @param var Index of the variable - * @param val Value to be set - * @return BDB_SUCCESS or BDB_ERROR_NVM_* - */ -int nvmrw_set(struct vba_context *ctx, enum nvmrw_var var, uint32_t val); - -#endif diff --git a/firmware/bdb/rsa.c b/firmware/bdb/rsa.c deleted file mode 100644 index 35bfcb47..00000000 --- a/firmware/bdb/rsa.c +++ /dev/null @@ -1,337 +0,0 @@ -/* Copyright 2016 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. - * - * Boot descriptor block firmware RSA - */ - -#include <string.h> -#include "bdb.h" - -/* Public key structure in RAM */ -struct public_key { - uint32_t arrsize; /* Size of n[] and rr[] arrays in elements */ - uint32_t n0inv; /* -1 / n[0] mod 2^32 */ - const uint32_t *n; /* Modulus as little endian array */ - const uint32_t *rr; /* R^2 as little endian array */ -}; - -/** - * a[] -= mod - */ -static void subM(const struct public_key *key, uint32_t *a) -{ - int64_t A = 0; - uint32_t i; - for (i = 0; i < key->arrsize; ++i) { - A += (uint64_t)a[i] - key->n[i]; - a[i] = (uint32_t)A; - A >>= 32; - } -} - -/** - * Return a[] >= mod - */ -static int mont_ge(const struct public_key *key, uint32_t *a) -{ - uint32_t i; - for (i = key->arrsize; i;) { - --i; - if (a[i] < key->n[i]) - return 0; - if (a[i] > key->n[i]) - return 1; - } - return 1; /* equal */ -} - -/** - * Montgomery c[] += a * b[] / R % mod - */ -static void montMulAdd(const struct public_key *key, - uint32_t *c, - const uint32_t a, - const uint32_t *b) -{ - uint64_t A = (uint64_t)a * b[0] + c[0]; - uint32_t d0 = (uint32_t)A * key->n0inv; - uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A; - uint32_t i; - - for (i = 1; i < key->arrsize; ++i) { - A = (A >> 32) + (uint64_t)a * b[i] + c[i]; - B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A; - c[i - 1] = (uint32_t)B; - } - - A = (A >> 32) + (B >> 32); - - c[i - 1] = (uint32_t)A; - - if (A >> 32) { - subM(key, c); - } -} - -/** - * Montgomery c[] = a[] * b[] / R % mod - */ -static void montMul(const struct public_key *key, - uint32_t *c, - const uint32_t *a, - const uint32_t *b) -{ - uint32_t i; - for (i = 0; i < key->arrsize; ++i) { - c[i] = 0; - } - for (i = 0; i < key->arrsize; ++i) { - montMulAdd(key, c, a[i], b); - } -} - -static int safe_memcmp(const void *s1, const void *s2, size_t size) -{ - const unsigned char *us1 = s1; - const unsigned char *us2 = s2; - int result = 0; - - if (0 == size) - return 0; - - /* - * Code snippet without data-dependent branch due to Nate Lawson - * (nate@root.org) of Root Labs. - */ - while (size--) - result |= *us1++ ^ *us2++; - - return result != 0; -} - -/* - * PKCS 1.5 padding (from the RSA PKCS#1 v2.1 standard) - * - * Depending on the RSA key size and hash function, the padding is calculated - * as follows: - * - * 0x00 || 0x01 || PS || 0x00 || T - * - * T: DER Encoded DigestInfo value which depends on the hash function used. - * - * SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H. - * - * Length(T) = 51 octets for SHA-256 - * - * PS: octet string consisting of {Length(RSA Key) - Length(T) - 3} 0xFF - */ -static const uint8_t sha256_tail[] = { - 0x00,0x30,0x31,0x30,0x0d,0x06,0x09,0x60, - 0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, - 0x05,0x00,0x04,0x20 -}; - -static int check_padding(const uint8_t *sig, const struct public_key *key, - uint32_t pad_size) -{ - /* Determine padding to use depending on the signature type */ - const uint32_t tail_size = sizeof(sha256_tail); - int result = 0; - int i; - - /* First 2 bytes are always 0x00 0x01 */ - result |= *sig++ ^ 0x00; - result |= *sig++ ^ 0x01; - - /* Then 0xff bytes until the tail */ - for (i = 0; i < pad_size - tail_size - 2; i++) - result |= *sig++ ^ 0xff; - - /* - * Then the tail. Even though there are probably no timing issues - * here, we use safe_memcmp() just to be on the safe side. - */ - result |= safe_memcmp(sig, sha256_tail, tail_size); - - return result ? BDB_ERROR_DIGEST : BDB_SUCCESS; -} - -/* Array size for RSA4096 */ -#define ARRSIZE4096 (4096 / 32) - -/** - * In-place public exponentiation. (exponent 65537, key size 4096 bits) - * - * @param key Key to use in signing - * @param inout Input and output big-endian byte array - */ -static void modpowF4(const struct public_key *key, uint8_t *inout) -{ - uint32_t a[ARRSIZE4096]; - uint32_t aR[ARRSIZE4096]; - uint32_t aaR[ARRSIZE4096]; - uint32_t *aaa = aaR; /* Re-use location. */ - int i; - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0; i < ARRSIZE4096; ++i) { - uint32_t tmp = - (inout[((ARRSIZE4096 - 1 - i) * 4) + 0] << 24) | - (inout[((ARRSIZE4096 - 1 - i) * 4) + 1] << 16) | - (inout[((ARRSIZE4096 - 1 - i) * 4) + 2] << 8) | - (inout[((ARRSIZE4096 - 1 - i) * 4) + 3] << 0); - a[i] = tmp; - } - - montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ - for (i = 0; i < 16; i+=2) { - montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ - montMul(key, aR, aaR, aaR); /* aR = aaR * aaR / R mod M */ - } - montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */ - - /* Make sure aaa < mod; aaa is at most 1x mod too large. */ - if (mont_ge(key, aaa)) { - subM(key, aaa); - } - - /* Convert to bigendian byte array */ - for (i = ARRSIZE4096 - 1; i >= 0; --i) { - uint32_t tmp = aaa[i]; - *inout++ = (uint8_t)(tmp >> 24); - *inout++ = (uint8_t)(tmp >> 16); - *inout++ = (uint8_t)(tmp >> 8); - *inout++ = (uint8_t)(tmp >> 0); - } -} - -int bdb_rsa4096_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest) -{ - const uint32_t *kdata32 = (const uint32_t *)key_data; - struct public_key key; - uint8_t sig_work[BDB_RSA4096_SIG_SIZE]; - uint32_t pad_size; - int rv; - - /* Unpack key */ - if (kdata32[0] != ARRSIZE4096) - return BDB_ERROR_DIGEST; /* Wrong key size */ - - key.arrsize = kdata32[0]; - key.n0inv = kdata32[1]; - key.n = kdata32 + 2; - key.rr = kdata32 + 2 + key.arrsize; - - /* Copy signature to work buffer */ - memcpy(sig_work, sig, sizeof(sig_work)); - - modpowF4(&key, sig_work); - - /* - * Check padding. Continue on to check the digest even if error to - * reduce the risk of timing based attacks. - */ - pad_size = key.arrsize * sizeof(uint32_t) - BDB_SHA256_DIGEST_SIZE; - rv = check_padding(sig_work, &key, pad_size); - - /* - * Check digest. Even though there are probably no timing issues here, - * use safe_memcmp() just to be on the safe side. (That's also why - * we don't return before this check if the padding check failed.) - */ - if (safe_memcmp(sig_work + pad_size, digest, BDB_SHA256_DIGEST_SIZE)) - rv = BDB_ERROR_DIGEST; - - return rv; -} - -/* Array size for RSA3072B */ -#define ARRSIZE3072B (3072 / 32) - -/** - * In-place public exponentiation. (exponent 3, key size 3072 bits) - * - * @param key Key to use in signing - * @param inout Input and output big-endian byte array - */ -static void modpow3(const struct public_key *key, uint8_t *inout) -{ - uint32_t a[ARRSIZE3072B]; - uint32_t aR[ARRSIZE3072B]; - uint32_t aaR[ARRSIZE3072B]; - uint32_t *aaa = aR; /* Re-use location */ - int i; - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0; i < ARRSIZE3072B; ++i) { - uint32_t tmp = - (inout[((ARRSIZE3072B - 1 - i) * 4) + 0] << 24) | - (inout[((ARRSIZE3072B - 1 - i) * 4) + 1] << 16) | - (inout[((ARRSIZE3072B - 1 - i) * 4) + 2] << 8) | - (inout[((ARRSIZE3072B - 1 - i) * 4) + 3] << 0); - a[i] = tmp; - } - - montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ - montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ - montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */ - - /* Make sure aaa < mod; aaa is at most 1x mod too large. */ - if (mont_ge(key, aaa)) { - subM(key, aaa); - } - - /* Convert to bigendian byte array */ - for (i = ARRSIZE3072B - 1; i >= 0; --i) { - uint32_t tmp = aaa[i]; - *inout++ = (uint8_t)(tmp >> 24); - *inout++ = (uint8_t)(tmp >> 16); - *inout++ = (uint8_t)(tmp >> 8); - *inout++ = (uint8_t)(tmp >> 0); - } -} - -int bdb_rsa3072b_verify(const uint8_t *key_data, - const uint8_t *sig, - const uint8_t *digest) -{ - const uint32_t *kdata32 = (const uint32_t *)key_data; - struct public_key key; - uint8_t sig_work[BDB_RSA3072B_SIG_SIZE]; - uint32_t pad_size; - int rv; - - /* Unpack key */ - if (kdata32[0] != ARRSIZE3072B) - return BDB_ERROR_DIGEST; /* Wrong key size */ - - key.arrsize = kdata32[0]; - key.n0inv = kdata32[1]; - key.n = kdata32 + 2; - key.rr = kdata32 + 2 + key.arrsize; - - /* Copy signature to work buffer */ - memcpy(sig_work, sig, sizeof(sig_work)); - - modpow3(&key, sig_work); - - /* - * Check padding. Continue on to check the digest even if error to - * reduce the risk of timing based attacks. - */ - pad_size = key.arrsize * sizeof(uint32_t) - BDB_SHA256_DIGEST_SIZE; - rv = check_padding(sig_work, &key, pad_size); - - /* - * Check digest. Even though there are probably no timing issues here, - * use safe_memcmp() just to be on the safe side. (That's also why - * we don't return before this check if the padding check failed.) - */ - if (safe_memcmp(sig_work + pad_size, digest, BDB_SHA256_DIGEST_SIZE)) - rv = BDB_ERROR_DIGEST; - - return rv; -} diff --git a/firmware/bdb/secrets.c b/firmware/bdb/secrets.c deleted file mode 100644 index bd6c6fcf..00000000 --- a/firmware/bdb/secrets.c +++ /dev/null @@ -1,330 +0,0 @@ -/* Copyright 2016 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. - */ - -#include "2sysincludes.h" -#include "2hmac.h" -#include "2sha.h" -#include "bdb_api.h" -#include "bdb_struct.h" -#include "bdb.h" -#include "secrets.h" - -const uint8_t secret_constant_a[] = { - 0xad, 0xf8, 0xd1, 0xd9, 0x48, 0xe6, 0xb3, 0xe4, 0xe0, 0xc4, - 0xd8, 0x66, 0x97, 0x95, 0x71, 0xa8, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x01}; - -const uint8_t secret_constant_b[] = { - 0xba, 0x9d, 0x1d, 0x8b, 0x12, 0xbd, 0x8d, 0xcd, 0x4c, 0x89, - 0xd8, 0x18, 0x72, 0x98, 0xb5, 0x18, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x02}; - -const uint8_t secret_constant_x[] = { - 0xfd, 0xc1, 0xe5, 0x57, 0x34, 0xf4, 0xf6, 0x89, 0x6d, 0x1b, - 0x6f, 0xf2, 0xd0, 0x36, 0xdb, 0xf4, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x09}; - -const uint8_t secret_constant_y[] = { - 0x18, 0xef, 0x01, 0x8e, 0xcd, 0x62, 0xf1, 0xb0, 0x2d, 0xd4, - 0x11, 0xa4, 0xb5, 0x6e, 0x38, 0xf6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x0a}; - -const uint8_t secret_constant_c[] = { - 0x46, 0xda, 0x52, 0x8d, 0x08, 0x56, 0x14, 0xde, 0x75, 0x9c, - 0x9a, 0xeb, 0x08, 0x93, 0x3d, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x0b}; - -const uint8_t secret_constant_fv0[] = { - 0x93, 0x32, 0xf7, 0x8d, 0xec, 0x4b, 0x26, 0x2e, 0xb3, 0x5c, - 0x39, 0xd7, 0xfc, 0xc6, 0x9f, 0x09, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x05}; - -const uint8_t secret_constant_fv1[] = { - 0x60, 0x8d, 0x96, 0x35, 0xdf, 0xf6, 0x31, 0x67, 0xab, 0xb8, - 0x9f, 0x50, 0x81, 0x28, 0x82, 0xec, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x06}; - -const uint8_t secret_constant_kv0[] = { - 0x46, 0x6d, 0xef, 0x2c, 0x05, 0xc9, 0xbf, 0xa9, 0x6b, 0xee, - 0xaa, 0x6c, 0xb9, 0xb4, 0x6d, 0x37, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x07}; - -const uint8_t secret_constant_kv1[] = { - 0x0a, 0x9e, 0xc9, 0x20, 0x29, 0xa3, 0x5d, 0xd7, 0x27, 0x55, - 0xb6, 0xa6, 0xb4, 0x80, 0x7c, 0x73, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x08}; - -const uint8_t secret_constant_k[] = { - /* - * Digest of kernel data key struct fills first 32 bytes - */ - 0x1e, 0x1d, 0xec, 0xf2, 0x6d, 0x27, 0xa6, 0xd9, - 0x67, 0x0f, 0x34, 0xc5, 0xfa, 0x01, 0x68, 0xf6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x03}; - -const uint8_t secret_constant_l[] = { - /* - * Digest of kernel data key struct fills first 32 bytes - */ - 0x9b, 0xc0, 0x29, 0xd3, 0xc3, 0x90, 0x7f, 0x82, - 0x56, 0xe2, 0x67, 0x79, 0x11, 0x74, 0xbe, 0xd0, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x04}; - -const uint8_t secret_constant_p[] = { - /* - * Digest of KDB key struct fills first 32 bytes - */ - 0xfe, 0x31, 0xed, 0xed, 0x45, 0xfd, 0x8a, 0x5d, - 0x87, 0x90, 0xac, 0x17, 0x02, 0x89, 0x2c, 0xba, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x0c}; - -const uint8_t secret_constant_q[] = { - /* - * Digest of KDB key struct fills first 32 bytes - */ - 0xc7, 0x60, 0x83, 0x0f, 0x20, 0x44, 0x5d, 0x9c, - 0x70, 0x96, 0x05, 0x2d, 0x51, 0x4b, 0x15, 0x99, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0x0d}; - -/** - * Get constant with digest - * - * This function computes a digest of the given buffer and concatenates it - * to the given constant. - * - * @param buf Data from which a digest is computed - * @param buf_size Size of <buf> - * @param constant Buffer containing constant - * @param out Buffer where the result is stored - * @return BDB_SUCCESS on success or !BDB_SUCCESS otherwise - */ -static int get_constant_with_digest(const uint8_t *buf, uint32_t buf_size, - const uint8_t *constant, uint8_t *out) -{ - int digest_size = vb2_digest_size(VB2_HASH_SHA256); - const struct bdb_key *key = (const struct bdb_key *)buf; - - if (!buf) - return !BDB_SUCCESS; - - if (bdb_check_key(key, buf_size)) - return !BDB_SUCCESS; - - if (vb2_digest_buffer(buf, buf_size, VB2_HASH_SHA256, out, digest_size)) - return !BDB_SUCCESS; - - memcpy(out + digest_size, constant, - BDB_CONSTANT_BLOCK_SIZE - digest_size); - - return BDB_SUCCESS; -} - -/** - * Derive secrets for SP-RO - * - * This function extends a BDS to derive secrets as done by SP-RO (a.k.a. mask - * rom). - * - * @param ctx VBoot context - * @param type Type of secret to derive - * @param wsr Work secret register - * @param buf Data from which a digest is computed - * @param buf_size Size of <buf> - * @param extend sha256 extension function to be used - * @return BDB_SUCCESS on success or BDB_ERROR_* otherwise - */ -static int derive_secret_ro(struct vba_context *ctx, enum bdb_secret_type type, - uint8_t *wsr, const uint8_t *buf, uint32_t buf_size, - f_extend extend) -{ - uint8_t c[BDB_CONSTANT_BLOCK_SIZE]; - uint8_t *from; - const uint8_t *by = (const uint8_t *)c; - uint8_t *to; - - switch (type) { - case BDB_SECRET_TYPE_WSR: - from = to = wsr; - by = secret_constant_x; - break; - case BDB_SECRET_TYPE_BDB: - from = wsr; - to = ctx->secrets->bdb; - if (get_constant_with_digest(buf, buf_size, - secret_constant_p, c)) - return BDB_ERROR_SECRET_BDB; - break; - case BDB_SECRET_TYPE_BOOT_PATH: - from = wsr; - to = ctx->secrets->boot_path; - if (get_constant_with_digest(buf, buf_size, - secret_constant_k, c)) - return BDB_ERROR_SECRET_BOOT_PATH; - break; - case BDB_SECRET_TYPE_BOOT_VERIFIED: - from = wsr; - to = ctx->secrets->boot_verified; - if (ctx->flags & VBA_CONTEXT_FLAG_BDB_KEY_EFUSED) - by = secret_constant_fv0; - else - by = secret_constant_fv1; - break; - case BDB_SECRET_TYPE_NVM_WP: - from = wsr; - by = secret_constant_a; - to = ctx->secrets->nvm_wp; - break; - case BDB_SECRET_TYPE_NVM_RW: - from = ctx->secrets->nvm_wp; - by = secret_constant_b; - to = ctx->secrets->nvm_rw; - break; - default: - return BDB_ERROR_SECRET_TYPE; - } - - if (extend) - extend(from, by, to); - else - vb2_sha256_extend(from, by, to); - - return BDB_SUCCESS; -} - -int vba_derive_secret(struct vba_context *ctx, enum bdb_secret_type type, - uint8_t *wsr, const uint8_t *buf, uint32_t buf_size) -{ - uint8_t c[BDB_CONSTANT_BLOCK_SIZE]; - uint8_t *from; - const uint8_t *by = (const uint8_t *)c; - uint8_t *to; - - switch (type) { - case BDB_SECRET_TYPE_WSR: - from = to = wsr; - by = secret_constant_y; - break; - case BDB_SECRET_TYPE_BDB: - from = to = ctx->secrets->bdb; - if (get_constant_with_digest(buf, buf_size, - secret_constant_q, c)) - return BDB_ERROR_SECRET_BDB; - break; - case BDB_SECRET_TYPE_BOOT_PATH: - from = to = ctx->secrets->boot_path; - if (get_constant_with_digest(buf, buf_size, - secret_constant_l, c)) - return BDB_ERROR_SECRET_BOOT_PATH; - break; - case BDB_SECRET_TYPE_BOOT_VERIFIED: - from = to = ctx->secrets->boot_verified; - if (ctx->flags & VBA_CONTEXT_FLAG_KERNEL_DATA_KEY_VERIFIED) - by = secret_constant_kv1; - else - by = secret_constant_kv0; - break; - case BDB_SECRET_TYPE_BUC: - from = ctx->secrets->boot_verified; - by = secret_constant_c; - to = ctx->secrets->buc; - break; - default: - return BDB_ERROR_SECRET_TYPE; - } - - vb2_sha256_extend(from, by, to); - - return BDB_SUCCESS; -} - -int vba_clear_secret(struct vba_context *ctx, enum bdb_secret_type type) -{ - uint8_t *s; - - switch (type) { - case BDB_SECRET_TYPE_NVM_RW: - s = ctx->secrets->nvm_rw; - break; - case BDB_SECRET_TYPE_BDB: - s = ctx->secrets->bdb; - break; - case BDB_SECRET_TYPE_BOOT_PATH: - s = ctx->secrets->boot_path; - break; - case BDB_SECRET_TYPE_BOOT_VERIFIED: - s = ctx->secrets->boot_verified; - break; - case BDB_SECRET_TYPE_BUC: - s = ctx->secrets->buc; - break; - default: - return BDB_ERROR_SECRET_TYPE; - } - - memset(s, 0, BDB_SECRET_SIZE); - return BDB_SUCCESS; -} - -int vba_extend_secrets_ro(struct vba_context *ctx, const uint8_t *bdb, - uint8_t *wsr, f_extend extend) -{ - const struct bdb_key *bdbkey = bdb_get_bdbkey(bdb); - const struct bdb_key *datakey = bdb_get_datakey(bdb); - - derive_secret_ro(ctx, BDB_SECRET_TYPE_BDB, wsr, (const uint8_t *)bdbkey, - bdbkey->struct_size, extend); - derive_secret_ro(ctx, BDB_SECRET_TYPE_BOOT_PATH, wsr, - (const uint8_t *)datakey, datakey->struct_size, - extend); - derive_secret_ro(ctx, BDB_SECRET_TYPE_BOOT_VERIFIED, wsr, NULL, 0, - extend); - derive_secret_ro(ctx, BDB_SECRET_TYPE_NVM_WP, wsr, NULL, 0, extend); - /* Deriving NVM-RW has to be done after NVM-WP */ - derive_secret_ro(ctx, BDB_SECRET_TYPE_NVM_RW, wsr, NULL, 0, extend); - /* Extending WSR has to be done last. */ - derive_secret_ro(ctx, BDB_SECRET_TYPE_WSR, wsr, NULL, 0, extend); - - return BDB_SUCCESS; -} diff --git a/firmware/bdb/secrets.h b/firmware/bdb/secrets.h deleted file mode 100644 index 59c27cf6..00000000 --- a/firmware/bdb/secrets.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2016 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. - */ - -#ifndef VBOOT_REFERENCE_FIRMWARE_BDB_SECRETS_H_ -#define VBOOT_REFERENCE_FIRMWARE_BDB_SECRETS_H_ - -#define BDB_SECRET_SIZE 32 -#define BDB_CONSTANT_BLOCK_SIZE 64 - -enum bdb_secret_type { - BDB_SECRET_TYPE_WSR, - BDB_SECRET_TYPE_NVM_WP, - BDB_SECRET_TYPE_NVM_RW, - BDB_SECRET_TYPE_BDB, - BDB_SECRET_TYPE_BOOT_VERIFIED, - BDB_SECRET_TYPE_BOOT_PATH, - BDB_SECRET_TYPE_BUC, - BDB_SECRET_TYPE_COUNT, /* Last entry. Add new secrets before this. */ -}; - -/* - * Struct storing BDB secrets passed between SP-RO and SP-RW. - */ -struct bdb_secrets { - uint8_t nvm_rw[BDB_SECRET_SIZE]; - uint8_t bdb[BDB_SECRET_SIZE]; - uint8_t boot_verified[BDB_SECRET_SIZE]; - uint8_t boot_path[BDB_SECRET_SIZE]; - uint8_t nvm_wp[BDB_SECRET_SIZE]; - uint8_t buc[BDB_SECRET_SIZE]; -}; - -#endif diff --git a/firmware/bdb/sha.c b/firmware/bdb/sha.c deleted file mode 100644 index d73098df..00000000 --- a/firmware/bdb/sha.c +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright 2016 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. - */ - -#include <string.h> - -#include "2sha.h" -#include "bdb.h" - -int bdb_sha256(void *digest, const void *buf, size_t size) -{ - struct vb2_sha256_context ctx; - - vb2_sha256_init(&ctx); - vb2_sha256_update(&ctx, buf, size); - vb2_sha256_finalize(&ctx, digest); - - return BDB_SUCCESS; -} diff --git a/firmware/bdb/stub.c b/firmware/bdb/stub.c deleted file mode 100644 index 4af9126c..00000000 --- a/firmware/bdb/stub.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2016 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. - */ - -#include "bdb_api.h" -#include "bdb.h" - -__attribute__((weak)) -uint32_t vbe_get_vboot_register(enum vboot_register type) -{ - return 0; -} - -__attribute__((weak)) -void vbe_set_vboot_register(enum vboot_register type, uint32_t val) -{ - return; -} - -__attribute__((weak)) -void vbe_reset(void) -{ - return; -} - -__attribute__((weak)) -int vbe_read_nvm(enum nvm_type type, uint8_t *buf, uint32_t size) -{ - return BDB_ERROR_NOT_IMPLEMENTED; -} - -__attribute__((weak)) -int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size) -{ - return BDB_ERROR_NOT_IMPLEMENTED; -} - -__attribute__((weak)) -int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key, - uint8_t *out) -{ - return BDB_ERROR_NOT_IMPLEMENTED; -} - -__attribute__((weak)) -int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key, - uint8_t *out) -{ - return BDB_ERROR_NOT_IMPLEMENTED; -} diff --git a/firmware/bdb/vboot_register.h b/firmware/bdb/vboot_register.h deleted file mode 100644 index 8844bf62..00000000 --- a/firmware/bdb/vboot_register.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2016 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. - */ - -#ifndef VBOOT_REFERENCE_FIRMWARE_BDB_VBOOT_REGISTER_H -#define VBOOT_REFERENCE_FIRMWARE_BDB_VBOOT_REGISTER_H - -enum vboot_register { - /* Register cleared after every reset */ - VBOOT_REGISTER, - /* Register cleared after cold reset (persists after warm reset) */ - VBOOT_REGISTER_PERSIST, -}; - -/* Bit fields for VBOOT_REGISTER_PERSISTENT */ -#define VBOOT_REGISTER_RECOVERY_REQUEST (1 << 0) -#define VBOOT_REGISTER_TRY_SECONDARY_BDB (1 << 1) -#define VBOOT_REGISTER_FAILED_RW_PRIMARY (1 << 2) -#define VBOOT_REGISTER_FAILED_RW_SECONDARY (1 << 3) - -#endif diff --git a/futility/bdb_helper.c b/futility/bdb_helper.c deleted file mode 100644 index b0f2dcd0..00000000 --- a/futility/bdb_helper.c +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright 2016 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. - * - * Boot descriptor block helper functions - */ - -#include <inttypes.h> -#include <stdio.h> - -#include "2sha.h" -#include "bdb.h" -#include "bdb_struct.h" -#include "file_type.h" - -enum futil_file_type ft_recognize_bdb(uint8_t *buf, uint32_t len) -{ - const struct bdb_header *header = bdb_get_header(buf); - - if (bdb_check_header(header, len)) - return FILE_TYPE_UNKNOWN; - - return FILE_TYPE_BDB; -} - -static void print_digest(const char *label, const uint8_t *digest, size_t size) -{ - int i; - - if (label) - printf("%s", label); - for (i = 0; i < size; i++) - printf("%02x", digest[i]); - printf("\n"); -} - -static void print_hash_entry(const char *label, const struct bdb_hash *hash) -{ - if (label) - printf("%s", label); - printf(" Offset: 0x%" PRIx64 "\n", hash->offset); - printf(" Size: %d\n", hash->size); - printf(" Partition: %d\n", hash->partition); - printf(" Type: %d\n", hash->type); - printf(" Load Address: 0x%" PRIx64 "\n", hash->load_address); - print_digest(" Digest: ", hash->digest, sizeof(hash->digest)); -} - -static void print_key_info(const char *label, const struct bdb_key *key) -{ - uint8_t digest[BDB_SHA256_DIGEST_SIZE]; - - if (label) - printf("%s", label); - printf(" Struct Version: 0x%x:0x%x\n", - key->struct_major_version, key->struct_minor_version); - printf(" Size: %d\n", key->struct_size); - printf(" Hash Algorithm: %d\n", key->hash_alg); - printf(" Sign Algorithm: %d\n", key->sig_alg); - printf(" Version: %d\n", key->key_version); - printf(" Description: %s\n", key->description); - bdb_sha256(digest, key, key->struct_size); - print_digest(" Digest: ", digest, sizeof(digest)); -} - -static void print_sig_info(const char *label, const struct bdb_sig *sig) -{ - if (label) - printf("%s", label); - printf(" Struct Version: 0x%x:0x%x\n", - sig->struct_major_version, sig->struct_minor_version); - printf(" Hash Algorithm: %d\n", sig->hash_alg); - printf(" Sign Algorithm: %d\n", sig->sig_alg); - printf(" Signed Size: %d\n", sig->signed_size); - printf(" Description: %s\n", sig->description); -} - -static void show_bdb_header(const uint8_t *bdb) -{ - const struct bdb_header *header = bdb_get_header(bdb); - - printf("BDB Header:\n"); - printf(" Struct Version: 0x%x:0x%x\n", - header->struct_major_version, header->struct_minor_version); - printf(" Struct Size: %d\n", header->struct_size); - printf(" Load Address: 0x%" PRIx64 "\n", header->bdb_load_address); - printf(" Size: %d\n", header->bdb_size); - printf(" Signed Size: %d\n", header->signed_size); - printf(" OEM0 Size: %d\n", header->oem_area_0_size); -} - -static void show_bdbkey_info(const uint8_t *bdb) -{ - print_key_info("BDB key:\n", bdb_get_bdbkey(bdb)); -} - -static void show_datakey_info(const uint8_t *bdb) -{ - print_key_info("Data key:\n", bdb_get_datakey(bdb)); -} - -static void show_header_signature(const uint8_t *bdb) -{ - print_sig_info("Header Signature:\n" , bdb_get_header_sig(bdb)); -} - -static void show_data_header(const uint8_t *bdb) -{ - const struct bdb_data *data = bdb_get_data(bdb); - - printf("Data Header:\n"); - printf(" Struct Version: 0x%x:0x%x\n", - data->struct_major_version, data->struct_minor_version); - printf(" Data Version: %d\n", data->data_version); - printf(" # of Hashes: %d\n", data->num_hashes); - printf(" Hash Entry Size: %d\n", data->hash_entry_size); - printf(" Signed Size: %d\n", data->signed_size); - printf(" Description: %s\n", data->description); -} - -static void show_hashes(const uint8_t *bdb) -{ - const struct bdb_data *data = bdb_get_data(bdb); - int i; - - for (i = 0; i < data->num_hashes; i++) { - const struct bdb_hash *hash = bdb_get_hash_by_index(bdb, i); - printf("Hash #%d:\n", i); - print_hash_entry(NULL, hash); - } -} - -static void show_data_signature(const uint8_t *bdb) -{ - print_sig_info("Data Signature:\n" , bdb_get_data_sig(bdb)); -} - -int ft_show_bdb(const char *name, uint8_t *buf, uint32_t len, void *data) -{ - const struct bdb_header *header = bdb_get_header(buf); - int rv; - - /* We can get here because of '--type' option */ - rv = bdb_check_header(header, len); - if (rv) { - fprintf(stderr, "ERROR: Invalid BDB blob: %d\n", rv); - return 1; - } - - printf("Boot Descriptor Block: %s\n", name); - show_bdb_header(buf); - show_bdbkey_info(buf); - show_datakey_info(buf); - show_header_signature(buf); - show_data_header(buf); - show_hashes(buf); - show_data_signature(buf); - - return 0; -} diff --git a/futility/cmd_bdb.c b/futility/cmd_bdb.c deleted file mode 100644 index 491f7cfe..00000000 --- a/futility/cmd_bdb.c +++ /dev/null @@ -1,711 +0,0 @@ -/* Copyright 2016 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. - * - * Common boot flow utility - */ - -#include <getopt.h> -#include <stdio.h> -#include <unistd.h> - -#include "2sysincludes.h" -#include "2common.h" -#include "bdb.h" -#include "bdb_struct.h" -#include "futility.h" -#include "host.h" - -static long int version; - -/* Command line options */ -enum { - /* mode options */ - OPT_MODE_NONE, - OPT_MODE_ADD, - OPT_MODE_CREATE, - OPT_MODE_RESIGN, - OPT_MODE_VERIFY, - /* file options */ - OPT_BDBKEY_PRI, - OPT_BDBKEY_PUB, - OPT_DATAKEY_PRI, - OPT_DATAKEY_PUB, - OPT_DATA, - OPT_KEY_DIGEST, - /* versions */ - OPT_BDBKEY_VERSION, - OPT_DATAKEY_VERSION, - OPT_DATA_VERSION, - /* integer options */ - OPT_OFFSET, - OPT_PARTITION, - OPT_TYPE, - OPT_LOAD_ADDRESS, - /* Misc. options */ - OPT_IGNORE_KEY_DIGEST, - OPT_VERSION, - OPT_HELP, -}; - -static const struct option long_opts[] = { - {"add", 1, 0, OPT_MODE_ADD}, - {"create", 1, 0, OPT_MODE_CREATE}, - {"resign", 1, 0, OPT_MODE_RESIGN}, - {"verify", 1, 0, OPT_MODE_VERIFY}, - {"bdbkey_pri", 1, 0, OPT_BDBKEY_PRI}, - {"bdbkey_pub", 1, 0, OPT_BDBKEY_PUB}, - {"datakey_pri", 1, 0, OPT_DATAKEY_PRI}, - {"datakey_pub", 1, 0, OPT_DATAKEY_PUB}, - {"bdbkey_version", 1, 0, OPT_BDBKEY_VERSION}, - {"datakey_version", 1, 0, OPT_DATAKEY_VERSION}, - {"data_version", 1, 0, OPT_DATA_VERSION}, - {"data", 1, 0, OPT_DATA}, - {"key_digest", 1, 0, OPT_KEY_DIGEST}, - {"offset", 1, 0, OPT_OFFSET}, - {"partition", 1, 0, OPT_PARTITION}, - {"type", 1, 0, OPT_TYPE}, - {"load_address", 1, 0, OPT_LOAD_ADDRESS}, - {"ignore_key_digest", 0, 0, OPT_IGNORE_KEY_DIGEST}, - {"version", 1, 0, OPT_VERSION}, - {"help", 0, 0, OPT_HELP}, - {NULL, 0, 0, 0} -}; - -/** - * Add hash entry to BDB - * - * This adds a hash entry to a BDB. It does not change the signature. Hence, - * the produced BDB needs to be resigned using the resign sub-command. - */ -static int do_add(const char *bdb_filename, const char *data_filename, - uint64_t offset, uint8_t partition, - uint8_t type, uint64_t load_address) -{ - uint8_t *bdb, *data, *new_bdb = NULL; - uint32_t bdb_size, data_size; - struct bdb_header *bdb_header; - struct bdb_data *data_header; - struct bdb_hash *new_hash; - int rv = -1; - - bdb = read_file(bdb_filename, &bdb_size); - data = read_file(data_filename, &data_size); - if (!bdb || !data) { - fprintf(stderr, "Unable to load BDB or data\n"); - goto exit; - } - - /* Create a copy of BDB */ - new_bdb = calloc(1, bdb_size + sizeof(*new_hash)); - if (!new_bdb) { - fprintf(stderr, "Unable to allocate memory\n"); - goto exit; - } - /* Copy up to the end of hashes. This implicitly clears the data - * sig because it's not copied. */ - memcpy(new_bdb, bdb, vb2_offset_of(bdb, bdb_get_data_sig(bdb))); - - /* Update new BDB header */ - bdb_header = (struct bdb_header *)bdb_get_header(new_bdb); - bdb_header->bdb_size += sizeof(*new_hash); - - data_header = (struct bdb_data *)bdb_get_data(new_bdb); - - /* Update new hash. We're overwriting the data signature, which - * is already invalid anyway. */ - new_hash = (struct bdb_hash *)((uint8_t *)data_header - + data_header->signed_size); - new_hash->size = data_size; - new_hash->type = type; - new_hash->load_address = load_address; - new_hash->partition = partition; - new_hash->offset = offset; - if (bdb_sha256(new_hash->digest, data, data_size)) { - fprintf(stderr, "Unable to calculate hash\n"); - goto exit; - } - - /* Update data header */ - data_header->num_hashes++; - data_header->signed_size += sizeof(*new_hash); - - rv = write_file(bdb_filename, bdb_header, bdb_header->bdb_size); - if (rv) { - fprintf(stderr, "Unable to write BDB\n"); - goto exit; - } - - fprintf(stderr, "Hash is added to BDB successfully. Resign required\n"); - -exit: - free(bdb); - free(data); - free(new_bdb); - - return rv; -} - -/** - * Create a new BDB - * - * This creates a new BDB using a pair of BDB keys and a pair of data keys. - * A private data key is needed even with no hash entries. - */ -static int do_create(const char *bdb_filename, - const char *bdbkey_pri_filename, - const char *bdbkey_pub_filename, - uint32_t bdbkey_version, - const char *datakey_pri_filename, - const char *datakey_pub_filename, - uint32_t datakey_version, - uint64_t load_address) -{ - struct bdb_key *bdbkey; - struct bdb_key *datakey; - struct rsa_st *bdbkey_pri; - struct rsa_st *datakey_pri; - struct bdb_create_params params; - struct bdb_header *header; - int rv = -1; - - /* Check arguments */ - if (!bdb_filename || !bdbkey_pri_filename || !bdbkey_pub_filename - || !datakey_pri_filename || !datakey_pub_filename) { - fprintf(stderr, "Missing filenames\n"); - return rv; - } - - /* Load keys */ - bdbkey = bdb_create_key(bdbkey_pub_filename, bdbkey_version, NULL); - bdbkey_pri = read_pem(bdbkey_pri_filename); - datakey = bdb_create_key(datakey_pub_filename, datakey_version, NULL); - datakey_pri = read_pem(datakey_pri_filename); - if (!bdbkey || !bdbkey_pri || !datakey || !datakey_pri) { - fprintf(stderr, "Unable to load keys\n"); - goto exit; - } - - memset(¶ms, 0, sizeof(params)); - params.bdb_load_address = load_address; - params.bdbkey = bdbkey; - params.datakey = datakey; - params.private_bdbkey = bdbkey_pri; - params.private_datakey = datakey_pri; - params.num_hashes = 0; - - header = bdb_create(¶ms); - if (!header) { - fprintf(stderr, "Unable to create BDB\n"); - goto exit; - } - - rv = write_file(bdb_filename, header, header->bdb_size); - if (rv) { - fprintf(stderr, "Unable to write BDB\n"); - goto exit; - } - - fprintf(stderr, "BDB is created successfully\n"); - -exit: - /* Free keys and buffers */ - free(bdbkey); - free(datakey); - RSA_free(bdbkey_pri); - RSA_free(datakey_pri); - - return rv; -} - -static int install_bdbkey(uint8_t **bdb, const struct bdb_key *new_key) -{ - struct bdb_header *header; - const struct bdb_key *key; - uint8_t *p, *q; - uint8_t *new_bdb; - size_t new_size; - size_t l; - - header = (struct bdb_header *)bdb_get_header(*bdb); - key = bdb_get_bdbkey(*bdb); - new_size = bdb_size_of(*bdb) + new_key->struct_size - key->struct_size; - new_bdb = calloc(1, new_size); - if (!new_bdb) { - fprintf(stderr, "Unable to allocate memory\n"); - return -1; - } - - /* copy BDB header */ - p = *bdb; - q = new_bdb; - l = header->struct_size; - memcpy(q, p, l); - - /* copy new BDB key */ - p += l; - q += l; - memcpy(q, new_key, new_key->struct_size); - - /* copy the rest */ - p += key->struct_size; - q += new_key->struct_size; - l = bdb_size_of(*bdb) - vb2_offset_of(*bdb, p); - memcpy(q, p, l); - - /* update size */ - header = (struct bdb_header *)bdb_get_header(new_bdb); - header->bdb_size = new_size; - - free(*bdb); - *bdb = new_bdb; - - return 0; -} - -static int install_datakey(uint8_t **bdb, const struct bdb_key *new_key) -{ - struct bdb_header *header; - struct bdb_key *key; - uint8_t *p, *q; - uint8_t *new_bdb; - size_t new_size; - uint32_t l; - - key = (struct bdb_key *)bdb_get_datakey(*bdb); - new_size = bdb_size_of(*bdb) + new_key->struct_size - key->struct_size; - new_bdb = calloc(1, new_size); - if (!new_bdb) { - fprintf(stderr, "Unable to allocate memory\n"); - return -1; - } - - /* copy the stuff up to datakey */ - p = *bdb; - q = new_bdb; - l = bdb_offset_of_datakey(*bdb); - memcpy(q, p, l); - - /* copy new data key */ - p += l; - q += l; - memcpy(q, new_key, new_key->struct_size); - - /* copy the rest */ - p += key->struct_size; - q += new_key->struct_size; - l = bdb_size_of(*bdb) - vb2_offset_of(*bdb, p); - memcpy(q, p, l); - - /* update size */ - header = (struct bdb_header *)bdb_get_header(new_bdb); - header->bdb_size = new_size; - header->signed_size = header->oem_area_0_size + new_key->struct_size; - - free(*bdb); - *bdb = new_bdb; - - return 0; -} -/** - * Resign a BDB using new keys - * - * It first installs given public keys to the BDB, then, runs verification. - * If verification fails due to an invalid signature, it tries to 'fix' it - * by resigning it using a given private key, then runs verification again. - * Whether a key is required or not depends on which signature is invalid. - * If a private key is required but not provided, it returns an error. - */ -static int do_resign(const char *bdb_filename, - const char *bdbkey_pri_filename, - const char *bdbkey_pub_filename, - uint32_t bdbkey_version, - const char *datakey_pri_filename, - const char *datakey_pub_filename, - uint32_t datakey_version, - uint32_t data_version) -{ - uint8_t *bdb = NULL; - struct rsa_st *bdbkey_pri = NULL; - struct rsa_st *datakey_pri = NULL; - uint32_t bdb_size; - int resigned = 0; - int rv = -1; - - if (!bdb_filename) { - fprintf(stderr, "BDB file must be specified\n"); - goto exit; - } - - bdb = read_file(bdb_filename, &bdb_size); - if (!bdb) { - fprintf(stderr, "Unable to read %s\n", bdb_filename); - goto exit; - } - - if (data_version != -1) { - struct bdb_data *data = (struct bdb_data *)bdb_get_data(bdb); - data->data_version = data_version; - } - - if (bdbkey_pub_filename) { - struct bdb_key *key = bdb_create_key(bdbkey_pub_filename, - bdbkey_version, NULL); - if (!key) { - fprintf(stderr, "Unable to read BDB key\n"); - goto exit; - } - if (install_bdbkey(&bdb, key)) { - fprintf(stderr, "Unable to install new BDB key\n"); - goto exit; - } - } - - if (datakey_pub_filename) { - struct bdb_key *key = bdb_create_key(datakey_pub_filename, - datakey_version, NULL); - if (!key) { - fprintf(stderr, "Unable to read data key\n"); - goto exit; - } - if (install_datakey(&bdb, key)) { - fprintf(stderr, "Unable to install new data key\n"); - goto exit; - } - } - - /* Check validity for the new bdb key */ - rv = bdb_verify(bdb, bdb_size_of(bdb), NULL); - if (rv == BDB_ERROR_HEADER_SIG) { - /* This is expected failure if we installed a new BDB key. - * Let's resign to fix it. */ - resigned = 1; - fprintf(stderr, "Data key signature is invalid. Need to resign " - "the key.\n"); - if (!bdbkey_pri_filename) { - fprintf(stderr, "Private BDB key is required but not " - "provided.\n"); - goto exit; - } - bdbkey_pri = read_pem(bdbkey_pri_filename); - rv = bdb_sign_datakey(&bdb, bdbkey_pri); - if (rv) { - fprintf(stderr, "Failed to resign data key: %d\n", rv); - goto exit; - } - fprintf(stderr, "Data key is resigned.\n"); - } else { - fprintf(stderr, "Resigning data key is not required.\n"); - } - - /* Check validity for the new data key */ - rv = bdb_verify(bdb, bdb_size_of(bdb), NULL); - switch (rv) { - case BDB_ERROR_DATA_SIG: - case BDB_ERROR_DATA_CHECK_SIG: - /* This is expected failure if we installed a new data key - * or sig is corrupted, which happens when a new hash is added - * by 'add' sub-command. Let's resign the data */ - resigned = 1; - fprintf(stderr, - "Data signature is invalid. Need to resign data.\n"); - if (!datakey_pri_filename) { - fprintf(stderr, "Private data key is required but not " - "provided.\n"); - goto exit; - } - datakey_pri = read_pem(datakey_pri_filename); - rv = bdb_sign_data(&bdb, datakey_pri); - if (rv) { - fprintf(stderr, "Failed to resign hashes: %d\n", rv); - goto exit; - } - fprintf(stderr, "Data is resigned.\n"); - break; - case BDB_GOOD_OTHER_THAN_KEY: - case BDB_SUCCESS: - fprintf(stderr, "Resigning the data is not required.\n"); - break; - default: - fprintf(stderr, "Verifying BDB failed unexpectedly: %d\n", rv); - goto exit; - } - - if (!resigned) - goto exit; - - /* Check validity one last time */ - rv = bdb_verify(bdb, bdb_size_of(bdb), NULL); - if (rv && rv != BDB_GOOD_OTHER_THAN_KEY) { - /* This is not expected. We installed new keys and resigned - * BDB but it's still invalid. */ - fprintf(stderr, "BDB is resigned but it's invalid: %d\n", rv); - goto exit; - } - - rv = write_file(bdb_filename, bdb, bdb_size_of(bdb)); - if (rv) { - fprintf(stderr, "Unable to write BDB.\n"); - goto exit; - } - - fprintf(stderr, "Successfully resigned BDB.\n"); - -exit: - free(bdb); - RSA_free(bdbkey_pri); - RSA_free(datakey_pri); - - return rv; -} - -static int do_verify(const char *bdb_filename, const char *key_digest_filename, - int ignore_key_digest) -{ - uint8_t *bdb = NULL; - uint8_t *key_digest = NULL; - uint32_t bdb_size, key_digest_size; - int rv = -1; - - bdb = read_file(bdb_filename, &bdb_size); - if (!bdb) { - fprintf(stderr, "Unable to load BDB\n"); - goto exit; - } - - if (key_digest_filename) { - key_digest = read_file(key_digest_filename, &key_digest_size); - if (!key_digest) { - fprintf(stderr, "Unable to read key digest\n"); - goto exit; - } - if (key_digest_size != BDB_SHA256_DIGEST_SIZE) { - fprintf(stderr, - "Invalid digest size: %d\n", key_digest_size); - goto exit; - } - } - - rv = bdb_verify(bdb, bdb_size, key_digest); - switch (rv) { - case BDB_SUCCESS: - fprintf(stderr, "BDB is successfully verified.\n"); - break; - case BDB_GOOD_OTHER_THAN_KEY: - fprintf(stderr, "BDB is valid."); - if (ignore_key_digest) { - rv = BDB_SUCCESS; - fprintf(stderr, - " Key digest doesn't match but ignored.\n"); - } else { - fprintf(stderr, - " Key digest doesn't match.\n"); - } - break; - default: - /* TODO: Probably nice to print translation of the error code */ - fprintf(stderr, "BDB is invalid: %d.\n", rv); - } - -exit: - free(bdb); - free(key_digest); - - return rv; -} - -/* Print help and return error */ -static void print_help(int argc, char *argv[]) -{ - printf("\nUsage: " MYNAME " %s <--create|--add|--resign|--verify>\n" - "\n" - "Utility for managing boot descriptor blocks (BDBs).\n" - "\n" - "For '--add <bdb_file> [OPTIONS]', required OPTIONS are:\n" - " --data <file> Data to be added\n" - " --offset <offset> Offset\n" - " --partition <number> Partition number\n" - " --type <number> Data type\n" - " --load_address <number> Data load address\n" - "\n" - "For '--create <bdb_file> [OPTIONS]', required OPTIONS are:\n" - " --bdbkey_pri <file> BDB key in .pem format\n" - " --bdbkey_pub <file> BDB key in .keyb format\n" - " --datakey_pri <file> Data key in .pem format\n" - " --datakey_pub <file> Data key in .keyb format\n" - " --load_address <number> BDB load address\n" - "\n" - "For '--resign <bdb_file> [OPTIONS]', optional OPTIONS are:\n" - " --bdbkey_pri <file> New BDB key in .pem format\n" - " --bdbkey_pub <file> New BDB key in .keyb format\n" - " --datakey_pri <file> New data key in .pem format\n" - " --datakey_pub <file> New data key in .keyb format\n" - " --data_version <number> Data version\n" - "\n" - "For '--verify <bdb_file> [OPTIONS]', optional OPTIONS are:\n" - " --key_digest <file> BDB key digest\n" - " --ignore_key_digest Ignore key digest mismatch\n" - "\n", - argv[0]); -} - -static int do_bdb(int argc, char *argv[]) -{ - int mode = 0; - const char *bdb_filename = NULL; - const char *bdbkey_pri_filename = NULL; - const char *bdbkey_pub_filename = NULL; - const char *datakey_pri_filename = NULL; - const char *datakey_pub_filename = NULL; - const char *data_filename = NULL; - const char *key_digest_filename = NULL; - uint32_t bdbkey_version = 0; - uint32_t datakey_version = 0; - uint32_t data_version = -1; - uint64_t offset = 0; - uint8_t partition = 0; - uint8_t type = 0; - uint64_t load_address = -1; - int ignore_key_digest = 0; - int parse_error = 0; - char *e; - int i; - - while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { - switch (i) { - case '?': - /* Unhandled option */ - fprintf(stderr, "Unknown option or missing value\n"); - parse_error = 1; - break; - case OPT_HELP: - print_help(argc, argv); - return !!parse_error; - case OPT_MODE_CREATE: - mode = i; - bdb_filename = optarg; - break; - case OPT_MODE_ADD: - mode = i; - bdb_filename = optarg; - break; - case OPT_MODE_RESIGN: - mode = i; - bdb_filename = optarg; - break; - case OPT_MODE_VERIFY: - mode = i; - bdb_filename = optarg; - break; - case OPT_BDBKEY_PRI: - bdbkey_pri_filename = optarg; - break; - case OPT_BDBKEY_PUB: - bdbkey_pub_filename = optarg; - break; - case OPT_DATAKEY_PRI: - datakey_pri_filename = optarg; - break; - case OPT_DATAKEY_PUB: - datakey_pub_filename = optarg; - break; - case OPT_DATA: - data_filename = optarg; - break; - case OPT_KEY_DIGEST: - key_digest_filename = optarg; - break; - case OPT_BDBKEY_VERSION: - bdbkey_version = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --bdbkey_version\n"); - parse_error = 1; - } - break; - case OPT_DATAKEY_VERSION: - datakey_version = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --datakey_version\n"); - parse_error = 1; - } - break; - case OPT_DATA_VERSION: - data_version = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --data_version\n"); - parse_error = 1; - } - break; - case OPT_OFFSET: - offset = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --offset\n"); - parse_error = 1; - } - break; - case OPT_PARTITION: - partition = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --partition\n"); - parse_error = 1; - } - break; - case OPT_TYPE: - type = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --type\n"); - parse_error = 1; - } - break; - case OPT_LOAD_ADDRESS: - load_address = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --load_address\n"); - parse_error = 1; - } - break; - case OPT_IGNORE_KEY_DIGEST: - ignore_key_digest = 1; - break; - case OPT_VERSION: - version = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - fprintf(stderr, "Invalid --version\n"); - parse_error = 1; - } - break; - } - } - - if (parse_error) { - print_help(argc, argv); - return 1; - } - - switch (mode) { - case OPT_MODE_ADD: - return do_add(bdb_filename, data_filename, - offset, partition, type, load_address); - case OPT_MODE_CREATE: - return do_create(bdb_filename, bdbkey_pri_filename, - bdbkey_pub_filename, bdbkey_version, - datakey_pri_filename, datakey_pub_filename, - datakey_version, load_address); - case OPT_MODE_RESIGN: - return do_resign(bdb_filename, bdbkey_pri_filename, - bdbkey_pub_filename, bdbkey_version, - datakey_pri_filename, datakey_pub_filename, - datakey_version, data_version); - case OPT_MODE_VERIFY: - return do_verify(bdb_filename, - key_digest_filename, ignore_key_digest); - case OPT_MODE_NONE: - default: - fprintf(stderr, "Must specify a mode.\n"); - print_help(argc, argv); - return 1; - } -} - -DECLARE_FUTIL_COMMAND(bdb, do_bdb, VBOOT_VERSION_1_0, - "Common boot flow utility"); diff --git a/futility/file_type.inc b/futility/file_type.inc index 5fd83c2a..0d3acc99 100644 --- a/futility/file_type.inc +++ b/futility/file_type.inc @@ -80,7 +80,3 @@ FILE_TYPE(USBPD1, "usbpd1", "USB-PD charger image (v1.0)", R_(ft_recognize_usbpd1), S_(ft_show_usbpd1), S_(ft_sign_usbpd1)) -FILE_TYPE(BDB, "bdb", "Common Boot Flow Boot Descriptor Block", - R_(ft_recognize_bdb), - S_(ft_show_bdb), - NONE) diff --git a/tests/bdb_nvm_test.c b/tests/bdb_nvm_test.c deleted file mode 100644 index d69391c0..00000000 --- a/tests/bdb_nvm_test.c +++ /dev/null @@ -1,60 +0,0 @@ -/* 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. - * - * Unit tests NVM - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "bdb_api.h" -#include "test_common.h" - -static void test_nvmrw(void) -{ - struct vba_context ctx; - uint32_t val; - - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_UPDATE_COUNT, 1), NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_UPDATE_COUNT, &val), NULL); - TEST_EQ(val, 1, NULL); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION, 1), - NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_MIN_KERNEL_DATA_KEY_VERSION, &val), - NULL); - TEST_EQ(val, 1, NULL); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_MIN_KERNEL_VERSION, 1), NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_MIN_KERNEL_VERSION, &val), NULL); - TEST_EQ(val, 1, NULL); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_BUC_TYPE, 1), NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_BUC_TYPE, &val), NULL); - TEST_EQ(val, 1, NULL); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_FLAG_BUC_PRESENT, 1), NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_FLAG_BUC_PRESENT, &val), NULL); - TEST_TRUE(val, NULL); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_FLAG_DFM_DISABLE, 1), NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_FLAG_DFM_DISABLE, &val), NULL); - TEST_TRUE(val, NULL); - - TEST_SUCC(nvmrw_set(&ctx, NVMRW_VAR_FLAG_DOSM, 1), NULL); - TEST_SUCC(nvmrw_get(&ctx, NVMRW_VAR_FLAG_DOSM, &val), NULL); - TEST_TRUE(val, NULL); -} - -int main(int argc, char *argv[]) -{ - printf("Running BDB NVM tests...\n"); - - test_nvmrw(); - - return gTestSuccess ? 0 : 255; -} diff --git a/tests/bdb_sprw_test.c b/tests/bdb_sprw_test.c deleted file mode 100644 index 8395275c..00000000 --- a/tests/bdb_sprw_test.c +++ /dev/null @@ -1,684 +0,0 @@ -/* 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. - * - * Unit tests - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <openssl/aes.h> - -#include "2sha.h" -#include "2hmac.h" -#include "bdb.h" -#include "bdb_api.h" -#include "bdb_struct.h" -#include "host.h" -#include "test_common.h" -#include "vboot_register.h" -#include "secrets.h" - -static struct bdb_header *bdb, *bdb0, *bdb1; -static uint32_t vboot_register; -static uint32_t vboot_register_persist; -static char slot_selected; -static uint8_t aprw_digest[BDB_SHA256_DIGEST_SIZE]; -static uint8_t reset_count; - -/* NVM-RW image in storage (e.g. EEPROM) */ -static uint8_t nvmrw1[NVM_RW_MAX_STRUCT_SIZE]; -static uint8_t nvmrw2[NVM_RW_MAX_STRUCT_SIZE]; - -static struct bdb_secrets secrets = { - .nvm_wp = {0x00, }, - .nvm_rw = {0x00, }, - .bdb = {0x00, }, - .boot_verified = {0x00, }, - .boot_path = {0x00, }, - .buc = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff}, -}; - -static int vbe_write_nvm_failure = 0; - -static struct bdb_header *create_bdb(const char *key_dir, - struct bdb_hash *hash, int num_hashes) -{ - struct bdb_header *b; - uint8_t oem_area_0[32] = "Some OEM area."; - uint8_t oem_area_1[64] = "Some other OEM area."; - char filename[1024]; - - struct bdb_create_params p = { - .bdb_load_address = 0x11223344, - .oem_area_0 = oem_area_0, - .oem_area_0_size = sizeof(oem_area_0), - .oem_area_1 = oem_area_1, - .oem_area_1_size = sizeof(oem_area_1), - .header_sig_description = (char *)"The header sig", - .data_sig_description = (char *)"The data sig", - .data_description = (char *)"Test BDB data", - .data_version = 3, - .hash = hash, - .num_hashes = num_hashes, - }; - - uint8_t bdbkey_digest[BDB_SHA256_DIGEST_SIZE]; - - /* Load keys */ - snprintf(filename, sizeof(filename), "%s/bdbkey.keyb", key_dir); - p.bdbkey = bdb_create_key(filename, 100, "BDB key"); - snprintf(filename, sizeof(filename), "%s/datakey.keyb", key_dir); - p.datakey = bdb_create_key(filename, 200, "datakey"); - snprintf(filename, sizeof(filename), "%s/bdbkey.pem", key_dir); - p.private_bdbkey = read_pem(filename); - snprintf(filename, sizeof(filename), "%s/datakey.pem", key_dir); - p.private_datakey = read_pem(filename); - if (!p.bdbkey || !p.datakey || !p.private_bdbkey || !p.private_datakey) { - fprintf(stderr, "Unable to load test keys\n"); - exit(2); - } - - vb2_digest_buffer((uint8_t *)p.bdbkey, p.bdbkey->struct_size, - VB2_HASH_SHA256, - bdbkey_digest, BDB_SHA256_DIGEST_SIZE); - - b = bdb_create(&p); - if (!b) { - fprintf(stderr, "Unable to create test BDB\n"); - exit(2); - } - - /* Free keys and buffers */ - free(p.bdbkey); - free(p.datakey); - RSA_free(p.private_bdbkey); - RSA_free(p.private_datakey); - - return b; -} - -static void calculate_aprw_digest(const struct bdb_hash *hash, uint8_t *digest) -{ - /* Locate AP-RW */ - /* Calculate digest as loading AP-RW */ - memcpy(digest, aprw_digest, sizeof(aprw_digest)); -} - -static void verstage_main(void) -{ - struct vba_context ctx; - const struct bdb_hash *hash; - uint8_t digest[BDB_SHA256_DIGEST_SIZE]; - int rv; - - rv = vba_bdb_init(&ctx); - if (rv) { - fprintf(stderr, "Initializing context failed for (%d)\n", rv); - vba_bdb_fail(&ctx); - /* This return is needed for unit test. vba_bdb_fail calls - * vbe_reset, which calls verstage_main. If verstage_main - * successfully returns, we return here as well. */ - return; - } - fprintf(stderr, "Initialized context. Trying slot %c\n", - ctx.slot ? 'B' : 'A'); - - /* 1. Locate BDB */ - - /* 2. Get bdb_hash structure for AP-RW */ - hash = bdb_get_hash_by_type(bdb, BDB_DATA_AP_RW); - fprintf(stderr, "Got hash of AP-RW\n"); - - /* 3. Load & calculate digest of AP-RW */ - calculate_aprw_digest(hash, digest); - fprintf(stderr, "Calculated digest\n"); - - /* 4. Compare digests */ - if (memcmp(hash->digest, digest, BDB_SHA256_DIGEST_SIZE)) { - fprintf(stderr, "Digests do not match\n"); - vba_bdb_fail(&ctx); - /* This return is needed for unit test. vba_bdb_fail calls - * vbe_reset, which calls verstage_main. If verstage_main - * successfully returns, we return here as well. */ - return; - } - - /* 5. Record selected slot. This depends on the firmware */ - slot_selected = ctx.slot ? 'B' : 'A'; - fprintf(stderr, "Selected AP-RW in slot %c\n", slot_selected); - - /* X. This should be done upon AP-RW's request after everything is - * successful. We do it here for the unit test. */ - vba_bdb_finalize(&ctx); -} - -uint32_t vbe_get_vboot_register(enum vboot_register type) -{ - switch (type) { - case VBOOT_REGISTER: - return vboot_register; - case VBOOT_REGISTER_PERSIST: - return vboot_register_persist; - default: - fprintf(stderr, "Invalid vboot register type (%d)\n", type); - exit(2); - } -} - -void vbe_set_vboot_register(enum vboot_register type, uint32_t val) -{ - switch (type) { - case VBOOT_REGISTER: - vboot_register = val; - break; - case VBOOT_REGISTER_PERSIST: - vboot_register_persist = val; - break; - default: - fprintf(stderr, "Invalid vboot register type (%d)\n", type); - exit(2); - } -} - -void vbe_reset(void) -{ - uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST); - - fprintf(stderr, "Booting ...\n"); - - if (++reset_count > 5) { - fprintf(stderr, "Reset counter exceeded maximum value\n"); - exit(2); - } - - /* Emulate warm reset */ - vboot_register = 0; - if (val & VBOOT_REGISTER_RECOVERY_REQUEST) { - fprintf(stderr, "Recovery requested\n"); - return; - } - /* Selected by SP-RO */ - bdb = (val & VBOOT_REGISTER_TRY_SECONDARY_BDB) ? bdb1 : bdb0; - verstage_main(); -} - -static void test_verify_aprw(const char *key_dir) -{ - struct bdb_hash hash0 = { - .offset = 0x28000, - .size = 0x20000, - .partition = 1, - .type = BDB_DATA_AP_RW, - .load_address = 0x200000, - .digest = {0x11, 0x11, 0x11, 0x11}, - }; - struct bdb_hash hash1 = { - .offset = 0x28000, - .size = 0x20000, - .partition = 1, - .type = BDB_DATA_AP_RW, - .load_address = 0x200000, - .digest = {0x22, 0x22, 0x22, 0x22}, - }; - - bdb0 = create_bdb(key_dir, &hash0, 1); - bdb1 = create_bdb(key_dir, &hash1, 1); - memset(aprw_digest, 0, BDB_SHA256_DIGEST_SIZE); - - /* (slotA, slotB) = (good, bad) */ - reset_count = 0; - vboot_register_persist = 0; - slot_selected = 'X'; - memcpy(aprw_digest, hash0.digest, 4); - vbe_reset(); - TEST_EQ(reset_count, 1, NULL); - TEST_EQ(slot_selected, 'A', NULL); - TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY, - NULL); - TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY, - NULL); - - /* (slotA, slotB) = (bad, good) */ - reset_count = 0; - vboot_register_persist = 0; - slot_selected = 'X'; - memcpy(aprw_digest, hash1.digest, 4); - vbe_reset(); - TEST_EQ(reset_count, 3, NULL); - TEST_EQ(slot_selected, 'B', NULL); - TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY, - NULL); - TEST_FALSE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY, - NULL); - - /* (slotA, slotB) = (bad, bad) */ - reset_count = 0; - vboot_register_persist = 0; - slot_selected = 'X'; - memset(aprw_digest, 0, BDB_SHA256_DIGEST_SIZE); - vbe_reset(); - TEST_EQ(reset_count, 5, NULL); - TEST_EQ(slot_selected, 'X', NULL); - TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_PRIMARY, - NULL); - TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_FAILED_RW_SECONDARY, - NULL); - TEST_TRUE(vboot_register_persist & VBOOT_REGISTER_RECOVERY_REQUEST, - NULL); - - /* Clean up */ - free(bdb0); - free(bdb1); -} - -int vbe_read_nvm(enum nvm_type type, uint8_t *buf, uint32_t size) -{ - /* Read NVM-RW contents (from EEPROM for example) */ - switch (type) { - case NVM_TYPE_RW_PRIMARY: - if (sizeof(nvmrw1) < size) - return -1; - memcpy(buf, nvmrw1, size); - break; - case NVM_TYPE_RW_SECONDARY: - if (sizeof(nvmrw2) < size) - return -1; - memcpy(buf, nvmrw2, size); - break; - default: - return -1; - } - return 0; -} - -int vbe_write_nvm(enum nvm_type type, void *buf, uint32_t size) -{ - if (vbe_write_nvm_failure > 0) { - fprintf(stderr, "Failed to write NVM (type=%d failure=%d)\n", - type, vbe_write_nvm_failure); - vbe_write_nvm_failure--; - return -1; - } - - /* Write NVM-RW contents (to EEPROM for example) */ - switch (type) { - case NVM_TYPE_RW_PRIMARY: - memcpy(nvmrw1, buf, size); - break; - case NVM_TYPE_RW_SECONDARY: - memcpy(nvmrw2, buf, size); - break; - default: - return -1; - } - return 0; -} - -static void install_nvm(enum nvm_type type, - uint32_t min_kernel_data_key_version, - uint32_t min_kernel_version, - uint32_t update_count) -{ - struct nvmrw nvm = { - .struct_magic = NVM_RW_MAGIC, - .struct_major_version = NVM_HEADER_VERSION_MAJOR, - .struct_minor_version = NVM_HEADER_VERSION_MINOR, - .struct_size = sizeof(struct nvmrw), - .min_kernel_data_key_version = min_kernel_data_key_version, - .min_kernel_version = min_kernel_version, - .update_count = update_count, - }; - - /* Compute HMAC */ - hmac(VB2_HASH_SHA256, secrets.nvm_rw, BDB_SECRET_SIZE, - &nvm, nvm.struct_size - sizeof(nvm.hmac), - nvm.hmac, sizeof(nvm.hmac)); - - /* Install NVM-RWs (in EEPROM for example) */ - switch (type) { - case NVM_TYPE_RW_PRIMARY: - memset(nvmrw1, 0, sizeof(nvmrw1)); - memcpy(nvmrw1, &nvm, sizeof(nvm)); - break; - case NVM_TYPE_RW_SECONDARY: - memset(nvmrw2, 0, sizeof(nvmrw2)); - memcpy(nvmrw2, &nvm, sizeof(nvm)); - break; - default: - fprintf(stderr, "Unsupported NVM type (%d)\n", type); - exit(2); - return; - } -} - -static void test_nvm_read(void) -{ - struct vba_context ctx = { - .bdb = NULL, - .secrets = &secrets, - }; - struct nvmrw *nvm; - uint8_t nvmrw1_copy[NVM_RW_MAX_STRUCT_SIZE]; - uint8_t nvmrw2_copy[NVM_RW_MAX_STRUCT_SIZE]; - - install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0); - memcpy(nvmrw1_copy, nvmrw1, sizeof(nvmrw1)); - memcpy(nvmrw2_copy, nvmrw2, sizeof(nvmrw2)); - - /* Test nvm_read: both good -> pick primary, no sync */ - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - TEST_SUCC(nvmrw_read(&ctx), NULL); - TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw1, sizeof(*nvm)), NULL); - TEST_SUCC(memcmp(nvmrw1, nvmrw1_copy, sizeof(nvmrw1)), NULL); - TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL); - - /* Test nvm_read: primary bad -> pick secondary */ - install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0); - memcpy(nvmrw2_copy, nvmrw2, sizeof(*nvm)); - nvm = (struct nvmrw *)nvmrw1; - nvm->hmac[0] ^= 0xff; - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - TEST_SUCC(nvmrw_read(&ctx), NULL); - TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw2, sizeof(*nvm)), NULL); - TEST_SUCC(memcmp(nvmrw1, nvmrw2_copy, sizeof(nvmrw2)), NULL); - TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL); - - /* Test nvm_read: secondary bad -> pick primary */ - install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0); - memcpy(nvmrw1_copy, nvmrw1, sizeof(*nvm)); - nvm = (struct nvmrw *)nvmrw2; - nvm->hmac[0] ^= 0xff; - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - TEST_SUCC(nvmrw_read(&ctx), NULL); - TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw1, sizeof(*nvm)), NULL); - TEST_SUCC(memcmp(nvmrw1, nvmrw1_copy, sizeof(nvmrw1)), NULL); - TEST_SUCC(memcmp(nvmrw2, nvmrw1_copy, sizeof(nvmrw1)), NULL); - - /* Test nvm_read: both bad */ - nvm = (struct nvmrw *)nvmrw1; - nvm->hmac[0] ^= 0xff; - nvm = (struct nvmrw *)nvmrw2; - nvm->hmac[0] ^= 0xff; - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - TEST_EQ(nvmrw_read(&ctx), BDB_ERROR_NVM_RW_INVALID_HMAC, NULL); - - /* Test update count: secondary new -> pick secondary */ - install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 1); - memcpy(nvmrw2_copy, nvmrw2, sizeof(*nvm)); - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - TEST_SUCC(nvmrw_read(&ctx), NULL); - TEST_SUCC(memcmp(&ctx.nvmrw, nvmrw2, sizeof(*nvm)), NULL); - TEST_SUCC(memcmp(nvmrw1, nvmrw2_copy, sizeof(nvmrw1)), NULL); - TEST_SUCC(memcmp(nvmrw2, nvmrw2_copy, sizeof(nvmrw2)), NULL); - - /* Test old reader -> minor version downgrade */ - install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 1); - memset(&ctx.nvmrw, 0, sizeof(ctx.nvmrw)); - nvm = (struct nvmrw *)nvmrw1; - nvm->struct_minor_version++; - nvm->struct_size++; - TEST_SUCC(nvmrw_read(&ctx), NULL); - TEST_EQ(ctx.nvmrw.struct_minor_version, NVM_HEADER_VERSION_MINOR, NULL); - TEST_EQ(ctx.nvmrw.struct_size, sizeof(*nvm), NULL); -} - -static void verify_nvm_write(struct vba_context *ctx, - int expected_result) -{ - struct nvmrw *nvmrw; - struct nvmrw *nvm = &ctx->nvmrw; - - TEST_EQ(nvmrw_write(ctx, NVM_TYPE_RW_PRIMARY), expected_result, NULL); - - if (expected_result != BDB_SUCCESS) - return; - - nvmrw = (struct nvmrw *)nvmrw1; - TEST_EQ(nvmrw->min_kernel_data_key_version, - nvm->min_kernel_data_key_version, NULL); - TEST_EQ(nvmrw->min_kernel_version, nvm->min_kernel_version, NULL); - TEST_EQ(nvmrw->update_count, nvm->update_count, NULL); -} - -static void test_nvm_write(void) -{ - struct vba_context ctx = { - .bdb = NULL, - .secrets = &secrets, - }; - struct nvmrw nvm = { - .struct_magic = NVM_RW_MAGIC, - .struct_major_version = NVM_HEADER_VERSION_MAJOR, - .struct_minor_version = NVM_HEADER_VERSION_MINOR, - .struct_size = sizeof(struct nvmrw), - .min_kernel_data_key_version = 1, - .min_kernel_version = 2, - .update_count = 3, - }; - - /* Test normal case */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - vbe_write_nvm_failure = 0; - verify_nvm_write(&ctx, BDB_SUCCESS); - - /* Test write failure: once */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - vbe_write_nvm_failure = 1; - verify_nvm_write(&ctx, BDB_SUCCESS); - - /* Test write failure: twice */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - vbe_write_nvm_failure = 2; - verify_nvm_write(&ctx, BDB_ERROR_NVM_WRITE); - - /* Test invalid struct magic */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - ctx.nvmrw.struct_magic ^= 0xff; - verify_nvm_write(&ctx, BDB_ERROR_NVM_RW_MAGIC); - - /* Test struct size too small */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - ctx.nvmrw.struct_size = NVM_RW_MIN_STRUCT_SIZE - 1; - verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_SIZE); - - /* Test struct size too large */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - ctx.nvmrw.struct_size = NVM_RW_MAX_STRUCT_SIZE + 1; - verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_SIZE); - - /* Test invalid struct version */ - memcpy(&ctx.nvmrw, &nvm, sizeof(nvm)); - ctx.nvmrw.struct_major_version = NVM_HEADER_VERSION_MAJOR - 1; - verify_nvm_write(&ctx, BDB_ERROR_NVM_STRUCT_VERSION); - - vbe_write_nvm_failure = 0; -} - -static void verify_kernel_version(uint32_t min_kernel_data_key_version, - uint32_t new_kernel_data_key_version, - uint32_t min_kernel_version, - uint32_t new_kernel_version, - int expected_result) -{ - struct vba_context ctx = { - .bdb = NULL, - .secrets = &secrets, - }; - struct nvmrw *nvm = (struct nvmrw *)nvmrw1; - uint32_t expected_kernel_data_key_version = min_kernel_data_key_version; - uint32_t expected_kernel_version = min_kernel_version; - int should_update = 0; - - if (min_kernel_data_key_version < new_kernel_data_key_version) { - expected_kernel_data_key_version = new_kernel_data_key_version; - should_update = 1; - } - if (min_kernel_version < new_kernel_version) { - expected_kernel_version = new_kernel_version; - should_update = 1; - } - - install_nvm(NVM_TYPE_RW_PRIMARY, min_kernel_data_key_version, - min_kernel_version, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 0, 0, 0); - - TEST_EQ(vba_update_kernel_version(&ctx, new_kernel_data_key_version, - new_kernel_version), - expected_result, NULL); - - if (expected_result != BDB_SUCCESS) - return; - - /* Check data key version */ - TEST_EQ(nvm->min_kernel_data_key_version, - expected_kernel_data_key_version, NULL); - /* Check kernel version */ - TEST_EQ(nvm->min_kernel_version, expected_kernel_version, NULL); - /* Check update_count */ - TEST_EQ(nvm->update_count, 0 + should_update, NULL); - /* Check sync if update is expected */ - if (should_update) - TEST_SUCC(memcmp(nvmrw2, nvmrw1, sizeof(nvmrw1)), NULL); -} - -static void test_update_kernel_version(void) -{ - /* Test update: data key version */ - verify_kernel_version(0, 1, 0, 0, BDB_SUCCESS); - /* Test update: kernel version */ - verify_kernel_version(0, 0, 0, 1, BDB_SUCCESS); - /* Test no update: data key version */ - verify_kernel_version(1, 0, 0, 0, BDB_SUCCESS); - /* Test no update: kernel version */ - verify_kernel_version(0, 0, 1, 0, BDB_SUCCESS); -} - -int vbe_aes256_encrypt(const uint8_t *msg, uint32_t len, const uint8_t *key, - uint8_t *out) -{ - int i; - - for (i = 0; i < len; i++) - out[i] = msg[i] ^ key[i % 256/8]; - - return BDB_SUCCESS; -} - -int vbe_aes256_decrypt(const uint8_t *msg, uint32_t len, const uint8_t *key, - uint8_t *out) -{ - int i; - - for (i = 0; i < len; i++) - out[i] = msg[i] ^ key[i % 256/8]; - - return BDB_SUCCESS; -} - -static void test_update_buc(void) -{ - uint8_t new_buc[BUC_ENC_DIGEST_SIZE]; - uint8_t enc_buc[BUC_ENC_DIGEST_SIZE]; - struct nvmrw *nvm = (struct nvmrw *)nvmrw1; - struct vba_context ctx = { - .bdb = NULL, - .secrets = &secrets, - }; - - install_nvm(NVM_TYPE_RW_PRIMARY, 0, 1, 0); - install_nvm(NVM_TYPE_RW_SECONDARY, 1, 0, 0); - - TEST_SUCC(vba_update_buc(&ctx, new_buc), NULL); - vbe_aes256_encrypt(new_buc, sizeof(new_buc), ctx.secrets->buc, - enc_buc); - TEST_SUCC(memcmp(nvm->buc_enc_digest, enc_buc, sizeof(new_buc)), NULL); -} - -static void test_derive_secrets(void) -{ - uint8_t test_key[sizeof(struct bdb_key) + BDB_RSA4096_KEY_DATA_SIZE]; - struct bdb_key *key = (struct bdb_key *)test_key; - struct vba_context ctx = { - .bdb = NULL, - .secrets = &secrets, - }; - const struct bdb_secrets expected = { - .bdb = { - 0x75, 0xb6, 0x24, 0xaa, 0x72, 0x50, 0xf9, 0x33, - 0x59, 0x45, 0x8d, 0xbf, 0xfa, 0x42, 0xc4, 0xb7, - 0x1b, 0xff, 0xc6, 0x02, 0x02, 0x35, 0xc5, 0x1a, - 0x6c, 0xdc, 0x3a, 0x63, 0xfb, 0x8b, 0xac, 0x53}, - .boot_verified = { - 0x40, 0xf3, 0x9b, 0xdc, 0xf6, 0xb4, 0xe8, 0xdf, - 0x48, 0xc4, 0xfe, 0x02, 0xdd, 0x34, 0x06, 0xd9, - 0xed, 0xd9, 0x55, 0x79, 0xf4, 0x48, 0x58, 0xbf, - 0x32, 0x55, 0xba, 0x21, 0xca, 0xcc, 0x8c, 0xd1}, - .boot_path = { - 0xfb, 0x58, 0x89, 0x58, 0x2f, 0x54, 0xa2, 0xf7, - 0x96, 0x5b, 0x69, 0x77, 0x9b, 0x67, 0x80, 0x39, - 0x7a, 0xd4, 0xc5, 0x3b, 0xcf, 0x95, 0x3f, 0xec, - 0x28, 0x49, 0x55, 0x49, 0x38, 0x27, 0x5d, 0x3c}, - .buc = { - 0x63, 0xa5, 0x30, 0xd7, 0xca, 0xe1, 0x3e, 0x2e, - 0x72, 0x7e, 0x29, 0xc9, 0x37, 0x66, 0x6a, 0x63, - 0x91, 0xd4, 0x8e, 0x8b, 0xbc, 0x1a, 0x7a, 0xcf, - 0xc3, 0x19, 0xa0, 0x87, 0xfc, 0x4d, 0xe1, 0xe8}, - }; - - memset(test_key, 0, sizeof(test_key)); - key->struct_magic = BDB_KEY_MAGIC; - key->struct_major_version = BDB_KEY_VERSION_MAJOR; - key->struct_minor_version = BDB_KEY_VERSION_MINOR; - key->struct_size = sizeof(test_key); - key->hash_alg = BDB_HASH_ALG_SHA256; - key->sig_alg = BDB_SIG_ALG_RSA4096; - key->key_version = 1; - - TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BDB, NULL, - test_key, sizeof(test_key)), NULL); - TEST_SUCC(memcmp(ctx.secrets->bdb, expected.bdb, BDB_SECRET_SIZE), - NULL); - - TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_VERIFIED, NULL, - NULL, 0), NULL); - TEST_SUCC(memcmp(ctx.secrets->boot_verified, expected.boot_verified, - BDB_SECRET_SIZE), NULL); - - TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BOOT_PATH, NULL, - test_key, sizeof(test_key)), NULL); - TEST_SUCC(memcmp(ctx.secrets->boot_path, expected.boot_path, - BDB_SECRET_SIZE), NULL); - - TEST_SUCC(vba_derive_secret(&ctx, BDB_SECRET_TYPE_BUC, NULL, NULL, 0), - NULL); - TEST_SUCC(memcmp(ctx.secrets->buc, expected.buc, - BDB_SECRET_SIZE), NULL); -} - -int main(int argc, char *argv[]) -{ - if (argc != 2) { - fprintf(stderr, "Usage: %s <keys_dir>", argv[0]); - return -1; - } - printf("Running BDB SP-RW tests...\n"); - - test_verify_aprw(argv[1]); - test_nvm_read(); - test_nvm_write(); - test_update_kernel_version(); - test_update_buc(); - test_derive_secrets(); - - return gTestSuccess ? 0 : 255; -} diff --git a/tests/bdb_test.c b/tests/bdb_test.c deleted file mode 100644 index 693d6191..00000000 --- a/tests/bdb_test.c +++ /dev/null @@ -1,504 +0,0 @@ -/* 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. - * - * Unit tests - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "2sha.h" -#include "bdb.h" -#include "host.h" -#include "test_common.h" - -static void check_header_tests(void) -{ - struct bdb_header sgood = { - .struct_magic = BDB_HEADER_MAGIC, - .struct_major_version = BDB_HEADER_VERSION_MAJOR, - .struct_minor_version = BDB_HEADER_VERSION_MINOR, - .struct_size = sizeof(struct bdb_header), - .bdb_load_address = -1, - .bdb_size = 1024, - .signed_size = 512, - .oem_area_0_size = 256, - }; - const size_t ssize = sgood.struct_size; - struct bdb_header s; - - s = sgood; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_SUCCESS); - TEST_EQ_S(bdb_check_header(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - s = sgood; - s.oem_area_0_size++; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_ERROR_OEM_AREA_SIZE); - - s = sgood; - s.bdb_size = ssize - 1; - TEST_EQ_S(bdb_check_header(&s, ssize), BDB_ERROR_BDB_SIZE); -} - -static void check_key_tests(void) -{ - struct bdb_key sgood = { - .struct_magic = BDB_KEY_MAGIC, - .struct_major_version = BDB_KEY_VERSION_MAJOR, - .struct_minor_version = BDB_KEY_VERSION_MINOR, - .struct_size = (sizeof(struct bdb_key) + - BDB_RSA4096_KEY_DATA_SIZE), - .hash_alg = BDB_HASH_ALG_SHA256, - .sig_alg = BDB_SIG_ALG_RSA4096, - .key_version = 1, - .description = "Test key", - }; - const size_t ssize = sgood.struct_size; - struct bdb_key s; - - s = sgood; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_SUCCESS); - TEST_EQ_S(bdb_check_key(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_SUCCESS); - - /* Limited algorithm choices at present */ - s = sgood; - s.hash_alg = BDB_HASH_ALG_INVALID; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_HASH_ALG); - - /* This works because ECDSA521 signatures are smaller than RSA4096 */ - s = sgood; - s.sig_alg = BDB_SIG_ALG_ECSDSA521; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.sig_alg = BDB_SIG_ALG_INVALID; - TEST_EQ_S(bdb_check_key(&s, ssize), BDB_ERROR_SIG_ALG); -} - -static void check_sig_tests(void) -{ - struct bdb_sig sgood = { - .struct_magic = BDB_SIG_MAGIC, - .struct_major_version = BDB_SIG_VERSION_MAJOR, - .struct_minor_version = BDB_SIG_VERSION_MINOR, - .struct_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE, - .hash_alg = BDB_HASH_ALG_SHA256, - .sig_alg = BDB_SIG_ALG_RSA4096, - .signed_size = 123, - .description = "Test sig", - }; - const size_t ssize = sgood.struct_size; - struct bdb_sig s; - - s = sgood; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_SUCCESS); - TEST_EQ_S(bdb_check_sig(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size++; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_SUCCESS); - - /* Limited algorithm choices at present */ - s = sgood; - s.hash_alg = BDB_HASH_ALG_INVALID; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_HASH_ALG); - - /* This works because ECDSA521 signatures are smaller than RSA4096 */ - s = sgood; - s.sig_alg = BDB_SIG_ALG_ECSDSA521; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.sig_alg = BDB_SIG_ALG_INVALID; - TEST_EQ_S(bdb_check_sig(&s, ssize), BDB_ERROR_SIG_ALG); -} - -static void check_data_tests(void) -{ - struct bdb_data sgood = { - .struct_magic = BDB_DATA_MAGIC, - .struct_major_version = BDB_DATA_VERSION_MAJOR, - .struct_minor_version = BDB_DATA_VERSION_MINOR, - .struct_size = sizeof(struct bdb_data), - .data_version = 1, - .oem_area_1_size = 256, - .num_hashes = 3, - .hash_entry_size = sizeof(struct bdb_hash), - .signed_size = 2048, - .description = "Test data", - }; - const size_t ssize = sgood.signed_size; - struct bdb_data s; - - s = sgood; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_SUCCESS); - TEST_EQ_S(bdb_check_data(&s, ssize - 1), BDB_ERROR_BUF_SIZE); - - s = sgood; - s.struct_size--; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_SIZE); - - s = sgood; - s.struct_magic++; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_MAGIC); - - s = sgood; - s.struct_major_version++; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_STRUCT_VERSION); - - /* Description must contain a null */ - s = sgood; - memset(s.description, 'x', sizeof(s.description)); - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_DESCRIPTION); - - /* Data AFTER the null is explicitly allowed, though */ - s = sgood; - s.description[100] = 'x'; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_SUCCESS); - - s = sgood; - s.hash_entry_size--; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_HASH_ENTRY_SIZE); - - s = sgood; - s.oem_area_1_size++; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_OEM_AREA_SIZE); - - /* Check exact size needed */ - s = sgood; - s.signed_size = sizeof(s) + s.num_hashes * sizeof(struct bdb_hash) + - s.oem_area_1_size; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_SUCCESS); - s.signed_size--; - TEST_EQ_S(bdb_check_data(&s, ssize), BDB_ERROR_SIGNED_SIZE); - - /* - * TODO: Verify wraparound check works. That can only be tested on a - * platform where size_t is uint32_t, because otherwise a 32-bit - * oem_area_1_size can't cause wraparound. - */ -} - -/** - * Test bdb_verify() and bdb_create() - */ -static void check_bdb_verify(const char *key_dir) -{ - uint8_t oem_area_0[32] = "Some OEM area."; - uint8_t oem_area_1[64] = "Some other OEM area."; - char filename[1024]; - - struct bdb_hash hash[2] = { - { - .offset = 0x10000, - .size = 0x18000, - .partition = 1, - .type = BDB_DATA_SP_RW, - .load_address = 0x100000, - .digest = {0x11, 0x11, 0x11, 0x10}, - }, - { - .offset = 0x28000, - .size = 0x20000, - .partition = 1, - .type = BDB_DATA_AP_RW, - .load_address = 0x200000, - .digest = {0x22, 0x22, 0x22, 0x20}, - }, - }; - - struct bdb_create_params p = { - .bdb_load_address = 0x11223344, - .oem_area_0 = oem_area_0, - .oem_area_0_size = sizeof(oem_area_0), - .oem_area_1 = oem_area_1, - .oem_area_1_size = sizeof(oem_area_1), - .header_sig_description = (char *)"The header sig", - .data_sig_description = (char *)"The data sig", - .data_description = (char *)"Test BDB data", - .data_version = 3, - .hash = hash, - .num_hashes = 2, - }; - - uint8_t bdbkey_digest[BDB_SHA256_DIGEST_SIZE]; - struct bdb_header *hgood, *h; - size_t hsize; - - /* Load keys */ - snprintf(filename, sizeof(filename), "%s/bdbkey.keyb", key_dir); - p.bdbkey = bdb_create_key(filename, 100, "BDB key"); - snprintf(filename, sizeof(filename), "%s/datakey.keyb", key_dir); - p.datakey = bdb_create_key(filename, 200, "datakey"); - snprintf(filename, sizeof(filename), "%s/bdbkey.pem", key_dir); - p.private_bdbkey = read_pem(filename); - snprintf(filename, sizeof(filename), "%s/datakey.pem", key_dir); - p.private_datakey = read_pem(filename); - if (!p.bdbkey || !p.datakey || !p.private_bdbkey || !p.private_datakey) { - fprintf(stderr, "Unable to load test keys\n"); - exit(2); - } - - vb2_digest_buffer((uint8_t *)p.bdbkey, p.bdbkey->struct_size, - VB2_HASH_SHA256, - bdbkey_digest, BDB_SHA256_DIGEST_SIZE); - - /* Create the test BDB */ - hgood = bdb_create(&p); - if (!hgood) { - fprintf(stderr, "Unable to create test BDB\n"); - exit(2); - } - hsize = hgood->bdb_size; - - /* Allocate a copy we can mangle */ - h = calloc(hsize, 1); - - /* As created, it should pass */ - memcpy(h, hgood, hsize); - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_SUCCESS); - - /* It can accept a NULL pointer as bdb_key_digest */ - memcpy(h, hgood, hsize); - TEST_EQ_S(bdb_verify(h, hsize, NULL), BDB_GOOD_OTHER_THAN_KEY); - - /* Mangle each component in turn */ - memcpy(h, hgood, hsize); - h->struct_magic++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_bdbkey(h))->struct_magic++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_BDBKEY); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_bdbkey(h))->key_version++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_GOOD_OTHER_THAN_KEY); - - memcpy(h, hgood, hsize); - h->oem_area_0_size += hsize; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_OEM_AREA_0); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_datakey(h))->struct_magic++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATAKEY); - - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_datakey(h))->struct_size += 4; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_BDB_SIGNED_SIZE); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->struct_magic++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->signed_size--; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_header_sig(h))->sig_data[0] ^= 0x42; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - /* Also make sure the header sig really covers all the fields */ - memcpy(h, hgood, hsize); - ((struct bdb_key *)bdb_get_datakey(h))->key_version++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_0(h))[0] ^= 0x42; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_0(h))[p.oem_area_0_size - 1] ^= 0x24; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_HEADER_SIG); - - /* Check data header */ - memcpy(h, hgood, hsize); - ((struct bdb_data *)bdb_get_data(h))->struct_magic++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->struct_magic++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), - BDB_ERROR_DATA_CHECK_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->signed_size--; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), - BDB_ERROR_DATA_SIGNED_SIZE); - - memcpy(h, hgood, hsize); - ((struct bdb_sig *)bdb_get_data_sig(h))->sig_data[0] ^= 0x42; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - /* Also make sure the data sig really covers all the fields */ - memcpy(h, hgood, hsize); - ((struct bdb_data *)bdb_get_data(h))->data_version--; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_1(h))[0] ^= 0x42; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((uint8_t *)bdb_get_oem_area_1(h))[p.oem_area_1_size - 1] ^= 0x24; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_hash *)bdb_get_hash_by_type(h, BDB_DATA_SP_RW))->offset++; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - memcpy(h, hgood, hsize); - ((struct bdb_hash *)bdb_get_hash_by_type(h, BDB_DATA_AP_RW)) - ->digest[0] ^= 0x96; - TEST_EQ_S(bdb_verify(h, hsize, bdbkey_digest), BDB_ERROR_DATA_SIG); - - /* - * This is also a convenient place to test that all the parameters we - * fed into bdb_create() also worked. That also tests all the - * bdb_get_*() functions. - */ - memcpy(h, hgood, hsize); - TEST_EQ_S(h->bdb_load_address, p.bdb_load_address); - - TEST_EQ_S(strcmp(bdb_get_bdbkey(h)->description, p.bdbkey->description), - 0); - TEST_EQ_S(bdb_get_bdbkey(h)->key_version, p.bdbkey->key_version); - - TEST_EQ_S(h->oem_area_0_size, p.oem_area_0_size); - TEST_EQ_S(memcmp(bdb_get_oem_area_0(h), oem_area_0, sizeof(oem_area_0)), - 0); - - TEST_EQ_S(strcmp(bdb_get_datakey(h)->description, p.datakey->description), - 0); - TEST_EQ_S(bdb_get_datakey(h)->key_version, p.datakey->key_version); - - TEST_EQ_S(strcmp(bdb_get_header_sig(h)->description, - p.header_sig_description), 0); - - TEST_EQ_S(strcmp(bdb_get_data(h)->description, p.data_description), 0); - TEST_EQ_S(bdb_get_data(h)->data_version, p.data_version); - TEST_EQ_S(bdb_get_data(h)->num_hashes, p.num_hashes); - - TEST_EQ_S(bdb_get_data(h)->oem_area_1_size, p.oem_area_1_size); - TEST_EQ_S(memcmp(bdb_get_oem_area_1(h), oem_area_1, sizeof(oem_area_1)), - 0); - - TEST_EQ_S(strcmp(bdb_get_data_sig(h)->description, - p.data_sig_description), 0); - - /* Test getting hash entries */ - memcpy(h, hgood, hsize); - TEST_EQ_S(bdb_get_hash_by_type(h, BDB_DATA_SP_RW) - ->offset, hash[0].offset); - TEST_EQ_S(bdb_get_hash_by_index(h, 0) - ->offset, hash[0].offset); - TEST_EQ_S(bdb_get_hash_by_type(h, BDB_DATA_AP_RW) - ->offset, hash[1].offset); - TEST_EQ_S(bdb_get_hash_by_index(h, 1) - ->offset, hash[1].offset); - /* And a non-existent one */ - TEST_PTR_EQ(bdb_get_hash_by_type(h, BDB_DATA_MCU), NULL, NULL); - TEST_PTR_EQ(bdb_get_hash_by_index(h, 2), NULL, NULL); - - /* - * TODO: Verify wraparound checks works. That can only be tested on a - * platform where size_t is uint32_t, because otherwise a 32-bit - * oem_area_1_size can't cause wraparound. - */ - - /* Free keys and buffers */ - free(p.bdbkey); - free(p.datakey); - RSA_free(p.private_bdbkey); - RSA_free(p.private_datakey); - free(hgood); - free(h); -} - -/*****************************************************************************/ - -int main(int argc, char *argv[]) -{ - if (argc != 2) { - fprintf(stderr, "Usage: %s <keys_dir>", argv[0]); - return -1; - } - printf("Running BDB tests...\n"); - - check_header_tests(); - check_key_tests(); - check_sig_tests(); - check_data_tests(); - check_bdb_verify(argv[1]); - - printf("All tests passed!\n"); - - return gTestSuccess ? 0 : 255; -} diff --git a/tests/futility/data/bdb.bin b/tests/futility/data/bdb.bin Binary files differdeleted file mode 100644 index 1fe84463..00000000 --- a/tests/futility/data/bdb.bin +++ /dev/null diff --git a/tests/futility/run_test_scripts.sh b/tests/futility/run_test_scripts.sh index 7171b483..8ccbab6e 100755 --- a/tests/futility/run_test_scripts.sh +++ b/tests/futility/run_test_scripts.sh @@ -40,7 +40,6 @@ export OUTDIR # These are the scripts to run. Binaries are invoked directly by the Makefile. TESTS=" -${SCRIPTDIR}/test_bdb.sh ${SCRIPTDIR}/test_create.sh ${SCRIPTDIR}/test_dump_fmap.sh ${SCRIPTDIR}/test_gbb_utility.sh diff --git a/tests/futility/test_bdb.sh b/tests/futility/test_bdb.sh deleted file mode 100755 index 0f0c0249..00000000 --- a/tests/futility/test_bdb.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -eux -# 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. - -me=${0##*/} -TMP="$me.tmp" - -# Work in scratch directory -cd "$OUTDIR" -BDB_FILE=bdb.bin - -TESTKEY_DIR=${SRCDIR}/tests/testkeys -TESTDATA_DIR=${SRCDIR}/tests/testdata - -BDBKEY_PUB=${TESTKEY_DIR}/bdbkey.keyb -BDBKEY_PRI=${TESTKEY_DIR}/bdbkey.pem -DATAKEY_PUB=${TESTKEY_DIR}/datakey.keyb -DATAKEY_PRI=${TESTKEY_DIR}/datakey.pem -BDBKEY_DIGEST=${TESTDATA_DIR}/bdbkey_digest.bin -DATAKEY_DIGEST=${TESTDATA_DIR}/datakey_digest.bin -DATA_FILE=${TESTDATA_DIR}/sp-rw.bin - -declare -i num_hash - -# Verify a BDB -# -# $1: Key digest file -# $2: Any remaining option passed to futility bdb --verify -verify() { - local key_digest=${1:-${BDBKEY_DIGEST}} - local extra_option=${2:-} - ${FUTILITY} bdb --verify ${BDB_FILE} --key_digest ${key_digest} \ - ${extra_option} -} - -get_num_hash() { - printf "%d" \ - $(${FUTILITY} show ${BDB_FILE} \ - | grep '# of Hashes' | cut -d':' -f 2) -} - -# Tests field matches a specified value in a BDB -# e.g. check_field 'Data Version:' 2 returns error if the data version isn't 2. -check_field() { - # Find the field - x=$(${FUTILITY} show ${BDB_FILE} | grep "${1}") - [ "${x}" ] || return 1 - # Remove the field name - x=${x##*:} - [ "${x}" ] || return 1 - # Remove the leading and trailing spaces - x=${x//[[:blank:]]/} - [ "${x}" == "${2}" ] || return 1 -} - -# Demonstrate bdb --create can create a valid BDB -load_address=0x60061ec0de -${FUTILITY} bdb --create ${BDB_FILE} \ - --bdbkey_pri ${BDBKEY_PRI} --bdbkey_pub ${BDBKEY_PUB} \ - --datakey_pub ${DATAKEY_PUB} --datakey_pri ${DATAKEY_PRI} \ - --load_address ${load_address} -verify -check_field "Load Address:" ${load_address} - -# Demonstrate bdb --add can add a new hash -num_hash=$(get_num_hash) -${FUTILITY} bdb --add ${BDB_FILE} \ - --data ${DATA_FILE} --partition 1 --type 2 --offset 3 --load_address 4 -# Use futility show command to verify the hash is added -num_hash+=1 -[ $(get_num_hash) -eq $num_hash ] -# TODO: verify partition, type, offset, and load_address - -# Demonstrate futility bdb --resign can resign the BDB -data_version=2 -${FUTILITY} bdb --resign ${BDB_FILE} --datakey_pri ${DATAKEY_PRI} \ - --data_version $data_version -verify -check_field "Data Version:" $data_version - -# Demonstrate futility bdb --resign can resign with a new data key -# Note resigning with a new data key requires a private BDB key as well -${FUTILITY} bdb --resign ${BDB_FILE} \ - --bdbkey_pri ${BDBKEY_PRI} \ - --datakey_pri ${BDBKEY_PRI} --datakey_pub ${BDBKEY_PUB} -verify - -# Demonstrate futility bdb --resign can resign with a new BDB key -${FUTILITY} bdb --resign ${BDB_FILE} \ - --bdbkey_pri ${DATAKEY_PRI} --bdbkey_pub ${DATAKEY_PUB} -verify ${DATAKEY_DIGEST} - -# Demonstrate futility bdb --verify can return success when key digest doesn't -# match but --ignore_key_digest is specified. -verify ${BDBKEY_DIGEST} --ignore_key_digest - -# cleanup -rm -rf ${TMP}* -exit 0 diff --git a/tests/futility/test_file_types.c b/tests/futility/test_file_types.c index c77802bd..9999223d 100644 --- a/tests/futility/test_file_types.c +++ b/tests/futility/test_file_types.c @@ -37,7 +37,6 @@ static struct { {FILE_TYPE_VB2_PRIVKEY, "tests/futility/data/sample.vbprik2"}, {FILE_TYPE_PEM, "tests/testkeys/key_rsa2048.pem"}, {FILE_TYPE_USBPD1, "tests/futility/data/zinger_mp_image.bin"}, - {FILE_TYPE_BDB, "tests/futility/data/bdb.bin"}, {FILE_TYPE_RWSIG, }, /* need a test for this */ }; BUILD_ASSERT(ARRAY_SIZE(test_case) == NUM_FILE_TYPES); diff --git a/tests/futility/test_file_types.sh b/tests/futility/test_file_types.sh index b0248a94..4b7a9fb6 100755 --- a/tests/futility/test_file_types.sh +++ b/tests/futility/test_file_types.sh @@ -44,7 +44,6 @@ test_case "pubkey21" "tests/futility/data/sample.vbpubk2" test_case "prikey21" "tests/futility/data/sample.vbprik2" test_case "pem" "tests/testkeys/key_rsa2048.pem" test_case "pem" "tests/testkeys/key_rsa8192.pub.pem" -test_case "bdb" "tests/futility/data/bdb.bin" # Expect failure here. fail_case "/Sir/Not/Appearing/In/This/Film" diff --git a/tests/testdata/bdbkey_digest.bin b/tests/testdata/bdbkey_digest.bin deleted file mode 100644 index 47d4e68a..00000000 --- a/tests/testdata/bdbkey_digest.bin +++ /dev/null @@ -1 +0,0 @@ -ljVN"Isv}k͊b
'T
\ No newline at end of file diff --git a/tests/testkeys/bdbkey.crt b/tests/testkeys/bdbkey.crt deleted file mode 100644 index 383216a3..00000000 --- a/tests/testkeys/bdbkey.crt +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFtTCCA52gAwIBAgIJANitnQKymb5VMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQwHhcNMTAwOTI5MTgxNjM4WhcNMTAxMDI5MTgxNjM4WjBF -MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 -ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAm5v71oqFynujT4FVq5lKaYxpmKfXdeBNKDmLzgu7fXLUKaEqTGEDsseE -5qyaaP+dmTnQKfne7G31zgf46//YEl+u5Gt/S4oAgYyvs3rjymzD5kVOLEAzgrIX -AwyhDFARRzAFWos43hypunHGvu4fDBAzZ3zGVulhjgAzD/gNjToVYCP7bj6kTaDx -1u9siCKdYN09vGwSUt9WuV+yort7kns/B8ArVxt3bFSjsAxuWel/dJyLwCMQ9XAx -dgWpg3RBUsK/KgekQybPLrhLYJn1AeOApwzJ4HoJSqU/1jCEaGrKA/KtCRXiurZz -6lBi7sElsigjBvEZH0iCmmRgH3Oi/cbpHIs1C6YHvCCbO90ntwgtDf0+2WJtFtbG -t5Do3CXri0tcsXBWqISSK3VzzjHH691BVwLuoBvF1XICMEjmq9aJ+MdbEe4E+GU8 -TV9NnRnuYyOUoxeisyXiArUUI9+1qL6pIgulTlY2Ch51QZY5n2aYY97PtosNotbS -ylMrLvWXGiiQWxux12eOnB3c/3wNYWey8Km4cmOhEOYz7hLz2r1uIoC/SzM5wLnn -TEQmaiUDNV9R3Gj3E3xkpTq3UNSSPsV7k8lInMtWqzps6aTvBw1k6i6CUvWbEZqm -t/0bimQHOEdg3OrJjQpwTKSp4ouSyVu0IphDwy1yjKCfNWKRzrUCAwEAAaOBpzCB -pDAdBgNVHQ4EFgQUyBKBgFg+vONV1sbup7QtFa7DR78wdQYDVR0jBG4wbIAUyBKB -gFg+vONV1sbup7QtFa7DR7+hSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT -b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQDY -rZ0Cspm+VTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQA0wtlLEAKR -ctB41x/V10SMFIg5eLbDrUKQQT33BddrhFu0blc7U5jgXjqTYS80xIlOC0hXtN7D -Z478st3NAxjtvBKxNMWB9Ppz6+15UENnXNGLElhRPaeAbxBs7zVB64b8fY69EJRe -JOJNp6+c4WJsHWzxrmfHD0Wx18pJ877ThRi/ZH0QP2TjPc0gZT4szP1taoOJ7SXy -gO10WfPoF1GgI/VXhPLnk2zXpTlFdp+qyKOtDFxOOK/cVKdXAxDDDO9DAw6cvrEn -mPS2Zml9HI25/CrE00y+k4w7bqzNeGNzhSGPBvq5Yqnefc1dJSdDQZ3XLG9Fis4a -nVfuSTvP1MUrFEGEvuxRcA0rWPwQtYSHHs8ZnpT6eayTPcpDvWSihe4xUywirXTT -kbWgeABGQGaoAnFJYhjqBROGdVb4V3vbsjbCi8k2r4IIcqOzp6OIJxha2LvkZ+iu -f+OlMVAO/C1LbRsVQkfJp7NxEt6PVewQV5Kgnwlf+x7Q2tUfZfdpLd/EMtojv3BD -Ewx5X2yHGXcYZG/C1kNzyGTfg97/+55mtNlkTmo8elcPxlpnEuMXEv4JthnRy90x -ZLflcR9q0pOiV+n//KyQvfjH99JmRtVJGG8xlDEtRbJWjFQD/uSEBxeS0T6INrza -0WTaiIOZB1vMPe6CDYDWDzrFdQrD6HoWDQ== ------END CERTIFICATE----- diff --git a/tests/testkeys/bdbkey.keyb b/tests/testkeys/bdbkey.keyb Binary files differdeleted file mode 100644 index 515aaa98..00000000 --- a/tests/testkeys/bdbkey.keyb +++ /dev/null diff --git a/tests/testkeys/bdbkey.pem b/tests/testkeys/bdbkey.pem deleted file mode 100644 index 204b440f..00000000 --- a/tests/testkeys/bdbkey.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIJKQIBAAKCAgEAm5v71oqFynujT4FVq5lKaYxpmKfXdeBNKDmLzgu7fXLUKaEq -TGEDsseE5qyaaP+dmTnQKfne7G31zgf46//YEl+u5Gt/S4oAgYyvs3rjymzD5kVO -LEAzgrIXAwyhDFARRzAFWos43hypunHGvu4fDBAzZ3zGVulhjgAzD/gNjToVYCP7 -bj6kTaDx1u9siCKdYN09vGwSUt9WuV+yort7kns/B8ArVxt3bFSjsAxuWel/dJyL -wCMQ9XAxdgWpg3RBUsK/KgekQybPLrhLYJn1AeOApwzJ4HoJSqU/1jCEaGrKA/Kt -CRXiurZz6lBi7sElsigjBvEZH0iCmmRgH3Oi/cbpHIs1C6YHvCCbO90ntwgtDf0+ -2WJtFtbGt5Do3CXri0tcsXBWqISSK3VzzjHH691BVwLuoBvF1XICMEjmq9aJ+Mdb -Ee4E+GU8TV9NnRnuYyOUoxeisyXiArUUI9+1qL6pIgulTlY2Ch51QZY5n2aYY97P -tosNotbSylMrLvWXGiiQWxux12eOnB3c/3wNYWey8Km4cmOhEOYz7hLz2r1uIoC/ -SzM5wLnnTEQmaiUDNV9R3Gj3E3xkpTq3UNSSPsV7k8lInMtWqzps6aTvBw1k6i6C -UvWbEZqmt/0bimQHOEdg3OrJjQpwTKSp4ouSyVu0IphDwy1yjKCfNWKRzrUCAwEA -AQKCAgEAlbfvBu0g7UEoUEbQdtp2jjdbIlXbKL83fYxgx07ihkEFgUhfuj1doZX2 -eTt5Fa1bpSHK95hCtJjX9/QTvH3dF1CYpY4IXFXbRspmAvoqUYl0swnbvRfId+eB -3J06Fu6ysRuzCvsJLCvH4mu2Hd5eYOz1iIy1CMpj4oyulJ7F6ywHhQkZ0WjUDRzd -kz+p3RHw+lHkJHaW6sWYW6OH7KsWqkmKy5pKGPWEYebN14UeZ8QRrdExZRxYJM5d -yICKKMCiWU6nP3k6wqGElh8b50Y6RibukcvsMN86MWftk9f6jbyxwjqr4iH8lEkY -HkpZ5f5QlqmnifZPhZnujz4kfh50oteC2QPQ0hrNYCDG75wuiNX/vINVfrKG0ddg -iQDFqyQyQirxCGQgy7Wto08KAzKt146ST28N+kdF/kY14ou5f5+GlWQJcnqdHd2p -R25MueXUsY3I63dULR6k02Y6M7Tzo39lYe0LV82+G0A3iGpI+eM7xw/sQDNb2sQs -jCcz7XPrfTomrVJaW1FkM8vM6eWhuhAyDFP+unz0aMnKrkUrarh4t9QpriiCjm3E -HV2Hc7t/Do/w+B3rywKy3PE2yO49eGz20um0JqWcAbGDZY2vDnyV+/xibxqaIZUo -saI/btlyvCv00812momkX/qWwS+1GHvyYYcpIg0XQbZY1TvEi8ECggEBAM6LTfVu -MKNwW/QdZ6pxKl/Oy8zlb1o8HET5hKCdhoMvpwlvpO2qSvlCxH3VZTmcXIXd+Mkd -e4OZrzeMLVxMd64xP10k2ui/O2/8G38xmpMGqZihc+LnY6JgajujfAQHljOgrAJL -xzO2Gk4oWX72oA6jqP8LZkRp/9acTWqBTKs6MOdrfn6I3k0urBB29+jcbqFAfgMx -hfcTKAOHYmg/SeEZDvKP6fRDJGMGXqJ4TaBXjsnhNGCjGmuCqJhxxIGCI/AVK10B -CjEboo9vACzNE1/JMxH8aT5up7e+7R/WoiJ5e3jlvSKmcO7KiR27JVsAlZeIddKd -LzG9KKZ8Yla0U3MCggEBAMDefKVTqSPaG7cmAQGtXrbBDLdCWIaT08v+kMw/drlq -NqLD+1ct098iFwRtKaYPERPKqNtxfJdkUMqWELBWV2Sq4Fi+JVXjGOUctP7Atd2x -6NJ9xHqQKQwKUv0/9jN5Oie9sFvsLwPAJNOJej1BrmvPZvc0CoMyOjkmxEhYu3qG -i26ZTSZSCTrbE8eAL0EJdH0gB7Ryuks8O+jEF7eXuZLZyN3AromISJtmLVlMFZ7m -+0sQnZQqwNF+BIrOgO+3R61jjNzCJbFo7frvRIlDSnrbmWp6sYns1cjhZiKCnO78 -RgDiaJcuceqsalgBZi8/Fmam2IPeqhvTNg+5alCuWzcCggEAXFjglFmeGZVFJ9J1 -5TkPzyJw8L2smdXCdfxyFjYYTFNkBc4LGdBIEUaPAAwHZEjK/XePoqwx61cthlKA -fYIbCKEwSX8O+X13H8zCpo4RJKeX8IxPeiYm4BTnqp6f9lVGDPNLtQMYn8BN5qAX -07KFQcZe6xm3seMK5nOgEXyaQPyVnQLs3bpoWm4BtKLcmRrlw+dH8DmWQjAoddt0 -XlPdvm0rx7wcyH+0pynT6iSL4KMFTrIIbyS9zU/v/ajwSU9crh1o8/5hBi/q8OKa -W22dufgFg4ctryJejsMo1lFq0KssT5O4iuOMHtgjkk14mEWcnNIAjBiHX1/J6xY2 -Cbo6jQKCAQBtvmt4e1kz8Ehy92n9NVQ+cyy0HklXEkiiu9BSmA4LRPefuBqNKaN0 -ROaJ+z+GoO4br+ZTL4kwb8FU9Py8CfUib+TGOjPuYhFpVONcTfVuF2yeUTf6cYsZ -sco1Fi8WbPV9ZX8zXvoFjVCnGYP31SbVa6dwJCmTK4JbwMZRUEQlXOd74Dk5A9cC -qWPg0fyRajrhc9dOgzWj17tTIDlKm0fZ2phkLd5inayK2CIXvKZUy6PTu7medJFQ -4v7cqNJPFJ/xdkLR3psqDsXTUlBSNnrr24a5QuVA0QV4j2DZZC6+Acgneqz+0Uu6 -t66vMuSdH620bV2n84wh1xXc7qkjDYMTAoIBAQC6DsTyBGNNI0/DGwAsae5Zri8w -T/SOER7Tc/PCgQyFUNsJJc/OmSy66PPiH2HzqLjl6/jeiJP++oCnfO6pNTq1Fjz4 -Le2iS1szlcuJ9QLdtn2LTqORzdQVpka42X+o+NqJEdzkZb/N6eBA4PPQdTxHIiu1 -WGBpDc5vGkpuzLm9SVCw/4SD84z+Nhs0pqOvwWhmQWCtl28fgqU4LMeOX1Wz5P8E -IledlgbCZh2KwXuv3BJdkawuwrSPsahnZmoJapx2dE+FkNl4equaBwImfLf5Qifj -IhIN5GueO9k/D2/7/XvW2qJ3Vy0z0xMMNiTVYufVpbh77Kn2ebKfROlkzMEU ------END RSA PRIVATE KEY----- diff --git a/utility/bdb_extend.c b/utility/bdb_extend.c deleted file mode 100644 index c66f8bb2..00000000 --- a/utility/bdb_extend.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright 2016 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include "2sha.h" -#include "bdb.h" -#include "bdb_api.h" -#include "host.h" - -static f_extend extend = vb2_sha256_extend; - -static void help(void) -{ - fprintf(stderr, - "Usage: bdb_extend -b bdb_file -s bds_file " - "[-d digest_file] [-m]\n" - "\n" - "Extends BDS based on a given BDB. When '-m' is given, a " - "MVMAP2315's sha256_extend algorithm will be used. When " - "digest_file is specified, the validity of the BDB key is " - "checked and the secrets will be derived differently.\n"); -} - -#define PACK32(str, x) \ - { \ - *(x) = ((uint32_t) *((str) + 3) ) \ - | ((uint32_t) *((str) + 2) << 8) \ - | ((uint32_t) *((str) + 1) << 16) \ - | ((uint32_t) *((str) + 0) << 24); \ - } - -/** - * MVMAP2315's implementation of sha256 extend - * - * This performs incorrect but still cryptographically secure sha256 extension. - * This is provided for test purpose only. - * - * See vb2_sha256_extend for details on arguments. - */ -static void mvmap2315_sha256_extend(const uint8_t *from, const uint8_t *by, - uint8_t *to) -{ - struct vb2_sha256_context dc; - int i; - - vb2_sha256_init(&dc); - for (i = 0; i < 8; i++) { - PACK32(from, &dc.h[i]); - from += 4; - } - vb2_sha256_update(&dc, by, VB2_SHA256_BLOCK_SIZE); - vb2_sha256_finalize(&dc, to); -} - -static void dump_secret(const uint8_t *secret, const char *label) -{ - int i; - printf("%s = {", label); - for (i = 0; i < BDB_SECRET_SIZE; i++) { - if (i % 8 == 0) - printf("\n\t"); - else - printf(" "); - printf("0x%02x,", secret[i]); - } - printf("\n}\n"); -} - -static void dump_secrets(struct vba_context *ctx, const uint8_t *wsr) -{ - dump_secret(ctx->secrets->bdb, "bdb"); - dump_secret(ctx->secrets->boot_path, "boot_path"); - dump_secret(ctx->secrets->boot_verified, "boot_verified"); - dump_secret(ctx->secrets->nvm_wp, "nvm_wp"); - dump_secret(ctx->secrets->nvm_rw, "nvm_rw"); - dump_secret(wsr, "wsr"); -} - -static int derive_secrets(struct vba_context *ctx, - const uint8_t *bdb, uint8_t *wsr) -{ - struct bdb_secrets secrets; - - memset(&secrets, 0, sizeof(secrets)); - - ctx->secrets = &secrets; - if (vba_extend_secrets_ro(ctx, bdb, wsr, extend)) { - fprintf(stderr, "ERROR: Failed to derive secrets\n"); - return -1; - } - - fprintf(stderr, "LOG: Secrets are derived as follows\n"); - dump_secrets(ctx, wsr); - - return 0; -} - -int main(int argc, char *argv[]) -{ - struct vba_context ctx; - uint8_t *bdb, *bds; - uint8_t *key_digest = NULL; - uint32_t bdb_size, bds_size, digest_size; - const char *bdb_file = NULL; - const char *digest_file = NULL; - const char *bds_file = NULL; - int rv; - int opt; - - while ((opt = getopt(argc, argv, "b:d:hms:")) != -1) { - switch(opt) { - case 'b': - bdb_file = optarg; - break; - case 'd': - digest_file = optarg; - break; - case 'h': - help(); - return 0; - case 'm': - extend = mvmap2315_sha256_extend; - break; - case 's': - bds_file = optarg; - break; - default: - help(); - return -1; - } - } - - if (!bdb_file || !bds_file) { - fprintf(stderr, "ERROR: BDB and BDS aren't specified\n\n"); - help(); - return -1; - } - - /* Read BDB */ - bdb = read_file(bdb_file, &bdb_size); - if (!bdb) { - fprintf(stderr, "ERROR: Unable to read %s\n", bdb_file); - return -1; - } - - /* Read BDS */ - bds = read_file(bds_file, &bds_size); - if (!bds) { - fprintf(stderr, "ERROR: Unable to read %s\n", bds_file); - return -1; - } - if (bds_size != BDB_SECRET_SIZE) { - fprintf(stderr, "ERROR: Invalid BDS size: %d\n", bds_size); - return -1; - } - - /* Read key digest if provided */ - if (digest_file) { - key_digest = read_file(digest_file, &digest_size); - if (!key_digest) { - fprintf(stderr, - "ERROR: Unable to read %s\n", digest_file); - return -1; - } - } - - /* Verify BDB and set a flag based on the result */ - memset(&ctx, 0, sizeof(ctx)); - rv = bdb_verify(bdb, bdb_size, key_digest); - if (rv) { - if (rv != BDB_GOOD_OTHER_THAN_KEY) { - fprintf(stderr, "ERROR: BDB is invalid: %d\n", rv); - return -1; - } - fprintf(stderr, - "WARNING: BDB is valid but key digest doesn't match\n"); - } else { - ctx.flags |= VBA_CONTEXT_FLAG_BDB_KEY_EFUSED; - fprintf(stderr, "BDB is successfully verified by eFused key\n"); - } - - /* Derive secrets and dump the values */ - return derive_secrets(&ctx, bdb, bds); -} |