blob: 826c3fb1d04a7871cbd5280000c18d7976e71a44 [file] [log] [blame]
Randall Spangler837b4082014-11-10 13:40:52 -08001/* Copyright (c) 2014 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 misc library, new-style structs
6 */
7
8#include <stdio.h>
9
10#include "2sysincludes.h"
11#include "2api.h"
12#include "2common.h"
13#include "2misc.h"
14#include "2nvstorage.h"
15#include "2secdata.h"
16
Randall Spangler108d9912014-12-02 15:55:56 -080017#include "vb2_common.h"
18
Randall Spangler837b4082014-11-10 13:40:52 -080019#include "test_common.h"
20
21/* Common context for tests */
22static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
Bill Richardson73e5eb32015-01-26 12:18:25 -080023 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
Randall Spangler837b4082014-11-10 13:40:52 -080024static struct vb2_context ctx;
25static struct vb2_shared_data *sd;
26
27/* Mocked function data */
28
29static struct {
30 struct vb2_gbb_header h;
Randall Spangler308d2542014-12-04 09:54:37 -080031 struct vb2_packed_key rootkey;
Randall Spangler837b4082014-11-10 13:40:52 -080032 char rootkey_data[32];
33} mock_gbb;
34
35static struct {
36 /* Keyblock */
37 struct {
Randall Spangler308d2542014-12-04 09:54:37 -080038 struct vb2_keyblock kb;
39 struct vb2_packed_key data_key;
Randall Spangler837b4082014-11-10 13:40:52 -080040 char data_key_data[16];
41 uint8_t kbdata[128];
42 } k;
43 /* Preamble follows keyblock */
44 struct {
Randall Spangler308d2542014-12-04 09:54:37 -080045 struct vb2_fw_preamble pre;
Randall Spangler837b4082014-11-10 13:40:52 -080046 uint8_t predata[128];
47 } p;
48} mock_vblock;
49
50static int mock_read_res_fail_on_call;
51static int mock_unpack_key_retval;
52static int mock_verify_keyblock_retval;
53static int mock_verify_preamble_retval;
54
55/* Type of test to reset for */
56enum reset_type {
57 FOR_KEYBLOCK,
58 FOR_PREAMBLE
59};
60
61static void reset_common_data(enum reset_type t)
62{
Randall Spangler308d2542014-12-04 09:54:37 -080063 struct vb2_keyblock *kb = &mock_vblock.k.kb;
64 struct vb2_packed_key *dk = &mock_vblock.k.data_key;
65 struct vb2_fw_preamble *pre = &mock_vblock.p.pre;
Randall Spangler837b4082014-11-10 13:40:52 -080066
67 memset(workbuf, 0xaa, sizeof(workbuf));
68
69 memset(&ctx, 0, sizeof(ctx));
70 ctx.workbuf = workbuf;
71 ctx.workbuf_size = sizeof(workbuf);
72
73 vb2_init_context(&ctx);
74 sd = vb2_get_sd(&ctx);
75
76 vb2_nv_init(&ctx);
77
78 vb2_secdata_create(&ctx);
79 vb2_secdata_init(&ctx);
80
81 mock_read_res_fail_on_call = 0;
82 mock_unpack_key_retval = VB2_SUCCESS;
83 mock_verify_keyblock_retval = VB2_SUCCESS;
84 mock_verify_preamble_retval = VB2_SUCCESS;
85
86 /* Set up mock data for verifying keyblock */
Julius Werner21aedee2015-01-29 14:49:17 -080087 sd->fw_version_secdata = 0x20002;
88 vb2_secdata_set(&ctx, VB2_SECDATA_VERSIONS, sd->fw_version_secdata);
Randall Spangler837b4082014-11-10 13:40:52 -080089
90 sd->gbb_rootkey_offset = vb2_offset_of(&mock_gbb, &mock_gbb.rootkey);
91 sd->gbb_rootkey_size = sizeof(mock_gbb.rootkey_data);
92 sd->last_fw_result = VB2_FW_RESULT_SUCCESS;
93
94 mock_gbb.rootkey.sig_alg = VB2_SIG_RSA8192;
95 mock_gbb.rootkey.key_offset =
96 vb2_offset_of(&mock_gbb.rootkey,
97 &mock_gbb.rootkey_data);
98 mock_gbb.rootkey.key_size = sizeof(mock_gbb.rootkey_data);
99
100 kb->c.total_size = sizeof(mock_vblock.k);
101 kb->key_offset = vb2_offset_of(&mock_vblock.k.kb,
102 &mock_vblock.k.data_key);
103
104 dk->c.fixed_size = sizeof(mock_vblock.k.data_key);
105 dk->sig_alg = VB2_SIG_RSA4096;
106 dk->key_version = 2;
107 dk->key_offset = dk->c.fixed_size;
108 dk->key_size = sizeof(mock_vblock.k.data_key_data);
109 dk->c.total_size = dk->key_offset + dk->key_size;
110 strcpy(mock_vblock.k.data_key_data, "data key data!!");
111
112 pre->c.total_size = sizeof(mock_vblock.p);
Randall Spangler308d2542014-12-04 09:54:37 -0800113 pre->fw_version = 2;
Randall Spangler837b4082014-11-10 13:40:52 -0800114
115 /* If verifying preamble, verify keyblock first to set up data key */
116 if (t == FOR_PREAMBLE)
Randall Spangler308d2542014-12-04 09:54:37 -0800117 vb2_load_fw_keyblock(&ctx);
Randall Spangler837b4082014-11-10 13:40:52 -0800118};
119
120/* Mocked functions */
121
122int vb2ex_read_resource(struct vb2_context *ctx,
123 enum vb2_resource_index index,
124 uint32_t offset,
125 void *buf,
126 uint32_t size)
127{
128 uint8_t *rptr;
129 uint32_t rsize;
130
131 if (--mock_read_res_fail_on_call == 0)
132 return VB2_ERROR_EX_READ_RESOURCE_INDEX;
133
134 switch(index) {
135 case VB2_RES_GBB:
136 rptr = (uint8_t *)&mock_gbb;
137 rsize = sizeof(mock_gbb);
138 break;
139 case VB2_RES_FW_VBLOCK:
140 rptr = (uint8_t *)&mock_vblock;
141 rsize = sizeof(mock_vblock);
142 break;
143 default:
144 return VB2_ERROR_EX_READ_RESOURCE_INDEX;
145 }
146
147 if (offset > rsize || offset + size > rsize)
148 return VB2_ERROR_EX_READ_RESOURCE_SIZE;
149
150 memcpy(buf, rptr + offset, size);
151 return VB2_SUCCESS;
152}
153
Randall Spangler308d2542014-12-04 09:54:37 -0800154int vb2_unpack_key(struct vb2_public_key *key,
Randall Spangler837b4082014-11-10 13:40:52 -0800155 const uint8_t *buf,
156 uint32_t size)
157{
158 return mock_unpack_key_retval;
159}
160
Randall Spangler308d2542014-12-04 09:54:37 -0800161int vb2_verify_keyblock(struct vb2_keyblock *block,
Randall Spangler837b4082014-11-10 13:40:52 -0800162 uint32_t size,
163 const struct vb2_public_key *key,
164 const struct vb2_workbuf *wb)
165{
166 return mock_verify_keyblock_retval;
167}
168
Randall Spangler308d2542014-12-04 09:54:37 -0800169int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
Randall Spangler837b4082014-11-10 13:40:52 -0800170 uint32_t size,
171 const struct vb2_public_key *key,
172 const struct vb2_workbuf *wb)
173{
174 return mock_verify_preamble_retval;
175}
176
177/* Tests */
178
179static void load_keyblock_tests(void)
180{
Randall Spangler308d2542014-12-04 09:54:37 -0800181 struct vb2_keyblock *kb = &mock_vblock.k.kb;
182 struct vb2_packed_key *dk = &mock_vblock.k.data_key;
183 struct vb2_packed_key *k;
Randall Spangler837b4082014-11-10 13:40:52 -0800184 int wb_used_before;
185
186 /* Test successful call */
187 reset_common_data(FOR_KEYBLOCK);
188 wb_used_before = ctx.workbuf_used;
Randall Spangler308d2542014-12-04 09:54:37 -0800189 TEST_SUCC(vb2_load_fw_keyblock(&ctx), "keyblock verify");
Randall Spangler837b4082014-11-10 13:40:52 -0800190 TEST_EQ(sd->fw_version, 0x20000, "keyblock version");
191 TEST_EQ(sd->vblock_preamble_offset, sizeof(mock_vblock.k),
192 "preamble offset");
193 TEST_EQ(sd->workbuf_data_key_offset,
194 (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
195 ~(VB2_WORKBUF_ALIGN - 1),
196 "keyblock data key offset");
197 TEST_EQ(ctx.workbuf_used,
198 sd->workbuf_data_key_offset + sd->workbuf_data_key_size,
199 "workbuf used");
200
201 /* Make sure data key was properly saved */
Randall Spangler308d2542014-12-04 09:54:37 -0800202 k = (struct vb2_packed_key *)(ctx.workbuf +
203 sd->workbuf_data_key_offset);
Randall Spangler837b4082014-11-10 13:40:52 -0800204 TEST_EQ(k->sig_alg, VB2_SIG_RSA4096, "data key algorithm");
205 TEST_EQ(k->key_version, 2, "data key version");
206 TEST_EQ(k->key_size, sizeof(mock_vblock.k.data_key_data),
207 "data key size");
208 TEST_EQ(memcmp(ctx.workbuf + sd->workbuf_data_key_offset +
209 k->key_offset, mock_vblock.k.data_key_data,
210 sizeof(mock_vblock.k.data_key_data)),
211 0, "data key data");
212 TEST_EQ(ctx.workbuf_used,
213 sd->workbuf_data_key_offset + sd->workbuf_data_key_size,
214 "workbuf used after");
215
216 /* Test failures */
217 reset_common_data(FOR_KEYBLOCK);
218 ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size + 8;
Randall Spangler308d2542014-12-04 09:54:37 -0800219 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800220 VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY,
221 "keyblock not enough workbuf for root key");
222
223 reset_common_data(FOR_KEYBLOCK);
224 sd->gbb_rootkey_size = sizeof(mock_gbb);
Randall Spangler308d2542014-12-04 09:54:37 -0800225 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800226 VB2_ERROR_EX_READ_RESOURCE_SIZE,
227 "keyblock read root key");
228
229 reset_common_data(FOR_KEYBLOCK);
230 mock_unpack_key_retval = VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM;
Randall Spangler308d2542014-12-04 09:54:37 -0800231 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800232 VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM,
233 "keyblock unpack root key");
234
235 reset_common_data(FOR_KEYBLOCK);
236 ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size - 8;
Randall Spangler308d2542014-12-04 09:54:37 -0800237 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800238 VB2_ERROR_READ_RESOURCE_OBJECT_BUF,
239 "keyblock not enough workbuf for header");
240
241 reset_common_data(FOR_KEYBLOCK);
242 mock_read_res_fail_on_call = 2;
Randall Spangler308d2542014-12-04 09:54:37 -0800243 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800244 VB2_ERROR_EX_READ_RESOURCE_INDEX,
245 "keyblock read keyblock header");
246
247 reset_common_data(FOR_KEYBLOCK);
248 ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size
Randall Spangler308d2542014-12-04 09:54:37 -0800249 - sizeof(struct vb2_keyblock);
250 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800251 VB2_ERROR_READ_RESOURCE_OBJECT_BUF,
252 "keyblock not enough workbuf for entire keyblock");
253
254 reset_common_data(FOR_KEYBLOCK);
255 kb->c.total_size = sizeof(mock_vblock) + 1;
Randall Spangler308d2542014-12-04 09:54:37 -0800256 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800257 VB2_ERROR_EX_READ_RESOURCE_SIZE,
258 "keyblock read keyblock");
259
260 reset_common_data(FOR_KEYBLOCK);
261 mock_verify_keyblock_retval = VB2_ERROR_KEYBLOCK_MAGIC;
Randall Spangler308d2542014-12-04 09:54:37 -0800262 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800263 VB2_ERROR_KEYBLOCK_MAGIC,
264 "keyblock verify keyblock");
265
266 reset_common_data(FOR_KEYBLOCK);
267 dk->key_version = 0x10000;
Randall Spangler308d2542014-12-04 09:54:37 -0800268 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800269 VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE,
270 "keyblock version range");
271
272 reset_common_data(FOR_KEYBLOCK);
273 dk->key_version = 1;
Randall Spangler308d2542014-12-04 09:54:37 -0800274 TEST_EQ(vb2_load_fw_keyblock(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800275 VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK,
276 "keyblock rollback");
277}
278
279static void load_preamble_tests(void)
280{
Randall Spangler308d2542014-12-04 09:54:37 -0800281 struct vb2_fw_preamble *pre = &mock_vblock.p.pre;
Randall Spangler837b4082014-11-10 13:40:52 -0800282 int data_key_offset_before;
283 uint32_t v;
284
285 /* Test successful call */
286 reset_common_data(FOR_PREAMBLE);
287 data_key_offset_before = sd->workbuf_data_key_offset;
Randall Spangler308d2542014-12-04 09:54:37 -0800288 TEST_SUCC(vb2_load_fw_preamble(&ctx), "preamble good");
Randall Spangler837b4082014-11-10 13:40:52 -0800289 TEST_EQ(sd->fw_version, 0x20002, "combined version");
290 TEST_EQ(sd->workbuf_preamble_offset, data_key_offset_before,
291 "preamble offset");
292 TEST_EQ(sd->workbuf_preamble_size, pre->c.total_size, "preamble size");
293 TEST_EQ(ctx.workbuf_used,
294 sd->workbuf_preamble_offset + sd->workbuf_preamble_size,
295 "workbuf used");
296 TEST_EQ(sd->workbuf_data_key_offset, 0, "data key offset gone");
297 TEST_EQ(sd->workbuf_data_key_size, 0, "data key size gone");
298
299 /* Expected failures */
300 reset_common_data(FOR_PREAMBLE);
301 sd->workbuf_data_key_size = 0;
Randall Spangler308d2542014-12-04 09:54:37 -0800302 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800303 VB2_ERROR_FW_PREAMBLE2_DATA_KEY,
304 "preamble no data key");
305
306 reset_common_data(FOR_PREAMBLE);
307 mock_unpack_key_retval = VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM;
Randall Spangler308d2542014-12-04 09:54:37 -0800308 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800309 VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM,
310 "preamble unpack data key");
311
312 reset_common_data(FOR_PREAMBLE);
313 ctx.workbuf_used = ctx.workbuf_size
Randall Spangler308d2542014-12-04 09:54:37 -0800314 - sizeof(struct vb2_fw_preamble) + 8;
315 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800316 VB2_ERROR_READ_RESOURCE_OBJECT_BUF,
317 "preamble not enough workbuf for header");
318
319 reset_common_data(FOR_PREAMBLE);
320 sd->vblock_preamble_offset = sizeof(mock_vblock);
Randall Spangler308d2542014-12-04 09:54:37 -0800321 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800322 VB2_ERROR_EX_READ_RESOURCE_SIZE,
323 "preamble read header");
324
325 reset_common_data(FOR_PREAMBLE);
326 ctx.workbuf_used = ctx.workbuf_size - sizeof(mock_vblock.p) + 8;
Randall Spangler308d2542014-12-04 09:54:37 -0800327 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800328 VB2_ERROR_READ_RESOURCE_OBJECT_BUF,
329 "preamble not enough workbuf");
330
331 reset_common_data(FOR_PREAMBLE);
332 pre->c.total_size = sizeof(mock_vblock);
Randall Spangler308d2542014-12-04 09:54:37 -0800333 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800334 VB2_ERROR_EX_READ_RESOURCE_SIZE,
335 "preamble read full");
336
337 reset_common_data(FOR_PREAMBLE);
338 mock_verify_preamble_retval = VB2_ERROR_PREAMBLE_SIG_INVALID;
Randall Spangler308d2542014-12-04 09:54:37 -0800339 TEST_EQ(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800340 VB2_ERROR_PREAMBLE_SIG_INVALID,
341 "preamble verify");
342
343 reset_common_data(FOR_PREAMBLE);
Randall Spangler308d2542014-12-04 09:54:37 -0800344 pre->fw_version = 0x10000;
345 TEST_EQ(vb2_load_fw_preamble(&ctx),
346 VB2_ERROR_FW_PREAMBLE_VERSION_RANGE,
Randall Spangler837b4082014-11-10 13:40:52 -0800347 "preamble version range");
348
349 reset_common_data(FOR_PREAMBLE);
Randall Spangler308d2542014-12-04 09:54:37 -0800350 pre->fw_version = 1;
351 TEST_EQ(vb2_load_fw_preamble(&ctx),
352 VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK,
Randall Spangler837b4082014-11-10 13:40:52 -0800353 "preamble version rollback");
354
355 reset_common_data(FOR_PREAMBLE);
Randall Spangler308d2542014-12-04 09:54:37 -0800356 pre->fw_version = 3;
357 TEST_SUCC(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800358 "preamble version roll forward");
359 vb2_secdata_get(&ctx, VB2_SECDATA_VERSIONS, &v);
360 TEST_EQ(v, 0x20003, "roll forward");
361
362 /* Newer version without result success doesn't roll forward */
363 reset_common_data(FOR_PREAMBLE);
Randall Spangler308d2542014-12-04 09:54:37 -0800364 pre->fw_version = 3;
Randall Spangler837b4082014-11-10 13:40:52 -0800365 sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
Randall Spangler308d2542014-12-04 09:54:37 -0800366 TEST_SUCC(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800367 "preamble version no roll forward 1");
368 vb2_secdata_get(&ctx, VB2_SECDATA_VERSIONS, &v);
369 TEST_EQ(v, 0x20002, "no roll forward");
370
371 /* Newer version with success but for other slot doesn't roll forward */
372 reset_common_data(FOR_PREAMBLE);
Randall Spangler308d2542014-12-04 09:54:37 -0800373 pre->fw_version = 3;
Randall Spangler837b4082014-11-10 13:40:52 -0800374 sd->last_fw_slot = 1;
Randall Spangler308d2542014-12-04 09:54:37 -0800375 TEST_SUCC(vb2_load_fw_preamble(&ctx),
Randall Spangler837b4082014-11-10 13:40:52 -0800376 "preamble version no roll forward 2");
377 vb2_secdata_get(&ctx, VB2_SECDATA_VERSIONS, &v);
378 TEST_EQ(v, 0x20002, "no roll forward");
379}
380
381int main(int argc, char* argv[])
382{
383 load_keyblock_tests();
384 load_preamble_tests();
385
386 return gTestSuccess ? 0 : 255;
387}