summaryrefslogtreecommitdiff
path: root/tests/vboot_common2_tests.c
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/vboot_common2_tests.c
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/vboot_common2_tests.c')
-rw-r--r--tests/vboot_common2_tests.c210
1 files changed, 210 insertions, 0 deletions
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;
+}