blob: 7ecf02f8ef8d6b1810fedfb729c4fcb457280211 [file] [log] [blame]
Randall Spangler7f436692013-02-05 12:42:36 -08001/* 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_kernel, part 2
6 */
7
Bill Richardson0c3ba242013-03-29 11:09:30 -07008#include <stdint.h>
Randall Spangler7f436692013-02-05 12:42:36 -08009#include <stdio.h>
10#include <stdlib.h>
11
12#include "gbb_header.h"
13#include "host_common.h"
14#include "load_kernel_fw.h"
15#include "rollback_index.h"
16#include "test_common.h"
17#include "vboot_audio.h"
18#include "vboot_common.h"
19#include "vboot_kernel.h"
20#include "vboot_nvstorage.h"
21#include "vboot_struct.h"
22
23/* Mock data */
24static VbCommonParams cparams;
25static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
26static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
27static GoogleBinaryBlockHeader gbb;
28static LoadKernelParams lkp;
29
30static int shutdown_request_calls_left;
31static int audio_looping_calls_left;
32static uint32_t vbtlk_retval;
33static int vbexlegacy_called;
34static int trust_ec;
35static int virtdev_set;
36static uint32_t virtdev_retval;
Randall Spangler7f436692013-02-05 12:42:36 -080037static uint32_t mock_keypress[8];
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -080038static uint32_t mock_keyflags[8];
Randall Spangler7f436692013-02-05 12:42:36 -080039static uint32_t mock_keypress_count;
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -080040static uint32_t mock_switches[8];
41static uint32_t mock_switches_count;
42static int mock_switches_are_stuck;
Randall Spangler7f436692013-02-05 12:42:36 -080043static uint32_t screens_displayed[8];
44static uint32_t screens_count = 0;
45static uint32_t mock_num_disks[8];
46static uint32_t mock_num_disks_count;
47
48/* Reset mock data (for use before each test) */
49static void ResetMocks(void)
50{
51 Memset(&cparams, 0, sizeof(cparams));
52 cparams.shared_data_size = sizeof(shared_data);
53 cparams.shared_data_blob = shared_data;
54 cparams.gbb_data = &gbb;
Simon Glass527ba812013-07-25 08:48:47 -060055 cparams.gbb = &gbb;
Randall Spangler7f436692013-02-05 12:42:36 -080056
57 Memset(&gbb, 0, sizeof(gbb));
58 gbb.major_version = GBB_MAJOR_VER;
59 gbb.minor_version = GBB_MINOR_VER;
60 gbb.flags = 0;
61
62 /*
63 * Only the outermost vboot_api_kernel call sets vboot_api_kernel's
64 * vnc. So clear it here too.
65 */
66 Memset(VbApiKernelGetVnc(), 0, sizeof(VbNvContext));
67 VbNvSetup(VbApiKernelGetVnc());
68 VbNvTeardown(VbApiKernelGetVnc()); /* So CRC gets generated */
69
70 Memset(&shared_data, 0, sizeof(shared_data));
71 VbSharedDataInit(shared, sizeof(shared_data));
72
73 Memset(&lkp, 0, sizeof(lkp));
74
75 shutdown_request_calls_left = -1;
76 audio_looping_calls_left = 30;
77 vbtlk_retval = 1000;
78 vbexlegacy_called = 0;
79 trust_ec = 0;
80 virtdev_set = 0;
81 virtdev_retval = 0;
82
83 Memset(screens_displayed, 0, sizeof(screens_displayed));
84 screens_count = 0;
85
86 Memset(mock_keypress, 0, sizeof(mock_keypress));
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -080087 Memset(mock_keyflags, 0, sizeof(mock_keyflags));
Randall Spangler7f436692013-02-05 12:42:36 -080088 mock_keypress_count = 0;
89
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -080090 Memset(mock_switches, 0, sizeof(mock_switches));
91 mock_switches_count = 0;
92 mock_switches_are_stuck = 0;
93
Randall Spangler7f436692013-02-05 12:42:36 -080094 Memset(mock_num_disks, 0, sizeof(mock_num_disks));
95 mock_num_disks_count = 0;
96}
97
98/* Mock functions */
99
100uint32_t VbExIsShutdownRequested(void)
101{
102 if (shutdown_request_calls_left == 0)
103 return 1;
104 else if (shutdown_request_calls_left > 0)
105 shutdown_request_calls_left--;
106
107 return 0;
108}
109
110uint32_t VbExKeyboardRead(void)
111{
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800112 return VbExKeyboardReadWithFlags(NULL);
113}
114
115uint32_t VbExKeyboardReadWithFlags(uint32_t *key_flags)
116{
117 if (mock_keypress_count < ARRAY_SIZE(mock_keypress)) {
118 if (key_flags != NULL)
119 *key_flags = mock_keyflags[mock_keypress_count];
Randall Spangler7f436692013-02-05 12:42:36 -0800120 return mock_keypress[mock_keypress_count++];
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800121 } else
122 return 0;
123}
124
125uint32_t VbExGetSwitches(uint32_t request_mask)
126{
127 if (mock_switches_are_stuck)
128 return mock_switches[0] & request_mask;
129 if (mock_switches_count < ARRAY_SIZE(mock_switches))
130 return mock_switches[mock_switches_count++] & request_mask;
Randall Spangler7f436692013-02-05 12:42:36 -0800131 else
132 return 0;
133}
134
135int VbExLegacy(void)
136{
137 vbexlegacy_called++;
138 return 0;
139}
140
141VbError_t VbExDiskGetInfo(VbDiskInfo **infos_ptr, uint32_t *count,
142 uint32_t disk_flags)
143{
144 if (mock_num_disks_count < ARRAY_SIZE(mock_num_disks)) {
145 if (mock_num_disks[mock_num_disks_count] == -1)
146 return VBERROR_SIMULATED;
147 else
148 *count = mock_num_disks[mock_num_disks_count++];
149 } else {
150 *count = 0;
151 }
152 return VBERROR_SUCCESS;
153}
154
155VbError_t VbExDiskFreeInfo(VbDiskInfo *infos,
156 VbExDiskHandle_t preserve_handle)
157{
158 return VBERROR_SUCCESS;
159}
160
Randall Spanglere778ada2014-07-15 16:14:21 -0700161int VbExTrustEC(int devidx)
Randall Spangler7f436692013-02-05 12:42:36 -0800162{
163 return trust_ec;
164}
165
166int VbAudioLooping(VbAudioContext *audio)
167{
168 if (audio_looping_calls_left == 0)
169 return 0;
170 else if (audio_looping_calls_left > 0)
171 audio_looping_calls_left--;
172
173 return 1;
174}
175
176uint32_t VbTryLoadKernel(VbCommonParams *cparams, LoadKernelParams *p,
177 uint32_t get_info_flags)
178{
179 return vbtlk_retval + get_info_flags;
180}
181
182VbError_t VbDisplayScreen(VbCommonParams *cparams, uint32_t screen, int force,
183 VbNvContext *vncptr)
184{
185 if (screens_count < ARRAY_SIZE(screens_displayed))
186 screens_displayed[screens_count++] = screen;
187
188 return VBERROR_SUCCESS;
189}
190
191uint32_t SetVirtualDevMode(int val)
192{
193 virtdev_set = val;
194 return virtdev_retval;
195}
196
197/* Tests */
198
199static void VbUserConfirmsTest(void)
200{
201 printf("Testing VbUserConfirms()...\n");
202
203 ResetMocks();
204 shutdown_request_calls_left = 1;
205 TEST_EQ(VbUserConfirms(&cparams, 0), -1, "Shutdown requested");
206
207 ResetMocks();
208 mock_keypress[0] = '\r';
209 TEST_EQ(VbUserConfirms(&cparams, 0), 1, "Enter");
210
211 ResetMocks();
212 mock_keypress[0] = 0x1b;
213 TEST_EQ(VbUserConfirms(&cparams, 0), 0, "Esc");
214
215 ResetMocks();
216 mock_keypress[0] = ' ';
217 shutdown_request_calls_left = 1;
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800218 TEST_EQ(VbUserConfirms(&cparams, VB_CONFIRM_SPACE_MEANS_NO), 0,
219 "Space means no");
Randall Spangler7f436692013-02-05 12:42:36 -0800220
221 ResetMocks();
222 mock_keypress[0] = ' ';
223 shutdown_request_calls_left = 1;
224 TEST_EQ(VbUserConfirms(&cparams, 0), -1, "Space ignored");
225
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800226 ResetMocks();
227 mock_keypress[0] = '\r';
228 mock_keyflags[0] = VB_KEY_FLAG_TRUSTED_KEYBOARD;
229 TEST_EQ(VbUserConfirms(&cparams, VB_CONFIRM_MUST_TRUST_KEYBOARD),
230 1, "Enter with trusted keyboard");
231
232 ResetMocks();
233 mock_keypress[0] = '\r'; /* untrusted */
234 mock_keypress[1] = ' ';
235 TEST_EQ(VbUserConfirms(&cparams,
236 VB_CONFIRM_SPACE_MEANS_NO |
237 VB_CONFIRM_MUST_TRUST_KEYBOARD),
238 0, "Untrusted keyboard");
239
240 ResetMocks();
241 mock_switches[0] = VB_INIT_FLAG_REC_BUTTON_PRESSED;
242 TEST_EQ(VbUserConfirms(&cparams,
243 VB_CONFIRM_SPACE_MEANS_NO |
244 VB_CONFIRM_MUST_TRUST_KEYBOARD),
245 1, "Recovery button");
246
247 ResetMocks();
248 mock_keypress[0] = '\r';
249 mock_keypress[1] = 'y';
250 mock_keypress[2] = 'z';
251 mock_keypress[3] = ' ';
252 mock_switches[0] = VB_INIT_FLAG_REC_BUTTON_PRESSED;
253 mock_switches_are_stuck = 1;
254 TEST_EQ(VbUserConfirms(&cparams,
255 VB_CONFIRM_SPACE_MEANS_NO |
256 VB_CONFIRM_MUST_TRUST_KEYBOARD),
257 0, "Recovery button stuck");
258
Randall Spangler7f436692013-02-05 12:42:36 -0800259 printf("...done.\n");
260}
261
262static void VbBootTest(void)
263{
264 ResetMocks();
265 TEST_EQ(VbBootNormal(&cparams, &lkp), 1002, "VbBootNormal()");
266}
267
268static void VbBootDevTest(void)
269{
270 uint32_t u;
271
272 printf("Testing VbBootDeveloper()...\n");
273
274 /* Proceed after timeout */
275 ResetMocks();
276 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
277 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
278 " warning screen");
279 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
280 TEST_EQ(u, 0, " recovery reason");
281 TEST_EQ(audio_looping_calls_left, 0, " used up audio");
282
Randall Spanglerf2a1dc02013-06-11 16:53:07 -0700283 /* Proceed to legacy after timeout if GBB flag set */
284 ResetMocks();
285 gbb.flags |= GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY;
286 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
287 TEST_EQ(vbexlegacy_called, 1, " try legacy");
288
Randall Spangler7f436692013-02-05 12:42:36 -0800289 /* Up arrow is uninteresting / passed to VbCheckDisplayKey() */
290 ResetMocks();
291 mock_keypress[0] = VB_KEY_UP;
292 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Up arrow");
293
294 /* Shutdown requested in loop */
295 ResetMocks();
296 shutdown_request_calls_left = 2;
297 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
298 "Shutdown requested");
299 TEST_NEQ(audio_looping_calls_left, 0, " aborts audio");
300
301 /* Space goes straight to recovery if no virtual dev switch */
302 ResetMocks();
303 mock_keypress[0] = ' ';
304 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_LOAD_KERNEL_RECOVERY,
305 "Space = recovery");
306 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
307 TEST_EQ(u, VBNV_RECOVERY_RW_DEV_SCREEN, " recovery reason");
308
309 /* Space asks to disable virtual dev switch */
310 ResetMocks();
311 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
312 mock_keypress[0] = ' ';
313 mock_keypress[1] = '\r';
314 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
315 "Space = tonorm");
316 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
317 " warning screen");
318 TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
319 " tonorm screen");
320 TEST_EQ(screens_displayed[2], VB_SCREEN_TO_NORM_CONFIRMED,
321 " confirm screen");
322 VbNvGet(VbApiKernelGetVnc(), VBNV_DISABLE_DEV_REQUEST, &u);
323 TEST_EQ(u, 1, " disable dev request");
324
325 /* Space-space doesn't disable it */
326 ResetMocks();
327 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
328 mock_keypress[0] = ' ';
329 mock_keypress[1] = ' ';
330 mock_keypress[2] = 0x1b;
331 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Space-space");
332 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
333 " warning screen");
334 TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
335 " tonorm screen");
336 TEST_EQ(screens_displayed[2], VB_SCREEN_DEVELOPER_WARNING,
337 " warning screen");
338
339 /* Enter doesn't by default */
340 ResetMocks();
341 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
342 mock_keypress[0] = '\r';
343 mock_keypress[1] = '\r';
344 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Enter ignored");
345
346 /* Enter does if GBB flag set */
347 ResetMocks();
348 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
349 gbb.flags |= GBB_FLAG_ENTER_TRIGGERS_TONORM;
350 mock_keypress[0] = '\r';
351 mock_keypress[1] = '\r';
352 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
353 "Enter = tonorm");
354
355 /* Tonorm ignored if GBB forces dev switch on */
356 ResetMocks();
357 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
358 gbb.flags |= GBB_FLAG_FORCE_DEV_SWITCH_ON;
359 mock_keypress[0] = ' ';
360 mock_keypress[1] = '\r';
361 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Can't tonorm gbb-dev");
362
363 /* Shutdown requested at tonorm screen */
364 ResetMocks();
365 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
366 mock_keypress[0] = ' ';
367 shutdown_request_calls_left = 2;
368 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
369 "Shutdown requested at tonorm");
370 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
371 " warning screen");
372 TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
373 " tonorm screen");
374
375 /* Ctrl+D dismisses warning */
376 ResetMocks();
377 mock_keypress[0] = 0x04;
378 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+D");
379 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
380 TEST_EQ(u, 0, " recovery reason");
381 TEST_NEQ(audio_looping_calls_left, 0, " aborts audio");
Randall Spanglerf2a1dc02013-06-11 16:53:07 -0700382 TEST_EQ(vbexlegacy_called, 0, " not legacy");
383
384 /* Ctrl+D doesn't boot legacy even if GBB flag is set */
385 ResetMocks();
386 mock_keypress[0] = 0x04;
387 gbb.flags |= GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY;
388 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+D");
389 TEST_EQ(vbexlegacy_called, 0, " not legacy");
Randall Spangler7f436692013-02-05 12:42:36 -0800390
391 /* Ctrl+L tries legacy boot mode only if enabled */
392 ResetMocks();
393 mock_keypress[0] = 0x0c;
394 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L normal");
395 TEST_EQ(vbexlegacy_called, 0, " not legacy");
396
397 ResetMocks();
398
399 gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_LEGACY;
400 mock_keypress[0] = 0x0c;
401 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L force legacy");
402 TEST_EQ(vbexlegacy_called, 1, " try legacy");
403
404 ResetMocks();
405 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_LEGACY, 1);
406 mock_keypress[0] = 0x0c;
407 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L nv legacy");
408 TEST_EQ(vbexlegacy_called, 1, " try legacy");
409
410 /* Ctrl+U boots USB only if enabled */
411 ResetMocks();
412 mock_keypress[0] = 0x15;
413 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U normal");
414
415 /* Ctrl+U enabled, with good USB boot */
416 ResetMocks();
417 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
418 mock_keypress[0] = 0x15;
419 vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
420 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U USB");
421
422 /* Ctrl+U enabled via GBB */
423 ResetMocks();
424 gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_USB;
425 mock_keypress[0] = 0x15;
426 vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
427 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U force USB");
428
429 /* If no USB, eventually times out and tries fixed disk */
430 ResetMocks();
431 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
432 mock_keypress[0] = 0x15;
433 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U enabled");
434 TEST_EQ(vbexlegacy_called, 0, " not legacy");
435 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
436 TEST_EQ(u, 0, " recovery reason");
437 TEST_EQ(audio_looping_calls_left, 0, " used up audio");
438
439 printf("...done.\n");
440}
441
442static void VbBootRecTest(void)
443{
444 uint32_t u;
445
446 printf("Testing VbBootRecovery()...\n");
447
448 /* Shutdown requested in loop */
449 ResetMocks();
450 shutdown_request_calls_left = 10;
451 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
452 "Shutdown requested");
453 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
454 TEST_EQ(u, 0, " recovery reason");
455 TEST_EQ(screens_displayed[0], VB_SCREEN_BLANK,
456 " blank screen");
457 TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_NO_GOOD,
458 " no good screen");
459
460 /* Disk inserted after start */
461 ResetMocks();
462 vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
463 TEST_EQ(VbBootRecovery(&cparams, &lkp), 0, "Good");
464
465 /* No disk inserted */
466 ResetMocks();
467 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
468 shutdown_request_calls_left = 10;
469 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
470 "Bad disk");
471 TEST_EQ(screens_displayed[0], VB_SCREEN_BLANK,
472 " blank screen");
473 TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_INSERT,
474 " insert screen");
475
476 /* Remove disks */
477 ResetMocks();
478 shutdown_request_calls_left = 100;
479 mock_num_disks[0] = 1;
480 mock_num_disks[1] = 1;
Shawn Nematbakhsh04171532013-12-13 14:41:47 -0800481 mock_num_disks[2] = 1;
Randall Spangler7f436692013-02-05 12:42:36 -0800482 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
483 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
484 "Remove");
485 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_REMOVE,
486 " remove screen");
487 TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_REMOVE,
488 " remove screen");
489 TEST_EQ(screens_displayed[2], VB_SCREEN_BLANK,
490 " blank screen");
491 TEST_EQ(screens_displayed[3], VB_SCREEN_RECOVERY_INSERT,
492 " insert screen");
493
494 /* No removal if dev switch is on */
495 ResetMocks();
496 shutdown_request_calls_left = 100;
497 mock_num_disks[0] = 1;
498 mock_num_disks[1] = 1;
499 shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
500 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
501 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
502 "No remove in dev");
503 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
504 " insert screen");
505
506 /* No removal if recovery button physically pressed */
507 ResetMocks();
508 shutdown_request_calls_left = 100;
509 mock_num_disks[0] = 1;
510 mock_num_disks[1] = 1;
511 shared->flags |= VBSD_BOOT_REC_SWITCH_ON;
512 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
513 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
514 "No remove in rec");
515 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
516 " insert screen");
517
Shawn Nematbakhsh04171532013-12-13 14:41:47 -0800518 /* Removal if no disk initially found, but found on second attempt */
519 ResetMocks();
520 shutdown_request_calls_left = 100;
521 mock_num_disks[0] = 0;
522 mock_num_disks[1] = 1;
523 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
524 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
525 "Remove");
526 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_REMOVE,
527 " remove screen");
528 TEST_EQ(screens_displayed[1], VB_SCREEN_BLANK,
529 " blank screen");
530 TEST_EQ(screens_displayed[2], VB_SCREEN_RECOVERY_INSERT,
531 " insert screen");
532
Randall Spangler7f436692013-02-05 12:42:36 -0800533 /* Bad disk count doesn't require removal */
534 ResetMocks();
535 mock_num_disks[0] = -1;
536 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
537 shutdown_request_calls_left = 10;
538 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
539 "Bad disk count");
540 TEST_EQ(screens_displayed[0], VB_SCREEN_BLANK,
541 " blank screen");
542 TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_INSERT,
543 " insert screen");
544
545 /* Ctrl+D ignored for many reasons... */
546 ResetMocks();
547 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
548 shutdown_request_calls_left = 100;
549 mock_keypress[0] = 0x04;
550 trust_ec = 0;
551 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
552 "Ctrl+D ignored if EC not trusted");
553 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
554 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
555 " todev screen");
556
557 ResetMocks();
558 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON |
559 VBSD_BOOT_DEV_SWITCH_ON;
560 trust_ec = 1;
561 shutdown_request_calls_left = 100;
562 mock_keypress[0] = 0x04;
563 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
564 "Ctrl+D ignored if already in dev mode");
565 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
566 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
567 " todev screen");
568
569 ResetMocks();
570 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH;
571 trust_ec = 1;
572 shutdown_request_calls_left = 100;
573 mock_keypress[0] = 0x04;
574 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
575 "Ctrl+D ignored if recovery not manually triggered");
576 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
577 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
578 " todev screen");
579
580 ResetMocks();
581 shared->flags = VBSD_BOOT_REC_SWITCH_ON;
582 trust_ec = 1;
583 shutdown_request_calls_left = 100;
584 mock_keypress[0] = 0x04;
585 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
586 "Ctrl+D ignored if no virtual dev switch");
587 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
588 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
589 " todev screen");
590
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800591 /* Ctrl+D ignored because the physical recovery switch is still pressed
592 * and we don't like that.
593 */
594 ResetMocks();
595 shared->flags = VBSD_BOOT_REC_SWITCH_ON;
596 trust_ec = 1;
597 shutdown_request_calls_left = 100;
598 mock_keypress[0] = 0x04;
599 mock_switches[0] = VB_INIT_FLAG_REC_BUTTON_PRESSED;
600 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
601 "Ctrl+D ignored if phys rec button is still pressed");
602 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
603 " todev screen");
604
Randall Spangler7f436692013-02-05 12:42:36 -0800605 /* Ctrl+D then space means don't enable */
606 ResetMocks();
607 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
608 shutdown_request_calls_left = 100;
609 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
610 trust_ec = 1;
611 mock_keypress[0] = 0x04;
612 mock_keypress[1] = ' ';
613 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
614 "Ctrl+D todev abort");
615 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
616 " insert screen");
617 TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
618 " todev screen");
619 TEST_EQ(screens_displayed[2], VB_SCREEN_RECOVERY_INSERT,
620 " insert screen");
621 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
622
623 /* Ctrl+D then enter means enable */
624 ResetMocks();
625 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
626 shutdown_request_calls_left = 100;
627 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
628 trust_ec = 1;
629 mock_keypress[0] = 0x04;
630 mock_keypress[1] = '\r';
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800631 mock_keyflags[1] = VB_KEY_FLAG_TRUSTED_KEYBOARD;
Randall Spangler7f436692013-02-05 12:42:36 -0800632 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
633 "Ctrl+D todev confirm");
634 TEST_EQ(virtdev_set, 1, " virtual dev mode on");
635
636 /* Handle TPM error in enabling dev mode */
637 ResetMocks();
638 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
639 shutdown_request_calls_left = 100;
640 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
641 trust_ec = 1;
642 mock_keypress[0] = 0x04;
643 mock_keypress[1] = '\r';
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800644 mock_keyflags[1] = VB_KEY_FLAG_TRUSTED_KEYBOARD;
Randall Spangler7f436692013-02-05 12:42:36 -0800645 virtdev_retval = VBERROR_SIMULATED;
646 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_SET_BOOT_MODE_STATE,
647 "Ctrl+D todev failure");
648
649 printf("...done.\n");
650}
651
652
653int main(void)
654{
655 VbUserConfirmsTest();
656 VbBootTest();
657 VbBootDevTest();
658 VbBootRecTest();
659
Simon Glass25001852013-08-16 02:47:57 -0600660 if (vboot_api_stub_check_memory())
661 return 255;
662
Randall Spangler7f436692013-02-05 12:42:36 -0800663 return gTestSuccess ? 0 : 255;
664}