vb21_api_tests.c revision 6f1b82ac14f341d9733d6e95d518b3ee352002ef
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 api 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 "2rsa.h"
16#include "2secdata.h"
17
18#include "vb2_common.h"
19
20#include "host_key2.h"
21#include "host_signature2.h"
22
23#include "test_common.h"
24
25/* Common context for tests */
26static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
27	__attribute__ ((aligned (16)));
28static struct vb2_context ctx;
29static struct vb2_shared_data *sd;
30
31static const uint8_t mock_body[320] = "Mock body";
32static const int mock_body_size = sizeof(mock_body);
33static const int mock_hash_alg = VB2_HASH_SHA256;
34static int mock_sig_size;
35
36static const struct vb2_guid test_guid[4] = {
37	{.raw = {0x11}},
38	{.raw = {0x22}},
39	{.raw = {0x33}},
40	{.raw = {0x44}},
41};
42
43/* Mocked function data */
44static int retval_vb2_load_fw_keyblock;
45static int retval_vb2_load_fw_preamble;
46
47/* Type of test to reset for */
48enum reset_type {
49	FOR_MISC,
50	FOR_EXTEND_HASH,
51	FOR_CHECK_HASH,
52};
53
54static void reset_common_data(enum reset_type t)
55{
56	const struct vb2_private_key *hash_key;
57	struct vb2_fw_preamble2 *pre;
58	struct vb2_signature2 *sig;
59	uint32_t sig_offset;
60
61	int i;
62
63	memset(workbuf, 0xaa, sizeof(workbuf));
64
65	memset(&ctx, 0, sizeof(ctx));
66	ctx.workbuf = workbuf;
67	ctx.workbuf_size = sizeof(workbuf);
68
69	vb2_init_context(&ctx);
70	sd = vb2_get_sd(&ctx);
71
72	vb2_nv_init(&ctx);
73
74	vb2_secdata_create(&ctx);
75	vb2_secdata_init(&ctx);
76
77	retval_vb2_load_fw_keyblock = VB2_SUCCESS;
78	retval_vb2_load_fw_preamble = VB2_SUCCESS;
79
80	vb2_private_key_hash(&hash_key, mock_hash_alg);
81
82	sd->workbuf_preamble_offset = ctx.workbuf_used;
83	pre = (struct vb2_fw_preamble2 *)
84		(ctx.workbuf + sd->workbuf_preamble_offset);
85	pre->hash_count = 3;
86	pre->hash_offset = sig_offset = sizeof(*pre);
87
88	for (i = 0; i < 3; i++) {
89		vb2_sign_data(&sig, mock_body, mock_body_size - 16 * i,
90			      hash_key, NULL);
91		memcpy(&sig->guid, test_guid + i, sizeof(sig->guid));
92		memcpy((uint8_t *)pre + sig_offset, sig, sig->c.total_size);
93		sig_offset += sig->c.total_size;
94		mock_sig_size = sig->c.total_size;
95		free(sig);
96	}
97
98	sd->workbuf_preamble_size = sig_offset;
99	ctx.workbuf_used = sd->workbuf_preamble_offset
100		+ sd->workbuf_preamble_size;
101
102	if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
103		vb2api_init_hash2(&ctx, test_guid, NULL);
104
105	if (t == FOR_CHECK_HASH)
106		vb2api_extend_hash(&ctx, mock_body, mock_body_size);
107};
108
109/* Mocked functions */
110
111int vb2_load_fw_keyblock2(struct vb2_context *ctx)
112{
113	return retval_vb2_load_fw_keyblock;
114}
115
116int vb2_load_fw_preamble2(struct vb2_context *ctx)
117{
118	return retval_vb2_load_fw_preamble;
119}
120
121/* Tests */
122
123static void phase3_tests(void)
124{
125	reset_common_data(FOR_MISC);
126	TEST_SUCC(vb2api_fw_phase3_2(&ctx), "phase3 good");
127
128	reset_common_data(FOR_MISC);
129	retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
130	TEST_EQ(vb2api_fw_phase3_2(&ctx), VB2_ERROR_MOCK, "phase3 keyblock");
131	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST),
132		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
133
134	reset_common_data(FOR_MISC);
135	retval_vb2_load_fw_preamble = VB2_ERROR_MOCK;
136	TEST_EQ(vb2api_fw_phase3_2(&ctx), VB2_ERROR_MOCK, "phase3 keyblock");
137	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST),
138		VB2_RECOVERY_RO_INVALID_RW, "  recovery reason");
139}
140
141static void init_hash_tests(void)
142{
143	struct vb2_fw_preamble2 *pre;
144	struct vb2_signature2 *sig;
145	int wb_used_before;
146	uint32_t size;
147
148	reset_common_data(FOR_MISC);
149	pre = (struct vb2_fw_preamble2 *)
150		(ctx.workbuf + sd->workbuf_preamble_offset);
151	sig = (struct vb2_signature2 *)((uint8_t *)pre + pre->hash_offset);
152
153	wb_used_before = ctx.workbuf_used;
154	TEST_SUCC(vb2api_init_hash2(&ctx, test_guid, &size),
155		  "init hash good");
156	TEST_EQ(sd->workbuf_hash_offset,
157		(wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
158		~(VB2_WORKBUF_ALIGN - 1),
159		"hash context offset");
160	TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
161		"hash context size");
162	TEST_EQ(ctx.workbuf_used,
163		sd->workbuf_hash_offset + sd->workbuf_hash_size,
164		"hash uses workbuf");
165	TEST_EQ(sd->hash_tag,
166		sd->workbuf_preamble_offset + pre->hash_offset,
167		"hash signature offset");
168	TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining");
169
170	wb_used_before = ctx.workbuf_used;
171	TEST_SUCC(vb2api_init_hash2(&ctx, test_guid + 2, NULL),
172		  "init hash again");
173	TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context");
174	TEST_EQ(sd->hash_tag,
175		sd->workbuf_preamble_offset + pre->hash_offset +
176		2 * mock_sig_size,
177		"hash signature offset 2");
178
179	reset_common_data(FOR_MISC);
180	TEST_EQ(vb2api_init_hash2(&ctx, test_guid + 3, &size),
181		VB2_ERROR_API_INIT_HASH_GUID, "init hash invalid guid");
182
183	reset_common_data(FOR_MISC);
184	sd->workbuf_preamble_size = 0;
185	TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
186		VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble");
187
188	reset_common_data(FOR_MISC);
189	ctx.workbuf_used =
190		ctx.workbuf_size - sizeof(struct vb2_digest_context) + 8;
191	TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
192		VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
193
194	reset_common_data(FOR_MISC);
195	sig->hash_alg = VB2_HASH_INVALID;
196	TEST_EQ(vb2api_init_hash2(&ctx, test_guid, &size),
197		VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm");
198}
199
200static void extend_hash_tests(void)
201{
202	struct vb2_digest_context *dc;
203
204	reset_common_data(FOR_EXTEND_HASH);
205	TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, 32),
206		"hash extend good");
207	TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
208		"hash extend remaining");
209	TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, mock_body_size - 32),
210		"hash extend again");
211	TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2");
212
213	reset_common_data(FOR_EXTEND_HASH);
214	sd->workbuf_hash_size = 0;
215	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
216		VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf");
217
218	reset_common_data(FOR_EXTEND_HASH);
219	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size + 1),
220		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much");
221
222	reset_common_data(FOR_EXTEND_HASH);
223	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, 0),
224		VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
225
226	reset_common_data(FOR_EXTEND_HASH);
227	dc = (struct vb2_digest_context *)
228		(ctx.workbuf + sd->workbuf_hash_offset);
229	dc->hash_alg = VB2_HASH_INVALID;
230	TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size),
231		VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
232}
233
234static void check_hash_tests(void)
235{
236	struct vb2_fw_preamble2 *pre;
237	struct vb2_signature2 *sig;
238	struct vb2_digest_context *dc;
239
240	reset_common_data(FOR_CHECK_HASH);
241	pre = (struct vb2_fw_preamble2 *)
242		(ctx.workbuf + sd->workbuf_preamble_offset);
243	sig = (struct vb2_signature2 *)((uint8_t *)pre + pre->hash_offset);
244	dc = (struct vb2_digest_context *)
245		(ctx.workbuf + sd->workbuf_hash_offset);
246
247	TEST_SUCC(vb2api_check_hash2(&ctx), "check hash good");
248
249	reset_common_data(FOR_CHECK_HASH);
250	sd->hash_tag = 0;
251	TEST_EQ(vb2api_check_hash2(&ctx),
252		VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
253
254	reset_common_data(FOR_CHECK_HASH);
255	sd->workbuf_hash_size = 0;
256	TEST_EQ(vb2api_check_hash2(&ctx),
257		VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf");
258
259	reset_common_data(FOR_CHECK_HASH);
260	sd->hash_remaining_size = 1;
261	TEST_EQ(vb2api_check_hash2(&ctx),
262		VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
263
264	reset_common_data(FOR_CHECK_HASH);
265	ctx.workbuf_used = ctx.workbuf_size;
266	TEST_EQ(vb2api_check_hash2(&ctx),
267		VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf");
268
269	reset_common_data(FOR_CHECK_HASH);
270	dc->hash_alg = VB2_HASH_INVALID;
271	*((uint8_t *)sig + sig->sig_offset) ^= 0x55;
272	TEST_EQ(vb2api_check_hash2(&ctx),
273		VB2_ERROR_SHA_FINALIZE_ALGORITHM, "check hash finalize");
274
275	reset_common_data(FOR_CHECK_HASH);
276	*((uint8_t *)sig + sig->sig_offset) ^= 0x55;
277	TEST_EQ(vb2api_check_hash2(&ctx),
278		VB2_ERROR_API_CHECK_HASH_SIG, "check hash sig");
279}
280
281int main(int argc, char* argv[])
282{
283	phase3_tests();
284	init_hash_tests();
285	extend_hash_tests();
286	check_hash_tests();
287
288	return gTestSuccess ? 0 : 255;
289}
290