summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2010-06-10 09:59:04 -0700
committerRandall Spangler <rspangler@chromium.org>2010-06-10 09:59:04 -0700
commitd183644564ec27c106a3eb1931f565fae167a058 (patch)
tree195f2d44c8800b797189e6e0b9245541848f896b /tests
parent59204c57d0a4889e3cace81b3361ea06f7b3fb45 (diff)
downloadvboot-d183644564ec27c106a3eb1931f565fae167a058.tar.gz
Major refactoring of structures, with unit tests. This matches the doc I sent out earlier.
Firmware-side code for LoadKernel() is in place now. LoadFirmware() replacement coming soon. The new functions are implemented in parallel to the existing ones (i.e., everything that used to work still does). Review URL: http://codereview.chromium.org/2745007
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile17
-rwxr-xr-xtests/run_image_verification_tests.sh1
-rwxr-xr-xtests/run_vboot_common_tests.sh91
-rw-r--r--tests/vboot_common2_tests.c210
-rw-r--r--tests/vboot_common3_tests.c295
-rw-r--r--tests/vboot_common_tests.c101
6 files changed, 714 insertions, 1 deletions
diff --git a/tests/Makefile b/tests/Makefile
index 05577335..15799fb2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -6,8 +6,10 @@ TOP ?= ../
CC ?= gcc
CFLAGS ?= -Wall -DNDEBUG -O3 -Werror
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../vfirmware/include\
@@ -15,7 +17,7 @@ INCLUDES += -I./include \
IMAGE_LIBS = $(TOP)/vfirmware/firmware_image.o \
$(TOP)/vkernel/kernel_image.o
UTIL_LIBS = $(TOP)/misclibs/file_keys.o $(TOP)/misclibs/signature_digest.o
-LIBS = $(IMAGE_LIBS) $(UTIL_LIBS) $(FWLIB) -lcrypto
+LIBS = $(IMAGE_LIBS) $(UTIL_LIBS) $(HOSTLIB) $(FWLIB) -lcrypto
TEST_BINS = big_firmware_tests \
big_kernel_tests \
@@ -32,6 +34,9 @@ TEST_BINS = big_firmware_tests \
rsa_verify_benchmark \
sha_benchmark \
sha_tests \
+ vboot_common_tests \
+ vboot_common2_tests \
+ vboot_common3_tests \
verify_firmware_fuzz_driver \
verify_kernel_fuzz_driver
@@ -90,6 +95,15 @@ sha_benchmark: sha_benchmark.c timer_utils.c
sha_tests: sha_tests.c
$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(FWLIB)
+vboot_common_tests: vboot_common_tests.c rollback_index_mock.c test_common.c
+ $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
+vboot_common2_tests: vboot_common2_tests.c test_common.c $(HOSTLIB) $(FWLIB)
+ $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
+vboot_common3_tests: vboot_common3_tests.c test_common.c $(HOSTLIB) $(FWLIB)
+ $(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
verify_firmware_fuzz_driver: verify_firmware_fuzz_driver.c \
rollback_index_mock.c
$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
@@ -101,6 +115,7 @@ runtests:
# Crypto tests
./run_rsa_tests.sh
./sha_tests
+ ./run_vboot_common_tests.sh
./run_image_verification_tests.sh
# Splicing tests
./firmware_splicing_tests
diff --git a/tests/run_image_verification_tests.sh b/tests/run_image_verification_tests.sh
index b634b71c..025066a4 100755
--- a/tests/run_image_verification_tests.sh
+++ b/tests/run_image_verification_tests.sh
@@ -69,6 +69,7 @@ ${kernel_hashalgo}${COL_STOP}"
}
check_test_keys
+
echo
echo "Testing high-level firmware image verification..."
test_firmware_verification
diff --git a/tests/run_vboot_common_tests.sh b/tests/run_vboot_common_tests.sh
new file mode 100755
index 00000000..6295f404
--- /dev/null
+++ b/tests/run_vboot_common_tests.sh
@@ -0,0 +1,91 @@
+#!/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.
+
+# Run verified boot firmware and kernel verification tests.
+
+# Load common constants and variables.
+. "$(dirname "$0")/common.sh"
+
+return_code=0
+
+function test_vboot_common {
+ ${TEST_DIR}/vboot_common_tests
+ if [ $? -ne 0 ]
+ then
+ return_code=255
+ fi
+}
+
+function test_vboot_common2 {
+ algorithmcounter=0
+ for keylen in ${key_lengths[@]}
+ do
+ for hashalgo in ${hash_algos[@]}
+ do
+ echo -e "For signing key ${COL_YELLOW}RSA-$keylen/$hashalgo${COL_STOP}:"
+ ${TEST_DIR}/vboot_common2_tests $algorithmcounter \
+ ${TESTKEY_DIR}/key_rsa${keylen}.pem \
+ ${TESTKEY_DIR}/key_rsa${keylen}.keyb
+ if [ $? -ne 0 ]
+ then
+ return_code=255
+ fi
+ let algorithmcounter=algorithmcounter+1
+ done
+ done
+}
+
+function test_vboot_common3 {
+# Test for various combinations of firmware signing algorithm and
+# kernel signing algorithm
+ firmware_algorithmcounter=0
+ kernel_algorithmcounter=0
+ for firmware_keylen in ${key_lengths[@]}
+ do
+ for firmware_hashalgo in ${hash_algos[@]}
+ do
+ let kernel_algorithmcounter=0
+ for kernel_keylen in ${key_lengths[@]}
+ do
+ for kernel_hashalgo in ${hash_algos[@]}
+ do
+ echo -e "For ${COL_YELLOW}signing algorithm \
+RSA-${firmware_keylen}/${firmware_hashalgo}${COL_STOP} \
+and ${COL_YELLOW}data signing algorithm RSA-${kernel_keylen}/\
+${kernel_hashalgo}${COL_STOP}"
+ ${TEST_DIR}/vboot_common3_tests \
+ $firmware_algorithmcounter $kernel_algorithmcounter \
+ ${TESTKEY_DIR}/key_rsa${firmware_keylen}.pem \
+ ${TESTKEY_DIR}/key_rsa${firmware_keylen}.keyb \
+ ${TESTKEY_DIR}/key_rsa${kernel_keylen}.pem \
+ ${TESTKEY_DIR}/key_rsa${kernel_keylen}.keyb
+ if [ $? -ne 0 ]
+ then
+ return_code=255
+ fi
+ let kernel_algorithmcounter=kernel_algorithmcounter+1
+ done
+ done
+ let firmware_algorithmcounter=firmware_algorithmcounter+1
+ done
+ done
+}
+
+check_test_keys
+echo
+echo "Testing vboot_common tests which don't depend on keys..."
+test_vboot_common
+
+echo
+echo "Testing vboot_common tests which depend on one key..."
+test_vboot_common2
+
+echo
+echo "Testing vboot_common tests which depend on two keys..."
+test_vboot_common3
+
+
+exit $return_code
diff --git a/tests/vboot_common2_tests.c b/tests/vboot_common2_tests.c
new file mode 100644
index 00000000..361de83e
--- /dev/null
+++ b/tests/vboot_common2_tests.c
@@ -0,0 +1,210 @@
+/* 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 for firmware image library.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cryptolib.h"
+#include "file_keys.h"
+#include "firmware_image.h"
+#include "host_common.h"
+#include "test_common.h"
+#include "utility.h"
+#include "vboot_common.h"
+
+
+static void VerifyPublicKeyToRSA(const VbPublicKey* orig_key) {
+
+ RSAPublicKey *rsa;
+ VbPublicKey *key = PublicKeyAlloc(orig_key->key_size, 0, 0);
+
+ PublicKeyCopy(key, orig_key);
+ key->algorithm = kNumAlgorithms;
+ TEST_EQ((size_t)PublicKeyToRSA(key), 0,
+ "PublicKeyToRSA() invalid algorithm");
+
+ PublicKeyCopy(key, orig_key);
+ key->key_size -= 1;
+ TEST_EQ((size_t)PublicKeyToRSA(key), 0,
+ "PublicKeyToRSA() invalid size");
+
+ rsa = PublicKeyToRSA(orig_key);
+ TEST_NEQ((size_t)rsa, 0, "PublicKeyToRSA() ok");
+ if (rsa) {
+ TEST_EQ(rsa->algorithm, key->algorithm, "PublicKeyToRSA() algorithm");
+ RSAPublicKeyFree(rsa);
+ }
+}
+
+
+static void VerifyDataTest(const VbPublicKey* public_key,
+ const VbPrivateKey* private_key) {
+
+ const uint8_t test_data[] = "This is some test data to sign.";
+ VbSignature *sig;
+ RSAPublicKey *rsa;
+
+ sig = CalculateSignature(test_data, sizeof(test_data), private_key);
+ rsa = PublicKeyToRSA(public_key);
+ TEST_NEQ(sig && rsa, 0, "VerifyData() prerequisites");
+ if (!sig || !rsa)
+ return;
+
+ TEST_EQ(VerifyData(test_data, sig, rsa), 0, "VerifyData() ok");
+
+ sig->sig_size -= 16;
+ TEST_EQ(VerifyData(test_data, sig, rsa), 1, "VerifyData() wrong sig size");
+ sig->sig_size += 16;
+
+ GetSignatureData(sig)[0] ^= 0x5A;
+ TEST_EQ(VerifyData(test_data, sig, rsa), 1, "VerifyData() wrong sig");
+
+ RSAPublicKeyFree(rsa);
+ Free(sig);
+}
+
+
+static void ReSignKernelPreamble(VbKernelPreambleHeader *h,
+ const VbPrivateKey *key) {
+ VbSignature *sig = CalculateSignature((const uint8_t*)h,
+ h->preamble_signature.data_size, key);
+
+ SignatureCopy(&h->preamble_signature, sig);
+ Free(sig);
+}
+
+
+static void VerifyKernelPreambleTest(const VbPublicKey* public_key,
+ const VbPrivateKey* private_key) {
+
+ VbKernelPreambleHeader *hdr;
+ VbKernelPreambleHeader *h;
+ RSAPublicKey* rsa;
+ uint64_t hsize;
+
+ /* Create a dummy signature */
+ VbSignature *body_sig = SignatureAlloc(56, 78);
+
+ rsa = PublicKeyToRSA(public_key);
+ hdr = CreateKernelPreamble(0x1234, 0x100000, 0x300000, 0x4000, body_sig,
+ private_key);
+ TEST_NEQ(hdr && rsa, 0, "VerifyKernelPreamble2() prerequisites");
+ if (!hdr)
+ return;
+ hsize = hdr->preamble_size;
+ h = (VbKernelPreambleHeader*)Malloc(hsize + 16384);
+
+ TEST_EQ(VerifyKernelPreamble2(hdr, hsize, rsa), 0,
+ "VerifyKernelPreamble2() ok using key");
+ TEST_NEQ(VerifyKernelPreamble2(hdr, hsize-1, rsa), 0,
+ "VerifyKernelPreamble2() size");
+
+ /* Care about major version but not minor */
+ Memcpy(h, hdr, hsize);
+ h->header_version_major++;
+ ReSignKernelPreamble(h, private_key);
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() major++");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_major--;
+ ReSignKernelPreamble(h, private_key);
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() major--");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_minor++;
+ ReSignKernelPreamble(h, private_key);
+ TEST_EQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() minor++");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_minor--;
+ ReSignKernelPreamble(h, private_key);
+ TEST_EQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() minor--");
+
+ /* Check signature */
+ Memcpy(h, hdr, hsize);
+ h->preamble_signature.sig_offset = hsize;
+ ReSignKernelPreamble(h, private_key);
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() sig off end");
+
+ Memcpy(h, hdr, hsize);
+ h->preamble_signature.sig_size--;
+ ReSignKernelPreamble(h, private_key);
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() sig too small");
+
+ Memcpy(h, hdr, hsize);
+ GetSignatureData(&h->body_signature)[0] ^= 0x34;
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() sig mismatch");
+
+ /* Check that we signed header and body sig */
+ Memcpy(h, hdr, hsize);
+ h->preamble_signature.data_size = 4;
+ h->body_signature.sig_offset = 0;
+ h->body_signature.sig_size = 0;
+ ReSignKernelPreamble(h, private_key);
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() didn't sign header");
+
+ Memcpy(h, hdr, hsize);
+ h->body_signature.sig_offset = hsize;
+ ReSignKernelPreamble(h, private_key);
+ TEST_NEQ(VerifyKernelPreamble2(h, hsize, rsa), 0,
+ "VerifyKernelPreamble2() body sig off end");
+
+ /* TODO: verify parser can support a bigger header. */
+
+ Free(h);
+ RSAPublicKeyFree(rsa);
+ Free(hdr);
+}
+
+
+int main(int argc, char* argv[]) {
+ VbPrivateKey* private_key = NULL;
+ VbPublicKey* public_key = NULL;
+ int key_algorithm;
+
+ int error_code = 0;
+
+ if(argc != 4) {
+ fprintf(stderr, "Usage: %s <key_algorithm> <key> <processed pubkey>"
+ " <signing key> <processed signing key>\n", argv[0]);
+ return -1;
+ }
+
+ /* Read verification keys and create a test image. */
+ key_algorithm = atoi(argv[1]);
+
+ private_key = PrivateKeyRead(argv[2], key_algorithm);
+ if (!private_key) {
+ fprintf(stderr, "Error reading private_key");
+ return 1;
+ }
+
+ public_key = PublicKeyRead(argv[3], key_algorithm, 1);
+ if (!public_key) {
+ fprintf(stderr, "Error reading public_key");
+ return 1;
+ }
+
+ VerifyPublicKeyToRSA(public_key);
+ VerifyDataTest(public_key, private_key);
+ VerifyKernelPreambleTest(public_key, private_key);
+
+ if (public_key)
+ Free(public_key);
+ if (private_key)
+ Free(private_key);
+
+ return error_code;
+}
diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c
new file mode 100644
index 00000000..a4e69fd1
--- /dev/null
+++ b/tests/vboot_common3_tests.c
@@ -0,0 +1,295 @@
+/* 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 for firmware image library.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cryptolib.h"
+#include "file_keys.h"
+#include "firmware_image.h"
+#include "host_common.h"
+#include "test_common.h"
+#include "utility.h"
+#include "vboot_common.h"
+
+
+static void ReChecksumKeyBlock(VbKeyBlockHeader *h) {
+ uint8_t* newchk = DigestBuf((const uint8_t*)h,
+ h->key_block_checksum.data_size,
+ SHA512_DIGEST_ALGORITHM);
+ Memcpy(GetSignatureData(&h->key_block_checksum), newchk, SHA512_DIGEST_SIZE);
+ Free(newchk);
+}
+
+
+static void VerifyKeyBlockTest(const VbPublicKey* public_key,
+ const VbPrivateKey* private_key,
+ const VbPublicKey* data_key) {
+
+ VbKeyBlockHeader *hdr;
+ VbKeyBlockHeader *h;
+ uint64_t hsize;
+
+ hdr = CreateKeyBlock(data_key, private_key, 0x1234);
+ TEST_NEQ((size_t)hdr, 0, "VerifyKeyBlock() prerequisites");
+ if (!hdr)
+ return;
+ hsize = hdr->key_block_size;
+ h = (VbKeyBlockHeader*)Malloc(hsize + 1024);
+
+ TEST_EQ(VerifyKeyBlock(hdr, hsize, NULL), 0,
+ "VerifyKeyBlock() ok using checksum");
+ TEST_EQ(VerifyKeyBlock(hdr, hsize, public_key), 0,
+ "VerifyKeyBlock() ok using key");
+
+ TEST_NEQ(VerifyKeyBlock(hdr, hsize-1, NULL), 0, "VerifyKeyBlock() size");
+
+ Memcpy(h, hdr, hsize);
+ h->magic[0] &= 0x12;
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() magic");
+
+ /* Care about major version but not minor */
+ Memcpy(h, hdr, hsize);
+ h->header_version_major++;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() major++");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_major--;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() major--");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_minor++;
+ ReChecksumKeyBlock(h);
+ TEST_EQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() minor++");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_minor--;
+ ReChecksumKeyBlock(h);
+ TEST_EQ(VerifyKeyBlock(h, hsize, NULL), 0, "VerifyKeyBlock() minor--");
+
+ /* Check hash */
+ Memcpy(h, hdr, hsize);
+ h->key_block_checksum.sig_offset = hsize;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0,
+ "VerifyKeyBlock() checksum off end");
+
+ Memcpy(h, hdr, hsize);
+ h->key_block_checksum.sig_size /= 2;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0,
+ "VerifyKeyBlock() checksum too small");
+
+ Memcpy(h, hdr, hsize);
+ GetPublicKeyData(&h->data_key)[0] ^= 0x34;
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0,
+ "VerifyKeyBlock() checksum mismatch");
+
+ /* Check signature */
+ Memcpy(h, hdr, hsize);
+ h->key_block_signature.sig_offset = hsize;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0,
+ "VerifyKeyBlock() sig off end");
+
+ Memcpy(h, hdr, hsize);
+ h->key_block_signature.sig_size--;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0,
+ "VerifyKeyBlock() sig too small");
+
+ Memcpy(h, hdr, hsize);
+ GetPublicKeyData(&h->data_key)[0] ^= 0x34;
+ TEST_NEQ(VerifyKeyBlock(h, hsize, public_key), 0,
+ "VerifyKeyBlock() sig mismatch");
+
+ /* Check that we signed header and data key */
+ Memcpy(h, hdr, hsize);
+ h->key_block_checksum.data_size = 4;
+ h->data_key.key_offset = 0;
+ h->data_key.key_size = 0;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0,
+ "VerifyKeyBlock() didn't sign header");
+
+ Memcpy(h, hdr, hsize);
+ h->data_key.key_offset = hsize;
+ ReChecksumKeyBlock(h);
+ TEST_NEQ(VerifyKeyBlock(h, hsize, NULL), 0,
+ "VerifyKeyBlock() data key off end");
+
+ /* TODO: verify parser can support a bigger header (i.e., one where
+ * data_key.key_offset is bigger than expected). */
+
+ Free(h);
+ Free(hdr);
+}
+
+
+static void ReSignFirmwarePreamble(VbFirmwarePreambleHeader *h,
+ const VbPrivateKey *key) {
+ VbSignature *sig = CalculateSignature((const uint8_t*)h,
+ h->preamble_signature.data_size, key);
+
+ SignatureCopy(&h->preamble_signature, sig);
+ Free(sig);
+}
+
+
+static void VerifyFirmwarePreambleTest(const VbPublicKey* public_key,
+ const VbPrivateKey* private_key,
+ const VbPublicKey* kernel_subkey) {
+
+ VbFirmwarePreambleHeader *hdr;
+ VbFirmwarePreambleHeader *h;
+ RSAPublicKey* rsa;
+ uint64_t hsize;
+
+ /* Create a dummy signature */
+ VbSignature *body_sig = SignatureAlloc(56, 78);
+
+ rsa = PublicKeyToRSA(public_key);
+ hdr = CreateFirmwarePreamble(0x1234, kernel_subkey, body_sig, private_key);
+ TEST_NEQ(hdr && rsa, 0, "VerifyFirmwarePreamble2() prerequisites");
+ if (!hdr)
+ return;
+ hsize = hdr->preamble_size;
+ h = (VbFirmwarePreambleHeader*)Malloc(hsize + 16384);
+
+ TEST_EQ(VerifyFirmwarePreamble2(hdr, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() ok using key");
+ TEST_NEQ(VerifyFirmwarePreamble2(hdr, hsize-1, rsa), 0,
+ "VerifyFirmwarePreamble2() size");
+
+ /* Care about major version but not minor */
+ Memcpy(h, hdr, hsize);
+ h->header_version_major++;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() major++");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_major--;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() major--");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_minor++;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_EQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() minor++");
+
+ Memcpy(h, hdr, hsize);
+ h->header_version_minor--;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_EQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() minor--");
+
+ /* Check signature */
+ Memcpy(h, hdr, hsize);
+ h->preamble_signature.sig_offset = hsize;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() sig off end");
+
+ Memcpy(h, hdr, hsize);
+ h->preamble_signature.sig_size--;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() sig too small");
+
+ Memcpy(h, hdr, hsize);
+ GetPublicKeyData(&h->kernel_subkey)[0] ^= 0x34;
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() sig mismatch");
+
+ /* Check that we signed header, kernel subkey, and body sig */
+ Memcpy(h, hdr, hsize);
+ h->preamble_signature.data_size = 4;
+ h->kernel_subkey.key_offset = 0;
+ h->kernel_subkey.key_size = 0;
+ h->body_signature.sig_offset = 0;
+ h->body_signature.sig_size = 0;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() didn't sign header");
+
+ Memcpy(h, hdr, hsize);
+ h->kernel_subkey.key_offset = hsize;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() kernel subkey off end");
+
+ Memcpy(h, hdr, hsize);
+ h->body_signature.sig_offset = hsize;
+ ReSignFirmwarePreamble(h, private_key);
+ TEST_NEQ(VerifyFirmwarePreamble2(h, hsize, rsa), 0,
+ "VerifyFirmwarePreamble2() body sig off end");
+
+ /* TODO: verify parser can support a bigger header. */
+
+ Free(h);
+ RSAPublicKeyFree(rsa);
+ Free(hdr);
+}
+
+
+int main(int argc, char* argv[]) {
+ VbPrivateKey* signing_private_key = NULL;
+ VbPublicKey* signing_public_key = NULL;
+ int signing_key_algorithm;
+
+ VbPublicKey* data_public_key = NULL;
+ int data_key_algorithm;
+
+ int error_code = 0;
+
+ if(argc != 7) {
+ fprintf(stderr, "Usage: %s <signing_key_algorithm> <data_key_algorithm>"
+ " <signing key> <processed signing pubkey>"
+ " <data key> <processed data pubkey>\n", argv[0]);
+ return -1;
+ }
+
+ /* Read verification keys and create a test image. */
+ signing_key_algorithm = atoi(argv[1]);
+ data_key_algorithm = atoi(argv[2]);
+
+ signing_private_key = PrivateKeyRead(argv[3], signing_key_algorithm);
+ if (!signing_private_key) {
+ fprintf(stderr, "Error reading signing_private_key");
+ return 1;
+ }
+
+ signing_public_key = PublicKeyRead(argv[4], signing_key_algorithm, 1);
+ if (!signing_public_key) {
+ fprintf(stderr, "Error reading signing_public_key");
+ return 1;
+ }
+
+ data_public_key = PublicKeyRead(argv[6], data_key_algorithm, 1);
+ if (!data_public_key) {
+ fprintf(stderr, "Error reading data_public_key");
+ return 1;
+ }
+
+ VerifyKeyBlockTest(signing_public_key, signing_private_key, data_public_key);
+ VerifyFirmwarePreambleTest(signing_public_key, signing_private_key,
+ data_public_key);
+
+ if (signing_public_key)
+ Free(signing_public_key);
+ if (signing_private_key)
+ Free(signing_private_key);
+ if (data_public_key)
+ Free(data_public_key);
+
+ return error_code;
+}
diff --git a/tests/vboot_common_tests.c b/tests/vboot_common_tests.c
new file mode 100644
index 00000000..e467471e
--- /dev/null
+++ b/tests/vboot_common_tests.c
@@ -0,0 +1,101 @@
+/* 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 for firmware image library.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "test_common.h"
+#include "vboot_common.h"
+
+
+/* Helper functions not dependent on specific key sizes */
+void VerifyHelperFunctions(void) {
+
+ {
+ uint8_t p[1];
+ TEST_EQ(OffsetOf(p, p), 0, "OffsetOf() equal");
+ TEST_EQ(OffsetOf(p, p+10), 10, "OffsetOf() positive");
+ TEST_EQ(OffsetOf(p, p+0x12345678), 0x12345678, "OffsetOf() large");
+ }
+
+ {
+ VbPublicKey k = {sizeof(k), 2, 3, 4};
+ TEST_EQ(OffsetOf(&k, GetPublicKeyData(&k)), sizeof(k),
+ "GetPublicKeyData() adjacent");
+ TEST_EQ(OffsetOf(&k, GetPublicKeyDataC(&k)), sizeof(k),
+ "GetPublicKeyDataC() adjacent");
+ }
+
+ {
+ VbPublicKey k = {123, 2, 3, 4};
+ TEST_EQ(OffsetOf(&k, GetPublicKeyData(&k)), 123,
+ "GetPublicKeyData() spaced");
+ TEST_EQ(OffsetOf(&k, GetPublicKeyDataC(&k)), 123,
+ "GetPublicKeyDataC() spaced");
+ }
+
+ {
+ uint8_t p[1];
+ TEST_EQ(VerifyMemberInside(p, 20, p, 6, 11, 3), 0, "MemberInside ok 1");
+ TEST_EQ(VerifyMemberInside(p, 20, p+4, 4, 8, 4), 0, "MemberInside ok 2");
+ TEST_EQ(VerifyMemberInside(p, 20, p-4, 4, 8, 4), 1,
+ "MemberInside member before parent");
+ TEST_EQ(VerifyMemberInside(p, 20, p+20, 4, 8, 4), 1,
+ "MemberInside member after parent");
+ TEST_EQ(VerifyMemberInside(p, 20, p, 21, 0, 0), 1,
+ "MemberInside member too big");
+ TEST_EQ(VerifyMemberInside(p, 20, p, 4, 21, 0), 1,
+ "MemberInside data after parent");
+ TEST_EQ(VerifyMemberInside(p, 20, p, 4, -1, 0), 1,
+ "MemberInside data before parent");
+ TEST_EQ(VerifyMemberInside(p, 20, p, 4, 4, 17), 1,
+ "MemberInside data too big");
+ }
+
+ {
+ VbPublicKey k = {sizeof(k), 128, 0, 0};
+ TEST_EQ(VerifyPublicKeyInside(&k, sizeof(k)+128, &k), 0,
+ "PublicKeyInside ok 1");
+ TEST_EQ(VerifyPublicKeyInside(&k - 1, 2*sizeof(k)+128, &k), 0,
+ "PublicKeyInside ok 2");
+ TEST_EQ(VerifyPublicKeyInside(&k, 128, &k), 1,
+ "PublicKeyInside key too big");
+ }
+ {
+ VbPublicKey k = {100, 4, 0, 0};
+ TEST_EQ(VerifyPublicKeyInside(&k, 99, &k), 1,
+ "PublicKeyInside offset too big");
+ }
+ {
+ VbSignature s = {sizeof(s), 128, 2000};
+ TEST_EQ(VerifySignatureInside(&s, sizeof(s)+128, &s), 0,
+ "SignatureInside ok 1");
+ TEST_EQ(VerifySignatureInside(&s - 1, 2*sizeof(s)+128, &s), 0,
+ "SignatureInside ok 2");
+ TEST_EQ(VerifySignatureInside(&s, 128, &s), 1,
+ "SignatureInside sig too big");
+ }
+ {
+ VbSignature s = {100, 4, 0};
+ TEST_EQ(VerifySignatureInside(&s, 99, &s), 1,
+ "SignatureInside offset too big");
+ }
+
+}
+
+
+int main(int argc, char* argv[]) {
+ int error_code = 0;
+
+ /* Test helper functions */
+ VerifyHelperFunctions();
+
+ if (!gTestSuccess)
+ error_code = 255;
+
+ return error_code;
+}