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