1 /* 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 */
20 static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
21 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
22 static struct vb2_context cc;
23 static struct vb2_shared_data *sd;
24
25 const char mock_body[320] = "Mock body";
26 const int mock_body_size = sizeof(mock_body);
27 const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
28 const int mock_hash_alg = VB2_HASH_SHA256;
29 const int mock_sig_size = 64;
30
31 /* Mocked function data */
32
33 static enum {
34 HWCRYPTO_DISABLED,
35 HWCRYPTO_ENABLED,
36 HWCRYPTO_FORBIDDEN,
37 } hwcrypto_state;
38
39 static int retval_vb2_load_fw_keyblock;
40 static int retval_vb2_load_fw_preamble;
41 static int retval_vb2_digest_finalize;
42 static int retval_vb2_verify_digest;
43
44 /* Type of test to reset for */
45 enum reset_type {
46 FOR_MISC,
47 FOR_EXTEND_HASH,
48 FOR_CHECK_HASH,
49 };
50
reset_common_data(enum reset_type t)51 static 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;
83 if (hwcrypto_state == HWCRYPTO_FORBIDDEN)
84 pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;
85 else
86 pre->flags = 0;
87
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
vb2_load_fw_keyblock(struct vb2_context * ctx)105 int vb2_load_fw_keyblock(struct vb2_context *ctx)
106 {
107 return retval_vb2_load_fw_keyblock;
108 }
109
vb2_load_fw_preamble(struct vb2_context * ctx)110 int vb2_load_fw_preamble(struct vb2_context *ctx)
111 {
112 return retval_vb2_load_fw_preamble;
113 }
114
vb2_unpack_key(struct vb2_public_key * key,const uint8_t * buf,uint32_t size)115 int 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
vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,uint32_t data_size)130 int 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
vb2ex_hwcrypto_digest_extend(const uint8_t * buf,uint32_t size)147 int 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
vb2ex_hwcrypto_digest_finalize(uint8_t * digest,uint32_t digest_size)156 int 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
vb2_digest_init(struct vb2_digest_context * dc,enum vb2_hash_algorithm hash_alg)165 int vb2_digest_init(struct vb2_digest_context *dc,
166 enum vb2_hash_algorithm hash_alg)
167 {
168 if (hwcrypto_state == HWCRYPTO_ENABLED)
169 return VB2_ERROR_UNKNOWN;
170 if (hash_alg != mock_hash_alg)
171 return VB2_ERROR_SHA_INIT_ALGORITHM;
172
173 dc->hash_alg = hash_alg;
174 dc->using_hwcrypto = 0;
175
176 return VB2_SUCCESS;
177 }
178
vb2_digest_extend(struct vb2_digest_context * dc,const uint8_t * buf,uint32_t size)179 int vb2_digest_extend(struct vb2_digest_context *dc,
180 const uint8_t *buf,
181 uint32_t size)
182 {
183 if (hwcrypto_state == HWCRYPTO_ENABLED)
184 return VB2_ERROR_UNKNOWN;
185 if (dc->hash_alg != mock_hash_alg)
186 return VB2_ERROR_SHA_EXTEND_ALGORITHM;
187
188 return VB2_SUCCESS;
189 }
190
vb2_digest_finalize(struct vb2_digest_context * dc,uint8_t * digest,uint32_t digest_size)191 int vb2_digest_finalize(struct vb2_digest_context *dc,
192 uint8_t *digest,
193 uint32_t digest_size)
194 {
195 if (hwcrypto_state == HWCRYPTO_ENABLED)
196 return VB2_ERROR_UNKNOWN;
197 return retval_vb2_digest_finalize;
198 }
199
vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)200 uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
201 {
202 return mock_sig_size;
203 }
204
vb2_rsa_verify_digest(const struct vb2_public_key * key,uint8_t * sig,const uint8_t * digest,const struct vb2_workbuf * wb)205 int 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
phase3_tests(void)215 static 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
init_hash_tests(void)233 static 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
extend_hash_tests(void)297 static 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
323 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 }
331 }
332
check_hash_tests(void)333 static 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
main(int argc,char * argv[])392 int main(int argc, char* argv[])
393 {
394 phase3_tests();
395
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;
410 init_hash_tests();
411 extend_hash_tests();
412 check_hash_tests();
413
414 return gTestSuccess ? 0 : 255;
415 }
416