diff options
Diffstat (limited to 'tests/vboot_common2_tests.c')
-rw-r--r-- | tests/vboot_common2_tests.c | 210 |
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; +} |