diff options
author | Bill Richardson <wfrichar@chromium.org> | 2013-01-03 12:56:50 -0800 |
---|---|---|
committer | Bill Richardson <wfrichar@chromium.org> | 2013-01-03 12:57:32 -0800 |
commit | d4c1a6db8bb15ee9f075764b3dc2424663fc8ce4 (patch) | |
tree | 552424414b71e8ac412a8fd8688b75b2b21ed41a | |
parent | 70a78dd7b9cfa5823015878fed4518f6a4aba6a3 (diff) | |
parent | e8cfa31d548c069d73c304fea522b527fe7c7dd6 (diff) | |
download | vboot-d4c1a6db8bb15ee9f075764b3dc2424663fc8ce4.tar.gz |
Sync cros/futility with ToT
BUG=chromium-os:37062
BRANCH=none
TEST=none
Change-Id: I7b96b8ae72391fec567277135dcf14ca9174a8e6
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | Makefile | 42 | ||||
-rw-r--r-- | build.mk | 6 | ||||
-rw-r--r-- | firmware/Makefile | 6 | ||||
-rw-r--r-- | firmware/include/vboot_nvstorage.h | 2 | ||||
-rw-r--r-- | firmware/lib/cryptolib/sha512.c | 90 | ||||
-rw-r--r-- | firmware/lib/vboot_api_init.c | 4 | ||||
-rw-r--r-- | firmware/lib/vboot_nvstorage.c | 10 | ||||
-rw-r--r-- | firmware/stub/tpm_lite_stub.c | 30 | ||||
-rw-r--r-- | host/lib/crossystem.c | 4 | ||||
-rwxr-xr-x | scripts/image_signing/sign_official_build.sh | 59 | ||||
-rw-r--r-- | tests/Makefile | 19 | ||||
-rwxr-xr-x | tests/run_preamble_tests.sh | 9 | ||||
-rwxr-xr-x | tests/run_vboot_common_tests.sh | 126 | ||||
-rwxr-xr-x | tests/run_vbutil_tests.sh | 158 | ||||
-rw-r--r-- | utility/crossystem_main.c | 1 | ||||
-rw-r--r-- | utility/dump_fmap.c | 7 | ||||
-rw-r--r-- | utility/mount-encrypted.c | 29 |
17 files changed, 405 insertions, 197 deletions
@@ -1,9 +1,14 @@ -# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +ifneq ($(V),1) +Q := @ +endif + export FIRMWARE_ARCH export MOCK_TPM +export Q # This Makefile normally builds in a 'build' subdir, but use # @@ -97,7 +102,7 @@ SUBDIRS = firmware endif all: - set -e; \ + $(Q)set -e; \ for d in $(shell find ${SUBDIRS} -name '*.c' -exec dirname {} \; |\ sort -u); do \ newdir=${BUILD}/$$d; \ @@ -111,37 +116,40 @@ all: done libcgpt_cc: - mkdir -p ${BUILD}/cgpt ${BUILD}/firmware/lib/cgptlib ${BUILD}/firmware/stub - $(MAKE) -C cgpt libcgpt_cc + $(Q)mkdir -p ${BUILD}/cgpt ${BUILD}/firmware/lib/cgptlib ${BUILD}/firmware/stub + $(Q)$(MAKE) -C cgpt libcgpt_cc cgptmanager_tests: libcgpt_cc - mkdir -p ${BUILD}/tests - $(MAKE) -C tests cgptmanager_tests + $(Q)mkdir -p ${BUILD}/tests + $(Q)$(MAKE) -C tests cgptmanager_tests libdump_kernel_config: - mkdir -p ${BUILD}/utility - $(MAKE) -C utility $(DUMPKERNELCONFIGLIB) + $(Q)mkdir -p ${BUILD}/utility + $(Q)$(MAKE) -C utility $(DUMPKERNELCONFIGLIB) clean: - /bin/rm -rf ${BUILD} + $(Q)/bin/rm -rf ${BUILD} install: - $(MAKE) -C utility install - $(MAKE) -C cgpt install + $(Q)$(MAKE) -C utility install + $(Q)$(MAKE) -C cgpt install runtests: - $(MAKE) -C tests runtests + $(Q)$(MAKE) -C tests runtests + +runlongtests: + $(MAKE) -C tests runlongtests runcgptmanagertests: - $(MAKE) -C tests runcgptmanagertests + $(Q)$(MAKE) -C tests runcgptmanagertests rbtest: - $(MAKE) -C tests rbtest + $(Q)$(MAKE) -C tests rbtest runbmptests: - $(MAKE) -C tests runbmptests + $(Q)$(MAKE) -C tests runbmptests vboot_next: all [ -d "${BUILD}/futility" ] || mkdir -p "${BUILD}/futility" - $(MAKE) -C futility all - $(MAKE) -C tests futility + $(Q)$(MAKE) -C futility all + $(Q)$(MAKE) -C tests futility @@ -15,9 +15,11 @@ ALL_DEPS = $(ALL_OBJS:%.o=%.o.d) all: ${ALL_OBJS} ${BUILD_ROOT}/%.o : %.c - $(CC) $(CFLAGS) $(INCLUDES) -MMD -MF $@.d -c -o $@ $< + @printf " CC $(subst $(BUILD_ROOT)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) $(INCLUDES) -MMD -MF $@.d -c -o $@ $< ${BUILD_ROOT}/%.o : %.cc - $(CXX) $(CFLAGS) $(INCLUDES) -MMD -MF $@.d -c -o $@ $< + @printf " CXX $(subst $(BUILD_ROOT)/,,$(@))\n" + $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -MMD -MF $@.d -c -o $@ $< -include ${ALL_DEPS} diff --git a/firmware/Makefile b/firmware/Makefile index 8d8e2ee2..1612da95 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -129,5 +129,7 @@ endif include ../build.mk $(FWLIB) : $(LIB_OBJS) - rm -f $@ - ar qc $@ $^ + @printf " RM $(@))\n" + $(Q)rm -f $@ + @printf " AR $(@))\n" + $(Q)ar qc $@ $^ diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h index 7c8fca8e..8b41c8f1 100644 --- a/firmware/include/vboot_nvstorage.h +++ b/firmware/include/vboot_nvstorage.h @@ -63,6 +63,8 @@ typedef enum VbNvParam { VBNV_CLEAR_TPM_OWNER_REQUEST, /* Flag that TPM owner was cleared on request. */ VBNV_CLEAR_TPM_OWNER_DONE, + /* More details on recovery reason */ + VBNV_RECOVERY_SUBCODE, } VbNvParam; diff --git a/firmware/lib/cryptolib/sha512.c b/firmware/lib/cryptolib/sha512.c index ee30b602..3a45be51 100644 --- a/firmware/lib/cryptolib/sha512.c +++ b/firmware/lib/cryptolib/sha512.c @@ -150,17 +150,17 @@ static const uint64_t sha512_k[80] = { /* SHA-512 implementation */ void SHA512_init(SHA512_CTX *ctx) { -#ifndef UNROLL_LOOPS - int i; - for (i = 0; i < 8; i++) { - ctx->h[i] = sha512_h0[i]; - } -#else +#ifdef UNROLL_LOOPS_SHA512 ctx->h[0] = sha512_h0[0]; ctx->h[1] = sha512_h0[1]; ctx->h[2] = sha512_h0[2]; ctx->h[3] = sha512_h0[3]; ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5]; ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7]; -#endif /* !UNROLL_LOOPS */ +#else + int i; + + for (i = 0; i < 8; i++) + ctx->h[i] = sha512_h0[i]; +#endif /* UNROLL_LOOPS_SHA512 */ ctx->len = 0; ctx->tot_len = 0; @@ -178,37 +178,7 @@ static void SHA512_transform(SHA512_CTX* ctx, const uint8_t* message, for (i = 0; i < (int) block_nb; i++) { sub_block = message + (i << 7); -#ifndef UNROLL_LOOPS - for (j = 0; j < 16; j++) { - PACK64(&sub_block[j << 3], &w[j]); - } - - for (j = 16; j < 80; j++) { - SHA512_SCR(j); - } - - for (j = 0; j < 8; j++) { - wv[j] = ctx->h[j]; - } - - for (j = 0; j < 80; j++) { - t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) - + sha512_k[j] + w[j]; - t2 = SHA512_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]; - } -#else +#ifdef UNROLL_LOOPS_SHA512 PACK64(&sub_block[ 0], &w[ 0]); PACK64(&sub_block[ 8], &w[ 1]); PACK64(&sub_block[ 16], &w[ 2]); PACK64(&sub_block[ 24], &w[ 3]); PACK64(&sub_block[ 32], &w[ 4]); PACK64(&sub_block[ 40], &w[ 5]); @@ -257,7 +227,36 @@ static void SHA512_transform(SHA512_CTX* ctx, const uint8_t* message, ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; -#endif /* !UNROLL_LOOPS */ +#else + for (j = 0; j < 16; j++) { + PACK64(&sub_block[j << 3], &w[j]); + } + + for (j = 16; j < 80; j++) { + SHA512_SCR(j); + } + + for (j = 0; j < 8; j++) { + wv[j] = ctx->h[j]; + } + + for (j = 0; j < 80; j++) { + t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + + sha512_k[j] + w[j]; + t2 = SHA512_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]; +#endif /* UNROLL_LOOPS_SHA512 */ } } @@ -301,7 +300,7 @@ uint8_t* SHA512_final(SHA512_CTX* ctx) unsigned int pm_len; unsigned int len_b; -#ifndef UNROLL_LOOPS +#ifndef UNROLL_LOOPS_SHA512 int i; #endif @@ -317,11 +316,7 @@ uint8_t* SHA512_final(SHA512_CTX* ctx) SHA512_transform(ctx, ctx->block, block_nb); -#ifndef UNROLL_LOOPS - for (i = 0 ; i < 8; i++) { - UNPACK64(ctx->h[i], &ctx->buf[i << 3]); - } -#else +#ifdef UNROLL_LOOPS_SHA512 UNPACK64(ctx->h[0], &ctx->buf[ 0]); UNPACK64(ctx->h[1], &ctx->buf[ 8]); UNPACK64(ctx->h[2], &ctx->buf[16]); @@ -330,7 +325,10 @@ uint8_t* SHA512_final(SHA512_CTX* ctx) UNPACK64(ctx->h[5], &ctx->buf[40]); UNPACK64(ctx->h[6], &ctx->buf[48]); UNPACK64(ctx->h[7], &ctx->buf[56]); -#endif /* !UNROLL_LOOPS */ +#else + for (i = 0 ; i < 8; i++) + UNPACK64(ctx->h[i], &ctx->buf[i << 3]); +#endif /* UNROLL_LOOPS_SHA512 */ return ctx->buf; } diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c index d5524f28..a77b230d 100644 --- a/firmware/lib/vboot_api_init.c +++ b/firmware/lib/vboot_api_init.c @@ -153,7 +153,8 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { &is_virt_dev, &tpm_version); VBPERFEND("VB_TPMI"); if (0 != tpm_status) { - VBDEBUG(("Unable to setup TPM and read firmware version.\n")); + VBDEBUG(("Unable to setup TPM and read firmware version (0x%x)\n", + tpm_status)); if (TPM_E_MUST_REBOOT == tpm_status) { /* TPM wants to reboot into the same mode we're in now */ @@ -173,6 +174,7 @@ VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { if (!recovery) { VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_S_ERROR); + VbNvSet(&vnc, VBNV_RECOVERY_SUBCODE, tpm_status); retval = VBERROR_TPM_FIRMWARE_SETUP; goto VbInit_exit; } diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c index 618ff526..3497392e 100644 --- a/firmware/lib/vboot_nvstorage.c +++ b/firmware/lib/vboot_nvstorage.c @@ -38,6 +38,8 @@ #define TPM_CLEAR_OWNER_REQUEST 0x01 #define TPM_CLEAR_OWNER_DONE 0x02 +#define RECOVERY_SUBCODE_OFFSET 6 + #define KERNEL_FIELD_OFFSET 11 #define CRC_OFFSET 15 @@ -102,6 +104,10 @@ int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest) { *dest = raw[RECOVERY_OFFSET]; return 0; + case VBNV_RECOVERY_SUBCODE: + *dest = raw[RECOVERY_SUBCODE_OFFSET]; + return 0; + case VBNV_LOCALIZATION_INDEX: *dest = raw[LOCALIZATION_OFFSET]; return 0; @@ -194,6 +200,10 @@ int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value) { raw[RECOVERY_OFFSET] = (uint8_t)value; break; + case VBNV_RECOVERY_SUBCODE: + raw[RECOVERY_SUBCODE_OFFSET] = (uint8_t)value; + break; + case VBNV_LOCALIZATION_INDEX: /* Map values outside the valid range to the default index. */ if (value > 0xFF) diff --git a/firmware/stub/tpm_lite_stub.c b/firmware/stub/tpm_lite_stub.c index a60d6507..60065e64 100644 --- a/firmware/stub/tpm_lite_stub.c +++ b/firmware/stub/tpm_lite_stub.c @@ -21,9 +21,13 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> +#include <time.h> #include <unistd.h> #define TPM_DEVICE_PATH "/dev/tpm0" +/* Retry failed open()s for 5 seconds in 10ms polling intervals. */ +#define OPEN_RETRY_DELAY_NS (10 * 1000 * 1000) +#define OPEN_RETRY_MAX_NUM 500 /* TODO: these functions should pass errors back rather than returning void */ /* TODO: if the only callers to these are just wrappers, should just @@ -143,6 +147,8 @@ VbError_t VbExTpmClose(void) { VbError_t VbExTpmOpen(void) { char* device_path; + struct timespec delay; + int retries, saved_errno; if (tpm_fd >= 0) return VBERROR_SUCCESS; /* Already open */ @@ -152,13 +158,25 @@ VbError_t VbExTpmOpen(void) { device_path = TPM_DEVICE_PATH; } - tpm_fd = open(device_path, O_RDWR); - if (tpm_fd < 0) { - return DoError(TPM_E_NO_DEVICE, "TPM: Cannot open TPM device %s: %s\n", - device_path, strerror(errno)); + /* Retry TPM opens on EBUSY failures. */ + for (retries = 0; retries < OPEN_RETRY_MAX_NUM; ++ retries) { + errno = 0; + tpm_fd = open(device_path, O_RDWR); + saved_errno = errno; + if (tpm_fd >= 0) + return VBERROR_SUCCESS; + if (saved_errno != EBUSY) + break; + + VBDEBUG(("TPM: retrying %s: %s\n", device_path, strerror(errno))); + + /* Stall until TPM comes back. */ + delay.tv_sec = 0; + delay.tv_nsec = OPEN_RETRY_DELAY_NS; + nanosleep(&delay, NULL); } - - return VBERROR_SUCCESS; + return DoError(TPM_E_NO_DEVICE, "TPM: Cannot open TPM device %s: %s\n", + device_path, strerror(saved_errno)); } diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index e1ee4fc5..c4d0a607 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -427,6 +427,8 @@ int VbGetSystemPropertyInt(const char* name) { value = VbGetNvStorage(VBNV_DEV_BOOT_SIGNED_ONLY); } else if (!strcasecmp(name,"oprom_needed")) { value = VbGetNvStorage(VBNV_OPROM_NEEDED); + } else if (!strcasecmp(name,"recovery_subcode")) { + value = VbGetNvStorage(VBNV_RECOVERY_SUBCODE); } /* Other parameters */ else if (!strcasecmp(name,"cros_debug")) { @@ -501,6 +503,8 @@ int VbSetSystemPropertyInt(const char* name, int value) { return VbSetNvStorage(VBNV_KERNEL_SETTINGS_RESET, 0); } else if (!strcasecmp(name,"recovery_request")) { return VbSetNvStorage(VBNV_RECOVERY_REQUEST, value); + } else if (!strcasecmp(name,"recovery_subcode")) { + return VbSetNvStorage(VBNV_RECOVERY_SUBCODE, value); } else if (!strcasecmp(name,"dbg_reset")) { return VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value); } else if (!strcasecmp(name,"disable_dev_request")) { diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh index 0f9691ff..d6073dd3 100755 --- a/scripts/image_signing/sign_official_build.sh +++ b/scripts/image_signing/sign_official_build.sh @@ -41,12 +41,33 @@ If you are signing an image, you must specify an [output_image] and optionally, a [version_file]. EOF + if [[ $# -gt 0 ]]; then + error "$*" + exit 1 + fi + exit 0 } -if [ $# -lt 3 ] || [ $# -gt 5 ]; then - usage - exit 1 -fi +# Verify we have as many arguments as we expect, else show usage & quit. +# Usage: +# check_argc <number args> <exact number> +# check_argc <number args> <lower bound> <upper bound> +check_argc() { + case $# in + 2) + if [[ $1 -ne $2 ]]; then + usage "command takes exactly $2 args" + fi + ;; + 3) + if [[ $1 -lt $2 || $1 -gt $3 ]]; then + usage "command takes $2 to $3 args" + fi + ;; + *) + die "check_argc: incorrect number of arguments" + esac +} # Abort on errors. set -e @@ -610,16 +631,30 @@ sign_for_factory_install() { } # Verification -if [ "${TYPE}" == "verify" ]; then +case ${TYPE} in +dump_config) + check_argc $# 2 + for partnum in 2 4; do + echo "kernel config in partition number ${partnum}:" + grab_kernel_config "${INPUT_IMAGE}" ${partnum} + echo + done + exit 0 + ;; +verify) + check_argc $# 2 verify_image exit 0 -fi - -# Signing requires an output image name -if [ -z "${OUTPUT_IMAGE}" ]; then - usage - exit 1 -fi + ;; +*) + # All other signing commands take 4 to 5 args. + if [ -z "${OUTPUT_IMAGE}" ]; then + # Friendlier message. + usage "Missing output image name" + fi + check_argc $# 4 5 + ;; +esac # If a version file was specified, read the firmware and kernel # versions from there. diff --git a/tests/Makefile b/tests/Makefile index 73df34f9..df169209 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -151,7 +151,6 @@ runcryptotests: ${BUILD_ROOT}/rsa_utility_tests ${BUILD_ROOT}/sha_tests ./run_vboot_common_tests.sh - ./run_vboot_ec_tests.sh # Run other misc tests runmisctests: @@ -165,9 +164,12 @@ runmisctests: ${BUILD_ROOT}/vboot_api_firmware_tests ${BUILD_ROOT}/vboot_firmware_tests -#This will exercise vbutil_kernel and vbutil_firmware -runfuzztests: +# Generate test cases for fuzzing +genfuzztestcases: ./gen_fuzz_test_cases.sh + +# This will exercise vbutil_kernel and vbutil_firmware +runfuzztests: genfuzztestcases ./run_preamble_tests.sh ./run_vbutil_kernel_arg_tests.sh @@ -182,8 +184,17 @@ runsoundtests: ALLTESTS=runcgpttests runcryptotests runmisctests runfuzztests \ runbmptests runsoundtests +# Run a subset of tests runtests: genkeys ${ALLTESTS} +# Run long tests, including all permutations of encryption keys (instead of +# just the ones we use) and tests of currently-unused code (e.g. vboot_ec) +runlongtests: genkeys genfuzztestcases + ./run_vboot_common_tests.sh --all + ./run_vbutil_tests.sh --all + ./run_preamble_tests.sh --all + ./run_vboot_ec_tests.sh + # TODO: tests to run when ported to new API # ./run_image_verification_tests.sh # # Splicing tests diff --git a/tests/run_preamble_tests.sh b/tests/run_preamble_tests.sh index ffbd9afc..2ca86ad6 100755 --- a/tests/run_preamble_tests.sh +++ b/tests/run_preamble_tests.sh @@ -12,8 +12,13 @@ # Load common constants and variables for tests. . "$(dirname "$0")/common.sh" -# all algs -algs="0 1 2 3 4 5 6 7 8 9 10 11" +if [ "${1:---some}" == "--all" ] ; then + # all algs + algs="0 1 2 3 4 5 6 7 8 9 10 11" +else + # just the algs we use + algs="4 7 11" +fi # output directories PREAMBLE_DIR="${SCRIPT_DIR}/preamble_tests" diff --git a/tests/run_vboot_common_tests.sh b/tests/run_vboot_common_tests.sh index 9d4373f7..658f8dd5 100755 --- a/tests/run_vboot_common_tests.sh +++ b/tests/run_vboot_common_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -19,61 +19,102 @@ function test_vboot_common { fi } -function test_vboot_common2 { +# Test a single key+hash algorithm +function test_vboot_common2_single { + local algonum=$1 + local keylen=$2 + local hashalgo=$3 + echo -e "For signing key ${COL_YELLOW}RSA-$keylen/$hashalgo${COL_STOP}:" + echo ${TEST_DIR}/vboot_common2_tests $algonum \ + ${TESTKEY_DIR}/key_rsa${keylen}.pem \ + ${TESTKEY_DIR}/key_rsa${keylen}.keyb + ${TEST_DIR}/vboot_common2_tests $algonum \ + ${TESTKEY_DIR}/key_rsa${keylen}.pem \ + ${TESTKEY_DIR}/key_rsa${keylen}.keyb + if [ $? -ne 0 ] + then + return_code=255 + fi +} + +# Test all key+hash algorithms +function test_vboot_common2_all { algorithmcounter=0 for keylen in ${key_lengths[@]} do for hashalgo in ${hash_algos[@]} do - echo -e "For signing key ${COL_YELLOW}RSA-$keylen/$hashalgo${COL_STOP}:" - ${TEST_DIR}/vboot_common2_tests $algorithmcounter \ - ${TESTKEY_DIR}/key_rsa${keylen}.pem \ - ${TESTKEY_DIR}/key_rsa${keylen}.keyb - if [ $? -ne 0 ] - then - return_code=255 - fi + test_vboot_common2_single $algorithmcounter $keylen $hashalgo let algorithmcounter=algorithmcounter+1 done done } -function test_vboot_common3 { -# Test for various combinations of firmware signing algorithm and -# kernel signing algorithm - firmware_algorithmcounter=0 - kernel_algorithmcounter=0 - for firmware_keylen in ${key_lengths[@]} +# Test only the algorithms we actually use +function test_vboot_common2 { + test_vboot_common2_single 4 2048 sha256 + test_vboot_common2_single 7 4096 sha256 + test_vboot_common2_single 11 8192 sha512 +} + +# Test a single block algorithm + data algorithm +function test_vboot_common3_single { + local signing_algonum=$1 + local signing_keylen=$2 + local signing_hashalgo=$3 + local data_algonum=$4 + local data_keylen=$5 + local data_hashalgo=$6 + + echo -e "For ${COL_YELLOW}signing algorithm \ +RSA-${signing_keylen}/${signing_hashalgo}${COL_STOP} \ +and ${COL_YELLOW}data signing algorithm RSA-${data_keylen}/\ +${data_hashalgo}${COL_STOP}" + ${TEST_DIR}/vboot_common3_tests \ + $signing_algonum $data_algonum \ + ${TESTKEY_DIR}/key_rsa${signing_keylen}.pem \ + ${TESTKEY_DIR}/key_rsa${signing_keylen}.keyb \ + ${TESTKEY_DIR}/key_rsa${data_keylen}.pem \ + ${TESTKEY_DIR}/key_rsa${data_keylen}.keyb + if [ $? -ne 0 ] + then + return_code=255 + fi +} + +# Test all combinations of key block signing algorithm and data signing +# algorithm +function test_vboot_common3_all { + signing_algorithmcounter=0 + data_algorithmcounter=0 + for signing_keylen in ${key_lengths[@]} do - for firmware_hashalgo in ${hash_algos[@]} + for signing_hashalgo in ${hash_algos[@]} do - let kernel_algorithmcounter=0 - for kernel_keylen in ${key_lengths[@]} + let data_algorithmcounter=0 + for data_keylen in ${key_lengths[@]} do - for kernel_hashalgo in ${hash_algos[@]} + for data_hashalgo in ${hash_algos[@]} do - echo -e "For ${COL_YELLOW}signing algorithm \ -RSA-${firmware_keylen}/${firmware_hashalgo}${COL_STOP} \ -and ${COL_YELLOW}data signing algorithm RSA-${kernel_keylen}/\ -${kernel_hashalgo}${COL_STOP}" - ${TEST_DIR}/vboot_common3_tests \ - $firmware_algorithmcounter $kernel_algorithmcounter \ - ${TESTKEY_DIR}/key_rsa${firmware_keylen}.pem \ - ${TESTKEY_DIR}/key_rsa${firmware_keylen}.keyb \ - ${TESTKEY_DIR}/key_rsa${kernel_keylen}.pem \ - ${TESTKEY_DIR}/key_rsa${kernel_keylen}.keyb - if [ $? -ne 0 ] - then - return_code=255 - fi - let kernel_algorithmcounter=kernel_algorithmcounter+1 + test_vboot_common3_single \ + $signing_algorithmcounter $signing_keylen $signing_hashalgo \ + $data_algorithmcounter $data_keylen $data_hashalgo + let data_algorithmcounter=data_algorithmcounter+1 done done - let firmware_algorithmcounter=firmware_algorithmcounter+1 + let signing_algorithmcounter=signing_algorithmcounter+1 done done } +# Test only the combinations of key block signing algorithm and data signing +# algorithm that we actually use +function test_vboot_common3 { + test_vboot_common3_single 7 4096 sha256 4 2048 sha256 + test_vboot_common3_single 11 8192 sha512 4 2048 sha256 + test_vboot_common3_single 11 8192 sha512 7 4096 sha256 +} + check_test_keys echo echo "Testing vboot_common tests which don't depend on keys..." @@ -81,11 +122,18 @@ test_vboot_common echo echo "Testing vboot_common tests which depend on one key..." -test_vboot_common2 +if [ "$1" == "--all" ] ; then + test_vboot_common2_all +else + test_vboot_common2 +fi echo echo "Testing vboot_common tests which depend on two keys..." -test_vboot_common3 - +if [ "$1" == "--all" ] ; then + test_vboot_common3_all +else + test_vboot_common3 +fi exit $return_code diff --git a/tests/run_vbutil_tests.sh b/tests/run_vbutil_tests.sh index b56f4c12..2b15d53f 100755 --- a/tests/run_vbutil_tests.sh +++ b/tests/run_vbutil_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -11,68 +11,74 @@ return_code=0 -function test_vbutil_key { - algorithmcounter=0 - for keylen in ${key_lengths[@]} - do - for hashalgo in ${hash_algos[@]} - do - echo -e "For signing key ${COL_YELLOW}RSA-$keylen/$hashalgo${COL_STOP}:" - # Pack the key - ${UTIL_DIR}/vbutil_key \ - --pack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk \ +function test_vbutil_key_single { + local algonum=$1 + local keylen=$2 + local hashalgo=$3 + + echo -e "For signing key ${COL_YELLOW}RSA-$keylen/$hashalgo${COL_STOP}:" + # Pack the key + ${UTIL_DIR}/vbutil_key \ + --pack ${TESTKEY_SCRATCH_DIR}/key_alg${algonum}.vbpubk \ --key ${TESTKEY_DIR}/key_rsa${keylen}.keyb \ --version 1 \ - --algorithm $algorithmcounter - if [ $? -ne 0 ] - then + --algorithm $algonum + if [ $? -ne 0 ] + then return_code=255 - fi - - # Unpack the key - # TODO: should verify we get the same key back out? - ${UTIL_DIR}/vbutil_key \ - --unpack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk - if [ $? -ne 0 ] - then + fi + + # Unpack the key + # TODO: should verify we get the same key back out? + ${UTIL_DIR}/vbutil_key \ + --unpack ${TESTKEY_SCRATCH_DIR}/key_alg${algonum}.vbpubk + if [ $? -ne 0 ] + then return_code=255 - fi + fi +} - let algorithmcounter=algorithmcounter+1 - done +function test_vbutil_key_all { + algorithmcounter=0 + for keylen in ${key_lengths[@]} + do + for hashalgo in ${hash_algos[@]} + do + test_vbutil_key_single $algorithmcounter $keylen $hashalgo + let algorithmcounter=algorithmcounter+1 + done done } +function test_vbutil_key { + test_vbutil_key_single 4 2048 sha256 + test_vbutil_key_single 7 4096 sha256 + test_vbutil_key_single 11 8192 sha512 +} + +function test_vbutil_keyblock_single { + local signing_algonum=$1 + local signing_keylen=$2 + local signing_hashalgo=$3 + local data_algonum=$4 + local data_keylen=$5 + local data_hashalgo=$6 -function test_vbutil_keyblock { -# Test for various combinations of firmware signing algorithm and -# kernel signing algorithm - signing_algorithmcounter=0 - data_algorithmcounter=0 - for signing_keylen in ${key_lengths[@]} - do - for signing_hashalgo in ${hash_algos[@]} - do - let data_algorithmcounter=0 - for datakeylen in ${key_lengths[@]} - do - for datahashalgo in ${hash_algos[@]} - do echo -e "For ${COL_YELLOW}signing algorithm \ RSA-${signing_keylen}/${signing_hashalgo}${COL_STOP} \ and ${COL_YELLOW}data key algorithm RSA-${datakeylen}/\ ${datahashalgo}${COL_STOP}" # Remove old file keyblockfile="${TESTKEY_SCRATCH_DIR}/" - keyblockfile+="sign${signing_algorithmcounter}_data" - keyblockfile+="${data_algorithmcounter}.keyblock" + keyblockfile+="sign${signing_algonum}_data" + keyblockfile+="${data_algonum}.keyblock" rm -f ${keyblockfile} # Wrap private key ${UTIL_DIR}/vbutil_key \ - --pack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbprivk \ + --pack ${TESTKEY_SCRATCH_DIR}/key_alg${algonum}.vbprivk \ --key ${TESTKEY_DIR}/key_rsa${signing_keylen}.pem \ - --algorithm $signing_algorithmcounter + --algorithm $signing_algonum if [ $? -ne 0 ] then echo -e "${COL_RED}Wrap vbprivk${COL_STOP}" @@ -81,9 +87,9 @@ ${datahashalgo}${COL_STOP}" # Wrap public key ${UTIL_DIR}/vbutil_key \ - --pack ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk \ + --pack ${TESTKEY_SCRATCH_DIR}/key_alg${algonum}.vbpubk \ --key ${TESTKEY_DIR}/key_rsa${signing_keylen}.keyb \ - --algorithm $signing_algorithmcounter + --algorithm $signing_algonum if [ $? -ne 0 ] then echo -e "${COL_RED}Wrap vbpubk${COL_STOP}" @@ -93,9 +99,9 @@ ${datahashalgo}${COL_STOP}" # Pack ${UTIL_DIR}/vbutil_keyblock --pack ${keyblockfile} \ --datapubkey \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \ + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk \ --signprivate \ - ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbprivk + ${TESTKEY_SCRATCH_DIR}/key_alg${algonum}.vbprivk if [ $? -ne 0 ] then echo -e "${COL_RED}Pack${COL_STOP}" @@ -105,9 +111,9 @@ ${datahashalgo}${COL_STOP}" # Unpack ${UTIL_DIR}/vbutil_keyblock --unpack ${keyblockfile} \ --datapubkey \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk2 \ + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk2 \ --signpubkey \ - ${TESTKEY_SCRATCH_DIR}/key_alg${algorithmcounter}.vbpubk + ${TESTKEY_SCRATCH_DIR}/key_alg${algonum}.vbpubk if [ $? -ne 0 ] then echo -e "${COL_RED}Unpack${COL_STOP}" @@ -116,8 +122,8 @@ ${datahashalgo}${COL_STOP}" # Check if ! cmp -s \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk2 + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk \ + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk2 then echo -e "${COL_RED}Check${COL_STOP}" return_code=255 @@ -130,10 +136,10 @@ external signer.${COL_STOP}" # Pack ${UTIL_DIR}/vbutil_keyblock --pack ${keyblockfile} \ --datapubkey \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \ + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk \ --signprivate_pem \ ${TESTKEY_DIR}/key_rsa${signing_keylen}.pem \ - --pem_algorithm "${signing_algorithmcounter}" \ + --pem_algorithm "${signing_algonum}" \ --externalsigner "${SCRIPT_DIR}/external_rsa_signer.sh" if [ $? -ne 0 ] @@ -145,9 +151,9 @@ external signer.${COL_STOP}" # Unpack ${UTIL_DIR}/vbutil_keyblock --unpack ${keyblockfile} \ --datapubkey \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk2 \ + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk2 \ --signpubkey \ - ${TESTKEY_SCRATCH_DIR}/key_alg${signing_algorithmcounter}.vbpubk + ${TESTKEY_SCRATCH_DIR}/key_alg${signing_algonum}.vbpubk if [ $? -ne 0 ] then echo -e "${COL_RED}Unpack${COL_STOP}" @@ -156,14 +162,33 @@ external signer.${COL_STOP}" # Check if ! cmp -s \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk \ - ${TESTKEY_SCRATCH_DIR}/key_alg${data_algorithmcounter}.vbpubk2 + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk \ + ${TESTKEY_SCRATCH_DIR}/key_alg${data_algonum}.vbpubk2 then echo -e "${COL_RED}Check${COL_STOP}" return_code=255 exit 1 fi +} + +function test_vbutil_keyblock_all { +# Test for various combinations of firmware signing algorithm and +# kernel signing algorithm + signing_algorithmcounter=0 + data_algorithmcounter=0 + for signing_keylen in ${key_lengths[@]} + do + for signing_hashalgo in ${hash_algos[@]} + do + let data_algorithmcounter=0 + for datakeylen in ${key_lengths[@]} + do + for datahashalgo in ${hash_algos[@]} + do + test_vbutil_keyblock_single \ + $signing_algorithmcounter $signing_keylen $signing_hashalgo \ + $data_algorithmcounter $data_keylen $data_hashalgo let data_algorithmcounter=data_algorithmcounter+1 done done @@ -172,17 +197,30 @@ external signer.${COL_STOP}" done } +function test_vbutil_keyblock { + test_vbutil_keyblock_single 7 4096 sha256 4 2048 sha256 + test_vbutil_keyblock_single 11 8192 sha512 4 2048 sha256 + test_vbutil_keyblock_single 11 8192 sha512 7 4096 sha256 +} + check_test_keys echo echo "Testing vbutil_key..." -test_vbutil_key +if [ "$1" == "--all" ] ; then + test_vbutil_key_all +else + test_vbutil_key +fi echo echo "Testing vbutil_keyblock..." -test_vbutil_keyblock - +if [ "$1" == "--all" ] ; then + test_vbutil_keyblock_all +else + test_vbutil_keyblock +fi exit $return_code diff --git a/utility/crossystem_main.c b/utility/crossystem_main.c index d8191075..91465002 100644 --- a/utility/crossystem_main.c +++ b/utility/crossystem_main.c @@ -66,6 +66,7 @@ const Param sys_param_list[] = { {"platform_family", IS_STRING, "Platform family type"}, {"recovery_reason", 0, "Recovery mode reason for current boot"}, {"recovery_request", CAN_WRITE, "Recovery mode request (writable)"}, + {"recovery_subcode", CAN_WRITE, "Recovery reason subcode (writable)"}, {"recoverysw_boot", 0, "Recovery switch position at boot"}, {"recoverysw_cur", 0, "Recovery switch current position"}, {"recoverysw_ec_boot", 0, "Recovery switch position at EC boot"}, diff --git a/utility/dump_fmap.c b/utility/dump_fmap.c index 4d14d8b8..28fd2f2d 100644 --- a/utility/dump_fmap.c +++ b/utility/dump_fmap.c @@ -22,6 +22,7 @@ enum { FMT_NORMAL, FMT_PRETTY, FMT_FLASHROM, FMT_HUMAN }; /* global variables */ static int opt_extract = 0; static int opt_format = FMT_NORMAL; +static int opt_overlap = 0; static char *progname; static void *base_of_rom; static int opt_gaps = 0; @@ -314,7 +315,10 @@ static int human_fmap(void *p) all_nodes[i].start, all_nodes[i].end); printf(" %s: 0x%x - 0x%x\n", all_nodes[j].name, all_nodes[j].start, all_nodes[j].end); - errorcnt++; + if (opt_overlap < 2) { + printf("Use more -h args to ignore this error\n"); + errorcnt++; + } continue; } if (encloses(j, i) && all_nodes[j].size < all_nodes[k].size) @@ -378,6 +382,7 @@ int main(int argc, char *argv[]) /* fallthrough */ case 'h': opt_format = FMT_HUMAN; + opt_overlap++; break; case '?': fprintf(stderr, "%s: unrecognized switch: -%c\n", diff --git a/utility/mount-encrypted.c b/utility/mount-encrypted.c index 2c975a39..a97db0c3 100644 --- a/utility/mount-encrypted.c +++ b/utility/mount-encrypted.c @@ -110,14 +110,21 @@ static gchar *encrypted_mount = NULL; static gchar *dmcrypt_name = NULL; static gchar *dmcrypt_dev = NULL; static int has_tpm = 0; +static int tpm_init_called = 0; static void tpm_init(void) { uint32_t result; + if (tpm_init_called) + return; + DEBUG("Opening TPM"); + setenv("TPM_NO_EXIT", "1", 1); result = TlclLibInit(); + + tpm_init_called = 1; has_tpm = (result == TPM_SUCCESS); INFO("TPM %s", has_tpm ? "ready" : "not available"); } @@ -129,6 +136,7 @@ static uint32_t tpm_owned(uint8_t *owned) { uint32_t result; + tpm_init(); DEBUG("Reading TPM Ownership Flag"); if (!has_tpm) result = TPM_E_NO_DEVICE; @@ -141,7 +149,10 @@ static uint32_t tpm_owned(uint8_t *owned) static void tpm_close(void) { + if (!has_tpm || !tpm_init_called) + return; TlclLibClose(); + tpm_init_called = 0; } static void sha256(char *string, uint8_t *digest) @@ -237,6 +248,7 @@ _read_nvram(uint8_t *buffer, size_t len, uint32_t index, uint32_t size) return 0; } + tpm_init(); DEBUG("Reading NVRAM area 0x%x (size %u)", index, size); if (!has_tpm) result = TPM_E_NO_DEVICE; @@ -425,6 +437,7 @@ static int get_random_bytes_tpm(unsigned char *buffer, int wanted) { uint32_t remaining = wanted; + tpm_init(); /* Read random bytes from TPM, which can return short reads. */ while (remaining) { uint32_t result, size; @@ -736,6 +749,7 @@ static int setup_encrypted(int mode) int sparsefd; struct statvfs stateful_statbuf; uint64_t blocks_min, blocks_max; + int valid_keyfile = 0; /* Use the "system key" to decrypt the "encryption key" stored in * the stateful partition. @@ -753,6 +767,7 @@ static int setup_encrypted(int mode) * so migration is finished. */ migrate_allowed = 0; + valid_keyfile = 1; } else { uint8_t useless_key[DIGEST_LENGTH]; sha256((char *)kStaticKeyFinalizationNeeded, useless_key); @@ -963,11 +978,16 @@ static int setup_encrypted(int mode) needs_finalization(encryption_key); } else { /* If we're not rebuilding and we have a sane system - * key, then we must have finalized. Force any required - * clean up. + * key, then we must either need finalization (if we + * failed to finalize in Cryptohome), or we have already + * finalized, but maybe failed to clean up. */ - if (has_system_key) - finalized(); + if (has_system_key) { + if (!valid_keyfile) + finalize(system_key, encryption_key); + else + finalized(); + } } free(lodev); @@ -1258,7 +1278,6 @@ int main(int argc, char *argv[]) INFO_INIT("Starting."); prepare_paths(); - tpm_init(); if (argc > 1) { if (!strcmp(argv[1], "umount")) |