futility: Use only vboot 2.0 APIs for keyblocks
[vboot.git] / tests / vboot_common3_tests.c
1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2  * 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
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "2sysincludes.h"
14 #include "2common.h"
15 #include "2sha.h"
16 #include "cryptolib.h"
17 #include "file_keys.h"
18 #include "host_common.h"
19 #include "test_common.h"
20 #include "vboot_common.h"
21
22
23 static void ReChecksumKeyBlock(VbKeyBlockHeader *h)
24 {
25         vb2_digest_buffer((const uint8_t *)h,
26                           h->key_block_checksum.data_size,
27                           VB2_HASH_SHA512,
28                           GetSignatureData(&h->key_block_checksum),
29                           VB2_SHA512_DIGEST_SIZE);
30 }
31
32 static void KeyBlockVerifyTest(const VbPublicKey *public_key,
33                                const struct vb2_private_key *private_key,
34                                const struct vb2_packed_key *data_key)
35 {
36         VbKeyBlockHeader *hdr;
37         VbKeyBlockHeader *h;
38         unsigned hsize;
39
40         hdr = (VbKeyBlockHeader *)
41                 vb2_create_keyblock((struct vb2_packed_key *)data_key,
42                                     private_key,
43                                     0x1234);
44         TEST_NEQ((size_t)hdr, 0, "KeyBlockVerify() prerequisites");
45         if (!hdr)
46                 return;
47         hsize = (unsigned) hdr->key_block_size;
48         h = (VbKeyBlockHeader *)malloc(hsize + 1024);
49
50         TEST_EQ(KeyBlockVerify(hdr, hsize, NULL, 1), 0,
51                 "KeyBlockVerify() ok using checksum");
52         TEST_EQ(KeyBlockVerify(hdr, hsize, public_key, 0), 0,
53                 "KeyBlockVerify() ok using key");
54         TEST_NEQ(KeyBlockVerify(hdr, hsize, NULL, 0), 0,
55                  "KeyBlockVerify() missing key");
56
57         TEST_NEQ(KeyBlockVerify(hdr, hsize - 1, NULL, 1), 0,
58                  "KeyBlockVerify() size--");
59         TEST_EQ(KeyBlockVerify(hdr, hsize + 1, NULL, 1), 0,
60                 "KeyBlockVerify() size++");
61
62         Memcpy(h, hdr, hsize);
63         h->magic[0] &= 0x12;
64         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
65                  "KeyBlockVerify() magic");
66
67         /* Care about major version but not minor */
68         Memcpy(h, hdr, hsize);
69         h->header_version_major++;
70         ReChecksumKeyBlock(h);
71         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
72                  "KeyBlockVerify() major++");
73
74         Memcpy(h, hdr, hsize);
75         h->header_version_major--;
76         ReChecksumKeyBlock(h);
77         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
78                  "KeyBlockVerify() major--");
79
80         Memcpy(h, hdr, hsize);
81         h->header_version_minor++;
82         ReChecksumKeyBlock(h);
83         TEST_EQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
84                 "KeyBlockVerify() minor++");
85
86         Memcpy(h, hdr, hsize);
87         h->header_version_minor--;
88         ReChecksumKeyBlock(h);
89         TEST_EQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
90                 "KeyBlockVerify() minor--");
91
92         /* Check hash */
93         Memcpy(h, hdr, hsize);
94         h->key_block_checksum.sig_offset = hsize;
95         ReChecksumKeyBlock(h);
96         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
97                  "KeyBlockVerify() checksum off end");
98
99         Memcpy(h, hdr, hsize);
100         h->key_block_checksum.sig_size /= 2;
101         ReChecksumKeyBlock(h);
102         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
103                  "KeyBlockVerify() checksum too small");
104
105         Memcpy(h, hdr, hsize);
106         GetPublicKeyData(&h->data_key)[0] ^= 0x34;
107         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
108                  "KeyBlockVerify() checksum mismatch");
109
110         /* Check signature */
111         Memcpy(h, hdr, hsize);
112         h->key_block_signature.sig_offset = hsize;
113         ReChecksumKeyBlock(h);
114         TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0,
115                  "KeyBlockVerify() sig off end");
116
117         Memcpy(h, hdr, hsize);
118         h->key_block_signature.sig_size--;
119         ReChecksumKeyBlock(h);
120         TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0,
121                  "KeyBlockVerify() sig too small");
122
123         Memcpy(h, hdr, hsize);
124         GetPublicKeyData(&h->data_key)[0] ^= 0x34;
125         TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 0), 0,
126                  "KeyBlockVerify() sig mismatch");
127
128         Memcpy(h, hdr, hsize);
129         h->key_block_checksum.data_size = h->key_block_size + 1;
130         TEST_NEQ(KeyBlockVerify(h, hsize, public_key, 1), 0,
131                  "KeyBlockVerify() checksum data past end of block");
132
133         /* Check that we signed header and data key */
134         Memcpy(h, hdr, hsize);
135         h->key_block_checksum.data_size = 4;
136         h->data_key.key_offset = 0;
137         h->data_key.key_size = 0;
138         ReChecksumKeyBlock(h);
139         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
140                  "KeyBlockVerify() didn't sign header");
141
142         Memcpy(h, hdr, hsize);
143         h->data_key.key_offset = hsize;
144         ReChecksumKeyBlock(h);
145         TEST_NEQ(KeyBlockVerify(h, hsize, NULL, 1), 0,
146                  "KeyBlockVerify() data key off end");
147
148         /* Corner cases for error checking */
149         TEST_NEQ(KeyBlockVerify(NULL, 4, NULL, 1), 0,
150                  "KeyBlockVerify size too small");
151
152         /*
153          * TODO: verify parser can support a bigger header (i.e., one where
154          * data_key.key_offset is bigger than expected).
155          */
156
157         free(h);
158         free(hdr);
159 }
160
161 int test_permutation(int signing_key_algorithm, int data_key_algorithm,
162                      const char *keys_dir)
163 {
164         char filename[1024];
165         int signing_rsa_len = siglen_map[signing_key_algorithm] * 8;
166         int data_rsa_len = siglen_map[data_key_algorithm] * 8;
167
168         VbPublicKey *signing_public_key = NULL;
169
170         printf("***Testing signing algorithm: %s\n",
171                algo_strings[signing_key_algorithm]);
172         printf("***With data key algorithm: %s\n",
173                algo_strings[data_key_algorithm]);
174
175         sprintf(filename, "%s/key_rsa%d.pem", keys_dir, signing_rsa_len);
176         struct vb2_private_key *signing_private_key =
177                 vb2_read_private_key_pem(filename, signing_key_algorithm);
178         if (!signing_private_key) {
179                 fprintf(stderr, "Error reading signing_private_key: %s\n",
180                         filename);
181                 return 1;
182         }
183
184         sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
185         signing_public_key = PublicKeyReadKeyb(filename,
186                                                signing_key_algorithm, 1);
187         if (!signing_public_key) {
188                 fprintf(stderr, "Error reading signing_public_key: %s\n",
189                         filename);
190                 return 1;
191         }
192
193         sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
194         struct vb2_packed_key *data_public_key = (struct vb2_packed_key *)
195                 PublicKeyReadKeyb(filename, data_key_algorithm, 1);
196         if (!data_public_key) {
197                 fprintf(stderr, "Error reading data_public_key: %s\n",
198                         filename);
199                 return 1;
200         }
201
202         KeyBlockVerifyTest(signing_public_key, signing_private_key,
203                            data_public_key);
204
205         if (signing_public_key)
206                 free(signing_public_key);
207         if (signing_private_key)
208                 free(signing_private_key);
209         if (data_public_key)
210                 free(data_public_key);
211
212         return 0;
213 }
214
215 struct test_perm
216 {
217         int signing_algorithm;
218         int data_key_algorithm;
219 };
220
221 /*
222  * Permutations of signing and data key algorithms in active use:
223  * 7 (rsa4096 sha256) - 4 (rsa2048 sha256)
224  * 11 (rsa8192 sha512) - 4 (rsa2048 sha256)
225  * 11 (rsa8192 sha512) - 7 (rsa4096 sha256)
226  */
227 const struct test_perm test_perms[] = {{7, 4}, {11, 4}, {11, 7}};
228
229 int main(int argc, char *argv[])
230 {
231         if (argc == 2) {
232                 /* Test only the algorithms we use */
233                 int i;
234
235                 for (i = 0; i < ARRAY_SIZE(test_perms); i++) {
236                         if (test_permutation(test_perms[i].signing_algorithm,
237                                              test_perms[i].data_key_algorithm,
238                                              argv[1]))
239                                 return 1;
240                 }
241
242         } else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
243                 /* Test all the algorithms */
244                 int sign_alg, data_alg;
245
246                 for (sign_alg = 0; sign_alg < kNumAlgorithms; sign_alg++) {
247                         for (data_alg = 0; data_alg < kNumAlgorithms;
248                              data_alg++) {
249                                 if (test_permutation(sign_alg, data_alg,
250                                                      argv[1]))
251                                         return 1;
252                         }
253                 }
254         } else {
255                 fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
256                 return -1;
257         }
258
259         if (vboot_api_stub_check_memory())
260                 return 255;
261
262         return gTestSuccess ? 0 : 255;
263 }