diff --git a/common/utility_stub.c b/common/utility_stub.c index 8d21897747..2d01226fb2 100644 --- a/common/utility_stub.c +++ b/common/utility_stub.c @@ -47,9 +47,12 @@ int SafeMemcmp(const void* s1, const void* s2, size_t n) { return match; } -void* StatefulMemcpy(MemcpyState* state, void* dst, int len) { +void* StatefulMemcpy(MemcpyState* state, void* dst, + uint64_t len) { + if (state->overrun) + return NULL; if (len > state->remaining_len) { - state->remaining_len = -1; + state->overrun = 1; return NULL; } Memcpy(dst, state->remaining_buf, len); @@ -58,9 +61,12 @@ void* StatefulMemcpy(MemcpyState* state, void* dst, int len) { return dst; } -const void* StatefulMemcpy_r(MemcpyState* state, const void* src, int len) { +const void* StatefulMemcpy_r(MemcpyState* state, const void* src, + uint64_t len) { + if (state->overrun) + return NULL; if (len > state->remaining_len) { - state->remaining_len = -1; + state->overrun = 1; return NULL; } Memcpy(state->remaining_buf, src, len); diff --git a/crypto/rsa_utility.c b/crypto/rsa_utility.c index 3559dfde30..5ac2db4b62 100644 --- a/crypto/rsa_utility.c +++ b/crypto/rsa_utility.c @@ -42,6 +42,8 @@ RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, int len) { st.remaining_buf = (uint8_t*) buf; st.remaining_len = len; + st.overrun = 0; + StatefulMemcpy(&st, &key->len, sizeof(key->len)); key_len = key->len * sizeof(uint32_t); /* key length in bytes. */ @@ -60,7 +62,7 @@ RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, int len) { StatefulMemcpy(&st, &key->n0inv, sizeof(key->n0inv)); StatefulMemcpy(&st, key->n, key_len); StatefulMemcpy(&st, key->rr, key_len); - if (st.remaining_len != 0) { /* Underrun or overrun. */ + if (st.overrun || st.remaining_len != 0) { /* Underrun or overrun. */ RSAPublicKeyFree(key); return NULL; } @@ -71,7 +73,7 @@ RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, int len) { int RSAVerifyBinary_f(const uint8_t* key_blob, const RSAPublicKey* key, const uint8_t* buf, - int len, + uint64_t len, const uint8_t* sig, int algorithm) { RSAPublicKey* verification_key = NULL; diff --git a/include/firmware_image.h b/include/firmware_image.h index 778669bc11..810e3a0456 100644 --- a/include/firmware_image.h +++ b/include/firmware_image.h @@ -141,7 +141,7 @@ int VerifyFirmwareHeader(const uint8_t* root_key_blob, int VerifyFirmwarePreamble(RSAPublicKey* sign_key, const uint8_t* preamble_blob, int algorithm, - int* firmware_len); + uint64_t* firmware_len); /* Checks the signature on the preamble + firmware data at * [preamble_start] and [firmware_data_start]. @@ -155,7 +155,7 @@ int VerifyFirmwarePreamble(RSAPublicKey* sign_key, int VerifyFirmwareData(RSAPublicKey* sign_key, const uint8_t* preamble_start, const uint8_t* firmware_data_start, - int firmware_len, + uint64_t firmware_len, int algorithm); /* Performs a chained verify of the firmware blob [firmware_blob]. diff --git a/include/kernel_image.h b/include/kernel_image.h index f8bddff4a1..3718624361 100644 --- a/include/kernel_image.h +++ b/include/kernel_image.h @@ -163,7 +163,7 @@ int VerifyKernelHeader(const uint8_t* firmware_sign_key_blob, int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, const uint8_t* kernel_config_blob, int algorithm, - int* kernel_len); + uint64_t* kernel_len); /* Checks the signature on the kernel data at location [kernel_data_start]. * The length of the actual kernel data is kernel _len and it is assumed to @@ -175,7 +175,7 @@ int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, int VerifyKernelData(RSAPublicKey* kernel_sign_key, const uint8_t* kernel_config_start, const uint8_t* kernel_data_start, - int kernel_len, + uint64_t kernel_len, int algorithm); /* Performs a chained verify of the kernel blob [kernel_blob]. If diff --git a/include/rsa_utility.h b/include/rsa_utility.h index d3c3e5c79a..652227c34c 100644 --- a/include/rsa_utility.h +++ b/include/rsa_utility.h @@ -44,7 +44,7 @@ RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, int len); int RSAVerifyBinary_f(const uint8_t* key_blob, const RSAPublicKey* key, const uint8_t* buf, - int len, + uint64_t len, const uint8_t* sig, int algorithm); diff --git a/include/utility.h b/include/utility.h index 79713477c8..429223cdf1 100644 --- a/include/utility.h +++ b/include/utility.h @@ -44,7 +44,8 @@ int SafeMemcmp(const void* s1, const void* s2, size_t n); /* Track remaining data to be read in a buffer. */ typedef struct MemcpyState { void* remaining_buf; - uint64_t remaining_len; + uint64_t remaining_len; /* Remaining length of the buffer. */ + uint8_t overrun; /* Flag set to 1 when an overrun occurs. */ } MemcpyState; /* Copy [len] bytes into [dst] only if there's enough data to read according @@ -55,7 +56,7 @@ typedef struct MemcpyState { * Useful for iterating through a binary blob to populate a struct. After the * first failure (buffer overrun), successive calls will always fail. */ -void* StatefulMemcpy(MemcpyState* state, void* dst, int len); +void* StatefulMemcpy(MemcpyState* state, void* dst, uint64_t len); /* Like StatefulMemcpy() but copies in the opposite direction, populating * data from [src] into the buffer encapsulated in state [state]. @@ -65,6 +66,6 @@ void* StatefulMemcpy(MemcpyState* state, void* dst, int len); * Useful for iterating through a structure to populate a binary blob. After the * first failure (buffer overrun), successive calls will always fail. */ -const void* StatefulMemcpy_r(MemcpyState* state, const void* src, int len); +const void* StatefulMemcpy_r(MemcpyState* state, const void* src, uint64_t len); #endif /* VBOOT_REFERENCE_UTILITY_H_ */ diff --git a/tests/Makefile b/tests/Makefile index 585327a326..3645e7dbce 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -12,7 +12,9 @@ IMAGE_LIBS = $(TOP)/utils/firmware_image.o $(TOP)/utils/kernel_image.o UTIL_LIBS = $(TOP)/utils/file_keys.o $(TOP)/utils/signature_digest.o LIBS = $(IMAGE_LIBS) $(UTIL_LIBS) -lcrypto $(BASE_LIBS) -tests: firmware_image_tests \ +tests: big_firmware_tests \ + big_kernel_tests \ + firmware_image_tests \ firmware_rollback_tests \ firmware_splicing_tests \ firmware_verify_benchmark \ @@ -27,6 +29,12 @@ tests: firmware_image_tests \ verify_firmware_fuzz_driver \ verify_kernel_fuzz_driver +big_firmware_tests: big_firmware_tests.c rollback_index_mock.c test_common.c + $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS) + +big_kernel_tests: big_kernel_tests.c rollback_index_mock.c test_common.c + $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS) + firmware_image_tests: firmware_image_tests.c rollback_index_mock.c test_common.c $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS) @@ -79,7 +87,9 @@ verify_kernel_fuzz_driver: verify_kernel_fuzz_driver.c rollback_index_mock.c $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS) clean: - rm -f firmware_image_tests \ + rm -f big_firmware_tests \ + big_kernel_tests \ + firmware_image_tests \ firmware_rollback_tests \ firmware_splicing_tests \ firmware_verify_benchmark \ diff --git a/tests/big_firmware_tests.c b/tests/big_firmware_tests.c new file mode 100644 index 0000000000..4079adde03 --- /dev/null +++ b/tests/big_firmware_tests.c @@ -0,0 +1,74 @@ +/* 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. + * + * Tests if firmware image library deals with very large firmware. This + * is a quick and dirty test for detecting integer overflow issues. + */ + +#include +#include + +#include "file_keys.h" +#include "firmware_image.h" +#include "rsa_utility.h" +#include "test_common.h" +#include "utility.h" + +/* Choose a firmware size greater than the range of 32-bits unsigned. */ +#define BIG_FIRMWARE_SIZE ((uint64_t) 0x100000000) + +#define ROOT_KEY_BASE_NAME "testkeys/key_rsa8192" +#define FIRMWARE_KEY_BASE_NAME "testkeys/key_rsa1024" + +const char* kRootKeyPublicFile = ROOT_KEY_BASE_NAME ".keyb"; +const char* kRootKeyFile = ROOT_KEY_BASE_NAME ".pem"; +const char* kFirmwareKeyPublicFile = FIRMWARE_KEY_BASE_NAME ".keyb"; +const char* kFirmwareKeyFile = FIRMWARE_KEY_BASE_NAME ".pem"; + +int BigFirmwareTest(void) { + int error_code = 0; + uint64_t len; + uint8_t* firmware_blob = NULL; + RSAPublicKey* root_key = RSAPublicKeyFromFile(kRootKeyPublicFile); + uint8_t* root_key_blob = BufferFromFile(kRootKeyPublicFile, &len); + uint8_t* firmware_sign_key_buf= BufferFromFile(kFirmwareKeyPublicFile, &len); + fprintf(stderr, "Generating Big FirmwareImage..."); + FirmwareImage* image = + GenerateTestFirmwareImage(0, /* RSA1024/SHA1 */ + firmware_sign_key_buf, + 1, /* Firmware Key Version. */ + 1, /* Firmware Version */ + BIG_FIRMWARE_SIZE, + kRootKeyFile, + kFirmwareKeyFile, + 'F'); /* Firmware data fill. */ + if (!root_key || !root_key_blob || !firmware_sign_key_buf || !image) { + error_code = 1; + goto cleanup; + } + fprintf(stderr, "Done.\n"); + TEST_EQ(VerifyFirmwareImage(root_key, image), + VERIFY_FIRMWARE_SUCCESS, + "Big FirmwareImage Verification"); + firmware_blob = GetFirmwareBlob(image, &len); + TEST_EQ(VerifyFirmware(root_key_blob, firmware_blob), + VERIFY_FIRMWARE_SUCCESS, + "Big Firmware Blob Verification"); + + cleanup: + Free(firmware_blob); + FirmwareImageFree(image); + Free(firmware_sign_key_buf); + RSAPublicKeyFree(root_key); + return error_code; +} + +int main(int argc, char* argv[1]) +{ + int error_code = 0; + error_code = BigFirmwareTest(); + if (!gTestSuccess) + error_code = 255; + return error_code; +} diff --git a/tests/big_kernel_tests.c b/tests/big_kernel_tests.c new file mode 100644 index 0000000000..81943ba662 --- /dev/null +++ b/tests/big_kernel_tests.c @@ -0,0 +1,76 @@ +/* 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. + * + * Tests if firmware image library deals with very large firmware. This + * is a quick and dirty test for detecting integer overflow issues. + */ + +#include +#include + +#include "file_keys.h" +#include "kernel_image.h" +#include "rsa_utility.h" +#include "test_common.h" +#include "utility.h" + +/* Choose a kernel size greater than the range of 32-bits unsigned. */ +#define BIG_KERNEL_SIZE ((uint64_t) 0x100000000) + +#define FIRMWARE_KEY_BASE_NAME "testkeys/key_rsa2048" +#define KERNEL_KEY_BASE_NAME "testkeys/key_rsa1024" + +const char* kFirmwareKeyPublicFile = FIRMWARE_KEY_BASE_NAME ".keyb"; +const char* kFirmwareKeyFile = FIRMWARE_KEY_BASE_NAME ".pem"; +const char* kKernelKeyPublicFile = KERNEL_KEY_BASE_NAME ".keyb"; +const char* kKernelKeyFile = KERNEL_KEY_BASE_NAME ".pem"; + +int BigKernelTest() { + int error_code = 0; + uint64_t len; + uint8_t* kernel_blob = NULL; + RSAPublicKey* firmware_key = RSAPublicKeyFromFile(kFirmwareKeyPublicFile); + uint8_t* firmware_key_blob = BufferFromFile(kFirmwareKeyPublicFile, &len); + uint8_t* kernel_sign_key_buf = BufferFromFile(kKernelKeyPublicFile, &len); + fprintf(stderr, "Generating Big KernelImage..."); + KernelImage* image = + GenerateTestKernelImage(3, /* RSA2048/SHA1 */ + 0, /* RSA1024/SHA1 */ + kernel_sign_key_buf, + 1, /* Kernel Key Version. */ + 1, /* Kernel Version */ + BIG_KERNEL_SIZE, + kFirmwareKeyFile, + kKernelKeyFile, + 'K'); /* Kernel Data Fill. */ + if (!firmware_key || !firmware_key_blob || !kernel_sign_key_buf || !image) { + error_code = 1; + goto cleanup; + } + fprintf(stderr, "Done.\n"); + TEST_EQ(VerifyKernelImage(firmware_key, image, 0), + VERIFY_FIRMWARE_SUCCESS, + "Big KernelImage Verification"); + kernel_blob = GetKernelBlob(image, &len); + TEST_EQ(VerifyKernel(firmware_key_blob, kernel_blob, 0), + VERIFY_FIRMWARE_SUCCESS, + "Big Kernel Blob Verification"); + +cleanup: + Free(kernel_blob); + KernelImageFree(image); + Free(kernel_sign_key_buf); + Free(firmware_key_blob); + RSAPublicKeyFree(firmware_key); + return error_code; +} + +int main(int argc, char* argv[1]) +{ + int error_code = 0; + error_code = BigKernelTest(); + if (!gTestSuccess) + error_code = 255; + return error_code; +} diff --git a/tests/firmware_rollback_tests.c b/tests/firmware_rollback_tests.c index e36c003a28..9973ec7305 100644 --- a/tests/firmware_rollback_tests.c +++ b/tests/firmware_rollback_tests.c @@ -15,6 +15,8 @@ #include "rollback_index.h" #include "test_common.h" +const char* kRootKeyPublicFile = "testkeys/key_rsa8192.keyb"; + /* Tests that check for correctness of the VerifyFirmwareDriver_f() logic * and rollback prevention. */ void VerifyFirmwareDriverTest(void) { @@ -23,8 +25,7 @@ void VerifyFirmwareDriverTest(void) { uint8_t* corrupt_firmwareA = NULL; uint8_t* corrupt_firmwareB = NULL; uint64_t len; - uint8_t* root_key_pub = BufferFromFile("testkeys/key_rsa8192.keyb", - &len); + uint8_t* root_key_pub = BufferFromFile(kRootKeyPublicFile, &len); /* Initialize rollback index state. */ g_firmware_key_version = 1; diff --git a/tests/firmware_splicing_tests.c b/tests/firmware_splicing_tests.c index 519e2a17ff..c71b8b42ab 100644 --- a/tests/firmware_splicing_tests.c +++ b/tests/firmware_splicing_tests.c @@ -15,6 +15,14 @@ #include "test_common.h" #include "utility.h" +#define ROOT_KEY_BASE_NAME "testkeys/key_rsa8192" +#define FIRMWARE_KEY_BASE_NAME "testkeys/key_rsa1024" + +const char* kRootKeyPublicFile = ROOT_KEY_BASE_NAME ".keyb"; +const char* kRootKeyFile = ROOT_KEY_BASE_NAME ".pem"; +const char* kFirmwareKeyPublicFile = FIRMWARE_KEY_BASE_NAME ".keyb"; +const char* kFirmwareKeyFile = FIRMWARE_KEY_BASE_NAME ".pem"; + void VerifyFirmwareSplicingTest() { uint64_t len; @@ -22,26 +30,25 @@ void VerifyFirmwareSplicingTest() FirmwareImage* image2 = NULL; uint8_t* firmware_blob = NULL; uint8_t* firmware_sign_key_buf = NULL; - RSAPublicKey* root_key = RSAPublicKeyFromFile("testkeys/key_rsa8192.keyb"); - uint8_t* root_key_blob = BufferFromFile("testkeys/key_rsa8192.keyb", - &len); - firmware_sign_key_buf= BufferFromFile("testkeys/key_rsa1024.keyb", &len); + RSAPublicKey* root_key = RSAPublicKeyFromFile(kRootKeyPublicFile); + uint8_t* root_key_blob = BufferFromFile(kRootKeyPublicFile, &len); + firmware_sign_key_buf= BufferFromFile(kFirmwareKeyPublicFile, &len); image1 = GenerateTestFirmwareImage(0, /* RSA1024/SHA1 */ firmware_sign_key_buf, 1, /* Firmware Key Version. */ 1, /* Firmware Version */ 1000, - "testkeys/key_rsa8192.pem", - "testkeys/key_rsa1024.pem", - (uint8_t) 'F'); /* Firmware data fill. */ + kRootKeyFile, + kFirmwareKeyFile, + 'F'); /* Firmware data fill. */ image2 = GenerateTestFirmwareImage(0, /* RSA1024/SHA1 */ firmware_sign_key_buf, 1, /* Firmware Key Version. */ 2, /* Firmware Version */ 1000, - "testkeys/key_rsa8192.pem", - "testkeys/key_rsa1024.pem", - (uint8_t) 'G'); /* Firmware data fill. */ + kRootKeyFile, + kFirmwareKeyFile, + 'G'); /* Different Firmware data fill. */ /* Verify that the originals verify. */ TEST_EQ(VerifyFirmwareImage(root_key, image1), VERIFY_FIRMWARE_SUCCESS, diff --git a/tests/kernel_rollback_tests.c b/tests/kernel_rollback_tests.c index c9563005d1..eafbaaa0b8 100644 --- a/tests/kernel_rollback_tests.c +++ b/tests/kernel_rollback_tests.c @@ -15,12 +15,14 @@ #include "test_common.h" #include "utility.h" +const char* kFirmwareKeyPublicFile = "testkeys/key_rsa1024.keyb"; + /* Tests that check for correctness of the VerifyFirmwareDriver_f() logic * and rollback prevention. */ void VerifyKernelDriverTest(void) { uint64_t len; - uint8_t* firmware_key_pub = BufferFromFile("testkeys/key_rsa1024.keyb", - &len); + uint8_t* firmware_key_pub = BufferFromFile(kFirmwareKeyPublicFile, &len); + /* Initialize kernel blobs, including their associated parition * table attributed. */ kernel_entry valid_kernelA = { diff --git a/tests/kernel_splicing_tests.c b/tests/kernel_splicing_tests.c index bdd3101682..da29eb1f2f 100644 --- a/tests/kernel_splicing_tests.c +++ b/tests/kernel_splicing_tests.c @@ -15,6 +15,14 @@ #include "test_common.h" #include "utility.h" +#define FIRMWARE_KEY_BASE_NAME "testkeys/key_rsa2048" +#define KERNEL_KEY_BASE_NAME "testkeys/key_rsa1024" + +const char* kFirmwareKeyPublicFile = FIRMWARE_KEY_BASE_NAME ".keyb"; +const char* kFirmwareKeyFile = FIRMWARE_KEY_BASE_NAME ".pem"; +const char* kKernelKeyPublicFile = KERNEL_KEY_BASE_NAME ".keyb"; +const char* kKernelKeyFile = KERNEL_KEY_BASE_NAME ".pem"; + void VerifyKernelSplicingTest() { uint64_t len; @@ -22,29 +30,27 @@ void VerifyKernelSplicingTest() KernelImage* image2 = NULL; uint8_t* kernel_blob = NULL; uint8_t* kernel_sign_key_buf = NULL; - RSAPublicKey* firmware_key = - RSAPublicKeyFromFile("testkeys/key_rsa2048.keyb"); - uint8_t* firmware_key_blob = BufferFromFile("testkeys/key_rsa2048.keyb", - &len); - kernel_sign_key_buf= BufferFromFile("testkeys/key_rsa1024.keyb", &len); + RSAPublicKey* firmware_key = RSAPublicKeyFromFile(kFirmwareKeyPublicFile); + uint8_t* firmware_key_blob = BufferFromFile(kFirmwareKeyPublicFile, &len); + kernel_sign_key_buf= BufferFromFile(kKernelKeyPublicFile, &len); image1 = GenerateTestKernelImage(3, /* RSA2048/SHA1 */ 0, /* RSA1024/SHA1 */ kernel_sign_key_buf, 1, /* Kernel Key Version. */ 1, /* Kernel Version */ 1000, /* Kernel Size. */ - "testkeys/key_rsa2048.pem", - "testkeys/key_rsa1024.pem", - (uint8_t) 'K'); /* Kernel data fill. */ + kFirmwareKeyFile, + kKernelKeyFile, + 'K'); /* Kernel data fill. */ image2 = GenerateTestKernelImage(3, /* RSA2058/SHA1 */ 0, /* RSA1024/SHA1 */ kernel_sign_key_buf, 1, /* Kernel Key Version. */ 2, /* Kernel Version */ 1000, /* Kernel Size */ - "testkeys/key_rsa2048.pem", - "testkeys/key_rsa1024.pem", - (uint8_t) 'K'); /* Kernel data fill. */ + kFirmwareKeyFile, + kKernelKeyFile, + 'L'); /* Different Kernel data fill. */ /* Make sure the originals verify. */ TEST_EQ(VerifyKernelImage(firmware_key, image1, 0), VERIFY_KERNEL_SUCCESS, diff --git a/tests/test_common.c b/tests/test_common.c index 929e91f3b2..b57f6ed85e 100644 --- a/tests/test_common.c +++ b/tests/test_common.c @@ -37,7 +37,7 @@ FirmwareImage* GenerateTestFirmwareImage(int algorithm, const uint8_t* firmware_sign_key, int firmware_key_version, int firmware_version, - int firmware_len, + uint64_t firmware_len, const char* root_key_file, const char* firmware_key_file, uint8_t firmware_data_fill_char) { @@ -84,7 +84,7 @@ uint8_t* GenerateTestFirmwareBlob(int algorithm, const uint8_t* firmware_sign_key, int firmware_key_version, int firmware_version, - int firmware_len, + uint64_t firmware_len, const char* root_key_file, const char* firmware_key_file) { FirmwareImage* image = NULL; @@ -142,7 +142,7 @@ KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, const uint8_t* kernel_sign_key, int kernel_key_version, int kernel_version, - int kernel_len, + uint64_t kernel_len, const char* firmware_key_file, const char* kernel_key_file, uint8_t kernel_data_fill_char) { @@ -197,7 +197,7 @@ uint8_t* GenerateTestKernelBlob(int firmware_sign_algorithm, const uint8_t* kernel_sign_key, int kernel_key_version, int kernel_version, - int kernel_len, + uint64_t kernel_len, const char* firmware_key_file, const char* kernel_key_file) { KernelImage* image = NULL; diff --git a/tests/test_common.h b/tests/test_common.h index 15746b5918..6fed1b489f 100644 --- a/tests/test_common.h +++ b/tests/test_common.h @@ -22,7 +22,7 @@ FirmwareImage* GenerateTestFirmwareImage(int algorithm, const uint8_t* firmware_sign_key, int firmware_key_version, int firmware_version, - int firmware_len, + uint64_t firmware_len, const char* root_key_file, const char* firmware_key_file, uint8_t firmware_data_fill_char); @@ -30,7 +30,7 @@ uint8_t* GenerateTestFirmwareBlob(int algorithm, const uint8_t* firmware_sign_key, int firmware_key_version, int firmware_version, - int firmware_len, + uint64_t firmware_len, const char* root_key_file, const char* firmware_key_file); @@ -40,7 +40,7 @@ KernelImage* GenerateTestKernelImage(int firmware_sign_algorithm, const uint8_t* kernel_sign_key, int kernel_key_version, int kernel_version, - int kernel_len, + uint64_t kernel_len, const char* firmware_key_file, const char* kernel_key_file, uint8_t kernel_data_fill_char); @@ -50,7 +50,7 @@ uint8_t* GenerateTestKernelBlob(int firmware_sign_algorithm, const uint8_t* kernel_sign_key, int kernel_key_version, int kernel_version, - int kernel_len, + uint64_t kernel_len, const char* firmware_key_file, const char* kernel_key_file); diff --git a/utils/firmware_image.c b/utils/firmware_image.c index a598f5447b..2e3f92441e 100644 --- a/utils/firmware_image.c +++ b/utils/firmware_image.c @@ -66,6 +66,7 @@ FirmwareImage* ReadFirmwareImage(const char* input_file) { st.remaining_len = image_len; st.remaining_buf = firmware_buf; + st.overrun = 0; /* Read and compare magic bytes. */ StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE); @@ -132,7 +133,7 @@ FirmwareImage* ReadFirmwareImage(const char* input_file) { image->firmware_data = (uint8_t*) Malloc(image->firmware_len); StatefulMemcpy(&st, image->firmware_data, image->firmware_len); - if(st.remaining_len != 0) { /* Overrun or underrun. */ + if(st.overrun || st.remaining_len != 0) { /* Overrun or underrun. */ Free(firmware_buf); return NULL; } @@ -174,6 +175,7 @@ uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image)); st.remaining_len = GetFirmwareHeaderLen(image); st.remaining_buf = header_blob; + st.overrun = 0; StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len)); @@ -183,7 +185,7 @@ uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { RSAProcessedKeySize(image->firmware_sign_algorithm)); StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); - if (st.remaining_len != 0) { /* Underrun or Overrun. */ + if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ Free(header_blob); return NULL; } @@ -202,12 +204,13 @@ uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image) { preamble_blob = (uint8_t*) Malloc(GetFirmwarePreambleLen()); st.remaining_len = GetFirmwarePreambleLen(); st.remaining_buf = preamble_blob; + st.overrun = 0; StatefulMemcpy_r(&st, &image->firmware_version, FIELD_LEN(firmware_version)); StatefulMemcpy_r(&st, &image->firmware_len, FIELD_LEN(firmware_len)); StatefulMemcpy_r(&st, image->preamble, FIELD_LEN(preamble)); - if (st.remaining_len != 0 ) { /* Underrun or Overrun. */ + if (st.overrun || st.remaining_len != 0 ) { /* Underrun or Overrun. */ Free(preamble_blob); return NULL; } @@ -235,6 +238,7 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) { firmware_blob = (uint8_t*) Malloc(*blob_len); st.remaining_len = *blob_len; st.remaining_buf = firmware_blob; + st.overrun = 0; header_blob = GetFirmwareHeaderBlob(image); preamble_blob = GetFirmwarePreambleBlob(image); @@ -251,7 +255,7 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) { Free(preamble_blob); Free(header_blob); - if (st.remaining_len != 0) { /* Underrun or Overrun. */ + if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ Free(firmware_blob); return NULL; } @@ -381,8 +385,8 @@ int VerifyFirmwareHeader(const uint8_t* root_key_blob, int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, const uint8_t* preamble_blob, int algorithm, - int* firmware_len) { - uint32_t len; + uint64_t* firmware_len) { + uint64_t len; int preamble_len; uint16_t firmware_version; @@ -400,14 +404,14 @@ int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), sizeof(len)); - *firmware_len = (int) len; + *firmware_len = len; return 0; } int VerifyFirmwareData(RSAPublicKey* firmware_sign_key, const uint8_t* preamble_start, const uint8_t* firmware_data_start, - int firmware_len, + uint64_t firmware_len, int algorithm) { int signature_len = siglen_map[algorithm]; uint8_t* digest; @@ -437,7 +441,8 @@ int VerifyFirmware(const uint8_t* root_key_blob, int error_code = 0; int algorithm; /* Signing key algorithm. */ RSAPublicKey* firmware_sign_key = NULL; - int firmware_sign_key_len, signature_len, header_len, firmware_len; + int firmware_sign_key_len, signature_len, header_len; + uint64_t firmware_len; const uint8_t* header_ptr = NULL; /* Pointer to header. */ const uint8_t* firmware_sign_key_ptr = NULL; /* Pointer to signing key. */ const uint8_t* preamble_ptr = NULL; /* Pointer to preamble block. */ @@ -473,6 +478,7 @@ int VerifyFirmware(const uint8_t* root_key_blob, algorithm, &firmware_len))) { RSAPublicKeyFree(firmware_sign_key); + fprintf(stderr, "Couldn't verify Firmware preamble.\n"); return error_code; /* AKA jump to recovery. */ } /* Only continue if firmware data verification succeeds. */ @@ -485,6 +491,7 @@ int VerifyFirmware(const uint8_t* root_key_blob, firmware_len, algorithm))) { RSAPublicKeyFree(firmware_sign_key); + fprintf(stderr, "Couldn't verify Firmware data.\n"); return error_code; /* AKA jump to recovery. */ } @@ -539,7 +546,7 @@ int VerifyFirmwareImage(const RSAPublicKey* root_key, /* Get sign key to verify the rest of the firmware. */ firmware_sign_key_size = RSAProcessedKeySize(image->firmware_sign_algorithm); firmware_sign_key = RSAPublicKeyFromBuf(image->firmware_sign_key, - firmware_sign_key_size); + firmware_sign_key_size); signature_size = siglen_map[image->firmware_sign_algorithm]; if (image->firmware_sign_algorithm >= kNumAlgorithms) @@ -555,8 +562,8 @@ int VerifyFirmwareImage(const RSAPublicKey* root_key, FIELD_LEN(preamble)); preamble_digest = DigestFinal(&ctx); if (!RSAVerify(firmware_sign_key, image->preamble_signature, - signature_size, image->firmware_sign_algorithm, - preamble_digest)) { + signature_size, image->firmware_sign_algorithm, + preamble_digest)) { error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; goto verify_failure; } diff --git a/utils/kernel_image.c b/utils/kernel_image.c index f92a9f84e3..32e12a85d6 100644 --- a/utils/kernel_image.c +++ b/utils/kernel_image.c @@ -69,6 +69,7 @@ KernelImage* ReadKernelImage(const char* input_file) { st.remaining_len = image_len; st.remaining_buf = kernel_buf; + st.overrun = 0; /* Read and compare magic bytes. */ StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); @@ -154,7 +155,7 @@ KernelImage* ReadKernelImage(const char* input_file) { image->kernel_data = (uint8_t*) Malloc(image->options.kernel_len); StatefulMemcpy(&st, image->kernel_data, image->options.kernel_len); - if(st.remaining_len != 0) { /* Overrun or underrun. */ + if(st.overrun || st.remaining_len != 0) { /* Overrun or underrun. */ Free(kernel_buf); return NULL; } @@ -200,6 +201,7 @@ uint8_t* GetKernelHeaderBlob(const KernelImage* image) { 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)); @@ -213,7 +215,7 @@ uint8_t* GetKernelHeaderBlob(const KernelImage* image) { RSAProcessedKeySize(image->kernel_sign_algorithm)); StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); - if (st.remaining_len != 0) { /* Underrun or Overrun. */ + if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ Free(header_blob); return NULL; } @@ -234,6 +236,7 @@ uint8_t* GetKernelConfigBlob(const KernelImage* image) { config_blob = (uint8_t*) Malloc(GetKernelConfigLen()); st.remaining_len = GetKernelConfigLen(); st.remaining_buf = config_blob; + st.overrun = 0; StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version)); @@ -244,7 +247,7 @@ uint8_t* GetKernelConfigBlob(const KernelImage* image) { FIELD_LEN(options.kernel_load_addr)); StatefulMemcpy_r(&st, &image->options.kernel_entry_addr, FIELD_LEN(options.kernel_entry_addr)); - if (st.remaining_len != 0) { /* Overrun or Underrun. */ + if (st.overrun || st.remaining_len != 0) { /* Overrun or Underrun. */ Free(config_blob); return NULL; } @@ -272,6 +275,7 @@ uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_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); config_blob = GetKernelConfigBlob(image); @@ -287,7 +291,7 @@ uint8_t* GetKernelBlob(const KernelImage* image, uint64_t* blob_len) { Free(config_blob); Free(header_blob); - if (st.remaining_len != 0) { /* Underrun or Overrun. */ + if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ Free(kernel_blob); return NULL; } @@ -451,9 +455,10 @@ int VerifyKernelHeader(const uint8_t* firmware_key_blob, int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, const uint8_t* config_blob, int algorithm, - int* kernel_len) { - uint32_t len, config_len; - config_len = GetKernelConfigLen(); + uint64_t* kernel_len) { + uint64_t len; + int config_len; + config_len = GetKernelConfigLen(NULL); if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ config_blob, /* Data to verify */ config_len, /* Length of data */ @@ -465,14 +470,14 @@ int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line)), sizeof(len)); - *kernel_len = (int) len; + *kernel_len = len; return 0; } int VerifyKernelData(RSAPublicKey* kernel_sign_key, const uint8_t* kernel_config_start, const uint8_t* kernel_data_start, - int kernel_len, + uint64_t kernel_len, int algorithm) { int signature_len = siglen_map[algorithm]; uint8_t* digest; @@ -505,7 +510,8 @@ int VerifyKernel(const uint8_t* firmware_key_blob, 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, kernel_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* config_ptr; /* Pointer to kernel config block. */