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