summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2021-08-06 19:21:01 -0500
committerCommit Bot <commit-bot@chromium.org>2021-09-07 17:52:51 +0000
commit1c3b00c3f7c0c819c330ddd98812d9085c578230 (patch)
tree8fe3a82953dffe2b178a738e3e123be7d02071b5
parent519a3cf7cdef12437ae27a58d0dd70e12ca07278 (diff)
downloadchrome-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.rules14
-rw-r--r--board/cr50/board.h2
-rw-r--r--include/config.h2
-rwxr-xr-xutil/inject_fips_fingerprint.sh71
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 "$@"