blob: f0bc98bf7ff3da978f95bedab75f78463d9fafe9 [file] [log] [blame]
Randall Spangler6f1b82a2014-12-03 12:29:37 -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
6 */
7
8#include <stdio.h>
9
10#include "2sysincludes.h"
11#include "2api.h"
12#include "2misc.h"
13#include "2nvstorage.h"
14#include "2rsa.h"
15#include "2secdata.h"
16#include "vb2_common.h"
17#include "test_common.h"
18
19/* Common context for tests */
20static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
Bill Richardson73e5eb32015-01-26 12:18:25 -080021 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
Randall Spangler6f1b82a2014-12-03 12:29:37 -080022static struct vb2_context cc;
23static struct vb2_shared_data *sd;
24
25const char mock_body[320] = "Mock body";
26const int mock_body_size = sizeof(mock_body);
27const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
28const int mock_hash_alg = VB2_HASH_SHA256;
29const int mock_sig_size = 64;
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -060030static uint8_t digest_result[VB2_SHA256_DIGEST_SIZE];
31static const uint32_t digest_result_size = sizeof(digest_result);
Randall Spangler6f1b82a2014-12-03 12:29:37 -080032
33/* Mocked function data */
34
Julius Wernerf10e9092014-12-16 19:24:54 -080035static enum {
36 HWCRYPTO_DISABLED,
37 HWCRYPTO_ENABLED,
38 HWCRYPTO_FORBIDDEN,
39} hwcrypto_state;
40
Randall Spangler6f1b82a2014-12-03 12:29:37 -080041static int retval_vb2_load_fw_keyblock;
42static int retval_vb2_load_fw_preamble;
43static int retval_vb2_digest_finalize;
44static int retval_vb2_verify_digest;
45
46/* Type of test to reset for */
47enum reset_type {
48 FOR_MISC,
49 FOR_EXTEND_HASH,
50 FOR_CHECK_HASH,
51};
52
53static void reset_common_data(enum reset_type t)
54{
55 struct vb2_fw_preamble *pre;
56 struct vb2_packed_key *k;
57
58 memset(workbuf, 0xaa, sizeof(workbuf));
59
60 memset(&cc, 0, sizeof(cc));
61 cc.workbuf = workbuf;
62 cc.workbuf_size = sizeof(workbuf);
63
64 vb2_init_context(&cc);
65 sd = vb2_get_sd(&cc);
66
67 vb2_nv_init(&cc);
68
69 vb2_secdata_create(&cc);
70 vb2_secdata_init(&cc);
71
72 retval_vb2_load_fw_keyblock = VB2_SUCCESS;
73 retval_vb2_load_fw_preamble = VB2_SUCCESS;
74 retval_vb2_digest_finalize = VB2_SUCCESS;
75 retval_vb2_verify_digest = VB2_SUCCESS;
76
77 sd->workbuf_preamble_offset = cc.workbuf_used;
78 sd->workbuf_preamble_size = sizeof(*pre);
79 cc.workbuf_used = sd->workbuf_preamble_offset
80 + sd->workbuf_preamble_size;
81 pre = (struct vb2_fw_preamble *)
82 (cc.workbuf + sd->workbuf_preamble_offset);
83 pre->body_signature.data_size = mock_body_size;
84 pre->body_signature.sig_size = mock_sig_size;
Julius Wernerf10e9092014-12-16 19:24:54 -080085 if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
86 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
87 else
88 pre->flags = 0;
Randall Spangler6f1b82a2014-12-03 12:29:37 -080089
90 sd->workbuf_data_key_offset = cc.workbuf_used;
91 sd->workbuf_data_key_size = sizeof(*k) + 8;
92 cc.workbuf_used = sd->workbuf_data_key_offset +
93 sd->workbuf_data_key_size;
94 k = (struct vb2_packed_key *)
95 (cc.workbuf + sd->workbuf_data_key_offset);
96 k->algorithm = mock_algorithm;
97
98 if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
99 vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
100
101 if (t == FOR_CHECK_HASH)
102 vb2api_extend_hash(&cc, mock_body, mock_body_size);
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -0600103
104 /* Always clear out the digest result. */
105 memset(digest_result, 0, digest_result_size);
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800106};
107
108/* Mocked functions */
109
110int vb2_load_fw_keyblock(struct vb2_context *ctx)
111{
112 return retval_vb2_load_fw_keyblock;
113}
114
115int vb2_load_fw_preamble(struct vb2_context *ctx)
116{
117 return retval_vb2_load_fw_preamble;
118}
119
120int vb2_unpack_key(struct vb2_public_key *key,
121 const uint8_t *buf,
122 uint32_t size)
123{
124 struct vb2_packed_key *k = (struct vb2_packed_key *)buf;
125
126 if (size != sizeof(*k) + 8)
127 return VB2_ERROR_UNPACK_KEY_SIZE;
128
129 key->sig_alg = vb2_crypto_to_signature(k->algorithm);
130 key->hash_alg = vb2_crypto_to_hash(k->algorithm);
131
132 return VB2_SUCCESS;
133}
134
Julius Wernerf10e9092014-12-16 19:24:54 -0800135int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
136 uint32_t data_size)
137{
138 switch (hwcrypto_state) {
139 case HWCRYPTO_DISABLED:
140 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
141 case HWCRYPTO_ENABLED:
142 if (hash_alg != mock_hash_alg)
143 return VB2_ERROR_SHA_INIT_ALGORITHM;
144 else
145 return VB2_SUCCESS;
146 case HWCRYPTO_FORBIDDEN:
147 default:
148 return VB2_ERROR_UNKNOWN;
149 }
150}
151
152int vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
153 uint32_t size)
154{
155 if (hwcrypto_state != HWCRYPTO_ENABLED)
156 return VB2_ERROR_UNKNOWN;
157
158 return VB2_SUCCESS;
159}
160
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -0600161static void fill_digest(uint8_t *digest, uint32_t digest_size)
162{
163 /* Set the result to a known value. */
164 memset(digest, 0x0a, digest_size);
165}
166
Julius Wernerf10e9092014-12-16 19:24:54 -0800167int vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
168 uint32_t digest_size)
169{
170 if (hwcrypto_state != HWCRYPTO_ENABLED)
171 return VB2_ERROR_UNKNOWN;
172
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -0600173 if (retval_vb2_digest_finalize == VB2_SUCCESS)
174 fill_digest(digest, digest_size);
175
Julius Wernerf10e9092014-12-16 19:24:54 -0800176 return retval_vb2_digest_finalize;
177}
178
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800179int vb2_digest_init(struct vb2_digest_context *dc,
180 enum vb2_hash_algorithm hash_alg)
181{
Julius Wernerf10e9092014-12-16 19:24:54 -0800182 if (hwcrypto_state == HWCRYPTO_ENABLED)
183 return VB2_ERROR_UNKNOWN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800184 if (hash_alg != mock_hash_alg)
185 return VB2_ERROR_SHA_INIT_ALGORITHM;
186
187 dc->hash_alg = hash_alg;
Julius Wernerf10e9092014-12-16 19:24:54 -0800188 dc->using_hwcrypto = 0;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800189
190 return VB2_SUCCESS;
191}
192
193int vb2_digest_extend(struct vb2_digest_context *dc,
194 const uint8_t *buf,
195 uint32_t size)
196{
Julius Wernerf10e9092014-12-16 19:24:54 -0800197 if (hwcrypto_state == HWCRYPTO_ENABLED)
198 return VB2_ERROR_UNKNOWN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800199 if (dc->hash_alg != mock_hash_alg)
200 return VB2_ERROR_SHA_EXTEND_ALGORITHM;
201
202 return VB2_SUCCESS;
203}
204
205int vb2_digest_finalize(struct vb2_digest_context *dc,
206 uint8_t *digest,
207 uint32_t digest_size)
208{
Julius Wernerf10e9092014-12-16 19:24:54 -0800209 if (hwcrypto_state == HWCRYPTO_ENABLED)
210 return VB2_ERROR_UNKNOWN;
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -0600211
212 if (retval_vb2_digest_finalize == VB2_SUCCESS)
213 fill_digest(digest, digest_size);
214
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800215 return retval_vb2_digest_finalize;
216}
217
218uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
219{
220 return mock_sig_size;
221}
222
223int vb2_rsa_verify_digest(const struct vb2_public_key *key,
224 uint8_t *sig,
225 const uint8_t *digest,
226 const struct vb2_workbuf *wb)
227{
228 return retval_vb2_verify_digest;
229}
230
231/* Tests */
232
233static void phase3_tests(void)
234{
235 reset_common_data(FOR_MISC);
236 TEST_SUCC(vb2api_fw_phase3(&cc), "phase3 good");
237
238 reset_common_data(FOR_MISC);
239 retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
240 TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
241 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
242 VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
243
244 reset_common_data(FOR_MISC);
245 retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
246 TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
247 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
248 VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
249}
250
251static void init_hash_tests(void)
252{
253 struct vb2_packed_key *k;
254 int wb_used_before;
255 uint32_t size;
256
257 /* For now, all we support is body signature hash */
258 reset_common_data(FOR_MISC);
259 wb_used_before = cc.workbuf_used;
260 TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
261 "init hash good");
262 TEST_EQ(sd->workbuf_hash_offset,
263 (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
264 ~(VB2_WORKBUF_ALIGN - 1),
265 "hash context offset");
266 TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
267 "hash context size");
268 TEST_EQ(cc.workbuf_used,
269 sd->workbuf_hash_offset + sd->workbuf_hash_size,
270 "hash uses workbuf");
271 TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag");
272 TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
273
274 wb_used_before = cc.workbuf_used;
275 TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
276 "init hash again");
277 TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
278
279 reset_common_data(FOR_MISC);
280 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
281 VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
282
283 reset_common_data(FOR_MISC);
284 sd->workbuf_preamble_size = 0;
285 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
286 VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
287
288 reset_common_data(FOR_MISC);
289 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
290 VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
291
292 reset_common_data(FOR_MISC);
293 cc.workbuf_used =
294 cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
295 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
296 VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
297
298 reset_common_data(FOR_MISC);
299 sd->workbuf_data_key_size = 0;
300 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
301 VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
302
303 reset_common_data(FOR_MISC);
304 sd->workbuf_data_key_size--;
305 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
306 VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
307
308 reset_common_data(FOR_MISC);
309 k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
310 k->algorithm--;
311 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
312 VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
313}
314
315static void extend_hash_tests(void)
316{
317 struct vb2_digest_context *dc;
318
319 reset_common_data(FOR_EXTEND_HASH);
320 TEST_SUCC(vb2api_extend_hash(&cc, mock_body, 32),
321 "hash extend good");
322 TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
323 "hash extend remaining");
324 TEST_SUCC(vb2api_extend_hash(&cc, mock_body, mock_body_size - 32),
325 "hash extend again");
326 TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
327
328 reset_common_data(FOR_EXTEND_HASH);
329 sd->workbuf_hash_size = 0;
330 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
331 VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
332
333 reset_common_data(FOR_EXTEND_HASH);
334 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size + 1),
335 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
336
337 reset_common_data(FOR_EXTEND_HASH);
338 TEST_EQ(vb2api_extend_hash(&cc, mock_body, 0),
339 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
340
Julius Wernerf10e9092014-12-16 19:24:54 -0800341 if (hwcrypto_state != HWCRYPTO_ENABLED) {
342 reset_common_data(FOR_EXTEND_HASH);
343 dc = (struct vb2_digest_context *)
344 (cc.workbuf + sd->workbuf_hash_offset);
345 dc->hash_alg = mock_hash_alg + 1;
346 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
347 VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
348 }
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800349}
350
351static void check_hash_tests(void)
352{
353 struct vb2_fw_preamble *pre;
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -0600354 const uint32_t digest_value = 0x0a0a0a0a;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800355
356 reset_common_data(FOR_CHECK_HASH);
357 TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
358
359 reset_common_data(FOR_CHECK_HASH);
Aaron Durbin7cbd1ce2016-01-22 15:06:05 -0600360 TEST_SUCC(vb2api_check_hash_get_digest(&cc, digest_result,
361 digest_result_size), "check hash good with result");
362 /* Check the first 4 bytes to ensure it was copied over. */
363 TEST_SUCC(memcmp(digest_result, &digest_value, sizeof(digest_value)),
364 "check digest value");
365
366 reset_common_data(FOR_CHECK_HASH);
367 TEST_EQ(vb2api_check_hash_get_digest(&cc, digest_result,
368 digest_result_size - 1),
369 VB2_ERROR_API_CHECK_DIGEST_SIZE, "check digest size");
370 TEST_NEQ(memcmp(digest_result, &digest_value, sizeof(digest_value)), 0,
371 "check digest wrong size");
372
373 reset_common_data(FOR_CHECK_HASH);
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800374 sd->workbuf_preamble_size = 0;
375 TEST_EQ(vb2api_check_hash(&cc),
376 VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
377
378 reset_common_data(FOR_CHECK_HASH);
379 sd->workbuf_hash_size = 0;
380 TEST_EQ(vb2api_check_hash(&cc),
381 VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
382
383 reset_common_data(FOR_CHECK_HASH);
384 sd->hash_remaining_size = 1;
385 TEST_EQ(vb2api_check_hash(&cc),
386 VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
387
388 reset_common_data(FOR_CHECK_HASH);
389 cc.workbuf_used = cc.workbuf_size;
390 TEST_EQ(vb2api_check_hash(&cc),
391 VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
392
393 reset_common_data(FOR_CHECK_HASH);
394 retval_vb2_digest_finalize = VB2_ERROR_MOCK;
395 TEST_EQ(vb2api_check_hash(&cc), VB2_ERROR_MOCK, "check hash finalize");
396
397 reset_common_data(FOR_CHECK_HASH);
398 sd->hash_tag = VB2_HASH_TAG_INVALID;
399 TEST_EQ(vb2api_check_hash(&cc),
400 VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
401
402 reset_common_data(FOR_CHECK_HASH);
403 sd->workbuf_data_key_size = 0;
404 TEST_EQ(vb2api_check_hash(&cc),
405 VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
406
407 reset_common_data(FOR_CHECK_HASH);
408 sd->workbuf_data_key_size--;
409 TEST_EQ(vb2api_check_hash(&cc),
410 VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
411
412 reset_common_data(FOR_CHECK_HASH);
413 pre = (struct vb2_fw_preamble *)
414 (cc.workbuf + sd->workbuf_preamble_offset);
415 pre->body_signature.sig_size++;
416 TEST_EQ(vb2api_check_hash(&cc),
417 VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size");
418
419 reset_common_data(FOR_CHECK_HASH);
420 retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST;
421 TEST_EQ(vb2api_check_hash(&cc),
422 VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
423}
424
425int main(int argc, char* argv[])
426{
427 phase3_tests();
Julius Wernerf10e9092014-12-16 19:24:54 -0800428
429 fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
430 hwcrypto_state = HWCRYPTO_DISABLED;
431 init_hash_tests();
432 extend_hash_tests();
433 check_hash_tests();
434
435 fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
436 hwcrypto_state = HWCRYPTO_ENABLED;
437 init_hash_tests();
438 extend_hash_tests();
439 check_hash_tests();
440
441 fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
442 hwcrypto_state = HWCRYPTO_FORBIDDEN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800443 init_hash_tests();
444 extend_hash_tests();
445 check_hash_tests();
446
447 return gTestSuccess ? 0 : 255;
448}