diff options
Diffstat (limited to 'tests/vboot_ec_tests.c')
-rw-r--r-- | tests/vboot_ec_tests.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tests/vboot_ec_tests.c b/tests/vboot_ec_tests.c new file mode 100644 index 00000000..831565fc --- /dev/null +++ b/tests/vboot_ec_tests.c @@ -0,0 +1,160 @@ +/* Copyright (c) 2011 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 EC firmware vboot stuff. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "cryptolib.h" +#include "file_keys.h" +#include "host_common.h" +#include "test_common.h" +#include "vboot_common.h" + +static void ReSignECPreamble(VbECPreambleHeader* 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 VerifyECPreambleTest(const VbPublicKey* public_key, + const VbPrivateKey* private_key) { + VbECPreambleHeader* hdr; + VbECPreambleHeader* h; + RSAPublicKey* rsa; + unsigned hsize; + + /* Create a dummy signature */ + VbSignature* body_sig = SignatureAlloc(56, 78); + + rsa = PublicKeyToRSA(public_key); + hdr = CreateECPreamble(0x1234, body_sig, private_key, + 0x5678, "Foo bar"); + TEST_NEQ(hdr && rsa, 0, "VerifyECPreamble() prerequisites"); + if (!hdr) + return; + + hsize = (unsigned) hdr->preamble_size; + h = (VbECPreambleHeader*)malloc(hsize + 16384); + + TEST_EQ(VerifyECPreamble(hdr, hsize, rsa), 0, + "VerifyECPreamble() ok using key"); + TEST_NEQ(VerifyECPreamble(hdr, hsize - 1, rsa), 0, + "VerifyECPreamble() size--"); + TEST_EQ(VerifyECPreamble(hdr, hsize + 1, rsa), 0, + "VerifyECPreamble() size++"); + + TEST_EQ(hdr->firmware_version, 0x1234, + "VerifyECPreamble() firmware version"); + TEST_EQ(hdr->flags, 0x5678, + "VerifyECPreamble() flags"); + TEST_EQ(strncmp(hdr->name, "Foo bar", sizeof(hdr->name)), 0, + "VerifyECPreamble() name"); + + /* Care about major version but not minor */ + Memcpy(h, hdr, hsize); + h->header_version_major++; + ReSignECPreamble(h, private_key); + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() major++"); + + Memcpy(h, hdr, hsize); + h->header_version_major--; + ReSignECPreamble(h, private_key); + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() major--"); + + Memcpy(h, hdr, hsize); + h->header_version_minor++; + ReSignECPreamble(h, private_key); + TEST_EQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() minor++"); + + Memcpy(h, hdr, hsize); + h->header_version_minor--; + ReSignECPreamble(h, private_key); + TEST_EQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() minor--"); + + /* Check signature */ + Memcpy(h, hdr, hsize); + h->preamble_signature.sig_offset = hsize; + ReSignECPreamble(h, private_key); + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() sig off end"); + + Memcpy(h, hdr, hsize); + h->preamble_signature.sig_size--; + ReSignECPreamble(h, private_key); + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() sig too small"); + + Memcpy(h, hdr, hsize); + GetSignatureData(&h->body_digest)[0] ^= 0x34; + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() sig mismatch"); + + /* Check that we signed header and body sig */ + Memcpy(h, hdr, hsize); + h->preamble_signature.data_size = 4; + h->body_digest.sig_offset = 0; + h->body_digest.sig_size = 0; + ReSignECPreamble(h, private_key); + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() didn't sign header"); + + Memcpy(h, hdr, hsize); + h->body_digest.sig_offset = hsize; + ReSignECPreamble(h, private_key); + TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, + "VerifyECPreamble() body sig off end"); + + /* TODO: verify with extra padding at end of header. */ + + free(h); + RSAPublicKeyFree(rsa); + free(hdr); +} + + +int main(int argc, char* argv[]) { + VbPrivateKey* signing_private_key = NULL; + VbPublicKey* signing_public_key = NULL; + + int error_code = 0; + + if(argc != 3) { + fprintf(stderr, "Usage: %s <signing privkey> <signing pubkey>", argv[0]); + return -1; + } + + signing_private_key = PrivateKeyRead(argv[1]); + if (!signing_private_key) { + fprintf(stderr, "Error reading signing_private_key\n"); + return 1; + } + + signing_public_key = PublicKeyRead(argv[2]); + if (!signing_public_key) { + fprintf(stderr, "Error reading signing_public_key\n"); + return 1; + } + + VerifyECPreambleTest(signing_public_key, signing_private_key); + + + if (signing_public_key) + free(signing_public_key); + if (signing_private_key) + free(signing_private_key); + + return error_code; +} |