mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
Add fuzz testing driver programs for kernel and firmware verification.
The driver programs are useful in quick and dirty fuzz testing of the verification code with blind smartfuzzers like Bunny (http://code.google.com/p/bunny-the-fuzzer/). Also fixes a bug with image generation in kernel_utility. Tests: All existing tests still pass. VerifyKernel() and VerifyFirmware() can successfully verify images generated by {firmware|kernel}_utility. Review URL: http://codereview.chromium.org/975007
This commit is contained in:
@@ -11,8 +11,9 @@ FIRMWARE_LIBS = $(TOP)/crypto/libcrypto.a $(TOP)/common/libcommon.a
|
||||
LIBS = $(TOP)/utils/kernel_image.o $(TOP)/utils/firmware_image.o \
|
||||
$(TOP)/utils/file_keys.o $(TOP)/utils/signature_digest.o -lcrypto
|
||||
|
||||
tests: firmware_image_tests kernel_image_tests sha_tests sha_benchmark \
|
||||
rsa_verify_benchmark rsa_padding_test
|
||||
tests: firmware_image_tests verify_firmware_fuzz_driver \
|
||||
kernel_image_tests verify_kernel_fuzz_driver \
|
||||
sha_tests sha_benchmark rsa_verify_benchmark rsa_padding_test
|
||||
|
||||
sha_tests: sha_tests.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(FIRMWARE_LIBS)
|
||||
@@ -20,9 +21,15 @@ sha_tests: sha_tests.c
|
||||
firmware_image_tests: firmware_image_tests.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) $(FIRMWARE_LIBS)
|
||||
|
||||
verify_firmware_fuzz_driver: verify_firmware_fuzz_driver.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) $(FIRMWARE_LIBS)
|
||||
|
||||
kernel_image_tests: kernel_image_tests.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) $(FIRMWARE_LIBS)
|
||||
|
||||
verify_kernel_fuzz_driver: verify_kernel_fuzz_driver.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) $(FIRMWARE_LIBS)
|
||||
|
||||
sha_benchmark: sha_benchmark.c timer_utils.c $(FIRMWARE_LIBS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ -lrt
|
||||
|
||||
@@ -34,4 +41,5 @@ rsa_verify_benchmark: rsa_verify_benchmark.c timer_utils.c
|
||||
|
||||
clean:
|
||||
rm -f sha_tests sha_benchmark rsa_verify_benchmark \
|
||||
firmware_image_tests kernel_image_tests rsa_padding_test
|
||||
firmware_image_tests kernel_image_tests rsa_padding_test \
|
||||
verify_firmware_fuzz_driver verify_kernel_fuzz_driver
|
||||
|
||||
68
tests/gen_fuzz_test_cases.sh
Executable file
68
tests/gen_fuzz_test_cases.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
# Generate test cases for use for the RSA verify benchmark.
|
||||
|
||||
TESTCASE_DIR=fuzz_testcases
|
||||
TESTKEY_DIR=testkeys
|
||||
UTIL_DIR=../utils/
|
||||
TEST_FILE=test_file
|
||||
TEST_FILE_SIZE=1000000
|
||||
|
||||
hash_algos=( sha1 sha256 sha512 )
|
||||
key_lengths=( 1024 2048 4096 8192 )
|
||||
|
||||
# Generate public key signatures and digest on an input file for
|
||||
# various combinations of message digest algorithms and RSA key sizes.
|
||||
function generate_fuzzing_images {
|
||||
echo "Generating signed firmware test image..."
|
||||
# Generate a test verified boot firmware image and copy root public key.
|
||||
${UTIL_DIR}/firmware_utility --generate \
|
||||
--in $1 \
|
||||
--root_key ${TESTKEY_DIR}/key_rsa8192.pem \
|
||||
--firmware_sign_key ${TESTKEY_DIR}/key_rsa4096.pem \
|
||||
--firmware_sign_key_pub ${TESTKEY_DIR}/key_rsa4096.keyb \
|
||||
--firmware_sign_algorithm 8 \
|
||||
--firmware_key_version 1 \
|
||||
--firmware_version 1 \
|
||||
--out ${TESTCASE_DIR}/firmware.signed
|
||||
cp ${TESTKEY_DIR}/key_rsa8192.keyb ${TESTCASE_DIR}/root_key.keyb
|
||||
|
||||
echo "Generating signed kernel test image..."
|
||||
# Generate a test verified boot kernel image and copy firmware public key.
|
||||
${UTIL_DIR}/kernel_utility --generate \
|
||||
--in $1 \
|
||||
--firmware_key ${TESTKEY_DIR}/key_rsa4096.pem \
|
||||
--kernel_key ${TESTKEY_DIR}/key_rsa1024.pem \
|
||||
--kernel_key_pub ${TESTKEY_DIR}/key_rsa1024.keyb \
|
||||
--firmware_sign_algorithm 8 \
|
||||
--kernel_sign_algorithm 2 \
|
||||
--kernel_key_version 1 \
|
||||
--kernel_version 1 \
|
||||
--out ${TESTCASE_DIR}/kernel.signed
|
||||
cp ${TESTKEY_DIR}/key_rsa4096.keyb ${TESTCASE_DIR}/firmware_key.keyb
|
||||
}
|
||||
|
||||
function pre_work {
|
||||
# Generate a file with random bytes for signature tests.
|
||||
echo "Generating test file..."
|
||||
dd if=/dev/urandom of=${TESTCASE_DIR}/${TEST_FILE} bs=${TEST_FILE_SIZE} \
|
||||
count=1
|
||||
}
|
||||
|
||||
if [ ! -d ${TESTKEY_DIR} ]
|
||||
then
|
||||
echo "You must run gen_test_keys.sh to generate test keys first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d ${TESTCASE_DIR} ]
|
||||
then
|
||||
mkdir ${TESTCASE_DIR}
|
||||
fi
|
||||
|
||||
pre_work
|
||||
generate_fuzzing_images ${TESTCASE_DIR}/$TEST_FILE
|
||||
57
tests/verify_firmware_fuzz_driver.c
Normal file
57
tests/verify_firmware_fuzz_driver.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 aiding fuzz testing of firmware image verification code.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "file_keys.h"
|
||||
#include "firmware_image.h"
|
||||
#include "utility.h"
|
||||
|
||||
int VerifySignedFirmware(const char* image_file,
|
||||
const char* root_key_file) {
|
||||
int error, error_code = 0;
|
||||
uint64_t len;
|
||||
uint8_t* firmware_blob = BufferFromFile(image_file, &len);
|
||||
uint8_t* root_key_blob = BufferFromFile(root_key_file, &len);
|
||||
|
||||
if (!root_key_blob) {
|
||||
fprintf(stderr, "Couldn't read pre-processed public root key.\n");
|
||||
error_code = 1;
|
||||
}
|
||||
|
||||
if (!error_code && !firmware_blob) {
|
||||
fprintf(stderr, "Couldn't read firmware image or malformed image.\n");
|
||||
error_code = 1;
|
||||
}
|
||||
|
||||
if (!error_code && (error = VerifyFirmware(root_key_blob, firmware_blob,
|
||||
0))) { /* Trusted Mode. */
|
||||
fprintf(stderr, "%s\n", VerifyFirmwareErrorString(error));
|
||||
error_code = 1;
|
||||
}
|
||||
Free(root_key_blob);
|
||||
Free(firmware_blob);
|
||||
if (error_code)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <image_to_verify> <root_keyb>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if (VerifySignedFirmware(argv[1], argv[2])) {
|
||||
fprintf(stderr, "Verification SUCCESS!\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Verification FAILURE!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
56
tests/verify_kernel_fuzz_driver.c
Normal file
56
tests/verify_kernel_fuzz_driver.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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 aiding fuzz testing of kernel image verification code.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "file_keys.h"
|
||||
#include "kernel_image.h"
|
||||
#include "utility.h"
|
||||
|
||||
int VerifySignedKernel(const char* image_file,
|
||||
const char* firmware_key_file) {
|
||||
int error, error_code = 0;
|
||||
uint64_t len;
|
||||
uint8_t* kernel_blob = BufferFromFile(image_file, &len);
|
||||
uint8_t* firmware_key_blob = BufferFromFile(firmware_key_file, &len);
|
||||
|
||||
if (!firmware_key_blob) {
|
||||
fprintf(stderr, "Couldn't read pre-processed public firmware key.\n");
|
||||
error_code = 1;
|
||||
}
|
||||
|
||||
if (!error_code && !kernel_blob) {
|
||||
fprintf(stderr, "Couldn't read kernel image or malformed image.\n");
|
||||
error_code = 1;
|
||||
}
|
||||
|
||||
if (!error_code && (error = VerifyKernel(firmware_key_blob, kernel_blob,
|
||||
0))) { /* Trusted Mode. */
|
||||
fprintf(stderr, "%s\n", VerifyKernelErrorString(error));
|
||||
error_code = 1;
|
||||
}
|
||||
Free(firmware_key_blob);
|
||||
Free(kernel_blob);
|
||||
if (error_code)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <image_to_verify> <firmware_keyb>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
if (VerifySignedKernel(argv[1], argv[2])) {
|
||||
fprintf(stderr, "Verification SUCCESS!\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Verification FAILURE!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -404,6 +404,7 @@ int VerifyKernelHeader(const uint8_t* firmware_key_blob,
|
||||
kernel_sign_key_len),
|
||||
FIELD_LEN(header_checksum))) {
|
||||
Free(header_checksum);
|
||||
fprintf(stderr, "VerifyKernelHeader: Invalid header hash\n");
|
||||
return VERIFY_KERNEL_INVALID_IMAGE;
|
||||
}
|
||||
Free(header_checksum);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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 firmware images.
|
||||
// Utility for manipulating verified boot kernel images.
|
||||
//
|
||||
|
||||
#include "kernel_utility.h"
|
||||
@@ -55,7 +55,7 @@ KernelUtility::~KernelUtility() {
|
||||
void KernelUtility::PrintUsage(void) {
|
||||
cerr <<
|
||||
"Utility to generate/verify a verified boot kernel image\n\n"
|
||||
"Usage: firmware_utility <--generate|--verify> [OPTIONS]\n\n"
|
||||
"Usage: kernel_utility <--generate|--verify> [OPTIONS]\n\n"
|
||||
"For \"--verify\", required OPTIONS are:\n"
|
||||
"--in <infile>\t\t\tVerified boot kernel image to verify.\n"
|
||||
"--firmware_key_pub <pubkeyfile>\tPre-processed public firmware key "
|
||||
@@ -227,7 +227,11 @@ bool KernelUtility::GenerateSignedImage(void) {
|
||||
sizeof(image_->header_version));
|
||||
DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->header_len),
|
||||
sizeof(image_->header_len));
|
||||
DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->kernel_sign_algorithm),
|
||||
DigestUpdate(&ctx,
|
||||
reinterpret_cast<uint8_t*>(&image_->firmware_sign_algorithm),
|
||||
sizeof(image_->firmware_sign_algorithm));
|
||||
DigestUpdate(&ctx,
|
||||
reinterpret_cast<uint8_t*>(&image_->kernel_sign_algorithm),
|
||||
sizeof(image_->kernel_sign_algorithm));
|
||||
DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->kernel_key_version),
|
||||
sizeof(image_->kernel_key_version));
|
||||
@@ -248,12 +252,12 @@ bool KernelUtility::GenerateSignedImage(void) {
|
||||
return false;
|
||||
// Generate and add the signatures.
|
||||
if (!AddKernelKeySignature(image_, firmware_key_file_.c_str())) {
|
||||
cerr << "Couldn't write key signature to verified boot image.\n";
|
||||
cerr << "Couldn't write key signature to verified boot kernel image.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AddKernelSignature(image_, kernel_key_file_.c_str())) {
|
||||
cerr << "Couldn't write firmware signature to verified boot image.\n";
|
||||
cerr << "Couldn't write firmware signature to verified boot kernel image.\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -270,7 +274,7 @@ bool KernelUtility::VerifySignedImage(void) {
|
||||
}
|
||||
|
||||
if (!image_) {
|
||||
cerr << "Couldn't read firmware image or malformed image.\n";
|
||||
cerr << "Couldn't read kernel image or malformed image.\n";
|
||||
return false;
|
||||
}
|
||||
if (!(error = VerifyKernelImage(firmware_key_pub_, image_, 0)))
|
||||
|
||||
Reference in New Issue
Block a user