diff options
author | Randall Spangler <rspangler@chromium.org> | 2010-06-17 14:45:22 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2010-06-17 14:45:22 -0700 |
commit | 620c38cf34eadcd222535b01fb71c5e9fbc1cb80 (patch) | |
tree | 55c883fd01447b0ffdf6c121f4b7c6817cbc53b0 | |
parent | d52030f340d14f8039360a39ec6a938d31e083d0 (diff) | |
download | vboot-620c38cf34eadcd222535b01fb71c5e9fbc1cb80.tar.gz |
Remove unused files, and tidy the directory structure of the remaining ones.
Review URL: http://codereview.chromium.org/2815011
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | README | 36 | ||||
-rw-r--r-- | firmware/Makefile (renamed from vboot_firmware/Makefile) | 0 | ||||
-rw-r--r-- | firmware/README (renamed from vboot_firmware/README) | 0 | ||||
-rw-r--r-- | firmware/include/boot_device.h (renamed from vboot_firmware/include/boot_device.h) | 0 | ||||
-rw-r--r-- | firmware/include/gbb_header.h (renamed from vboot_firmware/include/gbb_header.h) | 0 | ||||
-rw-r--r-- | firmware/include/load_firmware_fw.h (renamed from vboot_firmware/include/load_firmware_fw.h) | 0 | ||||
-rw-r--r-- | firmware/include/load_kernel_fw.h (renamed from vboot_firmware/include/load_kernel_fw.h) | 0 | ||||
-rw-r--r-- | firmware/include/rollback_index.h (renamed from vboot_firmware/include/rollback_index.h) | 0 | ||||
-rw-r--r-- | firmware/include/sysincludes.h (renamed from vboot_firmware/include/sysincludes.h) | 7 | ||||
-rw-r--r-- | firmware/include/tlcl.h (renamed from vboot_firmware/include/tlcl.h) | 0 | ||||
-rw-r--r-- | firmware/include/utility.h (renamed from vboot_firmware/include/utility.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cgptlib/cgptlib.c (renamed from vboot_firmware/lib/cgptlib/cgptlib.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cgptlib/cgptlib_internal.c (renamed from vboot_firmware/lib/cgptlib/cgptlib_internal.c) | 0 | ||||
-rwxr-xr-x | firmware/lib/cgptlib/crc32.c (renamed from vboot_firmware/lib/cgptlib/crc32.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib.h (renamed from vboot_firmware/lib/cgptlib/include/cgptlib.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/cgptlib_internal.h (renamed from vboot_firmware/lib/cgptlib/include/cgptlib_internal.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/crc32.h (renamed from vboot_firmware/lib/cgptlib/include/crc32.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cgptlib/include/gpt.h (renamed from vboot_firmware/lib/cgptlib/include/gpt.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/README (renamed from vboot_firmware/lib/cryptolib/README) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/include/cryptolib.h (renamed from vboot_firmware/lib/cryptolib/include/cryptolib.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/include/padding.h (renamed from vboot_firmware/lib/cryptolib/include/padding.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/include/rsa.h (renamed from vboot_firmware/lib/cryptolib/include/rsa.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/include/sha.h (renamed from vboot_firmware/lib/cryptolib/include/sha.h) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/padding.c (renamed from vboot_firmware/lib/cryptolib/padding.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/rsa.c (renamed from vboot_firmware/lib/cryptolib/rsa.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/rsa_utility.c (renamed from vboot_firmware/lib/cryptolib/rsa_utility.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/sha1.c (renamed from vboot_firmware/lib/cryptolib/sha1.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/sha2.c (renamed from vboot_firmware/lib/cryptolib/sha2.c) | 0 | ||||
-rw-r--r-- | firmware/lib/cryptolib/sha_utility.c (renamed from vboot_firmware/lib/cryptolib/sha_utility.c) | 0 | ||||
-rw-r--r-- | firmware/lib/include/stateful_util.h (renamed from vboot_firmware/lib/include/stateful_util.h) | 0 | ||||
-rw-r--r-- | firmware/lib/include/tss_constants.h (renamed from vboot_firmware/lib/include/tss_constants.h) | 0 | ||||
-rw-r--r-- | firmware/lib/include/vboot_common.h (renamed from vboot_firmware/lib/include/vboot_common.h) | 0 | ||||
-rw-r--r-- | firmware/lib/include/vboot_kernel.h (renamed from vboot_firmware/lib/include/vboot_kernel.h) | 0 | ||||
-rw-r--r-- | firmware/lib/include/vboot_struct.h (renamed from vboot_firmware/lib/include/vboot_struct.h) | 0 | ||||
-rw-r--r-- | firmware/lib/rollback_index.c (renamed from vboot_firmware/lib/rollback_index.c) | 0 | ||||
-rw-r--r-- | firmware/lib/stateful_util.c (renamed from vboot_firmware/lib/stateful_util.c) | 0 | ||||
-rw-r--r-- | firmware/lib/vboot_common.c (renamed from vboot_firmware/lib/vboot_common.c) | 0 | ||||
-rw-r--r-- | firmware/lib/vboot_firmware.c (renamed from vboot_firmware/lib/vboot_firmware.c) | 0 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c (renamed from vboot_firmware/lib/vboot_kernel.c) | 0 | ||||
-rw-r--r-- | firmware/linktest/main.c (renamed from vboot_firmware/linktest/main.c) | 0 | ||||
-rw-r--r-- | firmware/stub/boot_device_stub.c (renamed from vboot_firmware/stub/boot_device_stub.c) | 0 | ||||
-rw-r--r-- | firmware/stub/load_firmware_stub.c (renamed from vboot_firmware/stub/load_firmware_stub.c) | 0 | ||||
-rw-r--r-- | firmware/stub/tlcl.c (renamed from vboot_firmware/stub/tlcl.c) | 0 | ||||
-rw-r--r-- | firmware/stub/utility_stub.c (renamed from vboot_firmware/stub/utility_stub.c) | 0 | ||||
-rw-r--r-- | host/Makefile | 5 | ||||
-rw-r--r-- | host/include/file_keys.h (renamed from misclibs/include/file_keys.h) | 2 | ||||
-rw-r--r-- | host/include/signature_digest.h (renamed from misclibs/include/signature_digest.h) | 2 | ||||
-rw-r--r-- | host/lib/file_keys.c (renamed from misclibs/file_keys.c) | 0 | ||||
-rw-r--r-- | host/lib/signature_digest.c (renamed from misclibs/signature_digest.c) | 0 | ||||
-rw-r--r-- | host/linktest/main.c | 13 | ||||
-rw-r--r-- | misclibs/Makefile | 16 | ||||
-rw-r--r-- | tests/Makefile | 74 | ||||
-rwxr-xr-x | tests/run_image_verification_tests.sh | 7 | ||||
-rw-r--r-- | tests/test_common.c | 111 | ||||
-rw-r--r-- | tests/test_common.h | 27 | ||||
-rw-r--r-- | utility/Makefile | 23 | ||||
-rw-r--r-- | utility/include/firmware_utility.h | 76 | ||||
-rw-r--r-- | utility/include/kernel_utility.h | 87 | ||||
-rw-r--r-- | utility/kernel_utility.cc | 525 | ||||
-rw-r--r-- | utility/load_kernel_test_old.c | 147 | ||||
-rw-r--r-- | utility/sign_image.c | 115 | ||||
-rw-r--r-- | vkernel/Makefile | 19 | ||||
-rw-r--r-- | vkernel/include/kernel_image.h | 118 | ||||
-rw-r--r-- | vkernel/include/kernel_image_fw.h | 168 | ||||
-rw-r--r-- | vkernel/kernel_image.c | 754 | ||||
-rw-r--r-- | vkernel/kernel_image_fw.c | 384 | ||||
-rw-r--r-- | vkernel/load_kernel_fw.c | 251 |
68 files changed, 90 insertions, 2885 deletions
@@ -6,17 +6,15 @@ export CC ?= gcc export CXX ?= g++ export CFLAGS = -Wall -DNDEBUG -O3 -Werror export TOP = $(shell pwd) -export FWDIR=$(TOP)/vboot_firmware +export FWDIR=$(TOP)/firmware export HOSTDIR=$(TOP)/host -export INCLUDES = \ - -I$(FWDIR)/include \ - -I$(TOP)/misclibs/include +export INCLUDES = -I$(FWDIR)/include export BUILD = ${TOP}/build export FWLIB = ${BUILD}/vboot_fw.a export HOSTLIB= ${BUILD}/vboot_host.a -SUBDIRS = vboot_firmware misclibs host vkernel utility cgpt tests +SUBDIRS = firmware host utility cgpt tests all: set -e; \ @@ -7,22 +7,19 @@ Directory Structure The source is organized into distinct modules - -vboot_firmware/ - Contains ONLY the code required by the BIOS to validate -the secure boot components. There shouldn't be any code in here that signs -or generates images. BIOS should require ONLY this directory to implement -secure boot. Refer to vboot_firmware/README for futher details. +firmware/ - Contains ONLY the code required by the BIOS to validate +the secure boot components. There shouldn't be any code in here that +signs or generates images. BIOS should require ONLY this directory to +implement secure boot. Refer to firmware/README for futher details. -cgptlib/ - Work in progress for handling GPT headers. Parts of this will no -doubt be migrated into vboot_firmware/ +cgpt/ - Utility to read/write/modify GPT partitions. Much like the +gpt tool, but with support for Chrome OS extensiosn. -misclibs/ - Miscellaneous functions used by userland utilities. +host/ - Miscellaneous functions used by userland utilities. utility/ - Utilities for generating and verifying signed firmware and kernel images, as well as arbitrary blobs. -vfirmware/ and vkernel/ - Functions for generating, verifying, and -manipulating signed firmware and kernel images. - tests/ - User-land tests and benchmarks that test the reference implementation. Please have a look at these if you'd like to understand how to use the reference implementation. @@ -61,14 +58,17 @@ BUILD=../build make runtests Some useful utilities: ---------- -firmware_utility.c To generate verified boot firmware images. - -kernel_utility.c To generate verified boot kernel images. +vbutil_key Convert a public key into .vbpubk format +vbutil_keyblock Wrap a public key inside a signature and checksum +vbutil_firmware Create a .vblock with signature info for a + firmware image +vbutil_kernel Pack a kernel image, bootloader, and config into + a signed binary -dumpRSAPublicKey.c Dump RSA Public key (from a DER-encoded X509 - certificate) in a format suitable for - use by RSAVerify* functions in - crypto/. +dumpRSAPublicKey Dump RSA Public key (from a DER-encoded X509 + certificate) in a format suitable for + use by RSAVerify* functions in + crypto/. verify_data.c Verify a given signature on a given file. @@ -99,6 +99,8 @@ $ openssl req -batch -new -x509 -key signing_key.pem -out signing_key.crt $ utility/dumpRSAPublicKey root_key.crt > root_key.keyb $ utility/dumpRSAPublicKey signing_key.crt > signing_key.keyb +************** TODO: STUFF PAST HERE IS OUT OF DATE *************** + At this point we have all the requisite keys needed to generate a signed firmware image. diff --git a/vboot_firmware/Makefile b/firmware/Makefile index 07e113a0..07e113a0 100644 --- a/vboot_firmware/Makefile +++ b/firmware/Makefile diff --git a/vboot_firmware/README b/firmware/README index 2b0bff50..2b0bff50 100644 --- a/vboot_firmware/README +++ b/firmware/README diff --git a/vboot_firmware/include/boot_device.h b/firmware/include/boot_device.h index 10303ca4..10303ca4 100644 --- a/vboot_firmware/include/boot_device.h +++ b/firmware/include/boot_device.h diff --git a/vboot_firmware/include/gbb_header.h b/firmware/include/gbb_header.h index 18bb64b7..18bb64b7 100644 --- a/vboot_firmware/include/gbb_header.h +++ b/firmware/include/gbb_header.h diff --git a/vboot_firmware/include/load_firmware_fw.h b/firmware/include/load_firmware_fw.h index 8ba67cf7..8ba67cf7 100644 --- a/vboot_firmware/include/load_firmware_fw.h +++ b/firmware/include/load_firmware_fw.h diff --git a/vboot_firmware/include/load_kernel_fw.h b/firmware/include/load_kernel_fw.h index 4f86b403..4f86b403 100644 --- a/vboot_firmware/include/load_kernel_fw.h +++ b/firmware/include/load_kernel_fw.h diff --git a/vboot_firmware/include/rollback_index.h b/firmware/include/rollback_index.h index c359b4bb..c359b4bb 100644 --- a/vboot_firmware/include/rollback_index.h +++ b/firmware/include/rollback_index.h diff --git a/vboot_firmware/include/sysincludes.h b/firmware/include/sysincludes.h index 57172518..758e5820 100644 --- a/vboot_firmware/include/sysincludes.h +++ b/firmware/include/sysincludes.h @@ -4,12 +4,13 @@ */ /* System includes for vboot reference library. This is the ONLY - * place in vboot_firmware where system headers may be included via + * place in firmware/ where system headers may be included via * #include <...>, so that there's only one place that needs to be * fixed up for platforms which don't have all the system includes. * - * Stub files may still include system headers, because they're local - * implementations and will be ported to each system anyway. */ + * Files in firmware/stub may still include system headers, because + * they're local implementations and will be ported to each system + * anyway. */ #ifndef VBOOT_REFERENCE_SYSINCLUDES_H_ #define VBOOT_REFERENCE_SYSINCLUDES_H_ diff --git a/vboot_firmware/include/tlcl.h b/firmware/include/tlcl.h index 82947f63..82947f63 100644 --- a/vboot_firmware/include/tlcl.h +++ b/firmware/include/tlcl.h diff --git a/vboot_firmware/include/utility.h b/firmware/include/utility.h index 4cfb076b..4cfb076b 100644 --- a/vboot_firmware/include/utility.h +++ b/firmware/include/utility.h diff --git a/vboot_firmware/lib/cgptlib/cgptlib.c b/firmware/lib/cgptlib/cgptlib.c index 4856311a..4856311a 100644 --- a/vboot_firmware/lib/cgptlib/cgptlib.c +++ b/firmware/lib/cgptlib/cgptlib.c diff --git a/vboot_firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 7faf3832..7faf3832 100644 --- a/vboot_firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c diff --git a/vboot_firmware/lib/cgptlib/crc32.c b/firmware/lib/cgptlib/crc32.c index 9dacd178..9dacd178 100755 --- a/vboot_firmware/lib/cgptlib/crc32.c +++ b/firmware/lib/cgptlib/crc32.c diff --git a/vboot_firmware/lib/cgptlib/include/cgptlib.h b/firmware/lib/cgptlib/include/cgptlib.h index 4eadc817..4eadc817 100644 --- a/vboot_firmware/lib/cgptlib/include/cgptlib.h +++ b/firmware/lib/cgptlib/include/cgptlib.h diff --git a/vboot_firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h index f4a4d199..f4a4d199 100644 --- a/vboot_firmware/lib/cgptlib/include/cgptlib_internal.h +++ b/firmware/lib/cgptlib/include/cgptlib_internal.h diff --git a/vboot_firmware/lib/cgptlib/include/crc32.h b/firmware/lib/cgptlib/include/crc32.h index 23361138..23361138 100644 --- a/vboot_firmware/lib/cgptlib/include/crc32.h +++ b/firmware/lib/cgptlib/include/crc32.h diff --git a/vboot_firmware/lib/cgptlib/include/gpt.h b/firmware/lib/cgptlib/include/gpt.h index a65317fb..a65317fb 100644 --- a/vboot_firmware/lib/cgptlib/include/gpt.h +++ b/firmware/lib/cgptlib/include/gpt.h diff --git a/vboot_firmware/lib/cryptolib/README b/firmware/lib/cryptolib/README index e576bb7b..e576bb7b 100644 --- a/vboot_firmware/lib/cryptolib/README +++ b/firmware/lib/cryptolib/README diff --git a/vboot_firmware/lib/cryptolib/include/cryptolib.h b/firmware/lib/cryptolib/include/cryptolib.h index b65a71db..b65a71db 100644 --- a/vboot_firmware/lib/cryptolib/include/cryptolib.h +++ b/firmware/lib/cryptolib/include/cryptolib.h diff --git a/vboot_firmware/lib/cryptolib/include/padding.h b/firmware/lib/cryptolib/include/padding.h index 59b8dc39..59b8dc39 100644 --- a/vboot_firmware/lib/cryptolib/include/padding.h +++ b/firmware/lib/cryptolib/include/padding.h diff --git a/vboot_firmware/lib/cryptolib/include/rsa.h b/firmware/lib/cryptolib/include/rsa.h index 2d3ee955..2d3ee955 100644 --- a/vboot_firmware/lib/cryptolib/include/rsa.h +++ b/firmware/lib/cryptolib/include/rsa.h diff --git a/vboot_firmware/lib/cryptolib/include/sha.h b/firmware/lib/cryptolib/include/sha.h index 46e417d9..46e417d9 100644 --- a/vboot_firmware/lib/cryptolib/include/sha.h +++ b/firmware/lib/cryptolib/include/sha.h diff --git a/vboot_firmware/lib/cryptolib/padding.c b/firmware/lib/cryptolib/padding.c index 14d94458..14d94458 100644 --- a/vboot_firmware/lib/cryptolib/padding.c +++ b/firmware/lib/cryptolib/padding.c diff --git a/vboot_firmware/lib/cryptolib/rsa.c b/firmware/lib/cryptolib/rsa.c index bfc64469..bfc64469 100644 --- a/vboot_firmware/lib/cryptolib/rsa.c +++ b/firmware/lib/cryptolib/rsa.c diff --git a/vboot_firmware/lib/cryptolib/rsa_utility.c b/firmware/lib/cryptolib/rsa_utility.c index f15b97ee..f15b97ee 100644 --- a/vboot_firmware/lib/cryptolib/rsa_utility.c +++ b/firmware/lib/cryptolib/rsa_utility.c diff --git a/vboot_firmware/lib/cryptolib/sha1.c b/firmware/lib/cryptolib/sha1.c index 70653ba7..70653ba7 100644 --- a/vboot_firmware/lib/cryptolib/sha1.c +++ b/firmware/lib/cryptolib/sha1.c diff --git a/vboot_firmware/lib/cryptolib/sha2.c b/firmware/lib/cryptolib/sha2.c index e7f78885..e7f78885 100644 --- a/vboot_firmware/lib/cryptolib/sha2.c +++ b/firmware/lib/cryptolib/sha2.c diff --git a/vboot_firmware/lib/cryptolib/sha_utility.c b/firmware/lib/cryptolib/sha_utility.c index 4e266f7c..4e266f7c 100644 --- a/vboot_firmware/lib/cryptolib/sha_utility.c +++ b/firmware/lib/cryptolib/sha_utility.c diff --git a/vboot_firmware/lib/include/stateful_util.h b/firmware/lib/include/stateful_util.h index e782ed88..e782ed88 100644 --- a/vboot_firmware/lib/include/stateful_util.h +++ b/firmware/lib/include/stateful_util.h diff --git a/vboot_firmware/lib/include/tss_constants.h b/firmware/lib/include/tss_constants.h index a2371485..a2371485 100644 --- a/vboot_firmware/lib/include/tss_constants.h +++ b/firmware/lib/include/tss_constants.h diff --git a/vboot_firmware/lib/include/vboot_common.h b/firmware/lib/include/vboot_common.h index b7998a7a..b7998a7a 100644 --- a/vboot_firmware/lib/include/vboot_common.h +++ b/firmware/lib/include/vboot_common.h diff --git a/vboot_firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h index 9cb7f028..9cb7f028 100644 --- a/vboot_firmware/lib/include/vboot_kernel.h +++ b/firmware/lib/include/vboot_kernel.h diff --git a/vboot_firmware/lib/include/vboot_struct.h b/firmware/lib/include/vboot_struct.h index a60615c2..a60615c2 100644 --- a/vboot_firmware/lib/include/vboot_struct.h +++ b/firmware/lib/include/vboot_struct.h diff --git a/vboot_firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c index cb86e89e..cb86e89e 100644 --- a/vboot_firmware/lib/rollback_index.c +++ b/firmware/lib/rollback_index.c diff --git a/vboot_firmware/lib/stateful_util.c b/firmware/lib/stateful_util.c index 137ea77a..137ea77a 100644 --- a/vboot_firmware/lib/stateful_util.c +++ b/firmware/lib/stateful_util.c diff --git a/vboot_firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c index f76eed45..f76eed45 100644 --- a/vboot_firmware/lib/vboot_common.c +++ b/firmware/lib/vboot_common.c diff --git a/vboot_firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c index 88d6bb64..88d6bb64 100644 --- a/vboot_firmware/lib/vboot_firmware.c +++ b/firmware/lib/vboot_firmware.c diff --git a/vboot_firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index 1440eb44..1440eb44 100644 --- a/vboot_firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c diff --git a/vboot_firmware/linktest/main.c b/firmware/linktest/main.c index e6659a99..e6659a99 100644 --- a/vboot_firmware/linktest/main.c +++ b/firmware/linktest/main.c diff --git a/vboot_firmware/stub/boot_device_stub.c b/firmware/stub/boot_device_stub.c index c7bb86f5..c7bb86f5 100644 --- a/vboot_firmware/stub/boot_device_stub.c +++ b/firmware/stub/boot_device_stub.c diff --git a/vboot_firmware/stub/load_firmware_stub.c b/firmware/stub/load_firmware_stub.c index 9453856a..9453856a 100644 --- a/vboot_firmware/stub/load_firmware_stub.c +++ b/firmware/stub/load_firmware_stub.c diff --git a/vboot_firmware/stub/tlcl.c b/firmware/stub/tlcl.c index 23f0f09a..23f0f09a 100644 --- a/vboot_firmware/stub/tlcl.c +++ b/firmware/stub/tlcl.c diff --git a/vboot_firmware/stub/utility_stub.c b/firmware/stub/utility_stub.c index a41e3a3d..a41e3a3d 100644 --- a/vboot_firmware/stub/utility_stub.c +++ b/firmware/stub/utility_stub.c diff --git a/host/Makefile b/host/Makefile index 7f1c9f15..29b8231c 100644 --- a/host/Makefile +++ b/host/Makefile @@ -14,12 +14,13 @@ INCLUDES += \ # find ./lib -iname '*.c' | sort ALL_SRCS = \ + ./lib/file_keys.c \ ./lib/host_common.c \ ./lib/host_key.c \ ./lib/host_keyblock.c \ ./lib/host_misc.c \ - ./lib/host_signature.c - + ./lib/host_signature.c \ + ./lib/signature_digest.c test : $(HOSTLIB) $(CC) $(CFLAGS) $(INCLUDES) -o $(BUILD_ROOT)/a.out $(TESTDIR)/main.c \ diff --git a/misclibs/include/file_keys.h b/host/include/file_keys.h index eac4df0e..285a3e5b 100644 --- a/misclibs/include/file_keys.h +++ b/host/include/file_keys.h @@ -37,7 +37,7 @@ uint8_t* DigestFile(char* input_file, int sig_algorithm); * * Returns the signature. Caller owns the buffer and must Free() it. */ -uint8_t* SignatureFile(const char* input_fie, const char* key_file, +uint8_t* SignatureFile(const char* input_file, const char* key_file, int algorithm); #endif /* VBOOT_REFERENCE_FILE_KEYS_H_ */ diff --git a/misclibs/include/signature_digest.h b/host/include/signature_digest.h index 2376b972..55662b94 100644 --- a/misclibs/include/signature_digest.h +++ b/host/include/signature_digest.h @@ -11,7 +11,7 @@ /* Returns a buffer with DigestInfo (which depends on [algorithm]) * prepended to [digest]. */ -uint8_t* prepend_digestinfo(int algorithm, uint8_t* digest); +uint8_t* PrependDigestInfo(int algorithm, uint8_t* digest); /* Function that outputs the message digest of the contents of a buffer in a * format that can be used as input to OpenSSL for an RSA signature. diff --git a/misclibs/file_keys.c b/host/lib/file_keys.c index c7774306..c7774306 100644 --- a/misclibs/file_keys.c +++ b/host/lib/file_keys.c diff --git a/misclibs/signature_digest.c b/host/lib/signature_digest.c index 4dba95a6..4dba95a6 100644 --- a/misclibs/signature_digest.c +++ b/host/lib/signature_digest.c diff --git a/host/linktest/main.c b/host/linktest/main.c index 5fb7dd3d..93c5ac2a 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -1,6 +1,8 @@ #include <stdio.h> #include "host_common.h" +#include "file_keys.h" +#include "signature_digest.h" int main(void) { @@ -32,5 +34,16 @@ int main(void) CreateFirmwarePreamble(0, 0, 0, 0); CreateKernelPreamble(0, 0, 0, 0, 0, 0, 0); + /* file_keys.h */ + BufferFromFile(0, 0); + RSAPublicKeyFromFile(0); + DigestFile(0, 0); + SignatureFile(0, 0, 0); + + /* signature_digest.h */ + PrependDigestInfo(0, 0); + SignatureDigest(0, 0, 0); + SignatureBuf(0, 0, 0, 0); + return 0; } diff --git a/misclibs/Makefile b/misclibs/Makefile deleted file mode 100644 index e4968714..00000000 --- a/misclibs/Makefile +++ /dev/null @@ -1,16 +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. - -INCLUDES += -I./include \ - -I$(TOP)/common/include \ - -I$(TOP)/vboot_firmware/lib/cryptolib/include \ - -I$(TOP)/vfirmware/include \ - -I$(TOP)/vkernel/include - -BUILD_ROOT := ${BUILD}/misclibs - -ALL_SRCS = file_keys.c signature_digest.c - -include ../common.mk - diff --git a/tests/Makefile b/tests/Makefile index dc8620e4..1e8fc9da 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -6,29 +6,17 @@ INCLUDES += -I./include \ -I$(FWDIR)/lib/include \ -I$(FWDIR)/lib/cgptlib/include \ -I$(FWDIR)/lib/cryptolib/include \ - -I../host/include \ - -I../misclibs/include \ - -I../vboot_firmware/lib/include\ - -I../vkernel/include -IMAGE_LIBS = $(BUILD)/vkernel/kernel_image.o \ - $(BUILD)/vkernel/kernel_image_fw.o -UTIL_LIBS = $(BUILD)/misclibs/file_keys.o $(BUILD)/misclibs/signature_digest.o + -I$(HOSTDIR)/include BUILD_ROOT = ${BUILD}/tests -TEST_NAMES = big_kernel_tests \ - cgptlib_test \ - kernel_image_tests \ - kernel_rollback_tests \ - kernel_splicing_tests \ - kernel_verify_benchmark \ +TEST_NAMES = cgptlib_test \ rsa_padding_test \ rsa_verify_benchmark \ sha_benchmark \ sha_tests \ vboot_common_tests \ vboot_common2_tests \ - vboot_common3_tests \ - verify_kernel_fuzz_driver + vboot_common3_tests TEST_BINS = $(addprefix ${BUILD_ROOT}/,$(TEST_NAMES)) TEST_LIB = ${BUILD_ROOT}/test.a @@ -37,7 +25,7 @@ TEST_LIB_OBJS = $(TEST_LIB_SRCS:%.c=${BUILD_ROOT}/%.o) ALL_DEPS = $(addsuffix .d,${TEST_BINS} ${TEST_LIB_OBJS}) CFLAGS += -MMD -MF $@.d -LIBS := ${TEST_LIB} $(IMAGE_LIBS) $(UTIL_LIBS) $(HOSTLIB) $(FWLIB) +LIBS := ${TEST_LIB} $(HOSTLIB) $(FWLIB) all: $(TEST_BINS) ${EXTRA_TARGET} @@ -51,37 +39,57 @@ ${BUILD_ROOT}/%.o : %.c ${BUILD_ROOT}/%: %.c ${LIBS} $(CC) $(CFLAGS) $(INCLUDES) $< ${LIBS} -o $@ -lcrypto -lrt -# TODO: port these tests to vboot_firmware, if not already eqivalent -# functionality +# TODO: port these tests to new API, if not already eqivalent +# functionality in other tests +# # big_firmware_tests # firmware_image_tests # firmware_rollback_tests # firmware_splicing_tests # firmware_verify_benchmark # verify_firmware_fuzz_driver +# +# big_kernel_tests +# kernel_image_tests +# kernel_rollback_tests +# kernel_splicing_tests +# kernel_verify_benchmark +# verify_kernel_fuzz_driver ifneq (${RUNTESTS},) EXTRA_TARGET = runtests endif -runtests: +# Generate test keys +genkeys: ./gen_test_keys.sh - # Crypto tests + +# Run cgpt tests +runcgpttests: + ${BUILD_ROOT}/cgptlib_test + ./run_cgpt_tests.sh ${BUILD}/cgpt/cgpt + +# Run crypto tests +runcryptotests: ./run_rsa_tests.sh ${BUILD_ROOT}/sha_tests - ./run_vbutil_tests.sh ./run_vboot_common_tests.sh - ./run_image_verification_tests.sh - # Splicing tests - #${BUILD_ROOT}/firmware_splicing_tests - ${BUILD_ROOT}/kernel_splicing_tests - # Rollback Tests - #${BUILD_ROOT}/firmware_rollback_tests - ${BUILD_ROOT}/kernel_rollback_tests - # Helper Library Tests - ${BUILD_ROOT}/cgptlib_test - # Tool tests - ./run_cgpt_tests.sh ${BUILD}/cgpt/cgpt --include ${ALL_DEPS}
\ No newline at end of file +# Run other misc tests +runmisctests: + ./run_vbutil_tests.sh + + +runtests: genkeys runcgpttests runcryptotests runmisctests + +# TODO: tests to run when ported to new API +# ./run_image_verification_tests.sh +# # Splicing tests +# ${BUILD_ROOT}/firmware_splicing_tests +# ${BUILD_ROOT}/kernel_splicing_tests +# # Rollback Tests +# ${BUILD_ROOT}/firmware_rollback_tests +# ${BUILD_ROOT}/kernel_rollback_tests + +-include ${ALL_DEPS} diff --git a/tests/run_image_verification_tests.sh b/tests/run_image_verification_tests.sh index 9a2e68cb..025066a4 100755 --- a/tests/run_image_verification_tests.sh +++ b/tests/run_image_verification_tests.sh @@ -70,10 +70,9 @@ ${kernel_hashalgo}${COL_STOP}" check_test_keys -# TODO: re-enable when tests are ported to new vboot -#echo -#echo "Testing high-level firmware image verification..." -#test_firmware_verification +echo +echo "Testing high-level firmware image verification..." +test_firmware_verification echo echo "Testing high-level kernel image verification..." diff --git a/tests/test_common.c b/tests/test_common.c index 1c0fae23..e53f596b 100644 --- a/tests/test_common.c +++ b/tests/test_common.c @@ -44,114 +44,3 @@ int TEST_NEQ(int result, int not_expected_result, char* testname) { return 0; } } - -KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, - int kernel_sign_algorithm, - const uint8_t* kernel_sign_key, - int kernel_key_version, - int kernel_version, - uint64_t kernel_len, - const char* firmware_key_file, - const char* kernel_key_file, - uint8_t kernel_data_fill_char) { - KernelImage* image = KernelImageNew(); - - Memcpy(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE); - image->header_version = 1; - image->firmware_sign_algorithm = firmware_sign_algorithm; - image->kernel_sign_algorithm = kernel_sign_algorithm; - image->kernel_key_version = kernel_key_version; - image->kernel_sign_key = (uint8_t*) Malloc( - RSAProcessedKeySize(image->kernel_sign_algorithm)); - Memcpy(image->kernel_sign_key, kernel_sign_key, - RSAProcessedKeySize(image->kernel_sign_algorithm)); - - /* Update correct header length. */ - image->header_len = GetKernelHeaderLen(image); - - /* Calculate SHA-512 digest on header and populate header_checksum. */ - CalculateKernelHeaderChecksum(image, image->header_checksum); - - /* Populate kernel options and data with dummy data. */ - image->kernel_version = kernel_version; - image->bootloader_offset = 0; - image->bootloader_size = 512; - image->padded_header_size = 100; - image->kernel_len = kernel_len; - image->kernel_key_signature = image->kernel_signature = NULL; - image->kernel_data = Malloc(kernel_len); - Memset(image->kernel_data, kernel_data_fill_char, kernel_len); - - /* Generate and populate signatures. */ - if (!AddKernelKeySignature(image, firmware_key_file)) { - debug("Couldn't create key signature.\n"); - KernelImageFree(image); - return NULL; - } - - if (!AddKernelSignature(image, kernel_key_file)) { - debug("Couldn't create kernel option and kernel signature.\n"); - KernelImageFree(image); - return NULL; - } - - return image; -} - -uint8_t* GenerateTestKernelBlob(int firmware_sign_algorithm, - int kernel_sign_algorithm, - const uint8_t* kernel_sign_key, - int kernel_key_version, - int kernel_version, - uint64_t kernel_len, - const char* firmware_key_file, - const char* kernel_key_file) { - KernelImage* image = NULL; - uint8_t* kernel_blob = NULL; - uint64_t kernel_blob_len = 0; - - image = GenerateTestKernelImage(firmware_sign_algorithm, - kernel_sign_algorithm, - kernel_sign_key, - kernel_key_version, - kernel_version, - kernel_len, - firmware_key_file, - kernel_key_file, - 'K'); - - kernel_blob = GetKernelBlob(image, &kernel_blob_len); - KernelImageFree(image); - return kernel_blob; -} - -uint8_t* GenerateRollbackTestKernelBlob(int kernel_key_version, - int kernel_version, - int is_corrupt) { - KernelImage* image = NULL; - uint64_t len; - uint8_t* kernel_blob = NULL; - uint8_t* kernel_sign_key = NULL; - kernel_sign_key = BufferFromFile("testkeys/key_rsa1024.keyb", - &len); - if (!kernel_sign_key) - return NULL; - image = GenerateTestKernelImage(0, /* Firmware algo: RSA1024/SHA1 */ - 0, /* Kernel algo: RSA1024/SHA1 */ - kernel_sign_key, - kernel_key_version, - kernel_version, - 1, /* kernel length. */ - "testkeys/key_rsa1024.pem", - "testkeys/key_rsa1024.pem", - 'K'); - if (!image) - return NULL; - if (is_corrupt) { - /* Invalidate image. */ - Memset(image->kernel_data, 'X', image->kernel_len); - } - kernel_blob = GetKernelBlob(image, &len); - KernelImageFree(image); - return kernel_blob; -} diff --git a/tests/test_common.h b/tests/test_common.h index 5485fc45..d62071f7 100644 --- a/tests/test_common.h +++ b/tests/test_common.h @@ -9,8 +9,6 @@ #include <stdint.h> -#include "kernel_image.h" - extern int gTestSuccess; /* Return 1 if result is equal to expected_result, else return 0. @@ -20,29 +18,4 @@ int TEST_EQ(int result, int expected_result, char* testname); * Also update the global gTestSuccess flag if test fails. */ int TEST_NEQ(int result, int not_expected_result, char* testname); -/* Test kernel image generation functions. */ -KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, - int kernel_sign_algorithm, - const uint8_t* kernel_sign_key, - int kernel_key_version, - int kernel_version, - uint64_t kernel_len, - const char* firmware_key_file, - const char* kernel_key_file, - uint8_t kernel_data_fill_char); -uint8_t* GenerateTestKernelBlob(int firmware_sign_algorithm, - int kernel_sign_algorithm, - const uint8_t* kernel_sign_key, - int kernel_key_version, - int kernel_version, - uint64_t kernel_len, - const char* firmware_key_file, - const char* kernel_key_file); - -/* Generates a test kernel iamge for rollback tests with a given - * [kernel_key_version} and [kernel_version]. If [is_corrupt] is 1, - * then the image has invalid signatures and will fail verification. */ -uint8_t* GenerateRollbackTestKernelBlob(int kernel_key_version, - int kernel_version, - int is_corrupt); #endif /* VBOOT_REFERENCE_TEST_COMMON_H_ */ diff --git a/utility/Makefile b/utility/Makefile index 9fa7aacc..2f686492 100644 --- a/utility/Makefile +++ b/utility/Makefile @@ -6,19 +6,10 @@ INCLUDES += -I./include \ -I$(FWDIR)/lib/include \ -I$(FWDIR)/lib/cgptlib/include \ -I$(FWDIR)/lib/cryptolib/include \ - -I$(HOSTDIR)/include \ - -I../misclibs/include \ - -I../vboot_firmware/include\ - -I../vkernel/include + -I$(HOSTDIR)/include CFLAGS += $(INCLUDES) CFLAGS += -MMD -MF $@.d -LIBS = $(BUILD)/misclibs/file_keys.o \ - $(BUILD)/misclibs/signature_digest.o \ - $(BUILD)/vkernel/kernel_image.o \ - $(BUILD)/vkernel/kernel_image_fw.o \ - $(BUILD)/vkernel/load_kernel_fw.o \ - $(HOSTLIB) \ - $(FWLIB) +LIBS = $(HOSTLIB) $(FWLIB) BUILD_ROOT = ${BUILD}/utility @@ -26,10 +17,7 @@ DESTDIR ?= /usr/bin TARGET_NAMES = dumpRSAPublicKey \ gbb_utility \ - kernel_utility \ load_kernel_test \ - load_kernel_test_old \ - sign_image \ signature_digest_utility \ vbutil_firmware \ vbutil_kernel \ @@ -51,13 +39,6 @@ ${BUILD_ROOT}/gbb_utility: gbb_utility.cc ${BUILD_ROOT}/load_kernel_test: load_kernel_test.c $(LIBS) $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto -${BUILD_ROOT}/load_kernel_test_old: load_kernel_test_old.c $(LIBS) - $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto - -${BUILD_ROOT}/kernel_utility: kernel_utility.cc $(LIBS) - $(CXX) $(CFLAGS) $(INCLUDES) -ggdb -D__STDC_LIMIT_MACROS $< \ - -o $@ $(LIBS) -lcrypto - ${BUILD_ROOT}/signature_digest_utility: signature_digest_utility.c $(LIBS) $(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto diff --git a/utility/include/firmware_utility.h b/utility/include/firmware_utility.h deleted file mode 100644 index 27c154fa..00000000 --- a/utility/include/firmware_utility.h +++ /dev/null @@ -1,76 +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. - -#ifndef VBOOT_REFERENCE_FIRMWARE_UTILITY_H_ -#define VBOOT_REFERENCE_FIRMWARE_UTILITY_H_ - -#include <string> - -class FirmwareImage; -struct RSAPublicKey; - -namespace vboot_reference { - -// A class for handling verified boot firmware images. -class FirmwareUtility { - public: - FirmwareUtility(); - ~FirmwareUtility(); - - // Print usage to stderr. - void PrintUsage(void); - - // Parse command line options and populate data members. - // Return true on success, false on failure. - bool ParseCmdLineOptions(int argc, char* argv[]); - - // Print descriptio of verified boot firmware image. - void DescribeSignedImage(); - - // Generate a verified boot image by reading firmware data from in_file_. - // Return true on success, false on failure. - bool GenerateSignedImage(); - - // Verify a previously generated signed firmware image using the root key read - // from [root_key_pub_file_]. - bool VerifySignedImage(); - - // Output the verified boot image to out_file_. - void OutputSignedImage(); - - - bool is_generate() { return is_generate_; } - bool is_verify() { return is_verify_; } - bool is_describe() { return is_describe_; } - - private: - - // Check if all options were specified and sane. - // Return true on success, false on failure. - bool CheckOptions(); - - FirmwareImage* image_; - RSAPublicKey* root_key_pub_; - std::string root_key_file_; - std::string root_key_pub_file_; - std::string firmware_key_file_; - std::string firmware_key_pub_file_; - std::string subkey_in_file_; // Existing key signature header. - std::string in_file_; - std::string out_file_; - std::string kernel_subkey_sign_pub_file_; - int firmware_key_version_; - int firmware_sign_algorithm_; - int firmware_version_; - int kernel_subkey_sign_algorithm_; - bool is_generate_; // Are we generating a new image? - bool is_verify_; // Are we just verifying an already signed image? - bool is_describe_; // Should we print out description of the image? - bool is_only_vblock_; // Should we just output the verification block? - bool is_subkey_out_; // Should we just output the subkey header? -}; - -} // namespace vboot_reference - -#endif // VBOOT_REFERENCE_FIRMWARE_UTILITY_H_ diff --git a/utility/include/kernel_utility.h b/utility/include/kernel_utility.h deleted file mode 100644 index 12ad9b83..00000000 --- a/utility/include/kernel_utility.h +++ /dev/null @@ -1,87 +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. - -#ifndef VBOOT_REFERENCE_KERNEL_UTILITY_H_ -#define VBOOT_REFERENCE_KERNEL_UTILITY_H_ - -#include <string> - -extern "C" { -#include "kernel_image.h" -} - -struct RSAPublicKey; - -namespace vboot_reference { - -// A class for handling verified boot kernel images. -class KernelUtility { - public: - KernelUtility(); - ~KernelUtility(); - - // Print usage to stderr. - void PrintUsage(void); - - // Parse command line options and populate data members. - // Return true on success, false on failure. - bool ParseCmdLineOptions(int argc, char* argv[]); - - // Print description of a verified boot kernel image. - void DescribeSignedImage(); - - // Generate a verified boot image by reading kernel data from in_file_. - // Return true on success, false on failure. - bool GenerateSignedImage(); - - // Verify a previously generated signed firmware image using the key read - // from [firmware_key_pub_file_]. - bool VerifySignedImage(); - - // Output the verified boot kernel image to out_file_. - void OutputSignedImage(); - - bool is_generate() { return is_generate_; } - bool is_verify() { return is_verify_; } - bool is_describe() { return is_describe_; } - - private: - - // Check if all options were specified and sane. - // Return true on success, false on failure. - bool CheckOptions(); - - KernelImage* image_; - RSAPublicKey* firmware_key_pub_; // Root key used for verification. - std::string firmware_key_file_; // Private key for signing the kernel key. - std::string firmware_key_pub_file_; - std::string kernel_key_file_; // Private key for signing the kernel. - std::string kernel_key_pub_file_; - std::string subkey_in_file_; // Existing key signature header. - std::string config_file_; // File containing kernel commandline parameters - std::string bootloader_file_; // Embedded bootloader code - std::string vmlinuz_file_; // Input vmlinuz to be embedded in signed blob. - - // Fields of a KernelImage. (read from the command line). - int header_version_; - int firmware_sign_algorithm_; - int kernel_sign_algorithm_; - int kernel_key_version_; - int kernel_version_; - int padding_; - uint64_t kernel_len_; - uint8_t* kernel_config_; - - std::string in_file_; - std::string out_file_; - bool is_generate_; // Are we generating a new image? - bool is_verify_; // Are we just verifying an already signed image? - bool is_describe_; // Should we print out description of the image? - bool is_only_vblock_; // Should we just output the verification block? - bool is_subkey_out_; // Should we just output the subkey header? -}; - -} // namespace vboot_reference - -#endif // VBOOT_REFERENCE_FIRMWARE_UTILITY_H_ diff --git a/utility/kernel_utility.cc b/utility/kernel_utility.cc deleted file mode 100644 index 4940112d..00000000 --- a/utility/kernel_utility.cc +++ /dev/null @@ -1,525 +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. -// -// Utility for manipulating verified boot kernel images. -// - -#include "kernel_utility.h" - -#include <getopt.h> -#include <stdio.h> -#include <stdint.h> // Needed for UINT16_MAX. -#include <stdlib.h> -#include <unistd.h> - -#include <iostream> - -extern "C" { -#include "cryptolib.h" -#include "file_keys.h" -#include "kernel_image.h" -#include "stateful_util.h" -#include "utility.h" -} - -using std::cerr; - -// Macro to determine the size of a field structure in the KernelImage -// structure. -#define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) - -namespace vboot_reference { - -KernelUtility::KernelUtility(): image_(NULL), - firmware_key_pub_(NULL), - header_version_(1), - firmware_sign_algorithm_(-1), - kernel_sign_algorithm_(-1), - kernel_key_version_(-1), - kernel_version_(-1), - padding_(0), - kernel_len_(0), - is_generate_(false), - is_verify_(false), - is_describe_(false), - is_only_vblock_(false) {} - -KernelUtility::~KernelUtility() { - RSAPublicKeyFree(firmware_key_pub_); - KernelImageFree(image_); -} - -void KernelUtility::PrintUsage(void) { - cerr << "\n" - "Utility to generate/verify/describe a verified boot kernel image\n" - "\n" - "Usage: kernel_utility <--generate|--verify|--describe> [OPTIONS]\n" - "\n" - "For \"--describe\", the required OPTIONS are:\n" - " --in <infile>\t\t\t\tSigned boot image to describe.\n" - "\n" - "For \"--verify\", required OPTIONS are:\n" - " --in <infile>\t\t\t\tSigned boot image to verify.\n" - " --firmware_key_pub <pubkeyfile>\tPre-processed public firmware key\n" - "\n" - "For \"--generate\", required OPTIONS are:\n" - " --firmware_key <privkeyfile>\t\tPrivate firmware signing key file\n" - " --kernel_key_pub <pubkeyfile>\t\tPre-processed public kernel signing" - " key\n" - " --firmware_sign_algorithm <algoid>\tSigning algorithm for firmware\n" - " --kernel_sign_algorithm <algoid>\tSigning algorithm for kernel\n" - " --kernel_key_version <number>\t\tKernel signing key version number\n" - "OR\n" - " --subkey_in <subkeyfile>\t\tExisting key signature header\n" - "\n" - " --kernel_key <privkeyfile>\t\tPrivate kernel signing key file\n" - " --kernel_version <number>\t\tKernel Version number\n" - " --config <file>\t\t\tEmbedded kernel command-line parameters\n" - " --bootloader <file>\t\t\tEmbedded bootloader stub\n" - " --vmlinuz <file>\t\t\tEmbedded kernel image\n" - " --out <outfile>\t\t\tOutput file for verified boot image\n" - "\n" - "Optional arguments for \"--generate\" are:\n" - " --padding <size>\t\t\tPad the header to this size\n" - " --subkey_out\t\t\t\tJust output the subkey (key verification) header\n" - " --vblock\t\t\t\tJust output the verification block\n" - "\n" - "<algoid> (for --*_sign_algorithm) is one of the following:\n"; - for (int i = 0; i < kNumAlgorithms; i++) { - cerr << " " << i << " for " << algo_strings[i] << "\n"; - } - cerr << "\n\n"; -} - -bool KernelUtility::ParseCmdLineOptions(int argc, char* argv[]) { - int option_index, i; - char *e = 0; - enum { - OPT_FIRMWARE_KEY = 1000, - OPT_FIRMWARE_KEY_PUB, - OPT_KERNEL_KEY, - OPT_KERNEL_KEY_PUB, - OPT_SUBKEY_IN, - OPT_FIRMWARE_SIGN_ALGORITHM, - OPT_KERNEL_SIGN_ALGORITHM, - OPT_KERNEL_KEY_VERSION, - OPT_KERNEL_VERSION, - OPT_IN, - OPT_OUT, - OPT_GENERATE, - OPT_VERIFY, - OPT_DESCRIBE, - OPT_VBLOCK, - OPT_BOOTLOADER, - OPT_VMLINUZ, - OPT_CONFIG, - OPT_PADDING, - OPT_SUBKEY_OUT, - }; - static struct option long_options[] = { - {"firmware_key", 1, 0, OPT_FIRMWARE_KEY }, - {"firmware_key_pub", 1, 0, OPT_FIRMWARE_KEY_PUB }, - {"kernel_key", 1, 0, OPT_KERNEL_KEY }, - {"kernel_key_pub", 1, 0, OPT_KERNEL_KEY_PUB }, - {"subkey_in", 1, 0, OPT_SUBKEY_IN }, - {"firmware_sign_algorithm", 1, 0, OPT_FIRMWARE_SIGN_ALGORITHM }, - {"kernel_sign_algorithm", 1, 0, OPT_KERNEL_SIGN_ALGORITHM }, - {"kernel_key_version", 1, 0, OPT_KERNEL_KEY_VERSION }, - {"kernel_version", 1, 0, OPT_KERNEL_VERSION }, - {"in", 1, 0, OPT_IN }, - {"out", 1, 0, OPT_OUT }, - {"generate", 0, 0, OPT_GENERATE }, - {"verify", 0, 0, OPT_VERIFY }, - {"describe", 0, 0, OPT_DESCRIBE }, - {"vblock", 0, 0, OPT_VBLOCK }, - {"bootloader", 1, 0, OPT_BOOTLOADER }, - {"vmlinuz", 1, 0, OPT_VMLINUZ }, - {"config", 1, 0, OPT_CONFIG }, - {"padding", 1, 0, OPT_PADDING }, - {"subkey_out", 0, 0, OPT_SUBKEY_OUT }, - {NULL, 0, 0, 0} - }; - while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { - switch (i) { - case '?': - return false; - break; - case OPT_FIRMWARE_KEY: - firmware_key_file_ = optarg; - break; - case OPT_FIRMWARE_KEY_PUB: - firmware_key_pub_file_ = optarg; - break; - case OPT_KERNEL_KEY: - kernel_key_file_ = optarg; - break; - case OPT_KERNEL_KEY_PUB: - kernel_key_pub_file_ = optarg; - break; - case OPT_SUBKEY_IN: - subkey_in_file_ = optarg; - break; - case OPT_FIRMWARE_SIGN_ALGORITHM: - firmware_sign_algorithm_ = strtol(optarg, &e, 0); - if (!*optarg || (e && *e)) { - cerr << "Invalid argument to --" - << long_options[option_index].name - << ": " << optarg << "\n"; - return false; - } - break; - case OPT_KERNEL_SIGN_ALGORITHM: - kernel_sign_algorithm_ = strtol(optarg, &e, 0); - if (!*optarg || (e && *e)) { - cerr << "Invalid argument to --" - << long_options[option_index].name - << ": " << optarg << "\n"; - return false; - } - break; - case OPT_KERNEL_KEY_VERSION: - kernel_key_version_ = strtol(optarg, &e, 0); - if (!*optarg || (e && *e)) { - cerr << "Invalid argument to --" - << long_options[option_index].name - << ": " << optarg << "\n"; - return false; - } - break; - case OPT_KERNEL_VERSION: - kernel_version_ = strtol(optarg, &e, 0); - if (!*optarg || (e && *e)) { - cerr << "Invalid argument to --" - << long_options[option_index].name - << ": " << optarg << "\n"; - return false; - } - break; - case OPT_IN: - in_file_ = optarg; - break; - case OPT_OUT: - out_file_ = optarg; - break; - case OPT_GENERATE: - is_generate_ = true; - break; - case OPT_VERIFY: - is_verify_ = true; - break; - case OPT_DESCRIBE: - is_describe_ = true; - break; - case OPT_VBLOCK: - is_only_vblock_ = true; - break; - case OPT_BOOTLOADER: - bootloader_file_ = optarg; - break; - case OPT_VMLINUZ: - vmlinuz_file_ = optarg; - break; - case OPT_CONFIG: - config_file_ = optarg; - break; - case OPT_PADDING: - padding_ = strtol(optarg, &e, 0); - if (!*optarg || (e && *e)) { - cerr << "Invalid argument to --" - << long_options[option_index].name - << ": " << optarg << "\n"; - return false; - } - break; - case OPT_SUBKEY_OUT: - is_subkey_out_ = true; - break; - } - } - return CheckOptions(); -} - -void KernelUtility::OutputSignedImage(void) { - if (image_) { - if (!WriteKernelImage(out_file_.c_str(), image_, - is_only_vblock_, - is_subkey_out_)) { - cerr << "Couldn't write verified boot kernel image to file " - << out_file_ <<".\n"; - } - } -} - -void KernelUtility::DescribeSignedImage(void) { - image_ = ReadKernelImage(in_file_.c_str()); - if (!image_) { - cerr << "Couldn't read kernel image or malformed image.\n"; - return; - } - PrintKernelImage(image_); -} - -bool KernelUtility::GenerateSignedImage(void) { - uint64_t kernel_key_pub_len; - - image_ = KernelImageNew(); - Memcpy(image_->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE); - - if (subkey_in_file_.empty()) { - // We must generate the kernel key signature header (subkey header) - // ourselves. - image_->header_version = 1; - image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; - // Copy pre-processed public signing key. - image_->kernel_sign_algorithm = (uint16_t) kernel_sign_algorithm_; - image_->kernel_sign_key = BufferFromFile(kernel_key_pub_file_.c_str(), - &kernel_key_pub_len); - if (!image_->kernel_sign_key) - return false; - image_->kernel_key_version = kernel_key_version_; - - // Update header length. - image_->header_len = GetKernelHeaderLen(image_); - // Calculate header checksum. - CalculateKernelHeaderChecksum(image_, image_->header_checksum); - - // Generate and add the key signatures. - if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) { - cerr << "Couldn't write key signature to verified boot kernel image.\n"; - return false; - } - } else { - // Use existing subkey header. - MemcpyState st; - uint8_t* subkey_header_buf = NULL; - uint64_t subkey_len; - int header_len; - int kernel_key_signature_len; - int kernel_sign_key_len; - uint8_t header_checksum[FIELD_LEN(header_checksum)]; - - subkey_header_buf = BufferFromFile(subkey_in_file_.c_str(), &subkey_len); - if (!subkey_header_buf) { - cerr << "Couldn't read subkey header from file %s\n" - << subkey_in_file_.c_str(); - return false; - } - st.remaining_len = subkey_len; - st.remaining_buf = subkey_header_buf; - st.overrun = 0; - - // TODO(gauravsh): This is basically the same code as the first half of - // of ReadKernelImage(). Refactor to eliminate code duplication. - - StatefulMemcpy(&st, &image_->header_version, FIELD_LEN(header_version)); - StatefulMemcpy(&st, &image_->header_len, FIELD_LEN(header_len)); - StatefulMemcpy(&st, &image_->firmware_sign_algorithm, - FIELD_LEN(firmware_sign_algorithm)); - StatefulMemcpy(&st, &image_->kernel_sign_algorithm, - FIELD_LEN(kernel_sign_algorithm)); - - // Valid Kernel Key signing algorithm. - if (image_->firmware_sign_algorithm >= kNumAlgorithms) { - Free(subkey_header_buf); - return NULL; - } - - // Valid Kernel Signing Algorithm? - if (image_->kernel_sign_algorithm >= kNumAlgorithms) { - Free(subkey_header_buf); - return NULL; - } - - // Compute size of pre-processed RSA public keys and signatures. - kernel_key_signature_len = siglen_map[image_->firmware_sign_algorithm]; - kernel_sign_key_len = RSAProcessedKeySize(image_->kernel_sign_algorithm); - - // Check whether key header length is correct. - header_len = GetKernelHeaderLen(image_); - if (header_len != image_->header_len) { - debug("Header length mismatch. Got: %d, Expected: %d\n", - image_->header_len, header_len); - Free(subkey_header_buf); - return NULL; - } - - // Read pre-processed public half of the kernel signing key. - StatefulMemcpy(&st, &image_->kernel_key_version, - FIELD_LEN(kernel_key_version)); - image_->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len); - StatefulMemcpy(&st, image_->kernel_sign_key, kernel_sign_key_len); - StatefulMemcpy(&st, image_->header_checksum, FIELD_LEN(header_checksum)); - - // Check whether the header checksum matches. - CalculateKernelHeaderChecksum(image_, header_checksum); - if (SafeMemcmp(header_checksum, image_->header_checksum, - FIELD_LEN(header_checksum))) { - debug("Invalid kernel header checksum!\n"); - Free(subkey_header_buf); - return NULL; - } - - // Read key signature. - image_->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len); - StatefulMemcpy(&st, image_->kernel_key_signature, - kernel_key_signature_len); - - Free(subkey_header_buf); - if (st.overrun || st.remaining_len != 0) /* Overrun or underrun. */ - return false; - return true; - } - - // Fill up kernel preamble and kernel data. - image_->kernel_version = kernel_version_; - if (padding_) - image_->padded_header_size = padding_; - image_->kernel_data = GenerateKernelBlob(vmlinuz_file_.c_str(), - config_file_.c_str(), - bootloader_file_.c_str(), - &image_->kernel_len, - &image_->bootloader_offset, - &image_->bootloader_size); - if (!image_->kernel_data) - return false; - - // Generate and add the preamble and data signatures. - if (!AddKernelSignature(image_, kernel_key_file_.c_str())) { - cerr << "Couldn't write firmware signature to verified boot kernel image.\n"; - return false; - } - return true; -} - -bool KernelUtility::VerifySignedImage(void) { - int error; - firmware_key_pub_ = RSAPublicKeyFromFile(firmware_key_pub_file_.c_str()); - image_ = ReadKernelImage(in_file_.c_str()); - - if (!firmware_key_pub_) { - cerr << "Couldn't read pre-processed public root key.\n"; - return false; - } - - if (!image_) { - cerr << "Couldn't read kernel image or malformed image.\n"; - return false; - } - if (!(error = VerifyKernelImage(firmware_key_pub_, image_, 0))) - return true; - cerr << VerifyKernelErrorString(error) << "\n"; - return false; -} - -bool KernelUtility::CheckOptions(void) { - // Ensure that only one of --{describe|generate|verify} is set. - if (!((is_describe_ && !is_generate_ && !is_verify_) || - (!is_describe_ && is_generate_ && !is_verify_) || - (!is_describe_ && !is_generate_ && is_verify_))) { - cerr << "One (and only one) of --describe, --generate or --verify " - << "must be specified.\n"; - return false; - } - // Common required options. - // Required options for --describe. - if (is_describe_) { - if (in_file_.empty()) { - cerr << "No input file specified.\n"; - return false; - } - } - // Required options for --verify. - if (is_verify_) { - if (firmware_key_pub_file_.empty()) { - cerr << "No pre-processed public firmware key file specified.\n"; - return false; - } - if (in_file_.empty()) { - cerr << "No input file specified.\n"; - return false; - } - } - // Required options for --generate. - if (is_generate_) { - if (subkey_in_file_.empty()) { - // Firmware private key (root key), kernel signing public - // key, and signing algorithms are required to generate the key signature - // header. - if (firmware_key_file_.empty()) { - cerr << "No firmware key file specified.\n"; - return false; - } - if (kernel_key_pub_file_.empty()) { - cerr << "No pre-processed public kernel key file specified\n"; - return false; - } - if (kernel_key_version_ <= 0 || kernel_key_version_ > UINT16_MAX) { - cerr << "Invalid or no kernel key version specified.\n"; - return false; - } - if (firmware_sign_algorithm_ < 0 || - firmware_sign_algorithm_ >= kNumAlgorithms) { - cerr << "Invalid or no firmware signing key algorithm specified.\n"; - return false; - } - if (kernel_sign_algorithm_ < 0 || - kernel_sign_algorithm_ >= kNumAlgorithms) { - cerr << "Invalid or no kernel signing key algorithm specified.\n"; - return false; - } - } - if (kernel_key_file_.empty()) { - cerr << "No kernel key file specified.\n"; - return false; - } - if (kernel_version_ <=0 || kernel_version_ > UINT16_MAX) { - cerr << "Invalid or no kernel version specified.\n"; - return false; - } - if (out_file_.empty()) { - cerr <<"No output file specified.\n"; - return false; - } - if (config_file_.empty()) { - cerr << "No config file specified.\n"; - return false; - } - if (bootloader_file_.empty()) { - cerr << "No bootloader file specified.\n"; - return false; - } - if (vmlinuz_file_.empty()) { - cerr << "No vmlinuz file specified.\n"; - return false; - } - // TODO(gauravsh): Enforce only one of --vblock or --subkey_out is specified - } - return true; -} - -} // namespace vboot_reference - -int main(int argc, char* argv[]) { - vboot_reference::KernelUtility ku; - if (!ku.ParseCmdLineOptions(argc, argv)) { - ku.PrintUsage(); - return -1; - } - if (ku.is_describe()) { - ku.DescribeSignedImage(); - } - else if (ku.is_generate()) { - if (!ku.GenerateSignedImage()) - return -1; - ku.OutputSignedImage(); - } - else if (ku.is_verify()) { - cerr << "Verification "; - if (ku.VerifySignedImage()) - cerr << "SUCCESS.\n"; - else - cerr << "FAILURE.\n"; - } - return 0; -} diff --git a/utility/load_kernel_test_old.c b/utility/load_kernel_test_old.c deleted file mode 100644 index 84ba4ca3..00000000 --- a/utility/load_kernel_test_old.c +++ /dev/null @@ -1,147 +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. - */ - -/* Routines for verifying a file's signature. Useful in testing the core - * RSA verification implementation. - */ - -#include <inttypes.h> /* For PRIu64 macro */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -#include "load_kernel_fw.h" -#include "boot_device.h" -#include "host_common.h" -#include "rollback_index.h" -#include "utility.h" - -int LoadKernelOld(LoadKernelParams* params); -/* Attempts to load the kernel from the current device. - * - * Returns LOAD_KERNEL_SUCCESS if successful, error code on failure. */ - -/* ANSI Color coding sequences. */ -#define COL_GREEN "\e[1;32m" -#define COL_RED "\e[0;31m" -#define COL_STOP "\e[m" - - -#define LBA_BYTES 512 -#define KERNEL_BUFFER_SIZE 0x600000 - -/* Global variables for stub functions */ -static LoadKernelParams lkp; -static FILE *image_file = NULL; - - -/* Boot device stub implementations to read from the image file */ -int BootDeviceReadLBA(uint64_t lba_start, uint64_t lba_count, void *buffer) { - printf("Read(%" PRIu64 ", %" PRIu64 ")\n", lba_start, lba_count); - - if (lba_start > lkp.ending_lba || - lba_start + lba_count - 1 > lkp.ending_lba) { - fprintf(stderr, "Read overrun: %" PRIu64 " + %" PRIu64 " > %" PRIu64 "\n", - lba_start, lba_count, lkp.ending_lba); - return 1; - } - - fseek(image_file, lba_start * lkp.bytes_per_lba, SEEK_SET); - if (1 != fread(buffer, lba_count * lkp.bytes_per_lba, 1, image_file)) { - fprintf(stderr, "Read error."); - return 1; - } - return 0; -} - - -int BootDeviceWriteLBA(uint64_t lba_start, uint64_t lba_count, - const void *buffer) { - printf("Write(%" PRIu64 ", %" PRIu64 ")\n", lba_start, lba_count); - - if (lba_start > lkp.ending_lba || - lba_start + lba_count - 1 > lkp.ending_lba) { - fprintf(stderr, "Read overrun: %" PRIu64 " + %" PRIu64 " > %" PRIu64 "\n", - lba_start, lba_count, lkp.ending_lba); - return 1; - } - - /* TODO: enable writes, once we're sure it won't trash our example file */ - return 0; - - fseek(image_file, lba_start * lkp.bytes_per_lba, SEEK_SET); - if (1 != fwrite(buffer, lba_count * lkp.bytes_per_lba, 1, image_file)) { - fprintf(stderr, "Read error."); - return 1; - } - return 0; -} - - -/* Main routine */ -int main(int argc, char* argv[]) { - - const char* image_name; - const char* keyfile_name; - int rv; - - Memset(&lkp, 0, sizeof(LoadKernelParams)); - lkp.bytes_per_lba = LBA_BYTES; - - /* Read command line parameters */ - if (3 > argc) { - fprintf(stderr, "usage: %s <drive_image> <sign_key>\n", argv[0]); - return 1; - } - image_name = argv[1]; - keyfile_name = argv[2]; - - /* Read header signing key blob */ - { - uint64_t key_size; - lkp.header_sign_key_blob = ReadFile(keyfile_name, &key_size); - if (!lkp.header_sign_key_blob) { - fprintf(stderr, "Unable to read key file %s\n", keyfile_name); - return 1; - } - } - - /* Get image size */ - printf("Reading from image: %s\n", image_name); - image_file = fopen(image_name, "rb"); - if (!image_file) { - fprintf(stderr, "Unable to open image file %s\n", image_name); - return 1; - } - fseek(image_file, 0, SEEK_END); - lkp.ending_lba = (ftell(image_file) / LBA_BYTES) - 1; - rewind(image_file); - printf("Ending LBA: %" PRIu64 "\n", lkp.ending_lba); - - /* Allocate a buffer for the kernel */ - lkp.kernel_buffer = Malloc(KERNEL_BUFFER_SIZE); - if(!lkp.kernel_buffer) { - fprintf(stderr, "Unable to allocate kernel buffer.\n"); - return 1; - } - - /* TODO: Option for boot mode */ - lkp.boot_flags = 0; - - /* Call LoadKernel() */ - rv = LoadKernelOld(&lkp); - printf("LoadKernelOld() returned %d\n", rv); - - if (LOAD_KERNEL_SUCCESS == rv) { - printf("Partition number: %" PRIu64 "\n", lkp.partition_number); - printf("Bootloader address: %" PRIu64 "\n", lkp.bootloader_address); - printf("Bootloader size: %" PRIu64 "\n", lkp.bootloader_size); - } - - fclose(image_file); - Free(lkp.kernel_buffer); - return 0; -} diff --git a/utility/sign_image.c b/utility/sign_image.c deleted file mode 100644 index 672e47ff..00000000 --- a/utility/sign_image.c +++ /dev/null @@ -1,115 +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. - * - * Utility for signing boot firmware images. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "file_keys.h" -#include "utility.h" -#include "host_key.h" -#include "host_signature.h" -#include "host_common.h" - -static void usage() -{ - static char* help_mesg = - "Usage: sign_image <fw_version> <fw_key_block> <signing_key> " - "<kernel_public_key> <firmware_file> <output_file>\n"; - printf("%s", help_mesg); -} - -int SignAndWriteImage(uint64_t fw_version, VbKeyBlockHeader* wrapper_kb, - VbPrivateKey* signing_key, - VbPublicKey* nested_pubkey, - uint8_t* image, uint64_t image_size, - FILE* out_file) -{ - VbFirmwarePreambleHeader* fw_preamble = NULL; - int rv = 1; - do { /* to be able to bail out anywhere */ - VbSignature* firmware_sig; - - /* sign the firmware first */ - firmware_sig = CalculateSignature(image, image_size, signing_key); - - /* write the original keyblock */ - if (fwrite(wrapper_kb, wrapper_kb->key_block_size, 1, out_file) != 1) { - debug("failed writing key block\n"); - break; - } - - fw_preamble = CreateFirmwarePreamble(fw_version, nested_pubkey, - firmware_sig, signing_key); - - if (!fw_preamble) { - debug("failed creating preamble\n"); - break; - } - - /* write the preamble */ - if (fwrite(fw_preamble, fw_preamble->preamble_size, 1, out_file) != 1) { - debug("failed writing fw preamble\n"); - break; - } - - /* write the image */ - if (fwrite(image, image_size, 1, out_file) != 1) { - debug("failed writing image\n"); - break; - } - rv = 0; - } while(0); - - if (fw_preamble) { - Free(fw_preamble); - } - - return rv; -} - -int main(int argc, char* argv[]) { - VbKeyBlockHeader* firmware_kb; - VbPublicKey* kernel_pubk; - uint8_t* firmware; - uint64_t fw_size; - uint64_t version; - VbPrivateKey* signing_key = NULL; - FILE* out_file; - int rv; - - if (argc != 7) { - usage(); - exit(1); - } - - version = strtoul(argv[1], 0, 0); - firmware_kb = KeyBlockRead(argv[2]); - kernel_pubk = PublicKeyRead(argv[4]); - firmware = BufferFromFile(argv[5], &fw_size); - if (firmware_kb) { - signing_key = PrivateKeyRead(argv[3], firmware_kb->data_key.algorithm); - } - if (!firmware_kb || !kernel_pubk || !firmware || ! signing_key) { - return 1; - } - - out_file = fopen(argv[6], "wb"); - if (!out_file) { - debug("could not open %s for writing\n"); - return 1; - } - - rv = SignAndWriteImage(version, firmware_kb, signing_key, - kernel_pubk, firmware, fw_size, out_file); - - fclose(out_file); - if (rv) { - unlink(argv[6]); - } - return rv; -} diff --git a/vkernel/Makefile b/vkernel/Makefile deleted file mode 100644 index 5ada47e8..00000000 --- a/vkernel/Makefile +++ /dev/null @@ -1,19 +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. - -INCLUDES += -I./include \ - -I$(FWDIR)/include \ - -I$(FWDIR)/lib/include \ - -I$(FWDIR)/lib/cgptlib/include \ - -I$(FWDIR)/lib/cryptolib/include \ - -I../common/include \ - -I../utility/include \ - -I../misclibs/include - -BUILD_ROOT := ${BUILD}/vkernel - -ALL_SRCS = kernel_image.c kernel_image_fw.c load_kernel_fw.c - -include ../common.mk - diff --git a/vkernel/include/kernel_image.h b/vkernel/include/kernel_image.h deleted file mode 100644 index 5c14e45b..00000000 --- a/vkernel/include/kernel_image.h +++ /dev/null @@ -1,118 +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. - * - * API definitions for a generating and manipulating verified boot kernel images. - * (Userland portion.) - */ - -#ifndef VBOOT_REFERENCE_KERNEL_IMAGE_H_ -#define VBOOT_REFERENCE_KERNEL_IMAGE_H_ - -#include "kernel_image_fw.h" - -/* Allocate and return a new KernelImage structure. */ -KernelImage* KernelImageNew(void); - -/* Deep free the contents of [image]. */ -void KernelImageFree(KernelImage* image); - -/* Read kernel data from file named [input_file]. - * - * Returns a filled up KernelImage on success, NULL on error. - */ -KernelImage* ReadKernelImage(const char* input_file); - -/* Get the length of the header for kernel image [image]. */ -int GetKernelHeaderLen(const KernelImage* image); - -/* Calculate and store the kernel header checksum of [image] - * in [header_checksum]. - * - * [header_checksum] must be a valid pointer to a buffer of - * SHA512_DIGEST_SIZE. - */ -void CalculateKernelHeaderChecksum(const KernelImage* image, - uint8_t* header_checksum); - -/* Get kernel header binary blob from an [image]. - * - * Caller owns the returned pointer and must Free() it. - */ -uint8_t* GetKernelHeaderBlob(const KernelImage* image); - -/* Get kernel config binary blob from an [image]. - * - * Caller owns the returned pointer and must Free() it. - */ -uint8_t* GetKernelConfigBlob(const KernelImage* image); - -/* Get a verified kernel binary blob from an [image] and fill - * its length into blob_len. - * - * Caller owns the returned pointer and must Free() it. - */ -uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len); - - -/* Write kernel data from [image] to a file named [input_file]. - * - * If [is_only_vblock] is non-zero, only the verification block (excluding the - * actual kernel data) is output. - * If [is_subkey_out] is non-zero, only the kernel key verification (subkey) - * header is output. - * - * Return 1 on success, 0 on error. - */ -int WriteKernelImage(const char* input_file, - const KernelImage* image, - int is_only_vblock, - int is_subkey_out); - -/* Create a kernel_data blob from its components and fill - * its length into blob_len, plus some information about the bootloader. - * - * Caller owns the returned pointer and must Free() it. - */ -uint8_t* GenerateKernelBlob(const char* vmlinuz_file, - const char* config_file, - const char* bootloader_file, - uint64_t* blob_len, - uint64_t* bootloader_offset, - uint64_t* bootloader_size); - -/* Pretty print the contents of [image]. Only headers and metadata information - * is printed. - */ -void PrintKernelImage(const KernelImage* image); - -/* Performs a chained verify of the kernel [image]. If [dev_mode] is - * 0 (inactive), then the [firmware_signing_key] is used to verify the signature - * of the signing key, else the check is skipped. - * - * Returns 0 on success, error code on failure. - */ -int VerifyKernelImage(const RSAPublicKey* firmware_signing_key, - const KernelImage* image, - int dev_mode); - - -/* Maps error codes from VerifyKernel*() to error description. */ -const char* VerifyKernelErrorString(int error); - -/* Add a kernel signing key signature to the key header to a kernel image - * [image] using the private key in file [firmware_key_file]. - * - * Return 1 on success, 0 on failure. - */ -int AddKernelKeySignature(KernelImage* image, const char* firmware_key_file); - -/* Add a kernel and kernel config signature to a kernel image [image] - * using the private signing key in file [kernel_sigining_key_file]. - * - * Return 1 on success, 0 on failure. - */ -int AddKernelSignature(KernelImage* image, - const char* kernel_sigining_key_file); - -#endif /* VBOOT_REFERENCE_KERNEL_IMAGE_H_ */ diff --git a/vkernel/include/kernel_image_fw.h b/vkernel/include/kernel_image_fw.h deleted file mode 100644 index 60b9f99d..00000000 --- a/vkernel/include/kernel_image_fw.h +++ /dev/null @@ -1,168 +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. - * - * Data structure and API definitions for a verified boot kernel image. - * (Firmware Portion) - */ - -#ifndef VBOOT_REFERENCE_KERNEL_IMAGE_FW_H_ -#define VBOOT_REFERENCE_KERNEL_IMAGE_FW_H_ - -#include <stdint.h> - -#include "cryptolib.h" - -#define KERNEL_MAGIC "CHROMEOS" -#define KERNEL_MAGIC_SIZE 8 - -#define DEV_MODE_ENABLED 1 -#define DEV_MODE_DISABLED 0 - -typedef struct KernelImage { - uint8_t magic[KERNEL_MAGIC_SIZE]; - /* Key header */ - uint16_t header_version; /* Header version. */ - uint16_t header_len; /* Length of the header. */ - uint16_t firmware_sign_algorithm; /* Signature algorithm used by the firmware - * signing key (used to sign this kernel - * header. */ - uint16_t kernel_sign_algorithm; /* Signature algorithm used by the kernel - * signing key. */ - uint16_t kernel_key_version; /* Key Version# for preventing rollbacks. */ - uint8_t* kernel_sign_key; /* Pre-processed public half of signing key. */ - /* TODO(gauravsh): Do we need a choice of digest algorithms for the header - * checksum? */ - uint8_t header_checksum[SHA512_DIGEST_SIZE]; /* SHA-512 Crytographic hash of - * the concatenation of the - * header fields, i.e. - * [header_len, - * firmware_sign_algorithm, - * sign_algorithm, sign_key, - * key_version] */ - /* End of kernel key header. */ - uint8_t* kernel_key_signature; /* Signature of the header above. */ - - /* Kernel preamble */ - uint16_t kernel_version; /* Kernel Version# for preventing rollbacks. */ - uint64_t kernel_len; /* Length of the actual kernel image. */ - uint64_t bootloader_offset; /* Offset of bootloader in kernel_data. */ - uint64_t bootloader_size; /* Size of bootloader in bytes. */ - uint64_t padded_header_size; /* start of kernel_data in disk partition */ - uint8_t* kernel_signature; /* Signature on [kernel_data] below. - * NOTE: This is only considered valid - * if preamble_signature successfully verifies. */ - /* end of preamble */ - uint8_t* preamble_signature; /* signature on preamble, (includes - [kernel_signature]) */ - uint8_t* kernel_data; /* Actual kernel data. */ - -} KernelImage; - -/* Error Codes for VerifyFirmware. */ -#define VERIFY_KERNEL_SUCCESS 0 -#define VERIFY_KERNEL_INVALID_IMAGE 1 -#define VERIFY_KERNEL_KEY_SIGNATURE_FAILED 2 -#define VERIFY_KERNEL_INVALID_ALGORITHM 3 -#define VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED 4 -#define VERIFY_KERNEL_SIGNATURE_FAILED 5 -#define VERIFY_KERNEL_WRONG_MAGIC 6 -#define VERIFY_KERNEL_MAX 7 /* Generic catch-all. */ - -extern char* kVerifyKernelErrors[VERIFY_KERNEL_MAX]; - -/* Returns the length of the verified boot kernel preamble based on - * kernel signing algorithm [algorithm]. */ -uint64_t GetKernelPreambleLen(int algorithm); - -/* Returns the length of the Kernel Verified Boot header excluding - * [kernel_data]. - * - * This is always non-zero, so a return value of 0 signifies an error. - */ -uint64_t GetVBlockHeaderSize(const uint8_t* vkernel_blob); - -/* Checks for the sanity of the kernel key header at [kernel_header_blob]. - * If [dev_mode] is enabled, also checks the kernel key signature using the - * pre-processed public firmware signing key [firmware_sign_key_blob]. - * - * On success, puts firmware signature algorithm in [firmware_algorithm], - * kernel signature algorithm in [kernel_algorithm], kernel header - * length in [header_len], and return 0. - * Else, return error code on failure. - */ -int VerifyKernelKeyHeader(const uint8_t* firmware_sign_key_blob, - const uint8_t* kernel_header_blob, - const int dev_mode, - int* firmware_algorithm, - int* kernel_algorithm, - int* header_len); - -/* Checks the kernel preamble signature at [kernel_preamble_blob] - * using the signing key [kernel_sign_key]. - * - * On success, put kernel length into [kernel_len], and return 0. - * Else, return error code on failure. - */ -int VerifyKernelPreamble(RSAPublicKey* kernel_sign_key, - const uint8_t* kernel_preamble_blob, - int algorithm, - uint64_t* kernel_len); - -/* Checks [kernel_signature] on the kernel data at location [kernel_data]. The - * signature is assumed to be generated using algorithm [algorithm]. - * The length of the kernel data is [kernel_len]. - * - * Return 0 on success, error code on failure. - */ -int VerifyKernelData(RSAPublicKey* kernel_sign_key, - const uint8_t* kernel_signature, - const uint8_t* kernel_data, - uint64_t kernel_len, - int algorithm); - -/* Verifies the kernel key header and preamble at [kernel_header_blob] - * using the firmware public key [firmware_key_blob]. If [dev_mode] is 1 - * (active), then key header verification is skipped. - * - * On success, fills in the fields of image with the kernel header and - * preamble fields. - * - * Note that pointers in the image point directly into the input - * kernel_header_blob. image->kernel_data is set to NULL, since it's not - * part of the header and preamble data itself. - * - * On success, the signing key to use for kernel data verification is - * returned in [kernel_sign_key], This must be free-d explicitly by - * the caller after use. On failure, the signing key is set to NULL. - * - * Returns 0 on success, error code on failure. - */ -int VerifyKernelHeader(const uint8_t* firmware_key_blob, - const uint8_t* kernel_header_blob, - uint64_t kernel_header_blob_len, - const int dev_mode, - KernelImage* image, - RSAPublicKey** kernel_sign_key); - -/* Performs a chained verify of the kernel blob [kernel_blob]. If - * [dev_mode] is 0 [inactive], then the pre-processed public signing key - * [root_key_blob] is used to verify the signature of the signing key, - * else the check is skipped. - * Returns 0 on success, error code on failure. - * - * NOTE: The length of the kernel blob is derived from reading the fields - * in the first few bytes of the buffer. This might look risky but in firmware - * land, the start address of the kernel_blob will always be fixed depending - * on the memory map on the particular platform. In addition, the signature on - * length itself is checked early in the verification process for extra safety. - */ -int VerifyKernel(const uint8_t* signing_key_blob, - const uint8_t* kernel_blob, - const int dev_mode); - -/* Returns the logical version of a kernel blob which is calculated as - * (kernel_key_version << 16 | kernel_version). */ -uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob); - -#endif /* VBOOT_REFERENCE_KERNEL_IMAGE_FW_H_ */ diff --git a/vkernel/kernel_image.c b/vkernel/kernel_image.c deleted file mode 100644 index 392ee1fc..00000000 --- a/vkernel/kernel_image.c +++ /dev/null @@ -1,754 +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. - * - * Functions for generating and manipulating a verified boot kernel image. - * (Userland portion) - */ -#include "kernel_image.h" - -#include <fcntl.h> -#include <stddef.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "cryptolib.h" -#include "file_keys.h" -#include "kernel_blob.h" -#include "rollback_index.h" -#include "signature_digest.h" -#include "stateful_util.h" -#include "utility.h" - -/* Macro to determine the size of a field structure in the KernelImage - * structure. */ -#define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) - -KernelImage* KernelImageNew(void) { - KernelImage* image = (KernelImage*) Malloc(sizeof(KernelImage)); - if (image) { - image->kernel_sign_key = NULL; - image->kernel_key_signature = NULL; - image->preamble_signature = NULL; - image->kernel_signature = NULL; - image->kernel_data = NULL; - image->padded_header_size = 0x4000; - } - return image; -} - -void KernelImageFree(KernelImage* image) { - if (image) { - Free(image->kernel_sign_key); - Free(image->kernel_key_signature); - Free(image->preamble_signature); - Free(image->kernel_signature); - Free(image->kernel_data); - Free(image); - } -} - -uint64_t GetHeaderSizeOnDisk(const KernelImage* image) { - uint64_t kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; - uint64_t kernel_key_signature_len = - siglen_map[image->firmware_sign_algorithm]; - - return FIELD_LEN(magic) + - GetKernelHeaderLen(image) + - kernel_key_signature_len + - GetKernelPreambleLen(image->kernel_sign_algorithm) + - kernel_signature_len; -} - - -KernelImage* ReadKernelImage(const char* input_file) { - uint64_t file_size; - uint64_t on_disk_header_size; - uint64_t on_disk_padding; - int header_len = 0; - int kernel_key_signature_len; - int kernel_sign_key_len; - int kernel_signature_len; - uint8_t* kernel_buf; - uint8_t header_checksum[FIELD_LEN(header_checksum)]; - MemcpyState st; - KernelImage* image = KernelImageNew(); - - if (!image) - return NULL; - - kernel_buf = BufferFromFile(input_file, &file_size); - - st.remaining_len = file_size; - st.remaining_buf = kernel_buf; - st.overrun = 0; - - /* Read and compare magic bytes. */ - StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); - - if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { - debug("Wrong Kernel Magic.\n"); - Free(kernel_buf); - return NULL; - } - StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); - StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); - StatefulMemcpy(&st, &image->firmware_sign_algorithm, - FIELD_LEN(firmware_sign_algorithm)); - StatefulMemcpy(&st, &image->kernel_sign_algorithm, - FIELD_LEN(kernel_sign_algorithm)); - - /* Valid Kernel Key signing algorithm. */ - if (image->firmware_sign_algorithm >= kNumAlgorithms) { - Free(kernel_buf); - return NULL; - } - - /* Valid Kernel Signing Algorithm? */ - if (image->kernel_sign_algorithm >= kNumAlgorithms) { - Free(kernel_buf); - return NULL; - } - - /* Compute size of pre-processed RSA public keys and signatures. */ - kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; - kernel_sign_key_len = RSAProcessedKeySize(image->kernel_sign_algorithm); - kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; - - /* Check whether key header length is correct. */ - header_len = GetKernelHeaderLen(image); - if (header_len != image->header_len) { - debug("Header length mismatch. Got: %d, Expected: %d\n", - image->header_len, header_len); - Free(kernel_buf); - return NULL; - } - - /* Read pre-processed public half of the kernel signing key. */ - StatefulMemcpy(&st, &image->kernel_key_version, - FIELD_LEN(kernel_key_version)); - image->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len); - StatefulMemcpy(&st, image->kernel_sign_key, kernel_sign_key_len); - StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); - - /* Check whether the header checksum matches. */ - CalculateKernelHeaderChecksum(image, header_checksum); - if (SafeMemcmp(header_checksum, image->header_checksum, - FIELD_LEN(header_checksum))) { - debug("Invalid kernel header checksum!\n"); - Free(kernel_buf); - return NULL; - } - - /* Read key signature. */ - image->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len); - StatefulMemcpy(&st, image->kernel_key_signature, - kernel_key_signature_len); - - /* Read the kernel preamble. */ - StatefulMemcpy(&st, &image->kernel_version, FIELD_LEN(kernel_version)); - StatefulMemcpy(&st, &image->kernel_len, FIELD_LEN(kernel_len)); - StatefulMemcpy(&st, &image->bootloader_offset, FIELD_LEN(bootloader_offset)); - StatefulMemcpy(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); - StatefulMemcpy(&st, &image->padded_header_size, - FIELD_LEN(padded_header_size)); - - /* Read preamble and kernel signatures. */ - image->kernel_signature = (uint8_t*) Malloc(kernel_signature_len); - StatefulMemcpy(&st, image->kernel_signature, kernel_signature_len); - image->preamble_signature = (uint8_t*) Malloc(kernel_signature_len); - StatefulMemcpy(&st, image->preamble_signature, kernel_signature_len); - - /* Skip over the rest of the padded header, unless we're already past it. */ - on_disk_header_size = file_size - st.remaining_len; - if (image->padded_header_size > on_disk_header_size) { - on_disk_padding = image->padded_header_size - on_disk_header_size; - if (st.remaining_len < on_disk_padding) - st.overrun = -1; - st.remaining_buf += on_disk_padding; - st.remaining_len -= on_disk_padding; - } - - /* Read kernel image data. */ - image->kernel_data = (uint8_t*) Malloc(image->kernel_len); - StatefulMemcpy(&st, image->kernel_data, image->kernel_len); - - if(st.overrun) { - Free(kernel_buf); - return NULL; - } - Free(kernel_buf); - return image; -} - -int GetKernelHeaderLen(const KernelImage* image) { - return (FIELD_LEN(header_version) + FIELD_LEN(header_len) + - FIELD_LEN(firmware_sign_algorithm) + - FIELD_LEN(kernel_sign_algorithm) + FIELD_LEN(kernel_key_version) + - RSAProcessedKeySize(image->kernel_sign_algorithm) + - FIELD_LEN(header_checksum)); -} - -void CalculateKernelHeaderChecksum(const KernelImage* image, - uint8_t* header_checksum) { - uint8_t* checksum; - DigestContext ctx; - DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); - DigestUpdate(&ctx, (uint8_t*) &image->header_version, - sizeof(image->header_version)); - DigestUpdate(&ctx, (uint8_t*) &image->header_len, - sizeof(image->header_len)); - DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, - sizeof(image->firmware_sign_algorithm)); - DigestUpdate(&ctx, (uint8_t*) &image->kernel_sign_algorithm, - sizeof(image->kernel_sign_algorithm)); - DigestUpdate(&ctx, (uint8_t*) &image->kernel_key_version, - sizeof(image->kernel_key_version)); - DigestUpdate(&ctx, image->kernel_sign_key, - RSAProcessedKeySize(image->kernel_sign_algorithm)); - checksum = DigestFinal(&ctx); - Memcpy(header_checksum, checksum, FIELD_LEN(header_checksum)); - Free(checksum); - return; -} - -uint8_t* GetKernelHeaderBlob(const KernelImage* image) { - uint8_t* header_blob = NULL; - MemcpyState st; - - header_blob = (uint8_t*) Malloc(GetKernelHeaderLen(image)); - st.remaining_len = GetKernelHeaderLen(image); - st.remaining_buf = header_blob; - st.overrun = 0; - - StatefulMemcpy_r(&st, &image->header_version, FIELD_LEN(header_version)); - StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); - StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, - FIELD_LEN(firmware_sign_algorithm)); - StatefulMemcpy_r(&st, &image->kernel_sign_algorithm, - FIELD_LEN(kernel_sign_algorithm)); - StatefulMemcpy_r(&st, &image->kernel_key_version, - FIELD_LEN(kernel_key_version)); - StatefulMemcpy_r(&st, image->kernel_sign_key, - RSAProcessedKeySize(image->kernel_sign_algorithm)); - StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); - - if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ - Free(header_blob); - return NULL; - } - return header_blob; -} - -uint8_t* GetKernelPreambleBlob(const KernelImage* image) { - uint8_t* preamble_blob = NULL; - MemcpyState st; - - preamble_blob = (uint8_t*) Malloc( - GetKernelPreambleLen(image->kernel_sign_algorithm)); - st.remaining_len = GetKernelPreambleLen(image->kernel_sign_algorithm); - st.remaining_buf = preamble_blob; - st.overrun = 0; - - StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); - StatefulMemcpy_r(&st, &image->kernel_len, FIELD_LEN(kernel_len)); - StatefulMemcpy_r(&st, &image->bootloader_offset, FIELD_LEN(bootloader_offset)); - StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); - StatefulMemcpy_r(&st, &image->padded_header_size, - FIELD_LEN(padded_header_size)); - StatefulMemcpy_r(&st, image->kernel_signature, - siglen_map[image->kernel_sign_algorithm]); - - if (st.overrun || st.remaining_len != 0) { /* Overrun or Underrun. */ - Free(preamble_blob); - return NULL; - } - return preamble_blob; -} - -uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) { - int kernel_key_signature_len; - int kernel_signature_len; - uint8_t* kernel_blob = NULL; - uint8_t* header_blob = NULL; - MemcpyState st; - uint64_t on_disk_header_size; - uint64_t on_disk_padding = 0; - - if (!image) - return NULL; - kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; - kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; - on_disk_header_size = GetHeaderSizeOnDisk(image); - if (image->padded_header_size > on_disk_header_size) - on_disk_padding = image->padded_header_size - on_disk_header_size; - *blob_len = on_disk_header_size + on_disk_padding + image->kernel_len; - kernel_blob = (uint8_t*) Malloc(*blob_len); - st.remaining_len = *blob_len; - st.remaining_buf = kernel_blob; - st.overrun = 0; - header_blob = GetKernelHeaderBlob(image); - - StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic)); - StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image)); - StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len); - /* Copy over kernel preamble blob (including signatures.) */ - StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); - StatefulMemcpy_r(&st, &image->kernel_len, FIELD_LEN(kernel_len)); - StatefulMemcpy_r(&st, &image->bootloader_offset, - FIELD_LEN(bootloader_offset)); - StatefulMemcpy_r(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); - StatefulMemcpy_r(&st, &image->padded_header_size, - FIELD_LEN(padded_header_size)); - StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len); - StatefulMemcpy_r(&st, image->preamble_signature, kernel_signature_len); - /* Copy a bunch of zeros to pad out the header */ - if (on_disk_padding) - StatefulMemset_r(&st, 0, on_disk_padding); - StatefulMemcpy_r(&st, image->kernel_data, image->kernel_len); - - Free(header_blob); - - if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ - debug("GetKernelBlob() failed.\n"); - Free(kernel_blob); - return NULL; - } - return kernel_blob; -} - -int WriteKernelImage(const char* output_file, - const KernelImage* image, - int is_only_vblock, - int is_subkey_out) { - int fd; - int success = 1; - uint8_t* kernel_blob = NULL; - uint8_t* subkey_out_buf = NULL; - uint8_t* subkey_header = NULL; - uint64_t blob_len; - - if (!image) - return 0; - if (-1 == (fd = creat(output_file, 0666))) { - debug("Couldn't open file for writing kernel image: %s\n", - output_file); - return 0; - } - if (is_subkey_out) { - blob_len = GetKernelHeaderLen(image) + - siglen_map[image->firmware_sign_algorithm]; - subkey_out_buf = (uint8_t*) Malloc(blob_len); - subkey_header = GetKernelHeaderBlob(image); - Memcpy(subkey_out_buf, subkey_header, GetKernelHeaderLen(image)); - Memcpy(subkey_out_buf + GetKernelHeaderLen(image), - image->kernel_key_signature, - siglen_map[image->firmware_sign_algorithm]); - if (blob_len != write(fd, subkey_out_buf, blob_len)) { - debug("Couldn't write Kernel Subkey header to file: %s\n", - output_file); - success = 0; - } - Free(subkey_header); - Free(subkey_out_buf); - close(fd); - return success; - } - - kernel_blob = GetKernelBlob(image, &blob_len); - if (!kernel_blob) { - debug("Couldn't create kernel blob from KernelImage.\n"); - return 0; - } - if (!is_only_vblock) { - if (blob_len != write(fd, kernel_blob, blob_len)) { - debug("Couldn't write Kernel Image to file: %s\n", - output_file); - success = 0; - } - } else { - /* Exclude kernel_data. */ - int vblock_len = blob_len - (image->kernel_len); - if (vblock_len != write(fd, kernel_blob, vblock_len)) { - debug("Couldn't write Kernel Image Verification block to file: %s\n", - output_file); - success = 0; - } - } - Free(kernel_blob); - close(fd); - return success; -} - -void PrintKernelImage(const KernelImage* image) { - uint64_t header_size; - - if (!image) - return; - - header_size = GetHeaderSizeOnDisk(image); - if (image->padded_header_size > header_size) - header_size = image->padded_header_size; - - - /* Print header. */ - printf("Header Version = %d\n" - "Header Length = %d\n" - "Kernel Key Signature Algorithm = %s\n" - "Kernel Signature Algorithm = %s\n" - "Kernel Key Version = %d\n\n", - image->header_version, - image->header_len, - algo_strings[image->firmware_sign_algorithm], - algo_strings[image->kernel_sign_algorithm], - image->kernel_key_version); - /* TODO(gauravsh): Output hash and key signature here? */ - /* Print preamble. */ - printf("Kernel Version = %d\n" - "kernel Length = %" PRId64 " (0x%" PRIx64 ")\n" - "Bootloader Offset = %" PRId64 " (0x%" PRIx64 ")\n" - "Bootloader Size = %" PRId64 " (0x%" PRIx64 ")\n" - "Padded Header Size = %" PRId64 " (0x%" PRIx64 ")\n\n" - "Actual Header Size on disk = %" PRIu64 " (0x%" PRIx64 ")\n", - image->kernel_version, - image->kernel_len, image->kernel_len, - image->bootloader_offset, image->bootloader_offset, - image->bootloader_size, image->bootloader_size, - image->padded_header_size, image->padded_header_size, - header_size, header_size); - /* TODO(gauravsh): Output kernel signature here? */ -} - - -int VerifyKernelImage(const RSAPublicKey* firmware_key, - const KernelImage* image, - const int dev_mode) { - RSAPublicKey* kernel_sign_key = NULL; - uint8_t* header_digest = NULL; - uint8_t* preamble_digest = NULL; - uint8_t* kernel_digest = NULL; - int kernel_sign_key_size; - int kernel_signature_size; - int error_code = 0; - DigestContext ctx; - if (!image) - return VERIFY_KERNEL_INVALID_IMAGE; - - /* Verify kernel key signature on the key header if we - * are not in dev mode. - * - * TODO(gauravsh): Add additional sanity checks here for: - * 1) verifying the header length is correct. - * 2) header_checksum is correct. - */ - - if (image->firmware_sign_algorithm >= kNumAlgorithms) - return VERIFY_KERNEL_INVALID_ALGORITHM; - if (image->kernel_sign_algorithm >= kNumAlgorithms) - return VERIFY_KERNEL_INVALID_ALGORITHM; - - if (!dev_mode) { - DigestInit(&ctx, image->firmware_sign_algorithm); - DigestUpdate(&ctx, (uint8_t*) &image->header_version, - FIELD_LEN(header_version)); - DigestUpdate(&ctx, (uint8_t*) &image->header_len, - FIELD_LEN(header_len)); - DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, - FIELD_LEN(firmware_sign_algorithm)); - DigestUpdate(&ctx, (uint8_t*) &image->kernel_sign_algorithm, - FIELD_LEN(kernel_sign_algorithm)); - DigestUpdate(&ctx, (uint8_t*) &image->kernel_key_version, - FIELD_LEN(kernel_key_version)); - DigestUpdate(&ctx, image->kernel_sign_key, - RSAProcessedKeySize(image->kernel_sign_algorithm)); - DigestUpdate(&ctx, image->header_checksum, - FIELD_LEN(header_checksum)); - header_digest = DigestFinal(&ctx); - if (!RSAVerify(firmware_key, image->kernel_key_signature, - siglen_map[image->firmware_sign_algorithm], - image->firmware_sign_algorithm, - header_digest)) { - debug("VerifyKernelImage(): Key signature check failed.\n"); - error_code = VERIFY_KERNEL_KEY_SIGNATURE_FAILED; - goto verify_failure; - } - } - - /* Get kernel signing key to verify the rest of the kernel. */ - kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm); - kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, - kernel_sign_key_size); - kernel_signature_size = siglen_map[image->kernel_sign_algorithm]; - - /* Verify kernel preamble signature. */ - DigestInit(&ctx, image->kernel_sign_algorithm); - DigestUpdate(&ctx, (uint8_t*) &image->kernel_version, - FIELD_LEN(kernel_version)); - DigestUpdate(&ctx, (uint8_t*) &image->kernel_len, - FIELD_LEN(kernel_len)); - DigestUpdate(&ctx, (uint8_t*) &image->bootloader_offset, - FIELD_LEN(bootloader_offset)); - DigestUpdate(&ctx, (uint8_t*) &image->bootloader_size, - FIELD_LEN(bootloader_size)); - DigestUpdate(&ctx, (uint8_t*) &image->padded_header_size, - FIELD_LEN(padded_header_size)); - DigestUpdate(&ctx, (uint8_t*) image->kernel_signature, - kernel_signature_size); - preamble_digest = DigestFinal(&ctx); - if (!RSAVerify(kernel_sign_key, image->preamble_signature, - kernel_signature_size, image->kernel_sign_algorithm, - preamble_digest)) { - error_code = VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED; - goto verify_failure; - } - - /* Verify kernel signature - kernel signature is computed on the contents - * of kernel_data. - * Association between the kernel_data and preamble is maintained by making - * the kernel signature a part of the preamble and verifying it as part - * of preamble signature checking. */ - - kernel_digest = DigestBuf(image->kernel_data, - image->kernel_len, - image->kernel_sign_algorithm); - if (!RSAVerify(kernel_sign_key, image->kernel_signature, - kernel_signature_size, image->kernel_sign_algorithm, - kernel_digest)) { - error_code = VERIFY_KERNEL_SIGNATURE_FAILED; - goto verify_failure; - } - -verify_failure: - RSAPublicKeyFree(kernel_sign_key); - Free(kernel_digest); - Free(preamble_digest); - Free(header_digest); - return error_code; -} - -const char* VerifyKernelErrorString(int error) { - return kVerifyKernelErrors[error]; -} - -int AddKernelKeySignature(KernelImage* image, const char* firmware_key_file) { - uint8_t* header_blob = NULL; - uint8_t* signature = NULL; - int signature_len = siglen_map[image->firmware_sign_algorithm]; - if (!image || !firmware_key_file) - return 0; - header_blob = GetKernelHeaderBlob(image); - if (!header_blob) - return 0; - if (!(signature = SignatureBuf(header_blob, - GetKernelHeaderLen(image), - firmware_key_file, - image->firmware_sign_algorithm))) { - Free(header_blob); - return 0; - } - image->kernel_key_signature = Malloc(signature_len); - Memcpy(image->kernel_key_signature, signature, signature_len); - Free(signature); - Free(header_blob); - return 1; -} - -int AddKernelSignature(KernelImage* image, - const char* kernel_signing_key_file) { - uint8_t* preamble_blob = NULL; - uint8_t* preamble_signature = NULL; - uint8_t* kernel_signature = NULL; - uint8_t* kernel_buf; - int algorithm = image->kernel_sign_algorithm; - int signature_len = siglen_map[algorithm]; - - /* Kernel signature must be calculated first as its used for computing the - * preamble signature. */ - kernel_buf = (uint8_t*) Malloc(image->kernel_len); - Memcpy(kernel_buf, image->kernel_data, image->kernel_len); - if (!(kernel_signature = SignatureBuf(kernel_buf, - image->kernel_len, - kernel_signing_key_file, - algorithm))) { - Free(preamble_blob); - Free(kernel_buf); - debug("Could not compute signature on the kernel.\n"); - return 0; - } - image->kernel_signature = (uint8_t*) Malloc(signature_len); - Memcpy(image->kernel_signature, kernel_signature, signature_len); - - - preamble_blob = GetKernelPreambleBlob(image); - if (!(preamble_signature = SignatureBuf(preamble_blob, - GetKernelPreambleLen(algorithm), - kernel_signing_key_file, - algorithm))) { - debug("Could not compute signature on the kernel preamble.\n"); - Free(preamble_blob); - return 0; - } - image->preamble_signature = (uint8_t*) Malloc(signature_len); - Memcpy(image->preamble_signature, preamble_signature, signature_len); - - Free(preamble_signature); - Free(preamble_blob); - Free(kernel_signature); - Free(kernel_buf); - return 1; -} - -/* Return the smallest integral multiple of [alignment] that is equal to or - * greater than [val]. Used to determine the number of - * pages/sectors/blocks/whatever needed to contain [val] items/bytes/etc. */ -static uint64_t roundup(uint64_t val, uint64_t alignment) { - uint64_t rem = val % alignment; - if ( rem ) - return val + (alignment - rem); - return val; -} - -/* Match regexp /\b--\b/ to delimit the start of the kernel commandline. If we - * don't find one, we'll use the whole thing. */ -static unsigned int find_cmdline_start(char *input, unsigned int max_len) { - int start = 0; - int i; - for(i = 0; i < max_len-1 && input[i]; i++) { - if (input[i] == '-' && input[i+1] == '-') { /* found a "--" */ - if ((i == 0 || input[i-1] == ' ') && /* nothing before it */ - (i+2 >= max_len || input[i+2] == ' ')) { /* nothing after it */ - start = i+2; /* note: hope there's a trailing '\0' */ - break; - } - } - } - while(input[start] == ' ') /* skip leading spaces */ - start++; - - return start; -} - -uint8_t* GenerateKernelBlob(const char* kernel_file, - const char* config_file, - const char* bootloader_file, - uint64_t* ret_blob_len, - uint64_t* ret_bootloader_offset, - uint64_t* ret_bootloader_size) { - uint8_t* kernel_buf; - uint8_t* config_buf; - uint8_t* bootloader_buf; - uint8_t* blob = 0; - uint64_t kernel_size; - uint64_t config_size; - uint64_t bootloader_size; - uint64_t blob_size; - uint64_t kernel32_start = 0; - uint64_t kernel32_size = 0; - uint64_t bootloader_mem_start; - uint64_t bootloader_mem_size; - uint64_t now; - struct linux_kernel_header *lh = 0; - struct linux_kernel_params *params = 0; - uint32_t cmdline_addr; - uint64_t i; - - /* Read the input files. */ - kernel_buf = BufferFromFile(kernel_file, &kernel_size); - if (!kernel_buf) - goto done0; - - config_buf = BufferFromFile(config_file, &config_size); - if (!config_buf) - goto done1; - if (config_size >= CROS_CONFIG_SIZE) { /* need room for trailing '\0' */ - error("config file %s is too large (>= %d bytes)\n", - config_file, CROS_CONFIG_SIZE); - goto done1; - } - - /* Replace any newlines with spaces in the config file. */ - for (i=0; i < config_size; i++) - if (config_buf[i] == '\n') - config_buf[i] = ' '; - - bootloader_buf = BufferFromFile(bootloader_file, &bootloader_size); - if (!bootloader_buf) - goto done2; - - /* The first part of vmlinuz is a header, followed by a real-mode boot stub. - * We only want the 32-bit part. */ - if (kernel_size) { - lh = (struct linux_kernel_header *)kernel_buf; - kernel32_start = (lh->setup_sects+1) << 9; - kernel32_size = kernel_size - kernel32_start; - } - - /* Allocate and zero the blob we need. */ - blob_size = roundup(kernel32_size, CROS_ALIGN) + - CROS_CONFIG_SIZE + - CROS_PARAMS_SIZE + - roundup(bootloader_size, CROS_ALIGN); - blob = (uint8_t *)Malloc(blob_size); - if (!blob) { - error("Couldn't allocate %ld bytes.\n", blob_size); - goto done3; - } - Memset(blob, 0, blob_size); - now = 0; - - /* Copy the 32-bit kernel. */ - if (kernel32_size) - Memcpy(blob + now, kernel_buf + kernel32_start, kernel32_size); - now += roundup(now + kernel32_size, CROS_ALIGN); - - /* Find the load address of the commandline. We'll need it later. */ - cmdline_addr = CROS_32BIT_ENTRY_ADDR + now - + find_cmdline_start((char *)config_buf, config_size); - - /* Copy the config. */ - if (config_size) - Memcpy(blob + now, config_buf, config_size); - now += CROS_CONFIG_SIZE; - - /* The zeropage data is next. Overlay the linux_kernel_header onto it, and - * tweak a few fields. */ - params = (struct linux_kernel_params *)(blob + now); - - if (kernel_size) - Memcpy(&(params->setup_sects), &(lh->setup_sects), - sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects)); - params->boot_flag = 0; - params->ramdisk_image = 0; /* we don't support initrd */ - params->ramdisk_size = 0; - params->type_of_loader = 0xff; - params->cmd_line_ptr = cmdline_addr; - now += CROS_PARAMS_SIZE; - - /* Finally, append the bootloader. Remember where it will load in memory, too. - */ - bootloader_mem_start = CROS_32BIT_ENTRY_ADDR + now; - bootloader_mem_size = roundup(bootloader_size, CROS_ALIGN); - if (bootloader_size) - Memcpy(blob + now, bootloader_buf, bootloader_size); - now += bootloader_mem_size; - - /* Pass back some info. */ - if (ret_blob_len) - *ret_blob_len = blob_size; - if (ret_bootloader_offset) - *ret_bootloader_offset = bootloader_mem_start; - if (ret_bootloader_size) - *ret_bootloader_size = bootloader_mem_size; - - /* Clean up and return the blob. */ -done3: - Free(bootloader_buf); -done2: - Free(config_buf); -done1: - Free(kernel_buf); -done0: - return blob; -} diff --git a/vkernel/kernel_image_fw.c b/vkernel/kernel_image_fw.c deleted file mode 100644 index afa01dd5..00000000 --- a/vkernel/kernel_image_fw.c +++ /dev/null @@ -1,384 +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. - * - * Functions for verifying a verified boot kernel image. - * (Firmware portion) - */ - -#include "kernel_image_fw.h" - -#include "cryptolib.h" -#include "rollback_index.h" -#include "stateful_util.h" -#include "utility.h" - -/* Macro to determine the size of a field structure in the KernelImage - * structure. */ -#define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) - -char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { - "Success.", - "Invalid Image.", - "Kernel Key Signature Failed.", - "Invalid Kernel Verification Algorithm.", - "Preamble Signature Failed.", - "Kernel Signature Failed.", - "Wrong Kernel Magic.", -}; - -inline uint64_t GetKernelPreambleLen(int algorithm) { - return (FIELD_LEN(kernel_version) + - FIELD_LEN(kernel_len) + - FIELD_LEN(bootloader_offset) + - FIELD_LEN(bootloader_size) + - FIELD_LEN(padded_header_size) + - siglen_map[algorithm]); -} - -uint64_t GetVblockHeaderSize(const uint8_t* vkernel_blob) { - uint64_t len = 0; - uint16_t firmware_sign_algorithm; - uint16_t kernel_sign_algorithm; - int algorithms_offset = (FIELD_LEN(magic) + - FIELD_LEN(header_version) + - FIELD_LEN(header_len)); - if (SafeMemcmp(vkernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { - debug("Not a valid verified boot kernel blob.\n"); - return 0; - } - Memcpy(&firmware_sign_algorithm, - vkernel_blob + algorithms_offset, - sizeof(firmware_sign_algorithm)); - Memcpy(&kernel_sign_algorithm, - vkernel_blob + algorithms_offset + FIELD_LEN(kernel_sign_algorithm), - sizeof(kernel_sign_algorithm)); - if (firmware_sign_algorithm >= kNumAlgorithms) { - debug("Invalid firmware signing algorithm.\n"); - return 0; - } - if (kernel_sign_algorithm >= kNumAlgorithms) { - debug("Invalid kernel signing algorithm.\n"); - return 0; - } - len = algorithms_offset; /* magic, header length and version. */ - len += (FIELD_LEN(firmware_sign_algorithm) + - FIELD_LEN(kernel_sign_algorithm) + - FIELD_LEN(kernel_key_version) + - RSAProcessedKeySize(kernel_sign_algorithm) + /* kernel_sign_key */ - FIELD_LEN(header_checksum) + - siglen_map[firmware_sign_algorithm] + /* kernel_key_signature */ - GetKernelPreambleLen(kernel_sign_algorithm) + - siglen_map[kernel_sign_algorithm]); /* preamble_signature */ - return len; -} - -int VerifyKernelKeyHeader(const uint8_t* firmware_key_blob, - const uint8_t* header_blob, - const int dev_mode, - int* firmware_algorithm, - int* kernel_algorithm, - int* kernel_header_len) { - int kernel_sign_key_len; - int firmware_sign_key_len; - uint16_t header_version, header_len; - uint16_t firmware_sign_algorithm, kernel_sign_algorithm; - uint8_t* header_checksum = NULL; - - /* Base Offset for the header_checksum field. Actual offset is - * this + kernel_sign_key_len. */ - int base_header_checksum_offset = (FIELD_LEN(header_version) + - FIELD_LEN(header_len) + - FIELD_LEN(firmware_sign_algorithm) + - FIELD_LEN(kernel_sign_algorithm) + - FIELD_LEN(kernel_key_version)); - - Memcpy(&header_version, header_blob, sizeof(header_version)); - Memcpy(&header_len, header_blob + FIELD_LEN(header_version), - sizeof(header_len)); - Memcpy(&firmware_sign_algorithm, - header_blob + (FIELD_LEN(header_version) + - FIELD_LEN(header_len)), - sizeof(firmware_sign_algorithm)); - Memcpy(&kernel_sign_algorithm, - header_blob + (FIELD_LEN(header_version) + - FIELD_LEN(header_len) + - FIELD_LEN(firmware_sign_algorithm)), - sizeof(kernel_sign_algorithm)); - - /* TODO(gauravsh): Make this return two different error types depending - * on whether the firmware or kernel signing algorithm is invalid. */ - if (firmware_sign_algorithm >= kNumAlgorithms) - return VERIFY_KERNEL_INVALID_ALGORITHM; - if (kernel_sign_algorithm >= kNumAlgorithms) - return VERIFY_KERNEL_INVALID_ALGORITHM; - - *firmware_algorithm = (int) firmware_sign_algorithm; - *kernel_algorithm = (int) kernel_sign_algorithm; - kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); - firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); - - - /* Verify if header len is correct? */ - if (header_len != (base_header_checksum_offset + - kernel_sign_key_len + - FIELD_LEN(header_checksum))) { - debug("VerifyKernelKeyHeader: Header length mismatch\n"); - return VERIFY_KERNEL_INVALID_IMAGE; - } - *kernel_header_len = (int) header_len; - - /* Verify if the hash of the header is correct. */ - header_checksum = DigestBuf(header_blob, - header_len - FIELD_LEN(header_checksum), - SHA512_DIGEST_ALGORITHM); - if (SafeMemcmp(header_checksum, - header_blob + (base_header_checksum_offset + - kernel_sign_key_len), - FIELD_LEN(header_checksum))) { - Free(header_checksum); - debug("VerifyKernelKeyHeader: Invalid header hash\n"); - return VERIFY_KERNEL_INVALID_IMAGE; - } - Free(header_checksum); - - /* Verify kernel key signature unless we are in dev mode. */ - if (!dev_mode) { - if (!RSAVerifyBinary_f(firmware_key_blob, NULL, /* Key to use */ - header_blob, /* Data to verify */ - header_len, /* Length of data */ - header_blob + header_len, /* Expected Signature */ - firmware_sign_algorithm)) - return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; - } - return 0; -} - -int VerifyKernelPreamble(RSAPublicKey* kernel_sign_key, - const uint8_t* preamble_blob, - int algorithm, - uint64_t* kernel_len) { - int preamble_len = GetKernelPreambleLen(algorithm); - if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ - preamble_blob, /* Data to verify */ - preamble_len, /* Length of data */ - preamble_blob + preamble_len, /* Expected Signature */ - algorithm)) - return VERIFY_KERNEL_PREAMBLE_SIGNATURE_FAILED; - Memcpy(kernel_len, - preamble_blob + FIELD_LEN(kernel_version), - FIELD_LEN(kernel_len)); - return 0; -} - -int VerifyKernelData(RSAPublicKey* kernel_sign_key, - const uint8_t* kernel_signature, - const uint8_t* kernel_data, - uint64_t kernel_len, - int algorithm) { - - if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ - kernel_data, /* Data to verify */ - kernel_len, /* Length of data */ - kernel_signature, /* Expected Signature */ - algorithm)) - return VERIFY_KERNEL_SIGNATURE_FAILED; - return 0; -} - -int VerifyKernelHeader(const uint8_t* firmware_key_blob, - const uint8_t* kernel_header_blob, - uint64_t kernel_header_blob_len, - const int dev_mode, - KernelImage* image, - RSAPublicKey** kernel_sign_key) { - int error_code; - int firmware_sign_algorithm; /* Firmware signing key algorithm. */ - int kernel_sign_algorithm; /* Kernel signing key algorithm. */ - int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, - header_len; - uint64_t kernel_len; - const uint8_t* header_ptr = NULL; /* Pointer to key header. */ - const uint8_t* preamble_ptr = NULL; /* Pointer to start of preamble. */ - MemcpyState st; - - /* Note: All the offset calculations are based on struct KernelImage which - * is defined in include/kernel_image_fw.h. */ - st.remaining_buf = (void *)kernel_header_blob; - st.remaining_len = kernel_header_blob_len; - st.overrun = 0; - - /* Clear destination image struct */ - Memset(image, 0, sizeof(KernelImage)); - - /* Read and compare magic bytes. */ - StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); - if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { - return VERIFY_KERNEL_WRONG_MAGIC; - } - StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); - StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); - StatefulMemcpy(&st, &image->firmware_sign_algorithm, - FIELD_LEN(firmware_sign_algorithm)); - StatefulMemcpy(&st, &image->kernel_sign_algorithm, - FIELD_LEN(kernel_sign_algorithm)); - - header_ptr = kernel_header_blob + KERNEL_MAGIC_SIZE; - - /* Only continue if header verification succeeds. */ - if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, - dev_mode, - &firmware_sign_algorithm, - &kernel_sign_algorithm, - &header_len))) { - debug("VerifyKernelHeader: Kernel Key Header verification failed.\n"); - return error_code; /* AKA jump to recovery. */ - } - - /* Read pre-processed public half of the kernel signing key. */ - kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); - StatefulMemcpy(&st, &image->kernel_key_version, - FIELD_LEN(kernel_key_version)); - image->kernel_sign_key = (uint8_t*)st.remaining_buf; - StatefulSkip(&st, kernel_sign_key_len); - StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); - - /* Parse signing key into RSAPublicKey structure since it is - * required multiple times. */ - *kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, - kernel_sign_key_len); - kernel_signature_len = siglen_map[kernel_sign_algorithm]; - kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; - image->kernel_key_signature = (uint8_t*)st.remaining_buf; - StatefulSkip(&st, kernel_key_signature_len); - - /* Only continue if preamble verification succeeds. */ - /* TODO: should pass the remaining len into VerifyKernelPreamble() */ - preamble_ptr = (const uint8_t*)st.remaining_buf; - if ((error_code = VerifyKernelPreamble(*kernel_sign_key, preamble_ptr, - kernel_sign_algorithm, - &kernel_len))) { - RSAPublicKeyFree(*kernel_sign_key); - *kernel_sign_key = NULL; - return error_code; /* AKA jump to recovery. */ - } - - /* Copy preamble fields */ - StatefulMemcpy(&st, &image->kernel_version, FIELD_LEN(kernel_version)); - StatefulMemcpy(&st, &image->kernel_len, FIELD_LEN(kernel_len)); - StatefulMemcpy(&st, &image->bootloader_offset, FIELD_LEN(bootloader_offset)); - StatefulMemcpy(&st, &image->bootloader_size, FIELD_LEN(bootloader_size)); - StatefulMemcpy(&st, &image->padded_header_size, - FIELD_LEN(padded_header_size)); - image->kernel_signature = (uint8_t*)st.remaining_buf; - StatefulSkip(&st, kernel_signature_len); - image->preamble_signature = (uint8_t*)st.remaining_buf; - - return 0; -} - -int VerifyKernel(const uint8_t* firmware_key_blob, - const uint8_t* kernel_blob, - const int dev_mode) { - int error_code; - int firmware_sign_algorithm; /* Firmware signing key algorithm. */ - int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ - RSAPublicKey* kernel_sign_key; - int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len, - header_len; - uint64_t kernel_len; - const uint8_t* header_ptr; /* Pointer to header. */ - const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */ - const uint8_t* preamble_ptr; /* Pointer to kernel preamble block. */ - const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */ - const uint8_t* kernel_signature; - - /* Note: All the offset calculations are based on struct FirmwareImage which - * is defined in include/firmware_image.h. */ - - /* Compare magic bytes. */ - if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { - debug("VerifyKernel: Kernel magic bytes not found.\n"); - return VERIFY_KERNEL_WRONG_MAGIC; - } - header_ptr = kernel_blob + KERNEL_MAGIC_SIZE; - - /* Only continue if header verification succeeds. */ - if ((error_code = VerifyKernelKeyHeader(firmware_key_blob, header_ptr, dev_mode, - &firmware_sign_algorithm, - &kernel_sign_algorithm, &header_len))) { - debug("VerifyKernel: Kernel header verification failed.\n"); - return error_code; /* AKA jump to recovery. */ - } - /* Parse signing key into RSAPublicKey structure since it is required multiple - * times. */ - kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); - kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) + - FIELD_LEN(header_len) + - FIELD_LEN(firmware_sign_algorithm) + - FIELD_LEN(kernel_sign_algorithm) + - FIELD_LEN(kernel_key_version)); - kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr, - kernel_sign_key_len); - kernel_signature_len = siglen_map[kernel_sign_algorithm]; - kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; - - /* Only continue if preamble verification succeeds. */ - preamble_ptr = (header_ptr + header_len + kernel_key_signature_len); - if ((error_code = VerifyKernelPreamble(kernel_sign_key, preamble_ptr, - kernel_sign_algorithm, - &kernel_len))) { - debug("VerifyKernel: Kernel preamble verification failed.\n"); - RSAPublicKeyFree(kernel_sign_key); - return error_code; /* AKA jump to recovery. */ - } - /* Only continue if kernel data verification succeeds. */ - kernel_ptr = (preamble_ptr + - GetKernelPreambleLen(kernel_sign_algorithm) + - kernel_signature_len); /* preamble signature. */ - kernel_signature = kernel_ptr - 2 * kernel_signature_len; /* end of kernel - * preamble. */ - - if ((error_code = VerifyKernelData(kernel_sign_key, /* Verification key */ - kernel_signature, /* kernel signature */ - kernel_ptr, /* Start of kernel data */ - kernel_len, /* Length of kernel data. */ - kernel_sign_algorithm))) { - RSAPublicKeyFree(kernel_sign_key); - return error_code; /* AKA jump to recovery. */ - } - RSAPublicKeyFree(kernel_sign_key); - return 0; /* Success! */ -} - -uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) { - uint8_t* kernel_ptr; - uint16_t kernel_key_version; - uint16_t kernel_version; - uint16_t firmware_sign_algorithm; - uint16_t kernel_sign_algorithm; - int kernel_key_signature_len; - int kernel_sign_key_len; - kernel_ptr = kernel_blob + (FIELD_LEN(magic) + - FIELD_LEN(header_version) + - FIELD_LEN(header_len)); - Memcpy(&firmware_sign_algorithm, kernel_ptr, sizeof(firmware_sign_algorithm)); - kernel_ptr += FIELD_LEN(firmware_sign_algorithm); - Memcpy(&kernel_sign_algorithm, kernel_ptr, sizeof(kernel_sign_algorithm)); - kernel_ptr += FIELD_LEN(kernel_sign_algorithm); - Memcpy(&kernel_key_version, kernel_ptr, sizeof(kernel_key_version)); - - if (firmware_sign_algorithm >= kNumAlgorithms) - return 0; - if (kernel_sign_algorithm >= kNumAlgorithms) - return 0; - - kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; - kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); - kernel_ptr += (FIELD_LEN(kernel_key_version) + - kernel_sign_key_len + - FIELD_LEN(header_checksum) + - kernel_key_signature_len); - Memcpy(&kernel_version, kernel_ptr, sizeof(kernel_version)); - return CombineUint16Pair(kernel_key_version, kernel_version); -} diff --git a/vkernel/load_kernel_fw.c b/vkernel/load_kernel_fw.c deleted file mode 100644 index a135628e..00000000 --- a/vkernel/load_kernel_fw.c +++ /dev/null @@ -1,251 +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. - * - * Functions for loading a kernel from disk. - * (Firmware portion) - */ - -#include "load_kernel_fw.h" - -#include "boot_device.h" -#include "cgptlib.h" -#include "kernel_image_fw.h" -#include "rollback_index.h" -#include "utility.h" -#include "vboot_kernel.h" - -#define GPT_ENTRIES_SIZE 16384 /* Bytes to read for GPT entries */ - -#ifdef PRINT_DEBUG_INFO -// TODO: for testing -#include <stdio.h> -#include <inttypes.h> /* For PRIu64 macro */ -#include "cgptlib_internal.h" -#endif - - -#define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */ - -int LoadKernelOld(LoadKernelParams* params) { - - GptData gpt; - uint64_t part_start, part_size; - uint64_t blba = params->bytes_per_lba; - uint8_t* kbuf = NULL; - uint64_t kbuf_sectors; - int found_partition = 0; - int good_partition = -1; - uint16_t tpm_kernel_key_version, tpm_kernel_version; - uint16_t lowest_kernel_key_version = 0xFFFF; - uint16_t lowest_kernel_version = 0xFFFF; - KernelImage *kim = NULL; - int is_dev = ((BOOT_FLAG_DEVELOPER & params->boot_flags) && - !(BOOT_FLAG_RECOVERY & params->boot_flags)); - int is_normal = (!(BOOT_FLAG_DEVELOPER & params->boot_flags) && - !(BOOT_FLAG_RECOVERY & params->boot_flags)); - - /* Clear output params in case we fail */ - params->partition_number = 0; - params->bootloader_address = 0; - params->bootloader_size = 0; - - if (is_normal) { - /* Read current kernel key index from TPM. Assumes TPM is already - * initialized. */ - if (0 != GetStoredVersions(KERNEL_VERSIONS, - &tpm_kernel_key_version, - &tpm_kernel_version)) - return LOAD_KERNEL_RECOVERY; - } - - do { - /* Read GPT data */ - gpt.sector_bytes = blba; - gpt.drive_sectors = params->ending_lba + 1; - if (0 != AllocAndReadGptData(&gpt)) - break; - - /* Initialize GPT library */ - if (GPT_SUCCESS != GptInit(&gpt)) - break; - - /* Allocate kernel header and image work buffers */ - kbuf = (uint8_t*)Malloc(KBUF_SIZE); - if (!kbuf) - break; - - kbuf_sectors = KBUF_SIZE / blba; - kim = (KernelImage*)Malloc(sizeof(KernelImage)); - if (!kim) - break; - - /* Loop over candidate kernel partitions */ - while (GPT_SUCCESS == GptNextKernelEntry(&gpt, &part_start, &part_size)) { - RSAPublicKey *kernel_sign_key = NULL; - int kernel_start, kernel_sectors; - - /* Found at least one kernel partition. */ - found_partition = 1; - - /* Read the first part of the kernel partition */ - if (part_size < kbuf_sectors) - continue; - if (0 != BootDeviceReadLBA(part_start, kbuf_sectors, kbuf)) - continue; - - /* Verify the kernel header and preamble */ - if (VERIFY_KERNEL_SUCCESS != VerifyKernelHeader( - params->header_sign_key_blob, - kbuf, - KBUF_SIZE, - (is_dev ? 1 : 0), - kim, - &kernel_sign_key)) { - continue; - } - -#ifdef PRINT_DEBUG_INFO - printf("Kernel header:\n"); - printf("header version: %d\n", kim->header_version); - printf("header len: %d\n", kim->header_len); - printf("firmware sign alg: %d\n", kim->firmware_sign_algorithm); - printf("kernel sign alg: %d\n", kim->kernel_sign_algorithm); - printf("kernel key version: %d\n", kim->kernel_key_version); - printf("kernel version: %d\n", kim->kernel_version); - printf("kernel len: %" PRIu64 "\n", kim->kernel_len); - printf("bootloader addr: %" PRIu64 "\n", kim->bootloader_offset); - printf("bootloader size: %" PRIu64 "\n", kim->bootloader_size); - printf("padded header size: %" PRIu64 "\n", kim->padded_header_size); -#endif - - /* Check for rollback of key version */ - if (kim->kernel_key_version < tpm_kernel_key_version) { - RSAPublicKeyFree(kernel_sign_key); - continue; - } - - /* Check for rollback of kernel version */ - if (kim->kernel_key_version == tpm_kernel_key_version && - kim->kernel_version < tpm_kernel_version) { - RSAPublicKeyFree(kernel_sign_key); - continue; - } - - /* Check for lowest key version from a valid header. */ - if (lowest_kernel_key_version > kim->kernel_key_version) { - lowest_kernel_key_version = kim->kernel_key_version; - lowest_kernel_version = kim->kernel_version; - } - else if (lowest_kernel_key_version == kim->kernel_key_version && - lowest_kernel_version > kim->kernel_version) { - lowest_kernel_version = kim->kernel_version; - } - - /* If we already have a good kernel, no need to read another - * one; we only needed to look at the versions to check for - * rollback. */ - if (-1 != good_partition) - continue; - - /* Verify kernel padding is a multiple of sector size. */ - if (0 != kim->padded_header_size % blba) { - RSAPublicKeyFree(kernel_sign_key); - continue; - } - - kernel_start = part_start + (kim->padded_header_size / blba); - kernel_sectors = (kim->kernel_len + blba - 1) / blba; - - /* Read the kernel data */ - if (0 != BootDeviceReadLBA(kernel_start, kernel_sectors, - params->kernel_buffer)) { - RSAPublicKeyFree(kernel_sign_key); - continue; - } - - /* Verify kernel data */ - if (0 != VerifyKernelData(kernel_sign_key, - kim->kernel_signature, - params->kernel_buffer, - kim->kernel_len, - kim->kernel_sign_algorithm)) { - RSAPublicKeyFree(kernel_sign_key); - continue; - } - - /* Done with the kernel signing key, so can free it now */ - RSAPublicKeyFree(kernel_sign_key); - - /* If we're still here, the kernel is valid. */ - /* Save the first good partition we find; that's the one we'll boot */ - if (-1 == good_partition) { - good_partition = gpt.current_kernel; - params->partition_number = gpt.current_kernel; - params->bootloader_address = kim->bootloader_offset; - params->bootloader_size = kim->bootloader_size; - - /* If we're in developer or recovery mode, there's no rollback - * protection, so we can stop at the first valid kernel. */ - if (!is_normal) - break; - - /* Otherwise, we're in normal boot mode, so we do care about - * the key index in the TPM. If the good partition's key - * version is the same as the tpm, then the TPM doesn't need - * updating; we can stop now. Otherwise, we'll check all the - * other headers to see if they contain a newer key. */ - if (kim->kernel_key_version == tpm_kernel_key_version && - kim->kernel_version == tpm_kernel_version) - break; - } - } /* while(GptNextKernelEntry) */ - } while(0); - - /* Free kernel work and image buffers */ - if (kbuf) - Free(kbuf); - if (kim) - Free(kim); - - /* Write and free GPT data */ - WriteAndFreeGptData(&gpt); - - /* Handle finding a good partition */ - if (good_partition >= 0) { - - if (is_normal) { - /* See if we need to update the TPM, for normal boot mode only. */ - if ((lowest_kernel_key_version > tpm_kernel_key_version) || - (lowest_kernel_key_version == tpm_kernel_key_version && - lowest_kernel_version > tpm_kernel_version)) { - if (0 != WriteStoredVersions(KERNEL_VERSIONS, - lowest_kernel_key_version, - lowest_kernel_version)) - return LOAD_KERNEL_RECOVERY; - } - } - - if (!(BOOT_FLAG_RECOVERY & params->boot_flags)) { - /* We can lock the TPM now, since we've decided which kernel we - * like. If we don't find a good kernel, we leave the TPM - * unlocked so we can try again on the next boot device. If no - * kernels are good, we'll reboot to recovery mode, so it's ok to - * leave the TPM unlocked in that case too. - * - * If we're already in recovery mode, we need to leave PP unlocked, - * so don't lock the kernel versions. */ - if (0 != LockKernelVersionsByLockingPP()) - return LOAD_KERNEL_RECOVERY; - } - - /* Success! */ - return LOAD_KERNEL_SUCCESS; - } - - /* Handle error cases */ - if (found_partition) - return LOAD_KERNEL_INVALID; - else - return LOAD_KERNEL_NOT_FOUND; -} |