blob: 40953117d6ee88a58b7479a47d93d3bd8bf4bf85 [file] [log] [blame]
Randall Spanglere061a252013-01-22 15:34:07 -08001/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Randall Spanglerd1836442010-06-10 09:59:04 -07002 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for firmware image library.
6 */
7
Bill Richardson0c3ba242013-03-29 11:09:30 -07008#include <stdint.h>
Randall Spanglerd1836442010-06-10 09:59:04 -07009#include <stdio.h>
10#include <stdlib.h>
Randall Spanglere061a252013-01-22 15:34:07 -080011#include <string.h>
Randall Spanglerd1836442010-06-10 09:59:04 -070012
13#include "cryptolib.h"
14#include "file_keys.h"
Randall Spanglerd1836442010-06-10 09:59:04 -070015#include "host_common.h"
16#include "test_common.h"
Randall Spanglerd1836442010-06-10 09:59:04 -070017#include "vboot_common.h"
18
Randall Spanglere061a252013-01-22 15:34:07 -080019static void VerifyPublicKeyToRSA(const VbPublicKey *orig_key)
20{
21 RSAPublicKey *rsa;
22 VbPublicKey *key = PublicKeyAlloc(orig_key->key_size, 0, 0);
Randall Spanglerd1836442010-06-10 09:59:04 -070023
Randall Spanglere061a252013-01-22 15:34:07 -080024 PublicKeyCopy(key, orig_key);
25 key->algorithm = kNumAlgorithms;
26 TEST_EQ((size_t)PublicKeyToRSA(key), 0,
27 "PublicKeyToRSA() invalid algorithm");
Randall Spanglerd1836442010-06-10 09:59:04 -070028
Randall Spanglere061a252013-01-22 15:34:07 -080029 PublicKeyCopy(key, orig_key);
30 key->key_size -= 1;
31 TEST_EQ((size_t)PublicKeyToRSA(key), 0,
32 "PublicKeyToRSA() invalid size");
Randall Spanglerd1836442010-06-10 09:59:04 -070033
Randall Spanglere061a252013-01-22 15:34:07 -080034 rsa = PublicKeyToRSA(orig_key);
35 TEST_NEQ((size_t)rsa, 0, "PublicKeyToRSA() ok");
36 if (rsa) {
37 TEST_EQ((int)rsa->algorithm, (int)key->algorithm,
38 "PublicKeyToRSA() algorithm");
39 RSAPublicKeyFree(rsa);
40 }
Randall Spanglerd1836442010-06-10 09:59:04 -070041}
42
Randall Spanglere061a252013-01-22 15:34:07 -080043static void VerifyDataTest(const VbPublicKey *public_key,
44 const VbPrivateKey *private_key)
45{
46 const uint8_t test_data[] = "This is some test data to sign.";
47 const uint64_t test_size = sizeof(test_data);
48 VbSignature *sig;
49 RSAPublicKey *rsa;
Randall Spanglerd1836442010-06-10 09:59:04 -070050
Randall Spanglere061a252013-01-22 15:34:07 -080051 sig = CalculateSignature(test_data, test_size, private_key);
52 TEST_PTR_NEQ(sig, 0, "VerifyData() calculate signature");
Randall Spanglerd1836442010-06-10 09:59:04 -070053
Randall Spanglere061a252013-01-22 15:34:07 -080054 rsa = PublicKeyToRSA(public_key);
55 TEST_PTR_NEQ(rsa, 0, "VerifyData() calculate rsa");
Randall Spanglerd1836442010-06-10 09:59:04 -070056
Randall Spanglere061a252013-01-22 15:34:07 -080057 if (!sig || !rsa)
58 return;
Randall Spanglerd1836442010-06-10 09:59:04 -070059
Randall Spanglere061a252013-01-22 15:34:07 -080060 TEST_EQ(VerifyData(test_data, test_size, sig, rsa), 0,
61 "VerifyData() ok");
Randall Spanglerd1836442010-06-10 09:59:04 -070062
Randall Spanglere061a252013-01-22 15:34:07 -080063 sig->sig_size -= 16;
64 TEST_EQ(VerifyData(test_data, test_size, sig, rsa), 1,
65 "VerifyData() wrong sig size");
66 sig->sig_size += 16;
Randall Spanglerd1836442010-06-10 09:59:04 -070067
Randall Spanglere061a252013-01-22 15:34:07 -080068 TEST_EQ(VerifyData(test_data, test_size - 1, sig, rsa), 1,
69 "VerifyData() input buffer too small");
Randall Spangler87c13d82010-07-19 10:35:40 -070070
Randall Spanglere061a252013-01-22 15:34:07 -080071 GetSignatureData(sig)[0] ^= 0x5A;
72 TEST_EQ(VerifyData(test_data, test_size, sig, rsa), 1,
73 "VerifyData() wrong sig");
Randall Spanglerd1836442010-06-10 09:59:04 -070074
Randall Spanglere061a252013-01-22 15:34:07 -080075 RSAPublicKeyFree(rsa);
76 free(sig);
Randall Spanglerd1836442010-06-10 09:59:04 -070077}
78
Randall Spanglere061a252013-01-22 15:34:07 -080079static void VerifyDigestTest(const VbPublicKey *public_key,
80 const VbPrivateKey *private_key)
81{
82 const uint8_t test_data[] = "This is some other test data to sign.";
83 VbSignature *sig;
84 RSAPublicKey *rsa;
85 uint8_t *digest;
Randall Spanglerd1836442010-06-10 09:59:04 -070086
Randall Spanglere061a252013-01-22 15:34:07 -080087 sig = CalculateSignature(test_data, sizeof(test_data), private_key);
88 rsa = PublicKeyToRSA(public_key);
89 digest = DigestBuf(test_data, sizeof(test_data),
90 (int)public_key->algorithm);
91 TEST_NEQ(sig && rsa && digest, 0, "VerifyData() prerequisites");
92 if (!sig || !rsa || !digest)
93 return;
Randall Spangler39ed88e2010-06-15 14:53:01 -070094
Randall Spanglere061a252013-01-22 15:34:07 -080095 TEST_EQ(VerifyDigest(digest, sig, rsa), 0, "VerifyDigest() ok");
Randall Spangler39ed88e2010-06-15 14:53:01 -070096
Randall Spanglere061a252013-01-22 15:34:07 -080097 GetSignatureData(sig)[0] ^= 0x5A;
98 TEST_EQ(VerifyDigest(digest, sig, rsa), 1, "VerifyDigest() wrong sig");
Randall Spangler39ed88e2010-06-15 14:53:01 -070099
Randall Spangler3b806ea2013-01-25 13:56:55 -0800100 sig->sig_size = 1;
101 TEST_EQ(VerifyDigest(digest, sig, rsa), 1, "VerifyDigest() sig size");
102
Randall Spanglere061a252013-01-22 15:34:07 -0800103 RSAPublicKeyFree(rsa);
104 free(sig);
Simon Glass25001852013-08-16 02:47:57 -0600105 VbExFree(digest);
Randall Spangler39ed88e2010-06-15 14:53:01 -0700106}
107
Randall Spanglerd1836442010-06-10 09:59:04 -0700108static void ReSignKernelPreamble(VbKernelPreambleHeader *h,
Randall Spanglere061a252013-01-22 15:34:07 -0800109 const VbPrivateKey *key)
110{
111 VbSignature *sig = CalculateSignature((const uint8_t *)h,
112 h->preamble_signature.data_size, key);
Randall Spanglerd1836442010-06-10 09:59:04 -0700113
Randall Spanglere061a252013-01-22 15:34:07 -0800114 SignatureCopy(&h->preamble_signature, sig);
115 free(sig);
Randall Spanglerd1836442010-06-10 09:59:04 -0700116}
117
Randall Spanglere061a252013-01-22 15:34:07 -0800118static void VerifyKernelPreambleTest(const VbPublicKey *public_key,
119 const VbPrivateKey *private_key)
120{
121 VbKernelPreambleHeader *hdr;
122 VbKernelPreambleHeader *h;
123 RSAPublicKey *rsa;
124 unsigned hsize;
Randall Spanglerd1836442010-06-10 09:59:04 -0700125
Randall Spanglere061a252013-01-22 15:34:07 -0800126 /* Create a dummy signature */
127 VbSignature *body_sig = SignatureAlloc(56, 78);
Randall Spanglerd1836442010-06-10 09:59:04 -0700128
Randall Spanglere061a252013-01-22 15:34:07 -0800129 rsa = PublicKeyToRSA(public_key);
130 hdr = CreateKernelPreamble(0x1234, 0x100000, 0x300000, 0x4000, body_sig,
Furquan Shaikh80e779d2015-02-03 15:34:29 -0800131 0, 0, 0, 0, private_key);
Randall Spanglere061a252013-01-22 15:34:07 -0800132 TEST_NEQ(hdr && rsa, 0, "VerifyKernelPreamble() prerequisites");
133 if (!hdr)
134 return;
135 hsize = (unsigned) hdr->preamble_size;
136 h = (VbKernelPreambleHeader *)malloc(hsize + 16384);
Randall Spanglerd1836442010-06-10 09:59:04 -0700137
Randall Spanglere061a252013-01-22 15:34:07 -0800138 TEST_EQ(VerifyKernelPreamble(hdr, hsize, rsa), 0,
139 "VerifyKernelPreamble() ok using key");
140 TEST_NEQ(VerifyKernelPreamble(hdr, hsize - 1, rsa), 0,
141 "VerifyKernelPreamble() size--");
Randall Spangler3b806ea2013-01-25 13:56:55 -0800142 TEST_NEQ(VerifyKernelPreamble(hdr, 4, rsa), 0,
143 "VerifyKernelPreamble() size tiny");
Randall Spanglere061a252013-01-22 15:34:07 -0800144 TEST_EQ(VerifyKernelPreamble(hdr, hsize + 1, rsa), 0,
145 "VerifyKernelPreamble() size++");
Randall Spanglerd1836442010-06-10 09:59:04 -0700146
Randall Spanglere061a252013-01-22 15:34:07 -0800147 /* Care about major version but not minor */
148 Memcpy(h, hdr, hsize);
149 h->header_version_major++;
150 ReSignKernelPreamble(h, private_key);
151 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
152 "VerifyKernelPreamble() major++");
Randall Spanglerd1836442010-06-10 09:59:04 -0700153
Randall Spanglere061a252013-01-22 15:34:07 -0800154 Memcpy(h, hdr, hsize);
155 h->header_version_major--;
156 ReSignKernelPreamble(h, private_key);
157 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
158 "VerifyKernelPreamble() major--");
Randall Spanglerd1836442010-06-10 09:59:04 -0700159
Randall Spanglere061a252013-01-22 15:34:07 -0800160 Memcpy(h, hdr, hsize);
161 h->header_version_minor++;
162 ReSignKernelPreamble(h, private_key);
163 TEST_EQ(VerifyKernelPreamble(h, hsize, rsa), 0,
164 "VerifyKernelPreamble() minor++");
Randall Spanglerd1836442010-06-10 09:59:04 -0700165
Randall Spanglere061a252013-01-22 15:34:07 -0800166 Memcpy(h, hdr, hsize);
167 h->header_version_minor--;
168 ReSignKernelPreamble(h, private_key);
169 TEST_EQ(VerifyKernelPreamble(h, hsize, rsa), 0,
170 "VerifyKernelPreamble() minor--");
Randall Spanglerd1836442010-06-10 09:59:04 -0700171
Randall Spanglere061a252013-01-22 15:34:07 -0800172 /* Check signature */
173 Memcpy(h, hdr, hsize);
174 h->preamble_signature.sig_offset = hsize;
175 ReSignKernelPreamble(h, private_key);
176 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
177 "VerifyKernelPreamble() sig off end");
Randall Spanglerd1836442010-06-10 09:59:04 -0700178
Randall Spanglere061a252013-01-22 15:34:07 -0800179 Memcpy(h, hdr, hsize);
180 h->preamble_signature.sig_size--;
181 ReSignKernelPreamble(h, private_key);
182 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
183 "VerifyKernelPreamble() sig too small");
Randall Spanglerd1836442010-06-10 09:59:04 -0700184
Randall Spanglere061a252013-01-22 15:34:07 -0800185 Memcpy(h, hdr, hsize);
186 GetSignatureData(&h->body_signature)[0] ^= 0x34;
187 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
188 "VerifyKernelPreamble() sig mismatch");
Randall Spanglerd1836442010-06-10 09:59:04 -0700189
Randall Spanglere061a252013-01-22 15:34:07 -0800190 /* Check that we signed header and body sig */
191 Memcpy(h, hdr, hsize);
192 h->preamble_signature.data_size = 4;
193 h->body_signature.sig_offset = 0;
194 h->body_signature.sig_size = 0;
195 ReSignKernelPreamble(h, private_key);
196 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
197 "VerifyKernelPreamble() didn't sign header");
Randall Spanglerd1836442010-06-10 09:59:04 -0700198
Randall Spanglere061a252013-01-22 15:34:07 -0800199 Memcpy(h, hdr, hsize);
200 h->body_signature.sig_offset = hsize;
201 ReSignKernelPreamble(h, private_key);
202 TEST_NEQ(VerifyKernelPreamble(h, hsize, rsa), 0,
203 "VerifyKernelPreamble() body sig off end");
Randall Spanglerd1836442010-06-10 09:59:04 -0700204
Randall Spanglere061a252013-01-22 15:34:07 -0800205 /* TODO: verify parser can support a bigger header. */
Randall Spanglerd1836442010-06-10 09:59:04 -0700206
Randall Spanglere061a252013-01-22 15:34:07 -0800207 free(h);
208 RSAPublicKeyFree(rsa);
209 free(hdr);
Randall Spanglerd1836442010-06-10 09:59:04 -0700210}
211
Randall Spanglere061a252013-01-22 15:34:07 -0800212int test_algorithm(int key_algorithm, const char *keys_dir)
213{
214 char filename[1024];
215 int rsa_len = siglen_map[key_algorithm] * 8;
Randall Spanglerd1836442010-06-10 09:59:04 -0700216
Randall Spanglere061a252013-01-22 15:34:07 -0800217 VbPrivateKey *private_key = NULL;
218 VbPublicKey *public_key = NULL;
Randall Spanglerd1836442010-06-10 09:59:04 -0700219
Randall Spanglere061a252013-01-22 15:34:07 -0800220 printf("***Testing algorithm: %s\n", algo_strings[key_algorithm]);
Randall Spanglerd1836442010-06-10 09:59:04 -0700221
Randall Spanglere061a252013-01-22 15:34:07 -0800222 sprintf(filename, "%s/key_rsa%d.pem", keys_dir, rsa_len);
223 private_key = PrivateKeyReadPem(filename, key_algorithm);
224 if (!private_key) {
225 fprintf(stderr, "Error reading private_key: %s\n", filename);
226 return 1;
227 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700228
Randall Spanglere061a252013-01-22 15:34:07 -0800229 sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len);
230 public_key = PublicKeyReadKeyb(filename, key_algorithm, 1);
231 if (!public_key) {
232 fprintf(stderr, "Error reading public_key: %s\n", filename);
233 return 1;
234 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700235
Randall Spanglere061a252013-01-22 15:34:07 -0800236 VerifyPublicKeyToRSA(public_key);
237 VerifyDataTest(public_key, private_key);
238 VerifyDigestTest(public_key, private_key);
239 VerifyKernelPreambleTest(public_key, private_key);
Randall Spanglerd1836442010-06-10 09:59:04 -0700240
Randall Spanglere061a252013-01-22 15:34:07 -0800241 if (public_key)
242 free(public_key);
243 if (private_key)
244 free(private_key);
Randall Spanglerd1836442010-06-10 09:59:04 -0700245
Randall Spanglere061a252013-01-22 15:34:07 -0800246 return 0;
247}
Randall Spanglerd1836442010-06-10 09:59:04 -0700248
Randall Spanglere061a252013-01-22 15:34:07 -0800249/*
250 * Test only the algorithms we use:
251 * 4 (rsa2048 sha256)
252 * 7 (rsa4096 sha256)
253 * 11 (rsa8192 sha512)
254 */
255const int key_algs[] = {4, 7, 11};
Randall Spanglerd1836442010-06-10 09:59:04 -0700256
Randall Spanglere061a252013-01-22 15:34:07 -0800257int main(int argc, char *argv[]) {
258 if (argc == 2) {
259 int i;
260
261 for (i = 0; i < ARRAY_SIZE(key_algs); i++) {
262 if (test_algorithm(key_algs[i], argv[1]))
263 return 1;
264 }
265
266 } else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
267 /* Test all the algorithms */
268 int alg;
269
270 for (alg = 0; alg < kNumAlgorithms; alg++) {
271 if (test_algorithm(alg, argv[1]))
272 return 1;
273 }
274
275 } else {
276 fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
277 return -1;
278 }
279
Simon Glass25001852013-08-16 02:47:57 -0600280 if (vboot_api_stub_check_memory())
281 return 255;
282
Randall Spanglere061a252013-01-22 15:34:07 -0800283 return gTestSuccess ? 0 : 255;
Randall Spanglerd1836442010-06-10 09:59:04 -0700284}