blob: a78930123f96b75b7eb93e9c8d781cc6d71d8955 [file] [log] [blame]
Randall Spanglera7ab8b52014-06-10 17:05:08 -07001/* 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
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 "2rsa.h"
16#include "2secdata.h"
17
18#include "test_common.h"
19
20/* Common context for tests */
21static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
22 __attribute__ ((aligned (16)));
23static struct vb2_context cc;
24static struct vb2_shared_data *sd;
25
26const char mock_body[320] = "Mock body";
27const int mock_body_size = sizeof(mock_body);
28const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
Randall Spangler4eef8122014-10-23 10:07:54 -070029const int mock_hash_alg = VB2_HASH_SHA256;
Randall Spanglera7ab8b52014-06-10 17:05:08 -070030const int mock_sig_size = 64;
31
32/* Mocked function data */
33
34static int retval_vb2_fw_parse_gbb;
35static int retval_vb2_check_dev_switch;
36static int retval_vb2_check_tpm_clear;
37static int retval_vb2_select_fw_slot;
Randall Spanglerf18038b2014-10-23 15:55:21 -070038static int retval_vb2_load_fw_keyblock;
39static int retval_vb2_load_fw_preamble;
Randall Spanglera7ab8b52014-06-10 17:05:08 -070040static int retval_vb2_digest_finalize;
41static int retval_vb2_verify_digest;
42
43/* Type of test to reset for */
44enum reset_type {
45 FOR_MISC,
46 FOR_EXTEND_HASH,
47 FOR_CHECK_HASH,
48};
49
50static void reset_common_data(enum reset_type t)
51{
52 struct vb2_fw_preamble *pre;
53 struct vb2_packed_key *k;
54
55 memset(workbuf, 0xaa, sizeof(workbuf));
56
57 memset(&cc, 0, sizeof(cc));
58 cc.workbuf = workbuf;
59 cc.workbuf_size = sizeof(workbuf);
60
61 vb2_init_context(&cc);
62 sd = vb2_get_sd(&cc);
63
64 vb2_nv_init(&cc);
65
66 vb2_secdata_create(&cc);
67 vb2_secdata_init(&cc);
68
69 retval_vb2_fw_parse_gbb = VB2_SUCCESS;
70 retval_vb2_check_dev_switch = VB2_SUCCESS;
71 retval_vb2_check_tpm_clear = VB2_SUCCESS;
72 retval_vb2_select_fw_slot = VB2_SUCCESS;
Randall Spanglerf18038b2014-10-23 15:55:21 -070073 retval_vb2_load_fw_keyblock = VB2_SUCCESS;
74 retval_vb2_load_fw_preamble = VB2_SUCCESS;
Randall Spanglera7ab8b52014-06-10 17:05:08 -070075 retval_vb2_digest_finalize = VB2_SUCCESS;
76 retval_vb2_verify_digest = VB2_SUCCESS;
77
Randall Spanglerefa37b82014-11-12 16:20:50 -080078 sd->workbuf_preamble_offset = cc.workbuf_used;
Randall Spanglera7ab8b52014-06-10 17:05:08 -070079 sd->workbuf_preamble_size = sizeof(*pre);
80 cc.workbuf_used = sd->workbuf_preamble_offset
81 + sd->workbuf_preamble_size;
82 pre = (struct vb2_fw_preamble *)
83 (cc.workbuf + sd->workbuf_preamble_offset);
84 pre->body_signature.data_size = mock_body_size;
85 pre->body_signature.sig_size = mock_sig_size;
86
87 sd->workbuf_data_key_offset = cc.workbuf_used;
88 sd->workbuf_data_key_size = sizeof(*k) + 8;
89 cc.workbuf_used = sd->workbuf_data_key_offset +
90 sd->workbuf_data_key_size;
91 k = (struct vb2_packed_key *)
92 (cc.workbuf + sd->workbuf_data_key_offset);
93 k->algorithm = mock_algorithm;
94
95 if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
96 vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
97
98 if (t == FOR_CHECK_HASH)
99 vb2api_extend_hash(&cc, mock_body, mock_body_size);
100};
101
102/* Mocked functions */
103
104int vb2_fw_parse_gbb(struct vb2_context *ctx)
105{
106 return retval_vb2_fw_parse_gbb;
107}
108
109int vb2_check_dev_switch(struct vb2_context *ctx)
110{
111 return retval_vb2_check_dev_switch;
112}
113
114int vb2_check_tpm_clear(struct vb2_context *ctx)
115{
116 return retval_vb2_check_tpm_clear;
117}
118
119int vb2_select_fw_slot(struct vb2_context *ctx)
120{
121 return retval_vb2_select_fw_slot;
122}
123
Randall Spanglerf18038b2014-10-23 15:55:21 -0700124int vb2_load_fw_keyblock(struct vb2_context *ctx)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700125{
Randall Spanglerf18038b2014-10-23 15:55:21 -0700126 return retval_vb2_load_fw_keyblock;
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700127}
128
Randall Spanglerf18038b2014-10-23 15:55:21 -0700129int vb2_load_fw_preamble(struct vb2_context *ctx)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700130{
Randall Spanglerf18038b2014-10-23 15:55:21 -0700131 return retval_vb2_load_fw_preamble;
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700132}
133
134int vb2_unpack_key(struct vb2_public_key *key,
135 const uint8_t *buf,
136 uint32_t size)
137{
138 struct vb2_packed_key *k = (struct vb2_packed_key *)buf;
139
140 if (size != sizeof(*k) + 8)
141 return VB2_ERROR_UNPACK_KEY_SIZE;
142
Randall Spanglerc8c2f022014-10-23 09:48:20 -0700143 key->sig_alg = vb2_crypto_to_signature(k->algorithm);
Randall Spangler4eef8122014-10-23 10:07:54 -0700144 key->hash_alg = vb2_crypto_to_hash(k->algorithm);
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700145
146 return VB2_SUCCESS;
147}
148
Randall Spangler4eef8122014-10-23 10:07:54 -0700149int vb2_digest_init(struct vb2_digest_context *dc,
150 enum vb2_hash_algorithm hash_alg)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700151{
Randall Spangler4eef8122014-10-23 10:07:54 -0700152 if (hash_alg != mock_hash_alg)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700153 return VB2_ERROR_SHA_INIT_ALGORITHM;
154
Randall Spangler4eef8122014-10-23 10:07:54 -0700155 dc->hash_alg = hash_alg;
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700156
157 return VB2_SUCCESS;
158}
159
160int vb2_digest_extend(struct vb2_digest_context *dc,
161 const uint8_t *buf,
162 uint32_t size)
163{
Randall Spangler4eef8122014-10-23 10:07:54 -0700164 if (dc->hash_alg != mock_hash_alg)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700165 return VB2_ERROR_SHA_EXTEND_ALGORITHM;
166
167 return VB2_SUCCESS;
168}
169
170int vb2_digest_finalize(struct vb2_digest_context *dc,
171 uint8_t *digest,
172 uint32_t digest_size)
173{
174 return retval_vb2_digest_finalize;
175}
176
Randall Spanglerc8c2f022014-10-23 09:48:20 -0700177uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700178{
179 return mock_sig_size;
180}
181
Randall Spangler95047542014-10-17 16:41:46 -0700182int vb2_rsa_verify_digest(const struct vb2_public_key *key,
183 uint8_t *sig,
184 const uint8_t *digest,
Randall Spanglera063a432014-11-04 16:45:37 -0800185 const struct vb2_workbuf *wb)
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700186{
187 return retval_vb2_verify_digest;
188}
189
190/* Tests */
191
192static void misc_tests(void)
193{
194 /* Test secdata passthru functions */
195 reset_common_data(FOR_MISC);
196 /* Corrupt secdata so initial check will fail */
197 cc.secdata[0] ^= 0x42;
198 TEST_EQ(vb2api_secdata_check(&cc), VB2_ERROR_SECDATA_CRC,
199 "secdata check");
200 TEST_SUCC(vb2api_secdata_create(&cc), "secdata create");
201 TEST_SUCC(vb2api_secdata_check(&cc), "secdata check 2");
202
203 /* Test fail passthru */
204 reset_common_data(FOR_MISC);
205 vb2api_fail(&cc, 12, 34);
206 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
207 12, "vb2api_fail request");
208 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
209 34, "vb2api_fail subcode");
210}
211
212static void phase1_tests(void)
213{
214 reset_common_data(FOR_MISC);
215 TEST_SUCC(vb2api_fw_phase1(&cc), "phase1 good");
216 TEST_EQ(sd->recovery_reason, 0, " not recovery");
217 TEST_EQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
218 TEST_EQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
219
220 reset_common_data(FOR_MISC);
Aaron Durbin941e25f2014-10-29 15:08:39 -0500221 retval_vb2_fw_parse_gbb = VB2_ERROR_GBB_MAGIC;
222 TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
223 "phase1 gbb");
224 TEST_EQ(sd->recovery_reason, VB2_RECOVERY_GBB_HEADER,
225 " recovery reason");
226 TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
227 TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
228
229
230 reset_common_data(FOR_MISC);
231 retval_vb2_check_dev_switch = VB2_ERROR_MOCK;
232 TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
233 "phase1 dev switch");
234 TEST_EQ(sd->recovery_reason, VB2_RECOVERY_DEV_SWITCH,
235 " recovery reason");
236 TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
237 TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
238
239 reset_common_data(FOR_MISC);
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700240 cc.secdata[0] ^= 0x42;
Aaron Durbin941e25f2014-10-29 15:08:39 -0500241 TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
242 "phase1 secdata");
243 TEST_EQ(sd->recovery_reason, VB2_RECOVERY_SECDATA_INIT,
244 " recovery reason");
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700245 TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
246 TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
247}
248
249static void phase2_tests(void)
250{
251 reset_common_data(FOR_MISC);
252 TEST_SUCC(vb2api_fw_phase2(&cc), "phase2 good");
253 TEST_EQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
254
255 reset_common_data(FOR_MISC);
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700256 cc.flags |= VB2_CONTEXT_DEVELOPER_MODE;
257 TEST_SUCC(vb2api_fw_phase2(&cc), "phase1 dev");
258 TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
259
260 reset_common_data(FOR_MISC);
261 retval_vb2_check_tpm_clear = VB2_ERROR_MOCK;
262 TEST_EQ(vb2api_fw_phase2(&cc), VB2_ERROR_MOCK, "phase2 tpm clear");
263 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
264 VB2_RECOVERY_TPM_CLEAR_OWNER, " recovery reason");
265
266 reset_common_data(FOR_MISC);
267 retval_vb2_select_fw_slot = VB2_ERROR_MOCK;
268 TEST_EQ(vb2api_fw_phase2(&cc), VB2_ERROR_MOCK, "phase2 slot");
269 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
270 VB2_RECOVERY_FW_SLOT, " recovery reason");
271}
272
273static void phase3_tests(void)
274{
275 reset_common_data(FOR_MISC);
276 TEST_SUCC(vb2api_fw_phase3(&cc), "phase3 good");
277
278 reset_common_data(FOR_MISC);
Randall Spanglerf18038b2014-10-23 15:55:21 -0700279 retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700280 TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
281 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
282 VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
283
284 reset_common_data(FOR_MISC);
Randall Spanglerf18038b2014-10-23 15:55:21 -0700285 retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700286 TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
287 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
288 VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
289}
290
291static void init_hash_tests(void)
292{
293 struct vb2_packed_key *k;
294 int wb_used_before;
295 uint32_t size;
296
297 /* For now, all we support is body signature hash */
298 reset_common_data(FOR_MISC);
299 wb_used_before = cc.workbuf_used;
300 TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
301 "init hash good");
302 TEST_EQ(sd->workbuf_hash_offset,
303 (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
304 ~(VB2_WORKBUF_ALIGN - 1),
305 "hash context offset");
306 TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
307 "hash context size");
308 TEST_EQ(cc.workbuf_used,
309 sd->workbuf_hash_offset + sd->workbuf_hash_size,
310 "hash uses workbuf");
311 TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag");
312 TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
313
314 wb_used_before = cc.workbuf_used;
315 TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
316 "init hash again");
317 TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
318
319 reset_common_data(FOR_MISC);
320 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
321 VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
322
323 reset_common_data(FOR_MISC);
324 sd->workbuf_preamble_size = 0;
325 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
326 VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
327
328 reset_common_data(FOR_MISC);
329 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
330 VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
331
332 reset_common_data(FOR_MISC);
333 cc.workbuf_used =
334 cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
335 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
336 VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
337
338 reset_common_data(FOR_MISC);
339 sd->workbuf_data_key_size = 0;
340 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
341 VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
342
343 reset_common_data(FOR_MISC);
344 sd->workbuf_data_key_size--;
345 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
346 VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
347
348 reset_common_data(FOR_MISC);
349 k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
350 k->algorithm--;
351 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
352 VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
353}
354
355static void extend_hash_tests(void)
356{
357 struct vb2_digest_context *dc;
358
359 reset_common_data(FOR_EXTEND_HASH);
360 TEST_SUCC(vb2api_extend_hash(&cc, mock_body, 32),
361 "hash extend good");
362 TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
363 "hash extend remaining");
364 TEST_SUCC(vb2api_extend_hash(&cc, mock_body, mock_body_size - 32),
365 "hash extend again");
366 TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
367
368 reset_common_data(FOR_EXTEND_HASH);
369 sd->workbuf_hash_size = 0;
370 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
371 VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
372
373 reset_common_data(FOR_EXTEND_HASH);
374 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size + 1),
375 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
376
377 reset_common_data(FOR_EXTEND_HASH);
378 TEST_EQ(vb2api_extend_hash(&cc, mock_body, 0),
379 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
380
381 reset_common_data(FOR_EXTEND_HASH);
382 dc = (struct vb2_digest_context *)
383 (cc.workbuf + sd->workbuf_hash_offset);
Randall Spangler4eef8122014-10-23 10:07:54 -0700384 dc->hash_alg = mock_hash_alg + 1;
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700385 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
386 VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
387}
388
389static void check_hash_tests(void)
390{
391 struct vb2_fw_preamble *pre;
392
393 reset_common_data(FOR_CHECK_HASH);
394 TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
395
396 reset_common_data(FOR_CHECK_HASH);
397 sd->workbuf_preamble_size = 0;
398 TEST_EQ(vb2api_check_hash(&cc),
399 VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
400
401 reset_common_data(FOR_CHECK_HASH);
402 sd->workbuf_hash_size = 0;
403 TEST_EQ(vb2api_check_hash(&cc),
404 VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
405
406 reset_common_data(FOR_CHECK_HASH);
407 sd->hash_remaining_size = 1;
408 TEST_EQ(vb2api_check_hash(&cc),
409 VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
410
411 reset_common_data(FOR_CHECK_HASH);
412 cc.workbuf_used = cc.workbuf_size;
413 TEST_EQ(vb2api_check_hash(&cc),
414 VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
415
416 reset_common_data(FOR_CHECK_HASH);
417 retval_vb2_digest_finalize = VB2_ERROR_MOCK;
418 TEST_EQ(vb2api_check_hash(&cc), VB2_ERROR_MOCK, "check hash finalize");
419
420 reset_common_data(FOR_CHECK_HASH);
421 sd->hash_tag = VB2_HASH_TAG_INVALID;
422 TEST_EQ(vb2api_check_hash(&cc),
423 VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
424
425 reset_common_data(FOR_CHECK_HASH);
426 sd->workbuf_data_key_size = 0;
427 TEST_EQ(vb2api_check_hash(&cc),
428 VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
429
430 reset_common_data(FOR_CHECK_HASH);
431 sd->workbuf_data_key_size--;
432 TEST_EQ(vb2api_check_hash(&cc),
433 VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
434
435 reset_common_data(FOR_CHECK_HASH);
436 pre = (struct vb2_fw_preamble *)
437 (cc.workbuf + sd->workbuf_preamble_offset);
438 pre->body_signature.sig_size++;
439 TEST_EQ(vb2api_check_hash(&cc),
Randall Spangler95047542014-10-17 16:41:46 -0700440 VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size");
Randall Spanglera7ab8b52014-06-10 17:05:08 -0700441
442 reset_common_data(FOR_CHECK_HASH);
443 retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST;
444 TEST_EQ(vb2api_check_hash(&cc),
445 VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
446}
447
448int main(int argc, char* argv[])
449{
450 misc_tests();
451 phase1_tests();
452 phase2_tests();
453 phase3_tests();
454 init_hash_tests();
455 extend_hash_tests();
456 check_hash_tests();
457
458 return gTestSuccess ? 0 : 255;
459}