mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 00:51:29 +00:00
Propagate use of uint64_t to more functions that may need to deal with arbitrary length data.
This CL fixes some functions to use uint64_t that I missed the first time around. It ended up requiring some minor changes to how some of the helper functions work (StatefulMemcpy*()). Also adds new tests to make sure that reference code can verify/process big firmware and kernel images. BUG=670 TEST=Adds some new, old ones still pass. Review URL: http://codereview.chromium.org/1519008
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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].
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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 \
|
||||
|
||||
74
tests/big_firmware_tests.c
Normal file
74
tests/big_firmware_tests.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
76
tests/big_kernel_tests.c
Normal file
76
tests/big_kernel_tests.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user