1e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * Use of this source code is governed by a BSD-style license that can be 3d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * found in the LICENSE file. 4d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * 5d183644564ec27c106a3eb1931f565fae167a058Randall Spangler * Tests for firmware image library. 6d183644564ec27c106a3eb1931f565fae167a058Randall Spangler */ 7d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 80c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include <stdint.h> 9d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <stdio.h> 10d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include <stdlib.h> 11e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler#include <string.h> 12d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 13d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "cryptolib.h" 14d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "file_keys.h" 15d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "host_common.h" 16d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "test_common.h" 17d183644564ec27c106a3eb1931f565fae167a058Randall Spangler#include "vboot_common.h" 18d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 19d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 2068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spanglerstatic void ReChecksumKeyBlock(VbKeyBlockHeader *h) 2168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler{ 2268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler uint8_t *newchk = DigestBuf((const uint8_t *)h, 2368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_checksum.data_size, 2468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler SHA512_DIGEST_ALGORITHM); 2568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(GetSignatureData(&h->key_block_checksum), newchk, 2668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler SHA512_DIGEST_SIZE); 272500185a83b453580f187087fffc6376f19f8ff0Simon Glass VbExFree(newchk); 28d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 29d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 3068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spanglerstatic void KeyBlockVerifyTest(const VbPublicKey *public_key, 3168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler const VbPrivateKey *private_key, 3268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler const VbPublicKey *data_key) 3368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler{ 3468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbKeyBlockHeader *hdr; 3568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbKeyBlockHeader *h; 3668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler unsigned hsize; 3768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 3868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler hdr = KeyBlockCreate(data_key, private_key, 0x1234); 3968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ((size_t)hdr, 0, "KeyBlockVerify() prerequisites"); 4068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler if (!hdr) 4168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler return; 4268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler hsize = (unsigned) hdr->key_block_size; 4368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h = (VbKeyBlockHeader *)malloc(hsize + 1024); 4468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 4568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(KeyBlockVerify(hdr, hsize, NULL, 1), 0, 4668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() ok using checksum"); 4768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(KeyBlockVerify(hdr, hsize, public_key, 0), 0, 4868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() ok using key"); 4968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(hdr, hsize, NULL, 0), 0, 5068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() missing key"); 5168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 5268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(hdr, hsize - 1, NULL, 1), 0, 5368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() size--"); 5468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(KeyBlockVerify(hdr, hsize + 1, NULL, 1), 0, 5568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() size++"); 5668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 5768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 5868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->magic[0] &= 0x12; 5968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 6068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() magic"); 6168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 6268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Care about major version but not minor */ 6368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 6468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_major++; 6568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 6668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 6768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() major++"); 6868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 6968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 7068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_major--; 7168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 7268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 7368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() major--"); 7468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 7568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 7668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_minor++; 7768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 7868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 7968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() minor++"); 8068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 8168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 8268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_minor--; 8368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 8468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 8568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() minor--"); 8668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 8768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Check hash */ 8868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 8968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_checksum.sig_offset = hsize; 9068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 9168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 9268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() checksum off end"); 9368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 9468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 9568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_checksum.sig_size /= 2; 9668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 9768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 9868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() checksum too small"); 9968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 10068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 10168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler GetPublicKeyData(&h->data_key)[0] ^= 0x34; 10268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 10368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() checksum mismatch"); 10468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 10568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Check signature */ 10668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 10768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_signature.sig_offset = hsize; 10868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 10968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0, 11068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() sig off end"); 11168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 11268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 11368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_signature.sig_size--; 11468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 11568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0, 11668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() sig too small"); 11768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 11868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 11968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler GetPublicKeyData(&h->data_key)[0] ^= 0x34; 12068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0, 12168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() sig mismatch"); 12268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 12368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 12468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_checksum.data_size = h->key_block_size + 1; 12568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 1), 0, 12668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() checksum data past end of block"); 12768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 12868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Check that we signed header and data key */ 12968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 13068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->key_block_checksum.data_size = 4; 13168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->data_key.key_offset = 0; 13268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->data_key.key_size = 0; 13368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 13468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 13568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() didn't sign header"); 13668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 13768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 13868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->data_key.key_offset = hsize; 13968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReChecksumKeyBlock(h); 14068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0, 14168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify() data key off end"); 14268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 14368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Corner cases for error checking */ 14468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(KeyBlockVerify(NULL, 4, NULL, 1), 0, 14568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "KeyBlockVerify size too small"); 14668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 14768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* 14868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler * TODO: verify parser can support a bigger header (i.e., one where 14968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler * data_key.key_offset is bigger than expected). 15068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler */ 15168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 15268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler free(h); 15368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler free(hdr); 154d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 155d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 15668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spanglerstatic void ReSignFirmwarePreamble(VbFirmwarePreambleHeader *h, 15768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler const VbPrivateKey *key) 15868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler{ 15968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbSignature *sig = CalculateSignature( 16068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler (const uint8_t *)h, h->preamble_signature.data_size, key); 161d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 16268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler SignatureCopy(&h->preamble_signature, sig); 16368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler free(sig); 164d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 165d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 16668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spanglerstatic void VerifyFirmwarePreambleTest(const VbPublicKey *public_key, 16768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler const VbPrivateKey *private_key, 16868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler const VbPublicKey *kernel_subkey) 16968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler{ 17068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbFirmwarePreambleHeader *hdr; 17168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbFirmwarePreambleHeader *h; 17268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler RSAPublicKey *rsa; 17368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler unsigned hsize; 17468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 17568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Create a dummy signature */ 17668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbSignature* body_sig = SignatureAlloc(56, 78); 17768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 17868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler rsa = PublicKeyToRSA(public_key); 17968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler hdr = CreateFirmwarePreamble(0x1234, kernel_subkey, body_sig, 18068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler private_key, 0x5678); 18168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(hdr && rsa, 0, "VerifyFirmwarePreamble() prerequisites"); 18268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler if (!hdr) 18368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler return; 18468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler hsize = (unsigned) hdr->preamble_size; 18568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h = (VbFirmwarePreambleHeader *)malloc(hsize + 16384); 18668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 18768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(VerifyFirmwarePreamble(hdr, hsize, rsa), 0, 18868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() ok using key"); 18968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(hdr, 4, rsa), 0, 19068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() size tiny"); 19168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(hdr, hsize - 1, rsa), 0, 19268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() size--"); 19368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(VerifyFirmwarePreamble(hdr, hsize + 1, rsa), 0, 19468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() size++"); 19568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 19668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Care about major version but not minor */ 19768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 19868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_major++; 19968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 20068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 20168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() major++"); 20268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 20368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 20468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_major--; 20568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 20668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 20768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() major--"); 20868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 20968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 21068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_minor++; 21168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 21268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 21368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() minor++"); 21468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 21568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 21668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_minor--; 21768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 21868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 21968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() minor--"); 22068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 22168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Check signature */ 22268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 22368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->preamble_signature.sig_offset = hsize; 22468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 22568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 22668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() sig off end"); 22768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 22868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 22968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->preamble_signature.sig_size--; 23068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 23168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 23268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() sig too small"); 23368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 23468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 23568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler GetPublicKeyData(&h->kernel_subkey)[0] ^= 0x34; 23668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 23768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() sig mismatch"); 23868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 23968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Check that we signed header, kernel subkey, and body sig */ 24068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 24168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->preamble_signature.data_size = 4; 24268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->kernel_subkey.key_offset = 0; 24368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->kernel_subkey.key_size = 0; 24468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->body_signature.sig_offset = 0; 24568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->body_signature.sig_size = 0; 24668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 24768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 24868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() didn't sign header"); 24968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 25068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 25168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->kernel_subkey.key_offset = hsize; 25268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 25368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 25468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() kernel subkey off end"); 25568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 25668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 25768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->body_signature.sig_offset = hsize; 25868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler ReSignFirmwarePreamble(h, private_key); 25968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, 26068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VerifyFirmwarePreamble() body sig off end"); 26168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 26268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* Check that we return flags properly for new and old structs */ 26368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler Memcpy(h, hdr, hsize); 26468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(VbGetFirmwarePreambleFlags(h), 0x5678, 26568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VbGetFirmwarePreambleFlags() v2.1"); 26668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler h->header_version_minor = 0; 26768f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler TEST_EQ(VbGetFirmwarePreambleFlags(h), 0, 26868f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler "VbGetFirmwarePreambleFlags() v2.0"); 26968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 27068f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler /* TODO: verify with extra padding at end of header. */ 27168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler 27268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler free(h); 27368f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler RSAPublicKeyFree(rsa); 27468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler free(hdr); 275d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 276d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 277e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spanglerint test_permutation(int signing_key_algorithm, int data_key_algorithm, 278e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler const char *keys_dir) 279e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler{ 280e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler char filename[1024]; 28168f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler int signing_rsa_len = siglen_map[signing_key_algorithm] * 8; 28268f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler int data_rsa_len = siglen_map[data_key_algorithm] * 8; 283e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 28468f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbPrivateKey *signing_private_key = NULL; 28568f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbPublicKey *signing_public_key = NULL; 28668f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spangler VbPublicKey *data_public_key = NULL; 287e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 288e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler printf("***Testing signing algorithm: %s\n", 289e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler algo_strings[signing_key_algorithm]); 290e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler printf("***With data key algorithm: %s\n", 291e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler algo_strings[data_key_algorithm]); 292e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 293e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler sprintf(filename, "%s/key_rsa%d.pem", keys_dir, signing_rsa_len); 294e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler signing_private_key = PrivateKeyReadPem(filename, 295e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler signing_key_algorithm); 296e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (!signing_private_key) { 297e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler fprintf(stderr, "Error reading signing_private_key: %s\n", 298e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler filename); 299e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return 1; 300e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 301e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 302e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len); 303e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler signing_public_key = PublicKeyReadKeyb(filename, 304e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler signing_key_algorithm, 1); 305e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (!signing_public_key) { 306e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler fprintf(stderr, "Error reading signing_public_key: %s\n", 307e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler filename); 308e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return 1; 309e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 310e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 311e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len); 312e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler data_public_key = PublicKeyReadKeyb(filename, 313e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler data_key_algorithm, 1); 314e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (!data_public_key) { 315e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler fprintf(stderr, "Error reading data_public_key: %s\n", 316e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler filename); 317e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return 1; 318e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 319e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 320e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler KeyBlockVerifyTest(signing_public_key, signing_private_key, 321e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler data_public_key); 322e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler VerifyFirmwarePreambleTest(signing_public_key, signing_private_key, 323e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler data_public_key); 324e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 325e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (signing_public_key) 326e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler free(signing_public_key); 327e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (signing_private_key) 328e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler free(signing_private_key); 329e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (data_public_key) 330e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler free(data_public_key); 331e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 332e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return 0; 333e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler} 334d183644564ec27c106a3eb1931f565fae167a058Randall Spangler 335e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spanglerstruct test_perm 336e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler{ 337e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler int signing_algorithm; 338e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler int data_key_algorithm; 339e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler}; 340e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 341e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler/* 342e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler * Permutations of signing and data key algorithms in active use: 343e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler * 7 (rsa4096 sha256) - 4 (rsa2048 sha256) 344e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler * 11 (rsa8192 sha512) - 4 (rsa2048 sha256) 345e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler * 11 (rsa8192 sha512) - 7 (rsa4096 sha256) 346e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler */ 347e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spanglerconst struct test_perm test_perms[] = {{7, 4}, {11, 4}, {11, 7}}; 348e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 34968f54d44756e8f0a777808b710a4ccc5d2ce353dRandall Spanglerint main(int argc, char *argv[]) 350e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler{ 351e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (argc == 2) { 352e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler /* Test only the algorithms we use */ 353e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler int i; 354e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 355e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler for (i = 0; i < ARRAY_SIZE(test_perms); i++) { 356e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (test_permutation(test_perms[i].signing_algorithm, 357e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler test_perms[i].data_key_algorithm, 358e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler argv[1])) 359e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return 1; 360e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 361e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 362e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } else if (argc == 3 && !strcasecmp(argv[2], "--all")) { 363e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler /* Test all the algorithms */ 364e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler int sign_alg, data_alg; 365e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 366e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler for (sign_alg = 0; sign_alg < kNumAlgorithms; sign_alg++) { 367e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler for (data_alg = 0; data_alg < kNumAlgorithms; 368e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler data_alg++) { 369e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler if (test_permutation(sign_alg, data_alg, 370e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler argv[1])) 371e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return 1; 372e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 373e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 374e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } else { 375e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]); 376e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return -1; 377e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler } 378e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler 3792500185a83b453580f187087fffc6376f19f8ff0Simon Glass if (vboot_api_stub_check_memory()) 3802500185a83b453580f187087fffc6376f19f8ff0Simon Glass return 255; 3812500185a83b453580f187087fffc6376f19f8ff0Simon Glass 382e061a256549607a56d771eb8ddae5d0dd90d519cRandall Spangler return gTestSuccess ? 0 : 255; 383d183644564ec27c106a3eb1931f565fae167a058Randall Spangler} 384