blob: 4d8045091edb56e17933843b433a63018ec144ec [file] [log] [blame]
Randall Spangler3333e572014-05-14 11:37:52 -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
Randall Spanglerda2b49c2014-06-10 17:03:40 -07008#include "2sysincludes.h"
Randall Spangler3333e572014-05-14 11:37:52 -07009#include "2api.h"
10#include "2common.h"
11#include "2misc.h"
Randall Spanglerda2b49c2014-06-10 17:03:40 -070012#include "2nvstorage.h"
13#include "2secdata.h"
Randall Spangler3333e572014-05-14 11:37:52 -070014
Randall Spanglerda2b49c2014-06-10 17:03:40 -070015#include "test_common.h"
16
17/* Common context for tests */
18static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
Bill Richardson73e5eb32015-01-26 12:18:25 -080019 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
Randall Spanglerda2b49c2014-06-10 17:03:40 -070020static struct vb2_context cc;
21static struct vb2_shared_data *sd;
22
23/* Mocked function data */
24enum vb2_resource_index mock_resource_index;
25void *mock_resource_ptr;
26uint32_t mock_resource_size;
27int mock_tpm_clear_called;
28int mock_tpm_clear_retval;
29
30
31static void reset_common_data(void)
Randall Spangler3333e572014-05-14 11:37:52 -070032{
Randall Spanglerda2b49c2014-06-10 17:03:40 -070033 memset(workbuf, 0xaa, sizeof(workbuf));
Randall Spangler3333e572014-05-14 11:37:52 -070034
Randall Spanglerda2b49c2014-06-10 17:03:40 -070035 memset(&cc, 0, sizeof(cc));
36 cc.workbuf = workbuf;
37 cc.workbuf_size = sizeof(workbuf);
38
39 vb2_init_context(&cc);
40 sd = vb2_get_sd(&cc);
41
42 vb2_nv_init(&cc);
43
44 vb2_secdata_create(&cc);
45 vb2_secdata_init(&cc);
46
47 mock_tpm_clear_called = 0;
48 mock_tpm_clear_retval = VB2_SUCCESS;
49};
50
51/* Mocked functions */
52
53int vb2ex_read_resource(struct vb2_context *ctx,
54 enum vb2_resource_index index,
55 uint32_t offset,
56 void *buf,
57 uint32_t size)
58{
59 if (index != mock_resource_index)
60 return VB2_ERROR_EX_READ_RESOURCE_INDEX;
61
62 if (offset > mock_resource_size || offset + size > mock_resource_size)
63 return VB2_ERROR_EX_READ_RESOURCE_SIZE;
64
65 memcpy(buf, (uint8_t *)mock_resource_ptr + offset, size);
66 return VB2_SUCCESS;
67}
68
69int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
70{
71 mock_tpm_clear_called++;
72
73 return mock_tpm_clear_retval;
74}
75
76/* Tests */
77
78static void init_context_tests(void)
79{
80 /* Use our own context struct so we can re-init it */
Randall Spangler3333e572014-05-14 11:37:52 -070081 struct vb2_context c = {
82 .workbuf = workbuf,
83 .workbuf_size = sizeof(workbuf),
84 };
85
Randall Spanglerda2b49c2014-06-10 17:03:40 -070086 reset_common_data();
87
Randall Spangler224f5ac2014-06-06 09:42:30 -070088 TEST_SUCC(vb2_init_context(&c), "Init context good");
Randall Spangler3333e572014-05-14 11:37:52 -070089 TEST_EQ(c.workbuf_used, sizeof(struct vb2_shared_data),
90 "Init vbsd");
91
92 /* Don't re-init if used is non-zero */
93 c.workbuf_used = 200;
Randall Spangler224f5ac2014-06-06 09:42:30 -070094 TEST_SUCC(vb2_init_context(&c), "Re-init context good");
Randall Spangler3333e572014-05-14 11:37:52 -070095 TEST_EQ(c.workbuf_used, 200, "Didn't re-init");
96
97 /* Handle workbuf errors */
98 c.workbuf_used = 0;
99 c.workbuf_size = sizeof(struct vb2_shared_data) - 1;
Randall Spangler224f5ac2014-06-06 09:42:30 -0700100 TEST_EQ(vb2_init_context(&c),
101 VB2_ERROR_INITCTX_WORKBUF_SMALL, "Init too small");
Randall Spangler3333e572014-05-14 11:37:52 -0700102 c.workbuf_size = sizeof(workbuf);
103
104 /* Handle workbuf unaligned */
105 c.workbuf++;
Randall Spangler224f5ac2014-06-06 09:42:30 -0700106 TEST_EQ(vb2_init_context(&c),
107 VB2_ERROR_INITCTX_WORKBUF_ALIGN, "Init unaligned");
Randall Spangler3333e572014-05-14 11:37:52 -0700108}
109
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700110static void misc_tests(void)
111{
112 struct vb2_workbuf wb;
113
114 reset_common_data();
115 cc.workbuf_used = 16;
116
117 vb2_workbuf_from_ctx(&cc, &wb);
118
119 TEST_PTR_EQ(wb.buf, workbuf + 16, "vb_workbuf_from_ctx() buf");
120 TEST_EQ(wb.size, cc.workbuf_size - 16, "vb_workbuf_from_ctx() size");
121}
122
123static void gbb_tests(void)
124{
125 struct vb2_gbb_header gbb = {
126 .signature = {'$', 'G', 'B', 'B'},
127 .major_version = VB2_GBB_MAJOR_VER,
128 .minor_version = VB2_GBB_MINOR_VER,
129 .header_size = sizeof(struct vb2_gbb_header),
130 .flags = 0x1234,
131 .rootkey_offset = 240,
132 .rootkey_size = 1040,
133 };
134
135 struct vb2_gbb_header gbbdest;
136
Bill Richardson6df3e332014-10-02 18:50:33 -0700137 TEST_EQ(sizeof(struct vb2_gbb_header),
Randall Spangler21f100c2014-10-16 10:32:43 -0700138 EXPECTED_VB2_GBB_HEADER_SIZE,
Bill Richardson6df3e332014-10-02 18:50:33 -0700139 "sizeof(struct vb2_gbb_header)");
140
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700141 reset_common_data();
142
143 /* Good contents */
144 mock_resource_index = VB2_RES_GBB;
145 mock_resource_ptr = &gbb;
146 mock_resource_size = sizeof(gbb);
147 TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest), "read gbb header good");
148 TEST_SUCC(memcmp(&gbb, &gbbdest, sizeof(gbb)), "read gbb contents");
149
150 mock_resource_index = VB2_RES_GBB + 1;
151 TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
152 VB2_ERROR_EX_READ_RESOURCE_INDEX, "read gbb header missing");
153 mock_resource_index = VB2_RES_GBB;
154
155 gbb.signature[0]++;
156 TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
157 VB2_ERROR_GBB_MAGIC, "read gbb header bad magic");
158 gbb.signature[0]--;
159
Randall Spanglerb035e372014-10-22 15:21:32 -0700160 gbb.major_version = VB2_GBB_MAJOR_VER + 1;
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700161 TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
162 VB2_ERROR_GBB_VERSION, "read gbb header major version");
Randall Spanglerb035e372014-10-22 15:21:32 -0700163 gbb.major_version = VB2_GBB_MAJOR_VER;
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700164
Randall Spanglerb035e372014-10-22 15:21:32 -0700165 gbb.minor_version = VB2_GBB_MINOR_VER + 1;
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700166 TEST_SUCC(vb2_read_gbb_header(&cc, &gbbdest),
167 "read gbb header minor++");
Randall Spanglerb035e372014-10-22 15:21:32 -0700168 gbb.minor_version = 1;
Daisuke Nojiridc49a682015-05-13 15:32:14 -0700169 TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
170 VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.1 fails");
Randall Spanglerb035e372014-10-22 15:21:32 -0700171 gbb.minor_version = 0;
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700172 TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
Randall Spanglerb035e372014-10-22 15:21:32 -0700173 VB2_ERROR_GBB_TOO_OLD, "read gbb header 1.0 fails");
174 gbb.minor_version = VB2_GBB_MINOR_VER;
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700175
176 gbb.header_size--;
177 TEST_EQ(vb2_read_gbb_header(&cc, &gbbdest),
178 VB2_ERROR_GBB_HEADER_SIZE, "read gbb header size");
179 TEST_EQ(vb2_fw_parse_gbb(&cc),
180 VB2_ERROR_GBB_HEADER_SIZE, "parse gbb failure");
181 gbb.header_size++;
182
183 /* Parse GBB */
184 TEST_SUCC(vb2_fw_parse_gbb(&cc), "parse gbb");
185 TEST_EQ(sd->gbb_flags, gbb.flags, "gbb flags");
186 TEST_EQ(sd->gbb_rootkey_offset, gbb.rootkey_offset, "rootkey offset");
187 TEST_EQ(sd->gbb_rootkey_size, gbb.rootkey_size, "rootkey size");
188
189 /* Workbuf failure */
190 reset_common_data();
191 cc.workbuf_used = cc.workbuf_size - 4;
192 TEST_EQ(vb2_fw_parse_gbb(&cc),
193 VB2_ERROR_GBB_WORKBUF, "parse gbb no workbuf");
194}
195
196static void fail_tests(void)
197{
198 /* Early fail (before even NV init) */
199 reset_common_data();
200 sd->status &= ~VB2_SD_STATUS_NV_INIT;
201 vb2_fail(&cc, 1, 2);
202 TEST_NEQ(sd->status & VB2_SD_STATUS_NV_INIT, 0, "vb2_fail inits NV");
203 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
204 1, "vb2_fail request");
205 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
206 2, "vb2_fail subcode");
207
208 /* Repeated fail doesn't overwrite the error code */
209 vb2_fail(&cc, 3, 4);
210 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
211 1, "vb2_fail repeat");
212 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
213 2, "vb2_fail repeat2");
214
215 /* Fail with other slot good doesn't trigger recovery */
216 reset_common_data();
217 vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
218 vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
219 sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
220 sd->fw_slot = 0;
221 sd->last_fw_slot = 1;
222 sd->last_fw_result = VB2_FW_RESULT_UNKNOWN;
223 vb2_fail(&cc, 5, 6);
224 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "vb2_failover");
225 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
226 VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
227 TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 0, "vb2_fail use up tries");
228 TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "vb2_fail try other slot");
229
230 /* Fail with other slot already failing triggers recovery */
231 reset_common_data();
232 sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
233 sd->fw_slot = 1;
234 sd->last_fw_slot = 0;
235 sd->last_fw_result = VB2_FW_RESULT_FAILURE;
236 vb2_fail(&cc, 7, 8);
237 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 7,
238 "vb2_fail both slots bad");
239 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
240 VB2_FW_RESULT_FAILURE, "vb2_fail this fw");
241 TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 0, "vb2_fail try other slot");
242}
243
244static void recovery_tests(void)
245{
246 /* No recovery */
247 reset_common_data();
248 vb2_check_recovery(&cc);
249 TEST_EQ(sd->recovery_reason, 0, "No recovery reason");
250 TEST_EQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
251 0, "Not manual recovery");
252 TEST_EQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE,
253 0, "Not recovery mode");
254
255 /* From request */
256 reset_common_data();
257 vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, 3);
258 vb2_check_recovery(&cc);
259 TEST_EQ(sd->recovery_reason, 3, "Recovery reason from request");
260 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0, "NV cleared");
261 TEST_EQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
262 0, "Not manual recovery");
263 TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE,
264 0, "Recovery mode");
265
266 /* From request, but already failed */
267 reset_common_data();
268 vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, 4);
269 sd->recovery_reason = 5;
270 vb2_check_recovery(&cc);
271 TEST_EQ(sd->recovery_reason, 5, "Recovery reason already failed");
272 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
273 0, "NV still cleared");
274
275 /* Override */
276 reset_common_data();
277 sd->recovery_reason = 6;
278 cc.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
279 vb2_check_recovery(&cc);
280 TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_MANUAL,
281 "Recovery reason forced");
282 TEST_NEQ(sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY,
283 0, "SD flag set");
284}
285
286static void dev_switch_tests(void)
287{
288 uint32_t v;
289
290 /* Normal mode */
291 reset_common_data();
292 TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
293 TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd not in dev");
294 TEST_EQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "ctx not in dev");
295 TEST_EQ(mock_tpm_clear_called, 0, "no tpm clear");
296
297 /* Dev mode */
298 reset_common_data();
299 vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
300 (VB2_SECDATA_FLAG_DEV_MODE |
301 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER));
302 TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode on");
303 TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd in dev");
304 TEST_NEQ(cc.flags & VB2_CONTEXT_DEVELOPER_MODE, 0, "ctx in dev");
305 TEST_EQ(mock_tpm_clear_called, 0, "no tpm clear");
306
307 /* Any normal mode boot clears dev boot flags */
308 reset_common_data();
309 vb2_nv_set(&cc, VB2_NV_DEV_BOOT_USB, 1);
310 vb2_nv_set(&cc, VB2_NV_DEV_BOOT_LEGACY, 1);
311 vb2_nv_set(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
312 TEST_SUCC(vb2_check_dev_switch(&cc), "dev mode off");
313 TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_USB),
314 0, "cleared dev boot usb");
315 TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_LEGACY),
316 0, "cleared dev boot legacy");
317 TEST_EQ(vb2_nv_get(&cc, VB2_NV_DEV_BOOT_SIGNED_ONLY),
318 0, "cleared dev boot signed only");
319
320 /* Normal-dev transition clears TPM */
321 reset_common_data();
322 vb2_secdata_set(&cc, VB2_SECDATA_FLAGS, VB2_SECDATA_FLAG_DEV_MODE);
323 TEST_SUCC(vb2_check_dev_switch(&cc), "to dev mode");
324 TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
325 vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
326 TEST_EQ(v, (VB2_SECDATA_FLAG_DEV_MODE |
327 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER),
328 "last boot developer now");
329
330 /* Dev-normal transition clears TPM too */
331 reset_common_data();
332 vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
333 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER);
334 TEST_SUCC(vb2_check_dev_switch(&cc), "from dev mode");
335 TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
336 vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
337 TEST_EQ(v, 0, "last boot not developer now");
338
339 /* Disable dev mode */
340 reset_common_data();
341 vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
342 (VB2_SECDATA_FLAG_DEV_MODE |
343 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER));
344 vb2_nv_set(&cc, VB2_NV_DISABLE_DEV_REQUEST, 1);
345 TEST_SUCC(vb2_check_dev_switch(&cc), "disable dev request");
346 TEST_EQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd not in dev");
347 TEST_EQ(vb2_nv_get(&cc, VB2_NV_DISABLE_DEV_REQUEST),
348 0, "request cleared");
349
350 /* Force enabled by gbb */
351 reset_common_data();
352 sd->gbb_flags |= VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON;
353 TEST_SUCC(vb2_check_dev_switch(&cc), "dev on via gbb");
354 TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd in dev");
355 vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
356 TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
357 "doesn't set dev on in secdata but does set last boot dev");
358 TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
359
360 /* Force enabled by ctx flag */
361 reset_common_data();
362 cc.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
363 TEST_SUCC(vb2_check_dev_switch(&cc), "dev on via ctx flag");
364 TEST_NEQ(sd->flags & VB2_SD_DEV_MODE_ENABLED, 0, "sd in dev");
365 vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
366 TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
367 "doesn't set dev on in secdata but does set last boot dev");
368 TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
369
370 /* Simulate clear owner failure */
371 reset_common_data();
372 vb2_secdata_set(&cc, VB2_SECDATA_FLAGS,
373 VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER);
374 mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
375 TEST_EQ(vb2_check_dev_switch(&cc),
376 VB2_ERROR_EX_TPM_CLEAR_OWNER, "tpm clear fail");
377 TEST_EQ(mock_tpm_clear_called, 1, "tpm clear");
378 vb2_secdata_get(&cc, VB2_SECDATA_FLAGS, &v);
379 TEST_EQ(v, VB2_SECDATA_FLAG_LAST_BOOT_DEVELOPER,
380 "last boot still developer");
381 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
382 VB2_RECOVERY_TPM_CLEAR_OWNER, "requests recovery");
383 TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_SUBCODE),
384 (uint8_t)VB2_ERROR_EX_TPM_CLEAR_OWNER, "recovery subcode");
385}
386
387static void tpm_clear_tests(void)
388{
389 /* No clear request */
390 reset_common_data();
391 TEST_SUCC(vb2_check_tpm_clear(&cc), "no clear request");
392 TEST_EQ(mock_tpm_clear_called, 0, "tpm not cleared");
393
394 /* Successful request */
395 reset_common_data();
396 vb2_nv_set(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
397 TEST_SUCC(vb2_check_tpm_clear(&cc), "clear request");
398 TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
399 0, "request cleared");
400 TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_DONE),
401 1, "done set");
402 TEST_EQ(mock_tpm_clear_called, 1, "tpm cleared");
403
404 /* Failed request */
405 reset_common_data();
406 mock_tpm_clear_retval = VB2_ERROR_EX_TPM_CLEAR_OWNER;
407 vb2_nv_set(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 1);
408 TEST_EQ(vb2_check_tpm_clear(&cc),
409 VB2_ERROR_EX_TPM_CLEAR_OWNER, "clear failure");
410 TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_REQUEST),
411 0, "request cleared");
412 TEST_EQ(vb2_nv_get(&cc, VB2_NV_CLEAR_TPM_OWNER_DONE),
413 0, "done not set");
414}
415
416static void select_slot_tests(void)
417{
418 /* Slot A */
419 reset_common_data();
420 TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A");
421 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
422 VB2_FW_RESULT_UNKNOWN, "result unknown");
423 TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
Randall Spanglerd300ca82014-10-02 11:59:30 -0700424 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700425 TEST_EQ(sd->fw_slot, 0, "selected A");
426 TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
427
428 /* Slot B */
429 reset_common_data();
430 vb2_nv_set(&cc, VB2_NV_TRY_NEXT, 1);
431 TEST_SUCC(vb2_select_fw_slot(&cc), "select slot B");
432 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
433 VB2_FW_RESULT_UNKNOWN, "result unknown");
434 TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
Randall Spanglerd300ca82014-10-02 11:59:30 -0700435 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700436 TEST_EQ(sd->fw_slot, 1, "selected B");
437 TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
438
439 /* Slot A ran out of tries */
440 reset_common_data();
441 vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
442 TEST_SUCC(vb2_select_fw_slot(&cc), "select slot A out of tries");
443 TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_NEXT), 1, "try B next");
444 TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
Randall Spanglerd300ca82014-10-02 11:59:30 -0700445 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 1, "tried B");
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700446 TEST_EQ(sd->fw_slot, 1, "selected B");
447 TEST_NEQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "ctx says choose B");
448
449 /* Slot A used up a try */
450 reset_common_data();
451 vb2_nv_set(&cc, VB2_NV_TRY_COUNT, 3);
452 TEST_SUCC(vb2_select_fw_slot(&cc), "try slot A");
453 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_RESULT),
454 VB2_FW_RESULT_TRYING, "result trying");
455 TEST_NEQ(sd->status & VB2_SD_STATUS_CHOSE_SLOT, 0, "chose slot");
Randall Spanglerd300ca82014-10-02 11:59:30 -0700456 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_TRIED), 0, "tried A");
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700457 TEST_EQ(sd->fw_slot, 0, "selected A");
458 TEST_EQ(cc.flags & VB2_CONTEXT_FW_SLOT_B, 0, "didn't choose B");
459 TEST_EQ(vb2_nv_get(&cc, VB2_NV_TRY_COUNT), 2, "tries decremented");
Randall Spangler782300d2014-09-23 12:20:31 -0700460
461 /* Tried/result get copied to the previous fields */
462 reset_common_data();
463 vb2_nv_set(&cc, VB2_NV_FW_TRIED, 0);
464 vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_SUCCESS);
465 vb2_select_fw_slot(&cc);
466 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_TRIED), 0, "prev A");
467 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_RESULT), VB2_FW_RESULT_SUCCESS,
468 "prev success");
469
470 reset_common_data();
471 vb2_nv_set(&cc, VB2_NV_FW_TRIED, 1);
472 vb2_nv_set(&cc, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
473 vb2_select_fw_slot(&cc);
474 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_TRIED), 1, "prev B");
475 TEST_EQ(vb2_nv_get(&cc, VB2_NV_FW_PREV_RESULT), VB2_FW_RESULT_FAILURE,
476 "prev failure");
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700477}
478
Randall Spangler3333e572014-05-14 11:37:52 -0700479int main(int argc, char* argv[])
480{
Randall Spanglerda2b49c2014-06-10 17:03:40 -0700481 init_context_tests();
482 misc_tests();
483 gbb_tests();
484 fail_tests();
485 recovery_tests();
486 dev_switch_tests();
487 tpm_clear_tests();
488 select_slot_tests();
Randall Spangler3333e572014-05-14 11:37:52 -0700489
490 return gTestSuccess ? 0 : 255;
491}