blob: 90141a9b1a6ebd678e418511af8cca52d7e83792 [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;
30
31/* Mocked function data */
32
Julius Wernerf10e9092014-12-16 19:24:54 -080033static enum {
34 HWCRYPTO_DISABLED,
35 HWCRYPTO_ENABLED,
36 HWCRYPTO_FORBIDDEN,
37} hwcrypto_state;
38
Randall Spangler6f1b82a2014-12-03 12:29:37 -080039static int retval_vb2_load_fw_keyblock;
40static int retval_vb2_load_fw_preamble;
41static int retval_vb2_digest_finalize;
42static int retval_vb2_verify_digest;
43
44/* Type of test to reset for */
45enum reset_type {
46 FOR_MISC,
47 FOR_EXTEND_HASH,
48 FOR_CHECK_HASH,
49};
50
51static void reset_common_data(enum reset_type t)
52{
53 struct vb2_fw_preamble *pre;
54 struct vb2_packed_key *k;
55
56 memset(workbuf, 0xaa, sizeof(workbuf));
57
58 memset(&cc, 0, sizeof(cc));
59 cc.workbuf = workbuf;
60 cc.workbuf_size = sizeof(workbuf);
61
62 vb2_init_context(&cc);
63 sd = vb2_get_sd(&cc);
64
65 vb2_nv_init(&cc);
66
67 vb2_secdata_create(&cc);
68 vb2_secdata_init(&cc);
69
70 retval_vb2_load_fw_keyblock = VB2_SUCCESS;
71 retval_vb2_load_fw_preamble = VB2_SUCCESS;
72 retval_vb2_digest_finalize = VB2_SUCCESS;
73 retval_vb2_verify_digest = VB2_SUCCESS;
74
75 sd->workbuf_preamble_offset = cc.workbuf_used;
76 sd->workbuf_preamble_size = sizeof(*pre);
77 cc.workbuf_used = sd->workbuf_preamble_offset
78 + sd->workbuf_preamble_size;
79 pre = (struct vb2_fw_preamble *)
80 (cc.workbuf + sd->workbuf_preamble_offset);
81 pre->body_signature.data_size = mock_body_size;
82 pre->body_signature.sig_size = mock_sig_size;
Julius Wernerf10e9092014-12-16 19:24:54 -080083 if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
84 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
85 else
86 pre->flags = 0;
Randall Spangler6f1b82a2014-12-03 12:29:37 -080087
88 sd->workbuf_data_key_offset = cc.workbuf_used;
89 sd->workbuf_data_key_size = sizeof(*k) + 8;
90 cc.workbuf_used = sd->workbuf_data_key_offset +
91 sd->workbuf_data_key_size;
92 k = (struct vb2_packed_key *)
93 (cc.workbuf + sd->workbuf_data_key_offset);
94 k->algorithm = mock_algorithm;
95
96 if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
97 vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
98
99 if (t == FOR_CHECK_HASH)
100 vb2api_extend_hash(&cc, mock_body, mock_body_size);
101};
102
103/* Mocked functions */
104
105int vb2_load_fw_keyblock(struct vb2_context *ctx)
106{
107 return retval_vb2_load_fw_keyblock;
108}
109
110int vb2_load_fw_preamble(struct vb2_context *ctx)
111{
112 return retval_vb2_load_fw_preamble;
113}
114
115int vb2_unpack_key(struct vb2_public_key *key,
116 const uint8_t *buf,
117 uint32_t size)
118{
119 struct vb2_packed_key *k = (struct vb2_packed_key *)buf;
120
121 if (size != sizeof(*k) + 8)
122 return VB2_ERROR_UNPACK_KEY_SIZE;
123
124 key->sig_alg = vb2_crypto_to_signature(k->algorithm);
125 key->hash_alg = vb2_crypto_to_hash(k->algorithm);
126
127 return VB2_SUCCESS;
128}
129
Julius Wernerf10e9092014-12-16 19:24:54 -0800130int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
131 uint32_t data_size)
132{
133 switch (hwcrypto_state) {
134 case HWCRYPTO_DISABLED:
135 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
136 case HWCRYPTO_ENABLED:
137 if (hash_alg != mock_hash_alg)
138 return VB2_ERROR_SHA_INIT_ALGORITHM;
139 else
140 return VB2_SUCCESS;
141 case HWCRYPTO_FORBIDDEN:
142 default:
143 return VB2_ERROR_UNKNOWN;
144 }
145}
146
147int vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
148 uint32_t size)
149{
150 if (hwcrypto_state != HWCRYPTO_ENABLED)
151 return VB2_ERROR_UNKNOWN;
152
153 return VB2_SUCCESS;
154}
155
156int vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
157 uint32_t digest_size)
158{
159 if (hwcrypto_state != HWCRYPTO_ENABLED)
160 return VB2_ERROR_UNKNOWN;
161
162 return retval_vb2_digest_finalize;
163}
164
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800165int vb2_digest_init(struct vb2_digest_context *dc,
166 enum vb2_hash_algorithm hash_alg)
167{
Julius Wernerf10e9092014-12-16 19:24:54 -0800168 if (hwcrypto_state == HWCRYPTO_ENABLED)
169 return VB2_ERROR_UNKNOWN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800170 if (hash_alg != mock_hash_alg)
171 return VB2_ERROR_SHA_INIT_ALGORITHM;
172
173 dc->hash_alg = hash_alg;
Julius Wernerf10e9092014-12-16 19:24:54 -0800174 dc->using_hwcrypto = 0;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800175
176 return VB2_SUCCESS;
177}
178
179int vb2_digest_extend(struct vb2_digest_context *dc,
180 const uint8_t *buf,
181 uint32_t size)
182{
Julius Wernerf10e9092014-12-16 19:24:54 -0800183 if (hwcrypto_state == HWCRYPTO_ENABLED)
184 return VB2_ERROR_UNKNOWN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800185 if (dc->hash_alg != mock_hash_alg)
186 return VB2_ERROR_SHA_EXTEND_ALGORITHM;
187
188 return VB2_SUCCESS;
189}
190
191int vb2_digest_finalize(struct vb2_digest_context *dc,
192 uint8_t *digest,
193 uint32_t digest_size)
194{
Julius Wernerf10e9092014-12-16 19:24:54 -0800195 if (hwcrypto_state == HWCRYPTO_ENABLED)
196 return VB2_ERROR_UNKNOWN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800197 return retval_vb2_digest_finalize;
198}
199
200uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
201{
202 return mock_sig_size;
203}
204
205int vb2_rsa_verify_digest(const struct vb2_public_key *key,
206 uint8_t *sig,
207 const uint8_t *digest,
208 const struct vb2_workbuf *wb)
209{
210 return retval_vb2_verify_digest;
211}
212
213/* Tests */
214
215static void phase3_tests(void)
216{
217 reset_common_data(FOR_MISC);
218 TEST_SUCC(vb2api_fw_phase3(&cc), "phase3 good");
219
220 reset_common_data(FOR_MISC);
221 retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
222 TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
223 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
224 VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
225
226 reset_common_data(FOR_MISC);
227 retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
228 TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
229 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
230 VB2_RECOVERY_RO_INVALID_RW, " recovery reason");
231}
232
233static void init_hash_tests(void)
234{
235 struct vb2_packed_key *k;
236 int wb_used_before;
237 uint32_t size;
238
239 /* For now, all we support is body signature hash */
240 reset_common_data(FOR_MISC);
241 wb_used_before = cc.workbuf_used;
242 TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
243 "init hash good");
244 TEST_EQ(sd->workbuf_hash_offset,
245 (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
246 ~(VB2_WORKBUF_ALIGN - 1),
247 "hash context offset");
248 TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
249 "hash context size");
250 TEST_EQ(cc.workbuf_used,
251 sd->workbuf_hash_offset + sd->workbuf_hash_size,
252 "hash uses workbuf");
253 TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag");
254 TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
255
256 wb_used_before = cc.workbuf_used;
257 TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
258 "init hash again");
259 TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
260
261 reset_common_data(FOR_MISC);
262 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
263 VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
264
265 reset_common_data(FOR_MISC);
266 sd->workbuf_preamble_size = 0;
267 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
268 VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
269
270 reset_common_data(FOR_MISC);
271 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
272 VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
273
274 reset_common_data(FOR_MISC);
275 cc.workbuf_used =
276 cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
277 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
278 VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
279
280 reset_common_data(FOR_MISC);
281 sd->workbuf_data_key_size = 0;
282 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
283 VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
284
285 reset_common_data(FOR_MISC);
286 sd->workbuf_data_key_size--;
287 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
288 VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
289
290 reset_common_data(FOR_MISC);
291 k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
292 k->algorithm--;
293 TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
294 VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
295}
296
297static void extend_hash_tests(void)
298{
299 struct vb2_digest_context *dc;
300
301 reset_common_data(FOR_EXTEND_HASH);
302 TEST_SUCC(vb2api_extend_hash(&cc, mock_body, 32),
303 "hash extend good");
304 TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
305 "hash extend remaining");
306 TEST_SUCC(vb2api_extend_hash(&cc, mock_body, mock_body_size - 32),
307 "hash extend again");
308 TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
309
310 reset_common_data(FOR_EXTEND_HASH);
311 sd->workbuf_hash_size = 0;
312 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
313 VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
314
315 reset_common_data(FOR_EXTEND_HASH);
316 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size + 1),
317 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
318
319 reset_common_data(FOR_EXTEND_HASH);
320 TEST_EQ(vb2api_extend_hash(&cc, mock_body, 0),
321 VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
322
Julius Wernerf10e9092014-12-16 19:24:54 -0800323 if (hwcrypto_state != HWCRYPTO_ENABLED) {
324 reset_common_data(FOR_EXTEND_HASH);
325 dc = (struct vb2_digest_context *)
326 (cc.workbuf + sd->workbuf_hash_offset);
327 dc->hash_alg = mock_hash_alg + 1;
328 TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
329 VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
330 }
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800331}
332
333static void check_hash_tests(void)
334{
335 struct vb2_fw_preamble *pre;
336
337 reset_common_data(FOR_CHECK_HASH);
338 TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
339
340 reset_common_data(FOR_CHECK_HASH);
341 sd->workbuf_preamble_size = 0;
342 TEST_EQ(vb2api_check_hash(&cc),
343 VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
344
345 reset_common_data(FOR_CHECK_HASH);
346 sd->workbuf_hash_size = 0;
347 TEST_EQ(vb2api_check_hash(&cc),
348 VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
349
350 reset_common_data(FOR_CHECK_HASH);
351 sd->hash_remaining_size = 1;
352 TEST_EQ(vb2api_check_hash(&cc),
353 VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
354
355 reset_common_data(FOR_CHECK_HASH);
356 cc.workbuf_used = cc.workbuf_size;
357 TEST_EQ(vb2api_check_hash(&cc),
358 VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
359
360 reset_common_data(FOR_CHECK_HASH);
361 retval_vb2_digest_finalize = VB2_ERROR_MOCK;
362 TEST_EQ(vb2api_check_hash(&cc), VB2_ERROR_MOCK, "check hash finalize");
363
364 reset_common_data(FOR_CHECK_HASH);
365 sd->hash_tag = VB2_HASH_TAG_INVALID;
366 TEST_EQ(vb2api_check_hash(&cc),
367 VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
368
369 reset_common_data(FOR_CHECK_HASH);
370 sd->workbuf_data_key_size = 0;
371 TEST_EQ(vb2api_check_hash(&cc),
372 VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
373
374 reset_common_data(FOR_CHECK_HASH);
375 sd->workbuf_data_key_size--;
376 TEST_EQ(vb2api_check_hash(&cc),
377 VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
378
379 reset_common_data(FOR_CHECK_HASH);
380 pre = (struct vb2_fw_preamble *)
381 (cc.workbuf + sd->workbuf_preamble_offset);
382 pre->body_signature.sig_size++;
383 TEST_EQ(vb2api_check_hash(&cc),
384 VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size");
385
386 reset_common_data(FOR_CHECK_HASH);
387 retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST;
388 TEST_EQ(vb2api_check_hash(&cc),
389 VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
390}
391
392int main(int argc, char* argv[])
393{
394 phase3_tests();
Julius Wernerf10e9092014-12-16 19:24:54 -0800395
396 fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
397 hwcrypto_state = HWCRYPTO_DISABLED;
398 init_hash_tests();
399 extend_hash_tests();
400 check_hash_tests();
401
402 fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
403 hwcrypto_state = HWCRYPTO_ENABLED;
404 init_hash_tests();
405 extend_hash_tests();
406 check_hash_tests();
407
408 fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
409 hwcrypto_state = HWCRYPTO_FORBIDDEN;
Randall Spangler6f1b82a2014-12-03 12:29:37 -0800410 init_hash_tests();
411 extend_hash_tests();
412 check_hash_tests();
413
414 return gTestSuccess ? 0 : 255;
415}