1 /* Copyright (c) 2013 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 vboot_api_init
6 */
7
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "gbb_header.h"
13 #include "host_common.h"
14 #include "rollback_index.h"
15 #include "test_common.h"
16 #include "vboot_common.h"
17 #include "vboot_nvstorage.h"
18 #include "vboot_struct.h"
19
20 /* Mock data */
21 static VbCommonParams cparams;
22 static VbInitParams iparams;
23 static VbNvContext vnc;
24 static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
25 static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
26 static uint64_t mock_timer;
27 static int rollback_s3_retval;
28 static int nv_write_called;
29 static GoogleBinaryBlockHeader gbb;
30 static int mock_virt_dev_sw;
31 static uint32_t mock_tpm_version;
32 static uint32_t mock_rfs_retval;
33 static int rfs_clear_tpm_request;
34 static int rfs_disable_dev_request;
35 static uint8_t backup_space[BACKUP_NV_SIZE];
36 static int backup_write_called;
37 static int backup_read_called;
38
39 /* Reset mock data (for use before each test) */
ResetMocks(void)40 static void ResetMocks(void)
41 {
42 Memset(&cparams, 0, sizeof(cparams));
43 cparams.shared_data_size = sizeof(shared_data);
44 cparams.shared_data_blob = shared_data;
45 cparams.gbb_data = &gbb;
46 cparams.gbb_size = sizeof(gbb);
47
48 Memset(&gbb, 0, sizeof(gbb));
49 gbb.major_version = GBB_MAJOR_VER;
50 gbb.minor_version = GBB_MINOR_VER;
51 gbb.flags = 0;
52
53 Memset(&iparams, 0, sizeof(iparams));
54
55 Memset(&vnc, 0, sizeof(vnc));
56 VbNvSetup(&vnc);
57 VbNvTeardown(&vnc); /* So CRC gets generated */
58
59 Memset(backup_space, 0, sizeof(backup_space));
60 backup_write_called = 0;
61 backup_read_called = 0;
62
63 Memset(&shared_data, 0, sizeof(shared_data));
64 VbSharedDataInit(shared, sizeof(shared_data));
65
66 mock_timer = 10;
67 rollback_s3_retval = TPM_SUCCESS;
68 nv_write_called = 0;
69
70 mock_virt_dev_sw = 0;
71 mock_tpm_version = 0x10001;
72 mock_rfs_retval = 0;
73
74 rfs_clear_tpm_request = 0;
75 rfs_disable_dev_request = 0;
76 }
77
78 /****************************************************************************/
79 /* Mocked verification functions */
80
VbExNvStorageRead(uint8_t * buf)81 VbError_t VbExNvStorageRead(uint8_t *buf)
82 {
83 Memcpy(buf, vnc.raw, sizeof(vnc.raw));
84 return VBERROR_SUCCESS;
85 }
86
VbExNvStorageWrite(const uint8_t * buf)87 VbError_t VbExNvStorageWrite(const uint8_t *buf)
88 {
89 nv_write_called++;
90 Memcpy(vnc.raw, buf, sizeof(vnc.raw));
91 return VBERROR_SUCCESS;
92 }
93
RollbackBackupRead(uint8_t * raw)94 uint32_t RollbackBackupRead(uint8_t *raw)
95 {
96 backup_read_called++;
97 Memcpy(raw, backup_space, sizeof(backup_space));
98 return TPM_SUCCESS;
99 }
100
RollbackBackupWrite(uint8_t * raw)101 uint32_t RollbackBackupWrite(uint8_t *raw)
102 {
103 backup_write_called++;
104 Memcpy(backup_space, raw, sizeof(backup_space));
105 return TPM_SUCCESS;
106 }
107
VbExGetTimer(void)108 uint64_t VbExGetTimer(void)
109 {
110 /*
111 * Exponential-ish rather than linear time, so that subtracting any
112 * two mock values will yield a unique result.
113 */
114 uint64_t new_timer = mock_timer * 2 + 1;
115 VbAssert(new_timer > mock_timer); /* Make sure we don't overflow */
116 mock_timer = new_timer;
117 return mock_timer;
118 }
119
RollbackS3Resume(void)120 uint32_t RollbackS3Resume(void)
121 {
122 return rollback_s3_retval;
123 }
124
RollbackFirmwareSetup(int is_hw_dev,int disable_dev_request,int clear_tpm_owner_request,int * is_virt_dev,uint32_t * version)125 uint32_t RollbackFirmwareSetup(int is_hw_dev,
126 int disable_dev_request,
127 int clear_tpm_owner_request,
128 /* two outputs on success */
129 int *is_virt_dev, uint32_t *version)
130 {
131 rfs_clear_tpm_request = clear_tpm_owner_request;
132 rfs_disable_dev_request = disable_dev_request;
133
134 *is_virt_dev = mock_virt_dev_sw;
135 *version = mock_tpm_version;
136 return mock_rfs_retval;
137 }
138
139 /****************************************************************************/
140 /* Test VbInit() and check expected return value and recovery reason */
141
TestVbInit(VbError_t expected_retval,uint8_t expected_recovery,const char * desc)142 static void TestVbInit(VbError_t expected_retval,
143 uint8_t expected_recovery, const char *desc)
144 {
145 uint32_t rr = 256;
146
147 TEST_EQ(VbInit(&cparams, &iparams), expected_retval, desc);
148 VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &rr);
149 TEST_EQ(rr, expected_recovery, " (recovery request)");
150 }
151
152 /****************************************************************************/
153
VbInitTest(void)154 static void VbInitTest(void)
155 {
156 uint32_t u;
157
158 /* Test passing in too small a shared data area */
159 ResetMocks();
160 cparams.shared_data_size = VB_SHARED_DATA_MIN_SIZE - 1;
161 TestVbInit(VBERROR_INIT_SHARED_DATA, 0, "Shared data too small");
162
163 /* Normal call; dev=0 rec=0 */
164 ResetMocks();
165 TestVbInit(0, 0, "Normal call");
166 TEST_EQ(shared->timer_vb_init_enter, 21, " time enter");
167 TEST_EQ(shared->timer_vb_init_exit, 43, " time exit");
168 TEST_EQ(shared->flags, 0, " shared flags");
169 TEST_EQ(iparams.out_flags, 0, " out flags");
170 TEST_EQ(nv_write_called, 0,
171 " NV write not called since nothing changed");
172
173 /* If NV data is trashed, we initialize it */
174 ResetMocks();
175 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
176 /*
177 * Note that we're not doing a VbNvTeardown(), so the CRC hasn't been
178 * regenerated yet. So VbInit() should ignore the corrupted recovery
179 * value and boot normally.
180 */
181 TestVbInit(0, 0, "NV data trashed");
182 TEST_EQ(nv_write_called, 1, " NV write called");
183
184 /*
185 * Test boot switch flags which are just passed through to shared
186 * flags, and don't have an effect on VbInit().
187 */
188 ResetMocks();
189 iparams.flags = VB_INIT_FLAG_WP_ENABLED;
190 TestVbInit(0, 0, "Flags test WP");
191 TEST_EQ(shared->flags, VBSD_BOOT_FIRMWARE_WP_ENABLED,
192 " shared flags");
193
194 ResetMocks();
195 iparams.flags = VB_INIT_FLAG_SW_WP_ENABLED;
196 TestVbInit(0, 0, "Flags test SW WP");
197 TEST_EQ(shared->flags, VBSD_BOOT_FIRMWARE_SW_WP_ENABLED,
198 " shared flags");
199
200 ResetMocks();
201 iparams.flags = VB_INIT_FLAG_RO_NORMAL_SUPPORT;
202 TestVbInit(0, 0, " flags test RO normal");
203 TEST_EQ(shared->flags, VBSD_BOOT_RO_NORMAL_SUPPORT,
204 " shared flags");
205
206 ResetMocks();
207 iparams.flags = VB_INIT_FLAG_EC_SOFTWARE_SYNC;
208 TestVbInit(0, 0, " flags test EC software sync");
209 TEST_EQ(shared->flags, VBSD_EC_SOFTWARE_SYNC, " shared flags");
210
211 ResetMocks();
212 iparams.flags = VB_INIT_FLAG_EC_SLOW_UPDATE;
213 TestVbInit(0, 0, " flags test EC slow update");
214 TEST_EQ(shared->flags, VBSD_EC_SLOW_UPDATE, " shared flags");
215
216 /* S3 resume */
217 ResetMocks();
218 iparams.flags = VB_INIT_FLAG_S3_RESUME;
219 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
220 VbNvTeardown(&vnc);
221 /* S3 resume doesn't clear the recovery request (or act on it) */
222 TestVbInit(0, 123, "S3 resume");
223 TEST_EQ(shared->flags, VBSD_BOOT_S3_RESUME, " shared flags S3");
224 TEST_EQ(iparams.out_flags, 0, " out flags");
225 TEST_EQ(shared->recovery_reason, 0,
226 " S3 doesn't look at recovery request");
227
228 /* S3 resume with TPM resume error */
229 ResetMocks();
230 iparams.flags = VB_INIT_FLAG_S3_RESUME;
231 rollback_s3_retval = 1;
232 /* S3 resume doesn't clear the recovery request (or act on it) */
233 TestVbInit(VBERROR_TPM_S3_RESUME, 0, "S3 resume rollback error");
234
235 /*
236 * Normal boot doesn't care about TPM resume error because it doesn't
237 * call RollbackS3Resume().
238 */
239 ResetMocks();
240 rollback_s3_retval = 1;
241 TestVbInit(0, 0, "Normal doesn't S3 resume");
242
243 /* S3 resume with debug reset */
244 ResetMocks();
245 iparams.flags = VB_INIT_FLAG_S3_RESUME;
246 VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 1);
247 VbNvTeardown(&vnc);
248 TestVbInit(0, 0, "S3 debug reset");
249 TEST_EQ(iparams.out_flags, VB_INIT_OUT_S3_DEBUG_BOOT, " out flags");
250 VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &u);
251 TEST_EQ(u, 0, " S3 clears nv debug reset mode");
252
253 /* Normal boot clears S3 debug reset mode; doesn't set output flag */
254 ResetMocks();
255 VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 1);
256 VbNvTeardown(&vnc);
257 TestVbInit(0, 0, "Normal with debug reset mode");
258 TEST_EQ(iparams.out_flags, 0, " out flags");
259 VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &u);
260 TEST_EQ(u, 0, " normal clears nv debug reset mode");
261
262 /*
263 * S3 resume with debug reset is a normal boot, so doesn't resume the
264 * TPM.
265 */
266 ResetMocks();
267 iparams.flags = VB_INIT_FLAG_S3_RESUME;
268 rollback_s3_retval = 1;
269 VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 1);
270 VbNvTeardown(&vnc);
271 TestVbInit(0, 0, "S3 debug reset rollback error");
272
273 /* Developer mode */
274 ResetMocks();
275 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON;
276 TestVbInit(0, 0, "Dev mode on");
277 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
278 TEST_EQ(iparams.out_flags,
279 VB_INIT_OUT_CLEAR_RAM |
280 VB_INIT_OUT_ENABLE_DISPLAY |
281 VB_INIT_OUT_ENABLE_USB_STORAGE |
282 VB_INIT_OUT_ENABLE_DEVELOPER |
283 VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
284 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
285
286 /* Developer mode forced by GBB flag */
287 ResetMocks();
288 iparams.flags = 0;
289 gbb.flags = GBB_FLAG_FORCE_DEV_SWITCH_ON;
290 TestVbInit(0, 0, "Dev mode via GBB");
291 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
292 TEST_EQ(iparams.out_flags,
293 VB_INIT_OUT_CLEAR_RAM |
294 VB_INIT_OUT_ENABLE_DISPLAY |
295 VB_INIT_OUT_ENABLE_USB_STORAGE |
296 VB_INIT_OUT_ENABLE_DEVELOPER |
297 VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
298 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
299
300 /* Developer mode when option ROM matters and isn't loaded */
301 ResetMocks();
302 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON |
303 VB_INIT_FLAG_OPROM_MATTERS;
304 TestVbInit(VBERROR_VGA_OPROM_MISMATCH, 0, "Dev mode need oprom");
305 VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u);
306 TEST_EQ(u, 1, " oprom requested");
307
308 /* Developer mode when option ROM matters and is already loaded */
309 ResetMocks();
310 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON |
311 VB_INIT_FLAG_OPROM_MATTERS | VB_INIT_FLAG_OPROM_LOADED;
312 TestVbInit(0, 0, "Dev mode has oprom");
313
314 /* Normal mode when option ROM matters and is loaded */
315 ResetMocks();
316 VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
317 VbNvTeardown(&vnc);
318 iparams.flags = VB_INIT_FLAG_OPROM_MATTERS | VB_INIT_FLAG_OPROM_LOADED;
319 TestVbInit(VBERROR_VGA_OPROM_MISMATCH, 0, "Normal mode with oprom");
320 VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u);
321 TEST_EQ(u, 0, " oprom not requested");
322
323 /* Option ROMs can be forced by GBB flag */
324 ResetMocks();
325 gbb.flags = GBB_FLAG_LOAD_OPTION_ROMS;
326 TestVbInit(0, 0, "GBB load option ROMs");
327 TEST_EQ(iparams.out_flags, VB_INIT_OUT_ENABLE_OPROM, " out flags");
328
329 /* If requiring signed only, don't enable alternate OS by default */
330 ResetMocks();
331 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
332 VbNvTeardown(&vnc);
333 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON;
334 TestVbInit(0, 0, "Dev signed only");
335 TEST_EQ(iparams.out_flags,
336 VB_INIT_OUT_CLEAR_RAM |
337 VB_INIT_OUT_ENABLE_DISPLAY |
338 VB_INIT_OUT_ENABLE_USB_STORAGE |
339 VB_INIT_OUT_ENABLE_DEVELOPER, " out flags");
340
341 /* But that can be overridden by the GBB */
342 ResetMocks();
343 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
344 VbNvTeardown(&vnc);
345 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON;
346 gbb.flags = GBB_FLAG_ENABLE_ALTERNATE_OS;
347 TestVbInit(0, 0, "Force option ROMs via GBB");
348 TEST_EQ(iparams.out_flags,
349 VB_INIT_OUT_CLEAR_RAM |
350 VB_INIT_OUT_ENABLE_DISPLAY |
351 VB_INIT_OUT_ENABLE_USB_STORAGE |
352 VB_INIT_OUT_ENABLE_DEVELOPER |
353 VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
354
355 /* The GBB override is ignored in normal mode */
356 ResetMocks();
357 gbb.flags = GBB_FLAG_ENABLE_ALTERNATE_OS;
358 TestVbInit(0, 0, "Normal mode ignores forcing option ROMs via GBB");
359 TEST_EQ(iparams.out_flags, 0, " out flags");
360
361 /* Recovery mode from NV storage */
362 ResetMocks();
363 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
364 VbNvTeardown(&vnc);
365 TestVbInit(0, 0, "Recovery mode - from nv");
366 TEST_EQ(shared->recovery_reason, 123, " recovery reason");
367 TEST_EQ(iparams.out_flags,
368 VB_INIT_OUT_ENABLE_RECOVERY |
369 VB_INIT_OUT_CLEAR_RAM |
370 VB_INIT_OUT_ENABLE_DISPLAY |
371 VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags");
372 TEST_EQ(shared->flags, 0, " shared flags");
373
374 /* Recovery mode from recovery button */
375 ResetMocks();
376 iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED;
377 TestVbInit(0, 0, "Recovery mode - button");
378 TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_MANUAL,
379 " recovery reason");
380 TEST_EQ(iparams.out_flags,
381 VB_INIT_OUT_ENABLE_RECOVERY |
382 VB_INIT_OUT_CLEAR_RAM |
383 VB_INIT_OUT_ENABLE_DISPLAY |
384 VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags");
385 TEST_EQ(shared->flags, VBSD_BOOT_REC_SWITCH_ON, " shared flags");
386
387 /* Recovery button reason supersedes NV reason */
388 ResetMocks();
389 iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED;
390 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
391 VbNvTeardown(&vnc);
392 TestVbInit(0, 0, "Recovery mode - button AND nv");
393 TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_MANUAL,
394 " recovery reason");
395
396 /* Recovery mode from previous boot fail */
397 ResetMocks();
398 iparams.flags = VB_INIT_FLAG_PREVIOUS_BOOT_FAIL;
399 TestVbInit(0, 0, "Recovery mode - previous boot fail");
400 TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_FIRMWARE,
401 " recovery reason");
402 TEST_EQ(iparams.out_flags,
403 VB_INIT_OUT_ENABLE_RECOVERY |
404 VB_INIT_OUT_CLEAR_RAM |
405 VB_INIT_OUT_ENABLE_DISPLAY |
406 VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags");
407 TEST_EQ(shared->flags, 0, " shared flags");
408
409 /* Recovery mode from NV supersedes previous boot fail */
410 ResetMocks();
411 iparams.flags = VB_INIT_FLAG_PREVIOUS_BOOT_FAIL;
412 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, 123);
413 VbNvTeardown(&vnc);
414 TestVbInit(0, 0, "Recovery mode - previous boot fail AND nv");
415 TEST_EQ(shared->recovery_reason, 123, " recovery reason");
416
417 /* Dev + recovery = recovery */
418 ResetMocks();
419 iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED |
420 VB_INIT_FLAG_DEV_SWITCH_ON;
421 TestVbInit(0, 0, "Recovery mode - button");
422 TEST_EQ(shared->recovery_reason, VBNV_RECOVERY_RO_MANUAL,
423 " recovery reason");
424 TEST_EQ(iparams.out_flags,
425 VB_INIT_OUT_ENABLE_RECOVERY |
426 VB_INIT_OUT_CLEAR_RAM |
427 VB_INIT_OUT_ENABLE_DISPLAY |
428 VB_INIT_OUT_ENABLE_USB_STORAGE, " out flags");
429 TEST_EQ(shared->flags,
430 VBSD_BOOT_REC_SWITCH_ON | VBSD_BOOT_DEV_SWITCH_ON,
431 " shared flags");
432 }
433
VbInitTestTPM(void)434 static void VbInitTestTPM(void)
435 {
436 uint32_t u;
437
438 /* Rollback setup needs to reboot */
439 ResetMocks();
440 mock_rfs_retval = TPM_E_MUST_REBOOT;
441 TestVbInit(VBERROR_TPM_REBOOT_REQUIRED, 0,
442 "Rollback TPM reboot (rec=0)");
443 ResetMocks();
444 mock_rfs_retval = TPM_E_MUST_REBOOT;
445 iparams.flags = VB_INIT_FLAG_REC_BUTTON_PRESSED;
446 TestVbInit(VBERROR_TPM_REBOOT_REQUIRED, VBNV_RECOVERY_RO_TPM_REBOOT,
447 "Rollback TPM reboot, in recovery, first time");
448 /* Ignore if we already tried rebooting */
449 ResetMocks();
450 mock_rfs_retval = TPM_E_MUST_REBOOT;
451 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_REBOOT);
452 VbNvTeardown(&vnc);
453 TestVbInit(0, 0, "Rollback TPM reboot, in recovery, already retried");
454 TEST_EQ(shared->fw_version_tpm, 0x10001, " shared fw_version_tpm");
455
456 /* Other rollback setup errors */
457 ResetMocks();
458 mock_rfs_retval = TPM_E_IOERROR;
459 mock_tpm_version = 0x20002;
460 TestVbInit(VBERROR_TPM_FIRMWARE_SETUP, VBNV_RECOVERY_RO_TPM_S_ERROR,
461 "Rollback TPM setup error - not in recovery");
462 TEST_EQ(shared->fw_version_tpm, 0, " shared fw_version_tpm not set");
463 ResetMocks();
464 mock_rfs_retval = TPM_E_IOERROR;
465 VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_US_TEST);
466 VbNvTeardown(&vnc);
467 TestVbInit(0, 0, "Rollback TPM setup error ignored in recovery");
468 TEST_EQ(shared->fw_version_tpm, 0x10001, " shared fw_version_tpm");
469
470 /* Virtual developer switch, but not enabled. */
471 ResetMocks();
472 VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 1);
473 VbNvTeardown(&vnc);
474 iparams.flags = VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
475 TestVbInit(0, 0, "TPM Dev mode off");
476 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
477 TEST_EQ(iparams.out_flags, 0, " out flags");
478 TEST_EQ(shared->flags, VBSD_HONOR_VIRT_DEV_SWITCH, " shared flags");
479 VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &u);
480 TEST_EQ(u, 0, " disable dev request");
481
482 /* Virtual developer switch, enabled. */
483 ResetMocks();
484 VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 1);
485 VbNvTeardown(&vnc);
486 iparams.flags = VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
487 mock_virt_dev_sw = 1;
488 TestVbInit(0, 0, "TPM Dev mode on");
489 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
490 TEST_EQ(iparams.out_flags,
491 VB_INIT_OUT_CLEAR_RAM |
492 VB_INIT_OUT_ENABLE_DISPLAY |
493 VB_INIT_OUT_ENABLE_USB_STORAGE |
494 VB_INIT_OUT_ENABLE_DEVELOPER |
495 VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
496 TEST_EQ(shared->flags,
497 VBSD_BOOT_DEV_SWITCH_ON | VBSD_HONOR_VIRT_DEV_SWITCH,
498 " shared flags");
499 /* Disable-request doesn't get cleared because dev mode is still on */
500 VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &u);
501 TEST_EQ(u, 1, " disable dev request");
502 /* Disable request was passed on to RollbackFirmwareSetup() */
503 TEST_EQ(rfs_disable_dev_request, 1, " rfs disable dev");
504
505 /* Ignore virtual developer switch, even though enabled. */
506 ResetMocks();
507 mock_virt_dev_sw = 1;
508 TestVbInit(0, 0, "TPM Dev mode on but ignored");
509 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
510 TEST_EQ(iparams.out_flags, 0, " out flags");
511 TEST_EQ(shared->flags, 0, " shared flags");
512
513 /* HW dev switch on, no virtual developer switch */
514 ResetMocks();
515 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON;
516 TestVbInit(0, 0, "HW Dev mode on");
517 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
518 TEST_EQ(iparams.out_flags,
519 VB_INIT_OUT_CLEAR_RAM |
520 VB_INIT_OUT_ENABLE_DISPLAY |
521 VB_INIT_OUT_ENABLE_USB_STORAGE |
522 VB_INIT_OUT_ENABLE_DEVELOPER |
523 VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
524 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
525
526 /* Check TPM owner clear request */
527 ResetMocks();
528 VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 1);
529 VbNvTeardown(&vnc);
530 TestVbInit(0, 0, "TPM clear owner");
531 VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, &u);
532 TEST_EQ(u, 0, " tpm clear request");
533 VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, &u);
534 TEST_EQ(u, 1, " tpm clear request");
535 TEST_EQ(rfs_clear_tpm_request, 1, "rfs tpm clear request");
536 }
537
VbInitTestBackup(void)538 static void VbInitTestBackup(void)
539 {
540 VbNvContext tmp_vnc;
541 uint32_t u, nv_w, bu_r;
542
543 ResetMocks();
544 /* Normal mode call */
545 TestVbInit(0, 0, "normal mode, no backup");
546 TEST_EQ(shared->flags, 0, " shared flags");
547 TEST_EQ(iparams.out_flags, 0, " out flags");
548 TEST_EQ(nv_write_called, 0,
549 " NV write not called since nothing changed");
550
551 ResetMocks();
552 /* Now set some params that should be backed up. */
553 VbNvSet(&vnc, VBNV_KERNEL_FIELD, 0xaabbccdd);
554 VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 0xa5);
555 VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 1);
556 VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 1);
557 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
558 /* and some that don't */
559 VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
560 VbNvSet(&vnc, VBNV_TRY_B_COUNT, 3);
561 /* Make sure they're clean */
562 VbNvTeardown(&vnc);
563 /* Normal mode call */
564 TestVbInit(0, 0, "normal mode, some backup");
565 TEST_EQ(shared->flags, 0, " shared flags");
566 TEST_EQ(iparams.out_flags, 0, " out flags");
567 TEST_EQ(nv_write_called, 1,
568 " Write NV because things have changed");
569 /* Some fields should be unchanged */
570 VbNvGet(&vnc, VBNV_KERNEL_FIELD, &u);
571 TEST_EQ(u, 0xaabbccdd, " NV kernel field");
572 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
573 TEST_EQ(u, 0xa5, " NV localization index");
574 VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u);
575 TEST_EQ(u, 1, " NV oprom_needed");
576 VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u);
577 TEST_EQ(u, 3, " NV try_b_count");
578 /* But normal mode should have cleared the DEV_BOOT flags */
579 VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &u);
580 TEST_EQ(u, 0, " NV dev_boot_usb");
581 VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &u);
582 TEST_EQ(u, 0, " NV dev_boot_legacy");
583 VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u);
584 TEST_EQ(u, 0, " NV dev_boot_signed_only");
585 /* So we should have written the backup */
586 TEST_EQ(backup_write_called, 1, " Backup written once");
587 /* And the backup should reflect the persisent flags. */
588 Memset(&tmp_vnc, 0, sizeof(tmp_vnc));
589 TEST_EQ(0, RestoreNvFromBackup(&tmp_vnc), "read from backup");
590 VbNvGet(&tmp_vnc, VBNV_KERNEL_FIELD, &u);
591 TEST_EQ(u, 0xaabbccdd, " BU kernel field");
592 VbNvGet(&tmp_vnc, VBNV_LOCALIZATION_INDEX, &u);
593 TEST_EQ(u, 0xa5, " BU localization index");
594 VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_USB, &u);
595 TEST_EQ(u, 0, " BU dev_boot_usb");
596 VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_LEGACY, &u);
597 TEST_EQ(u, 0, " BU dev_boot_legacy");
598 VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u);
599 TEST_EQ(u, 0, " BU dev_boot_signed_only");
600 /* but not the others */
601 VbNvGet(&tmp_vnc, VBNV_OPROM_NEEDED, &u);
602 TEST_EQ(u, 0, " BU oprom_needed");
603 VbNvGet(&tmp_vnc, VBNV_TRY_B_COUNT, &u);
604 TEST_EQ(u, 0, " BU try_b_count");
605
606 /*
607 * If we change one of the non-backed-up NVRAM params and try
608 * again, we shouldn't need to backup again.
609 */
610 VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0);
611 VbNvSet(&vnc, VBNV_TRY_B_COUNT, 2);
612 /* Make sure they're clean */
613 VbNvTeardown(&vnc);
614 /* Normal mode call */
615 TestVbInit(0, 0, "normal mode, expect no backup");
616 TEST_EQ(shared->flags, 0, " shared flags");
617 TEST_EQ(iparams.out_flags, 0, " out flags");
618 TEST_EQ(backup_write_called, 1, " Backup still only written once");
619
620 /* Now switch to dev-mode. */
621 iparams.flags = VB_INIT_FLAG_DEV_SWITCH_ON;
622 TestVbInit(0, 0, "Dev mode on");
623 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
624 TEST_EQ(iparams.out_flags,
625 VB_INIT_OUT_CLEAR_RAM |
626 VB_INIT_OUT_ENABLE_DISPLAY |
627 VB_INIT_OUT_ENABLE_USB_STORAGE |
628 VB_INIT_OUT_ENABLE_DEVELOPER |
629 VB_INIT_OUT_ENABLE_ALTERNATE_OS, " out flags");
630 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
631 TEST_EQ(backup_write_called, 1, " Still only one backup");
632
633 /* Now change some params that should be backed up. */
634 VbNvSet(&vnc, VBNV_KERNEL_FIELD, 0xdeadbeef);
635 VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 0x5a);
636 VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 1);
637 VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 1);
638 VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
639 /* and some that don't */
640 VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1);
641 VbNvSet(&vnc, VBNV_TRY_B_COUNT, 4);
642 /* Make sure they're clean */
643 VbNvTeardown(&vnc);
644 TestVbInit(0, 0, "Dev mode on");
645 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
646 TEST_EQ(iparams.out_flags,
647 VB_INIT_OUT_CLEAR_RAM |
648 VB_INIT_OUT_ENABLE_DISPLAY |
649 VB_INIT_OUT_ENABLE_USB_STORAGE |
650 VB_INIT_OUT_ENABLE_DEVELOPER, " out flags");
651 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
652 TEST_EQ(backup_write_called, 1, " Once more, one backup");
653
654 /* But if we explictly request a backup, they'll get saved. */
655 VbNvSet(&vnc, VBNV_BACKUP_NVRAM_REQUEST, 1);
656 VbNvTeardown(&vnc);
657 TestVbInit(0, 0, "Dev mode on");
658 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
659 TEST_EQ(iparams.out_flags,
660 VB_INIT_OUT_CLEAR_RAM |
661 VB_INIT_OUT_ENABLE_DISPLAY |
662 VB_INIT_OUT_ENABLE_USB_STORAGE |
663 VB_INIT_OUT_ENABLE_DEVELOPER, " out flags");
664 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
665 TEST_EQ(backup_write_called, 2, " Two backups now");
666 VbNvGet(&vnc, VBNV_BACKUP_NVRAM_REQUEST, &u);
667 TEST_EQ(u, 0, " backup_request cleared");
668 /* Quick check that the non-backed-up stuff is still valid */
669 VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u);
670 TEST_EQ(u, 1, " NV oprom_needed");
671 VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u);
672 TEST_EQ(u, 4, " NV try_b_count");
673 /* But only the stuff we care about was backed up */
674 Memset(&tmp_vnc, 0, sizeof(tmp_vnc));
675 TEST_EQ(0, RestoreNvFromBackup(&tmp_vnc), "read from backup");
676 VbNvGet(&tmp_vnc, VBNV_KERNEL_FIELD, &u);
677 TEST_EQ(u, 0xdeadbeef, " BU kernel field");
678 VbNvGet(&tmp_vnc, VBNV_LOCALIZATION_INDEX, &u);
679 TEST_EQ(u, 0x5a, " BU localization index");
680 VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_USB, &u);
681 TEST_EQ(u, 1, " BU dev_boot_usb");
682 VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_LEGACY, &u);
683 TEST_EQ(u, 1, " BU dev_boot_legacy");
684 VbNvGet(&tmp_vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u);
685 TEST_EQ(u, 1, " BU dev_boot_signed_only");
686 /* but not the others */
687 VbNvGet(&tmp_vnc, VBNV_OPROM_NEEDED, &u);
688 TEST_EQ(u, 0, " BU oprom_needed");
689 VbNvGet(&tmp_vnc, VBNV_TRY_B_COUNT, &u);
690 TEST_EQ(u, 0, " BU try_b_count");
691
692 /* If we lose the NV storage, the backup bits will be restored */
693 vnc.raw[0] = 0;
694 bu_r = backup_read_called;
695 nv_w = nv_write_called;
696 TestVbInit(0, 0, "Dev mode on");
697 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
698 TEST_EQ(iparams.out_flags,
699 VB_INIT_OUT_CLEAR_RAM |
700 VB_INIT_OUT_ENABLE_DISPLAY |
701 VB_INIT_OUT_ENABLE_USB_STORAGE |
702 VB_INIT_OUT_ENABLE_DEVELOPER, " out flags");
703 TEST_EQ(shared->flags, VBSD_BOOT_DEV_SWITCH_ON, " shared flags");
704 TEST_EQ(backup_write_called, 2, " Still just two backups now");
705 TEST_EQ(backup_read_called, bu_r + 1, " One more backup read");
706 TEST_EQ(nv_write_called, nv_w + 1, " One more NV write");
707 /* The non-backed-up stuff is reset to defaults */
708 VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u);
709 TEST_EQ(u, 0, " NV oprom_needed");
710 VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u);
711 TEST_EQ(u, 0, " NV try_b_count");
712 /* And the backed up stuff is restored */
713 VbNvGet(&vnc, VBNV_KERNEL_FIELD, &u);
714 TEST_EQ(u, 0xdeadbeef, " BU kernel field");
715 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
716 TEST_EQ(u, 0x5a, " BU localization index");
717 VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &u);
718 TEST_EQ(u, 1, " BU dev_boot_usb");
719 VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &u);
720 TEST_EQ(u, 1, " BU dev_boot_legacy");
721 VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u);
722 TEST_EQ(u, 1, " BU dev_boot_signed_only");
723
724 /*
725 * But if we lose the NV storage and go back to normal mode at the same
726 * time, then the DEV_BOOT_* flags will be cleared.
727 */
728 vnc.raw[0] = 0;
729 bu_r = backup_read_called;
730 nv_w = nv_write_called;
731 iparams.flags = 0;
732 TestVbInit(0, 0, "Back to normal mode");
733 TEST_EQ(shared->recovery_reason, 0, " recovery reason");
734 TEST_EQ(iparams.out_flags, 0, " out flags");
735 TEST_EQ(shared->flags, 0, " shared flags");
736 /* We read twice: once to restore, once for read-prior-to-write */
737 TEST_EQ(backup_read_called, bu_r + 2, " Two more backup reads");
738 TEST_EQ(backup_write_called, 3, " Backup write due clearing DEV_*");
739 TEST_EQ(nv_write_called, nv_w + 1, " One more NV write");
740 /* The non-backed-up stuff is reset to defaults */
741 VbNvGet(&vnc, VBNV_OPROM_NEEDED, &u);
742 TEST_EQ(u, 0, " NV oprom_needed");
743 VbNvGet(&vnc, VBNV_TRY_B_COUNT, &u);
744 TEST_EQ(u, 0, " NV try_b_count");
745 /* And the backed up stuff is restored */
746 VbNvGet(&vnc, VBNV_KERNEL_FIELD, &u);
747 TEST_EQ(u, 0xdeadbeef, " BU kernel field");
748 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u);
749 TEST_EQ(u, 0x5a, " BU localization index");
750 /* But not the DEV_BOOT_* flags */
751 VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &u);
752 TEST_EQ(u, 0, " BU dev_boot_usb");
753 VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &u);
754 TEST_EQ(u, 0, " BU dev_boot_legacy");
755 VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &u);
756 TEST_EQ(u, 0, " BU dev_boot_signed_only");
757 }
758
759
main(int argc,char * argv[])760 int main(int argc, char *argv[])
761 {
762 VbInitTest();
763 VbInitTestTPM();
764 VbInitTestBackup();
765
766 return gTestSuccess ? 0 : 255;
767 }
768