diff options
author | Mary Ruthven <mruthven@chromium.org> | 2021-08-06 19:21:01 -0500 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-07 17:52:51 +0000 |
commit | 1c3b00c3f7c0c819c330ddd98812d9085c578230 (patch) | |
tree | 8fe3a82953dffe2b178a738e3e123be7d02071b5 | |
parent | 519a3cf7cdef12437ae27a58d0dd70e12ca07278 (diff) | |
download | chrome-ec-1c3b00c3f7c0c819c330ddd98812d9085c578230.tar.gz |
add script to inject the fips fingerprint
Inject the fips fingerprint into the cr50 image, so it can verify the
fips module before starting to execute it. This change adds a script to
calculate the checksum and inject it into a elf file before signing.
If CONFIG_FIPS_CHECKSUM is defined, generate an elf file with the fips
checksum and use that to create signed images and hex files.
The build process doesn't change for RO artifacts. Nothing changes if
CONFIG_FIPS_CHECKSUM isn't defined.
The new chain for RW is
ec.RW.elf -> ec.RW.elf.fips -> ec.RW.flat
ec.RW.elf.fips is generated with util/inject_fips_fingerprint.sh.
util/inject_fips_fingerprint.sh calculates the fips module fingerprint,
copies ec.RW.elf to ec.RW.elf.fips, and then injects the fingerprint
into ec.RW.elf.fips.
util/signer/bs will be modified to use ec.RW.elf.fips if it exists in a
followup CL.
BUG=none
TEST=manual
# Verify cr50 is the only board that creates the fips artifacts
make buildall -j
objdump the text.fips_checksum section of ec.RW.elf and
ec.RW_B.elf. Make sure they match ec.RW.fips.checksum and
ec.RW_B.fips.checksum
# Verify cr50 can update to image signed with devid and that
# image shows Stored hash that matches the computed one.
H1_DEVIDS="${DEVID}" make -j BOARD=cr50 CR50_DEV=1
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Change-Id: Iab857ec1b7e3ae0d23681a25467e26286bd68210
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3078053
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r-- | Makefile.rules | 14 | ||||
-rw-r--r-- | board/cr50/board.h | 2 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rwxr-xr-x | util/inject_fips_fingerprint.sh | 71 |
4 files changed, 87 insertions, 2 deletions
diff --git a/Makefile.rules b/Makefile.rules index 41de0b7495..976e0a92e2 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -69,6 +69,7 @@ cmd_ec_elf_to_flat_dram ?= $(OBJCOPY) -j .dram* -O binary $< $@ cmd_elf_to_signed ?= $(SIGNER) --key=util/signer/$(3) \ --b --input=$< --format=bin --output=$@.signed $(SIGNER_EXTRAS) \ && sudo chown $(shell whoami) $@.signed && mv $@.signed $@ +cmd_elf_to_elf_fips = ./util/inject_fips_fingerprint.sh $(OBJCOPY) $(OBJDUMP) $^ cmd_elf_to_dis = $(OBJDUMP) -D $< > $@ cmd_elf_to_bin = $(OBJCOPY) -O binary $< $@ cmd_elf_to_hex = $(OBJCOPY) -O ihex $< $@ @@ -419,7 +420,16 @@ $(out)/$(PROJECT).obj: common/firmware_image.S $(out)/firmware_image.lds \ $(out)/%.dis: $(out)/%.elf $(call quiet,elf_to_dis,OBJDUMP) -$(out)/RW/%.hex: $(out)/RW/%.elf $(out)/RW/%.smap +ifeq ($(CONFIG_FIPS_CHECKSUM),) +rw_elf_ext= +else +rw_elf_ext=.fips + +$(out)/RW/%.elf.fips: $(out)/RW/%.elf + $(call quiet,elf_to_elf_fips,ELF_FIPS) +endif + +$(out)/RW/%.hex: $(out)/RW/%.elf$(rw_elf_ext) $(out)/RW/%.smap $(call quiet,elf_to_hex,OBJCOPY) ifeq ($(SIGNED_IMAGES),) @@ -435,7 +445,7 @@ else $(out)/RO/%.flat: $(out)/RO/%.elf $(out)/RO/%.smap $(call quiet,elf_to_signed,RO_SIGN,$(CR50_RO_KEY)) -$(out)/RW/%.flat: $(out)/RW/%.elf $(out)/RW/%.smap +$(out)/RW/%.flat: $(out)/RW/%.elf$(rw_elf_ext) $(out)/RW/%.smap $(call quiet,elf_to_signed,RW_SIGN,$(CR50_RW_KEY)) $(out)/RO/%.hex: $(out)/RO/%.flat diff --git a/board/cr50/board.h b/board/cr50/board.h index 4d886da85d..06fd5e1fd9 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -157,6 +157,8 @@ #define CONFIG_RESTRICTED_CONSOLE_COMMANDS #define CONFIG_CONSOLE_COMMAND_FLAGS_DEFAULT CMD_FLAG_RESTRICTED +/* Inject the fips checksum into the image. */ +#define CONFIG_FIPS_CHECKSUM /* Include crypto stuff, both software and hardware. Enable optimizations. */ /* Use board specific version of dcrypto */ #define CONFIG_FIPS_UTIL diff --git a/include/config.h b/include/config.h index 8914c92725..475c56f13f 100644 --- a/include/config.h +++ b/include/config.h @@ -1360,6 +1360,8 @@ #undef CONFIG_DCRYPTO_BOARD /* Build FIPS utils in the module */ #undef CONFIG_FIPS_UTIL +/* Inject the fips checksum into the image. */ +#undef CONFIG_FIPS_CHECKSUM /* * This provides struct definitions and function declarations that can be * implemented by unit tests for testing code that depends on dcrypto. diff --git a/util/inject_fips_fingerprint.sh b/util/inject_fips_fingerprint.sh new file mode 100755 index 0000000000..830310af3e --- /dev/null +++ b/util/inject_fips_fingerprint.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# +# Copyright 2021 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. +# +# Calculate hash of fips module and inject it into the .elf file. + +main() { + local objcopy="${1}" + local objdump="${2}" + local rw_elf_in="${3}" + local base="${rw_elf_in%.elf}" + local rw_elf_out="${rw_elf_in}.fips" + local checksum_section=".text.fips_checksum" + local fips_checksum="${base}.fips.checksum" + local fips_checksum_dump="${fips_checksum}.dump" + local size + local sections + local fips_start + local fips_end + local fips_offset + local file_offset + local base_addr + local result + + if [ ! -f "${rw_elf_in}" ] ; then + echo " ${rw_elf_in} doesn't exist" + return 1 + fi + + echo "${rw_elf_in} ${rw_elf_out}" + sections=$( objdump -t "${rw_elf_in}" ) + + if [[ "${sections}" =~ "${checksum_section}" ]] ; then + echo " get fips checksum" + else + echo " no fips checksum" + return 1 + fi + vals=( $(${objdump} -x -j .text "${rw_elf_in}" | awk ' + { + if ($2 == ".text" ) { + file_offs = $6 + base_addr = $5 + } + if ($5 == "__fips_module_start") {fips_start = $1 } + if ($5 == "__fips_module_end") {fips_end = $1 } + } + END { printf "0x%s 0x%s 0x%s 0x%s\n", file_offs, base_addr, fips_start, + fips_end }') ) + + file_offset=${vals[0]} + base_addr=${vals[1]} + fips_start=${vals[2]} + fips_end=${vals[3]} + size=$((fips_end - fips_start)) + fips_offset=$((file_offset + fips_start - base_addr)) + + result=$(dd if="${rw_elf_in}" skip="${fips_offset}" count="${size}" bs=1 | \ + sha256sum) + + echo "${result%% *}" > "${fips_checksum}" + echo "${result%% *}" | xxd -r -p > "${fips_checksum_dump}" + + cp "${rw_elf_in}" "${rw_elf_out}" + ${objcopy} --update-section "${checksum_section}"="${fips_checksum_dump}" \ + "${rw_elf_out}" +} + +main "$@" |