Index: tests/vboot_common2_tests.c |
diff --git a/tests/vboot_common2_tests.c b/tests/vboot_common2_tests.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..361de83e93a1a35b080b2f3130f521ad74bf495d |
--- /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; |
+} |