blob: aebfab64c42a1a467ca9dfd37f3c81ecf15feb70 [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();
Julius Werner0140cd22015-05-08 23:00:16 -0700291 gbb.flags |= GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY |
292 GBB_FLAG_FORCE_DEV_BOOT_LEGACY;
Randall Spanglerf2a1dc02013-06-11 16:53:07 -0700293 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
294 TEST_EQ(vbexlegacy_called, 1, " try legacy");
295
Mary Ruthven12a55f22015-10-06 10:42:31 -0700296 /* Proceed to legacy after timeout if boot legacy and default boot
297 * legacy are set */
298 ResetMocks();
299 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
300 VBNV_DEV_DEFAULT_BOOT_LEGACY);
301 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_LEGACY, 1);
302 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
303 TEST_EQ(vbexlegacy_called, 1, " try legacy");
304
305 /* Proceed to legacy boot mode only if enabled */
306 ResetMocks();
307 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
308 VBNV_DEV_DEFAULT_BOOT_LEGACY);
309 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
310 TEST_EQ(vbexlegacy_called, 0, " not legacy");
311
312 /* Proceed to usb after timeout if boot usb and default boot
313 * usb are set */
314 ResetMocks();
315 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
316 VBNV_DEV_DEFAULT_BOOT_USB);
317 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
318 vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
319 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U USB");
320
321 /* Proceed to usb boot mode only if enabled */
322 ResetMocks();
323 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
324 VBNV_DEV_DEFAULT_BOOT_USB);
325 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
326
327 /* If no USB tries fixed disk */
328 ResetMocks();
329 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
330 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_DEFAULT_BOOT,
331 VBNV_DEV_DEFAULT_BOOT_USB);
332 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U enabled");
333 TEST_EQ(vbexlegacy_called, 0, " not legacy");
334
Randall Spangler7f436692013-02-05 12:42:36 -0800335 /* Up arrow is uninteresting / passed to VbCheckDisplayKey() */
336 ResetMocks();
337 mock_keypress[0] = VB_KEY_UP;
338 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Up arrow");
339
340 /* Shutdown requested in loop */
341 ResetMocks();
342 shutdown_request_calls_left = 2;
343 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
344 "Shutdown requested");
345 TEST_NEQ(audio_looping_calls_left, 0, " aborts audio");
346
347 /* Space goes straight to recovery if no virtual dev switch */
348 ResetMocks();
349 mock_keypress[0] = ' ';
350 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_LOAD_KERNEL_RECOVERY,
351 "Space = recovery");
352 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
353 TEST_EQ(u, VBNV_RECOVERY_RW_DEV_SCREEN, " recovery reason");
354
355 /* Space asks to disable virtual dev switch */
356 ResetMocks();
357 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
358 mock_keypress[0] = ' ';
359 mock_keypress[1] = '\r';
360 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
361 "Space = tonorm");
362 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
363 " warning screen");
364 TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
365 " tonorm screen");
366 TEST_EQ(screens_displayed[2], VB_SCREEN_TO_NORM_CONFIRMED,
367 " confirm screen");
368 VbNvGet(VbApiKernelGetVnc(), VBNV_DISABLE_DEV_REQUEST, &u);
369 TEST_EQ(u, 1, " disable dev request");
370
371 /* Space-space doesn't disable it */
372 ResetMocks();
373 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
374 mock_keypress[0] = ' ';
375 mock_keypress[1] = ' ';
376 mock_keypress[2] = 0x1b;
377 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Space-space");
378 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
379 " warning screen");
380 TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
381 " tonorm screen");
382 TEST_EQ(screens_displayed[2], VB_SCREEN_DEVELOPER_WARNING,
383 " warning screen");
384
385 /* Enter doesn't by default */
386 ResetMocks();
387 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
388 mock_keypress[0] = '\r';
389 mock_keypress[1] = '\r';
390 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Enter ignored");
391
392 /* Enter does if GBB flag set */
393 ResetMocks();
394 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
395 gbb.flags |= GBB_FLAG_ENTER_TRIGGERS_TONORM;
396 mock_keypress[0] = '\r';
397 mock_keypress[1] = '\r';
398 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
399 "Enter = tonorm");
400
401 /* Tonorm ignored if GBB forces dev switch on */
402 ResetMocks();
403 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
404 gbb.flags |= GBB_FLAG_FORCE_DEV_SWITCH_ON;
405 mock_keypress[0] = ' ';
406 mock_keypress[1] = '\r';
407 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Can't tonorm gbb-dev");
408
409 /* Shutdown requested at tonorm screen */
410 ResetMocks();
411 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
412 mock_keypress[0] = ' ';
413 shutdown_request_calls_left = 2;
414 TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
415 "Shutdown requested at tonorm");
416 TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
417 " warning screen");
418 TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
419 " tonorm screen");
420
421 /* Ctrl+D dismisses warning */
422 ResetMocks();
423 mock_keypress[0] = 0x04;
424 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+D");
425 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
426 TEST_EQ(u, 0, " recovery reason");
427 TEST_NEQ(audio_looping_calls_left, 0, " aborts audio");
Randall Spanglerf2a1dc02013-06-11 16:53:07 -0700428 TEST_EQ(vbexlegacy_called, 0, " not legacy");
429
430 /* Ctrl+D doesn't boot legacy even if GBB flag is set */
431 ResetMocks();
432 mock_keypress[0] = 0x04;
433 gbb.flags |= GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY;
434 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+D");
435 TEST_EQ(vbexlegacy_called, 0, " not legacy");
Randall Spangler7f436692013-02-05 12:42:36 -0800436
437 /* Ctrl+L tries legacy boot mode only if enabled */
438 ResetMocks();
439 mock_keypress[0] = 0x0c;
440 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L normal");
441 TEST_EQ(vbexlegacy_called, 0, " not legacy");
442
443 ResetMocks();
Randall Spangler7f436692013-02-05 12:42:36 -0800444 gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_LEGACY;
445 mock_keypress[0] = 0x0c;
446 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L force legacy");
447 TEST_EQ(vbexlegacy_called, 1, " try legacy");
448
449 ResetMocks();
450 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_LEGACY, 1);
451 mock_keypress[0] = 0x0c;
452 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L nv legacy");
453 TEST_EQ(vbexlegacy_called, 1, " try legacy");
454
455 /* Ctrl+U boots USB only if enabled */
456 ResetMocks();
457 mock_keypress[0] = 0x15;
458 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U normal");
459
460 /* Ctrl+U enabled, with good USB boot */
461 ResetMocks();
462 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
463 mock_keypress[0] = 0x15;
464 vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
465 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U USB");
466
467 /* Ctrl+U enabled via GBB */
468 ResetMocks();
469 gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_USB;
470 mock_keypress[0] = 0x15;
471 vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
472 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U force USB");
473
474 /* If no USB, eventually times out and tries fixed disk */
475 ResetMocks();
476 VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
477 mock_keypress[0] = 0x15;
478 TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U enabled");
479 TEST_EQ(vbexlegacy_called, 0, " not legacy");
480 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
481 TEST_EQ(u, 0, " recovery reason");
482 TEST_EQ(audio_looping_calls_left, 0, " used up audio");
483
484 printf("...done.\n");
485}
486
487static void VbBootRecTest(void)
488{
489 uint32_t u;
490
491 printf("Testing VbBootRecovery()...\n");
492
493 /* Shutdown requested in loop */
494 ResetMocks();
495 shutdown_request_calls_left = 10;
Sheng-Liang Song487a54b2014-07-26 21:34:28 -0700496 VbExEcEnteringMode(0, VB_EC_RECOVERY);
Randall Spangler7f436692013-02-05 12:42:36 -0800497 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
498 "Shutdown requested");
Sheng-Liang Song487a54b2014-07-26 21:34:28 -0700499 TEST_EQ(VbGetMode(), VB_EC_RECOVERY, "vboot_mode recovery");
500
Randall Spangler7f436692013-02-05 12:42:36 -0800501 VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
502 TEST_EQ(u, 0, " recovery reason");
Daisuke Nojiri73a63722015-04-30 12:41:24 -0700503 TEST_EQ(screens_displayed[0], VB_SCREEN_OS_BROKEN,
504 " broken screen");
Randall Spangler7f436692013-02-05 12:42:36 -0800505
506 /* Remove disks */
507 ResetMocks();
508 shutdown_request_calls_left = 100;
509 mock_num_disks[0] = 1;
510 mock_num_disks[1] = 1;
Shawn Nematbakhsh04171532013-12-13 14:41:47 -0800511 mock_num_disks[2] = 1;
Randall Spangler7f436692013-02-05 12:42:36 -0800512 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
513 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
514 "Remove");
Daisuke Nojiri73a63722015-04-30 12:41:24 -0700515 TEST_EQ(screens_displayed[0], VB_SCREEN_OS_BROKEN,
516 " broken screen");
Randall Spangler7f436692013-02-05 12:42:36 -0800517
518 /* No removal if dev switch is on */
519 ResetMocks();
520 shutdown_request_calls_left = 100;
521 mock_num_disks[0] = 1;
522 mock_num_disks[1] = 1;
523 shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
524 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
525 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
526 "No remove in dev");
527 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
528 " insert screen");
529
530 /* No removal if recovery button physically pressed */
531 ResetMocks();
532 shutdown_request_calls_left = 100;
533 mock_num_disks[0] = 1;
534 mock_num_disks[1] = 1;
535 shared->flags |= VBSD_BOOT_REC_SWITCH_ON;
536 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
537 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
538 "No remove in rec");
539 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
540 " insert screen");
541
Shawn Nematbakhsh04171532013-12-13 14:41:47 -0800542 /* Removal if no disk initially found, but found on second attempt */
543 ResetMocks();
544 shutdown_request_calls_left = 100;
545 mock_num_disks[0] = 0;
546 mock_num_disks[1] = 1;
547 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
548 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
549 "Remove");
Daisuke Nojiri73a63722015-04-30 12:41:24 -0700550 TEST_EQ(screens_displayed[0], VB_SCREEN_OS_BROKEN,
551 " broken screen");
Shawn Nematbakhsh04171532013-12-13 14:41:47 -0800552
Randall Spangler7f436692013-02-05 12:42:36 -0800553 /* Bad disk count doesn't require removal */
554 ResetMocks();
Daisuke Nojiri73a63722015-04-30 12:41:24 -0700555 shutdown_request_calls_left = 100;
Randall Spangler7f436692013-02-05 12:42:36 -0800556 mock_num_disks[0] = -1;
557 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
558 shutdown_request_calls_left = 10;
559 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
560 "Bad disk count");
Daisuke Nojiri73a63722015-04-30 12:41:24 -0700561 TEST_EQ(screens_displayed[0], VB_SCREEN_OS_BROKEN,
562 " broken screen");
Randall Spangler7f436692013-02-05 12:42:36 -0800563
564 /* Ctrl+D ignored for many reasons... */
565 ResetMocks();
566 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
567 shutdown_request_calls_left = 100;
568 mock_keypress[0] = 0x04;
569 trust_ec = 0;
570 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
571 "Ctrl+D ignored if EC not trusted");
572 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
573 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
574 " todev screen");
575
576 ResetMocks();
577 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON |
578 VBSD_BOOT_DEV_SWITCH_ON;
579 trust_ec = 1;
580 shutdown_request_calls_left = 100;
581 mock_keypress[0] = 0x04;
582 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
583 "Ctrl+D ignored if already in dev mode");
584 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
585 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
586 " todev screen");
587
588 ResetMocks();
589 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH;
590 trust_ec = 1;
591 shutdown_request_calls_left = 100;
592 mock_keypress[0] = 0x04;
593 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
594 "Ctrl+D ignored if recovery not manually triggered");
595 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
596 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
597 " todev screen");
598
599 ResetMocks();
600 shared->flags = VBSD_BOOT_REC_SWITCH_ON;
601 trust_ec = 1;
602 shutdown_request_calls_left = 100;
603 mock_keypress[0] = 0x04;
604 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
605 "Ctrl+D ignored if no virtual dev switch");
606 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
607 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
608 " todev screen");
609
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800610 /* Ctrl+D ignored because the physical recovery switch is still pressed
611 * and we don't like that.
612 */
613 ResetMocks();
614 shared->flags = VBSD_BOOT_REC_SWITCH_ON;
615 trust_ec = 1;
616 shutdown_request_calls_left = 100;
617 mock_keypress[0] = 0x04;
618 mock_switches[0] = VB_INIT_FLAG_REC_BUTTON_PRESSED;
619 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
620 "Ctrl+D ignored if phys rec button is still pressed");
621 TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
622 " todev screen");
623
Randall Spangler7f436692013-02-05 12:42:36 -0800624 /* Ctrl+D then space means don't enable */
625 ResetMocks();
626 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
627 shutdown_request_calls_left = 100;
628 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
629 trust_ec = 1;
630 mock_keypress[0] = 0x04;
631 mock_keypress[1] = ' ';
632 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
633 "Ctrl+D todev abort");
634 TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
635 " insert screen");
636 TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
637 " todev screen");
638 TEST_EQ(screens_displayed[2], VB_SCREEN_RECOVERY_INSERT,
639 " insert screen");
640 TEST_EQ(virtdev_set, 0, " virtual dev mode off");
641
642 /* Ctrl+D then enter means enable */
643 ResetMocks();
644 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
645 shutdown_request_calls_left = 100;
646 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
647 trust_ec = 1;
648 mock_keypress[0] = 0x04;
649 mock_keypress[1] = '\r';
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800650 mock_keyflags[1] = VB_KEY_FLAG_TRUSTED_KEYBOARD;
Randall Spangler7f436692013-02-05 12:42:36 -0800651 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
652 "Ctrl+D todev confirm");
653 TEST_EQ(virtdev_set, 1, " virtual dev mode on");
654
655 /* Handle TPM error in enabling dev mode */
656 ResetMocks();
657 shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
658 shutdown_request_calls_left = 100;
659 vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
660 trust_ec = 1;
661 mock_keypress[0] = 0x04;
662 mock_keypress[1] = '\r';
Luigi Semenzatoa53a0b02014-01-10 16:26:08 -0800663 mock_keyflags[1] = VB_KEY_FLAG_TRUSTED_KEYBOARD;
Randall Spangler7f436692013-02-05 12:42:36 -0800664 virtdev_retval = VBERROR_SIMULATED;
665 TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_SET_BOOT_MODE_STATE,
666 "Ctrl+D todev failure");
667
668 printf("...done.\n");
669}
670
671
672int main(void)
673{
674 VbUserConfirmsTest();
675 VbBootTest();
676 VbBootDevTest();
677 VbBootRecTest();
678
Simon Glass25001852013-08-16 02:47:57 -0600679 if (vboot_api_stub_check_memory())
680 return 255;
681
Randall Spangler7f436692013-02-05 12:42:36 -0800682 return gTestSuccess ? 0 : 255;
683}