| 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;
|
| +}
|
|
|