vboot_api_kernel2_tests.c revision 0c3ba249abb1dc60f5ebabccf84ff13206440b83
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_kernel, part 2
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 "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;
37
38static uint32_t mock_keypress[8];
39static uint32_t mock_keypress_count;
40static uint32_t screens_displayed[8];
41static uint32_t screens_count = 0;
42static uint32_t mock_num_disks[8];
43static uint32_t mock_num_disks_count;
44
45/* Reset mock data (for use before each test) */
46static void ResetMocks(void)
47{
48	Memset(&cparams, 0, sizeof(cparams));
49	cparams.shared_data_size = sizeof(shared_data);
50	cparams.shared_data_blob = shared_data;
51	cparams.gbb_data = &gbb;
52
53	Memset(&gbb, 0, sizeof(gbb));
54	gbb.major_version = GBB_MAJOR_VER;
55	gbb.minor_version = GBB_MINOR_VER;
56	gbb.flags = 0;
57
58	/*
59	 * Only the outermost vboot_api_kernel call sets vboot_api_kernel's
60	 * vnc.  So clear it here too.
61	 */
62	Memset(VbApiKernelGetVnc(), 0, sizeof(VbNvContext));
63	VbNvSetup(VbApiKernelGetVnc());
64	VbNvTeardown(VbApiKernelGetVnc()); /* So CRC gets generated */
65
66	Memset(&shared_data, 0, sizeof(shared_data));
67	VbSharedDataInit(shared, sizeof(shared_data));
68
69	Memset(&lkp, 0, sizeof(lkp));
70
71	shutdown_request_calls_left = -1;
72	audio_looping_calls_left = 30;
73	vbtlk_retval = 1000;
74	vbexlegacy_called = 0;
75	trust_ec = 0;
76	virtdev_set = 0;
77	virtdev_retval = 0;
78
79	Memset(screens_displayed, 0, sizeof(screens_displayed));
80	screens_count = 0;
81
82	Memset(mock_keypress, 0, sizeof(mock_keypress));
83	mock_keypress_count = 0;
84
85	Memset(mock_num_disks, 0, sizeof(mock_num_disks));
86	mock_num_disks_count = 0;
87}
88
89/* Mock functions */
90
91uint32_t VbExIsShutdownRequested(void)
92{
93	if (shutdown_request_calls_left == 0)
94		return 1;
95	else if (shutdown_request_calls_left > 0)
96		shutdown_request_calls_left--;
97
98	return 0;
99}
100
101uint32_t VbExKeyboardRead(void)
102{
103	if (mock_keypress_count < ARRAY_SIZE(mock_keypress))
104		return mock_keypress[mock_keypress_count++];
105	else
106		return 0;
107}
108
109int VbExLegacy(void)
110{
111	vbexlegacy_called++;
112	return 0;
113}
114
115VbError_t VbExDiskGetInfo(VbDiskInfo **infos_ptr, uint32_t *count,
116                          uint32_t disk_flags)
117{
118	if (mock_num_disks_count < ARRAY_SIZE(mock_num_disks)) {
119		if (mock_num_disks[mock_num_disks_count] == -1)
120			return VBERROR_SIMULATED;
121		else
122			*count = mock_num_disks[mock_num_disks_count++];
123	} else {
124		*count = 0;
125	}
126	return VBERROR_SUCCESS;
127}
128
129VbError_t VbExDiskFreeInfo(VbDiskInfo *infos,
130                           VbExDiskHandle_t preserve_handle)
131{
132	return VBERROR_SUCCESS;
133}
134
135int VbExTrustEC(void)
136{
137	return trust_ec;
138}
139
140int VbAudioLooping(VbAudioContext *audio)
141{
142	if (audio_looping_calls_left == 0)
143		return 0;
144	else if (audio_looping_calls_left > 0)
145		audio_looping_calls_left--;
146
147	return 1;
148}
149
150uint32_t VbTryLoadKernel(VbCommonParams *cparams, LoadKernelParams *p,
151                         uint32_t get_info_flags)
152{
153	return vbtlk_retval + get_info_flags;
154}
155
156VbError_t VbDisplayScreen(VbCommonParams *cparams, uint32_t screen, int force,
157                          VbNvContext *vncptr)
158{
159	if (screens_count < ARRAY_SIZE(screens_displayed))
160		screens_displayed[screens_count++] = screen;
161
162	return VBERROR_SUCCESS;
163}
164
165uint32_t SetVirtualDevMode(int val)
166{
167	virtdev_set = val;
168	return virtdev_retval;
169}
170
171/* Tests */
172
173static void VbUserConfirmsTest(void)
174{
175	printf("Testing VbUserConfirms()...\n");
176
177	ResetMocks();
178	shutdown_request_calls_left = 1;
179	TEST_EQ(VbUserConfirms(&cparams, 0), -1, "Shutdown requested");
180
181	ResetMocks();
182	mock_keypress[0] = '\r';
183	TEST_EQ(VbUserConfirms(&cparams, 0), 1, "Enter");
184
185	ResetMocks();
186	mock_keypress[0] = 0x1b;
187	TEST_EQ(VbUserConfirms(&cparams, 0), 0, "Esc");
188
189	ResetMocks();
190	mock_keypress[0] = ' ';
191	shutdown_request_calls_left = 1;
192	TEST_EQ(VbUserConfirms(&cparams, 1), 0, "Space means no");
193
194	ResetMocks();
195	mock_keypress[0] = ' ';
196	shutdown_request_calls_left = 1;
197	TEST_EQ(VbUserConfirms(&cparams, 0), -1, "Space ignored");
198
199	printf("...done.\n");
200}
201
202static void VbBootTest(void)
203{
204	ResetMocks();
205	TEST_EQ(VbBootNormal(&cparams, &lkp), 1002, "VbBootNormal()");
206}
207
208static void VbBootDevTest(void)
209{
210	uint32_t u;
211
212	printf("Testing VbBootDeveloper()...\n");
213
214	/* Proceed after timeout */
215	ResetMocks();
216	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Timeout");
217	TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
218		"  warning screen");
219	VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
220	TEST_EQ(u, 0, "  recovery reason");
221	TEST_EQ(audio_looping_calls_left, 0, "  used up audio");
222
223	/* Up arrow is uninteresting / passed to VbCheckDisplayKey() */
224	ResetMocks();
225	mock_keypress[0] = VB_KEY_UP;
226	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Up arrow");
227
228	/* Shutdown requested in loop */
229	ResetMocks();
230	shutdown_request_calls_left = 2;
231	TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
232		"Shutdown requested");
233	TEST_NEQ(audio_looping_calls_left, 0, "  aborts audio");
234
235	/* Space goes straight to recovery if no virtual dev switch */
236	ResetMocks();
237	mock_keypress[0] = ' ';
238	TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_LOAD_KERNEL_RECOVERY,
239		"Space = recovery");
240	VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
241	TEST_EQ(u, VBNV_RECOVERY_RW_DEV_SCREEN, "  recovery reason");
242
243	/* Space asks to disable virtual dev switch */
244	ResetMocks();
245	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
246	mock_keypress[0] = ' ';
247	mock_keypress[1] = '\r';
248	TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
249		"Space = tonorm");
250	TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
251		"  warning screen");
252	TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
253		"  tonorm screen");
254	TEST_EQ(screens_displayed[2], VB_SCREEN_TO_NORM_CONFIRMED,
255		"  confirm screen");
256	VbNvGet(VbApiKernelGetVnc(), VBNV_DISABLE_DEV_REQUEST, &u);
257	TEST_EQ(u, 1, "  disable dev request");
258
259	/* Space-space doesn't disable it */
260	ResetMocks();
261	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
262	mock_keypress[0] = ' ';
263	mock_keypress[1] = ' ';
264	mock_keypress[2] = 0x1b;
265	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Space-space");
266	TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
267		"  warning screen");
268	TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
269		"  tonorm screen");
270	TEST_EQ(screens_displayed[2], VB_SCREEN_DEVELOPER_WARNING,
271		"  warning screen");
272
273	/* Enter doesn't by default */
274	ResetMocks();
275	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
276	mock_keypress[0] = '\r';
277	mock_keypress[1] = '\r';
278	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Enter ignored");
279
280	/* Enter does if GBB flag set */
281	ResetMocks();
282	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
283	gbb.flags |= GBB_FLAG_ENTER_TRIGGERS_TONORM;
284	mock_keypress[0] = '\r';
285	mock_keypress[1] = '\r';
286	TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
287		"Enter = tonorm");
288
289	/* Tonorm ignored if GBB forces dev switch on */
290	ResetMocks();
291	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
292	gbb.flags |= GBB_FLAG_FORCE_DEV_SWITCH_ON;
293	mock_keypress[0] = ' ';
294	mock_keypress[1] = '\r';
295	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Can't tonorm gbb-dev");
296
297	/* Shutdown requested at tonorm screen */
298	ResetMocks();
299	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
300	mock_keypress[0] = ' ';
301	shutdown_request_calls_left = 2;
302	TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
303		"Shutdown requested at tonorm");
304	TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
305		"  warning screen");
306	TEST_EQ(screens_displayed[1], VB_SCREEN_DEVELOPER_TO_NORM,
307		"  tonorm screen");
308
309	/* Ctrl+D dismisses warning */
310	ResetMocks();
311	mock_keypress[0] = 0x04;
312	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+D");
313	VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
314	TEST_EQ(u, 0, "  recovery reason");
315	TEST_NEQ(audio_looping_calls_left, 0, "  aborts audio");
316
317	/* Ctrl+L tries legacy boot mode only if enabled */
318	ResetMocks();
319	mock_keypress[0] = 0x0c;
320	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L normal");
321	TEST_EQ(vbexlegacy_called, 0, "  not legacy");
322
323	ResetMocks();
324
325	gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_LEGACY;
326	mock_keypress[0] = 0x0c;
327	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L force legacy");
328	TEST_EQ(vbexlegacy_called, 1, "  try legacy");
329
330	ResetMocks();
331	VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_LEGACY, 1);
332	mock_keypress[0] = 0x0c;
333	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+L nv legacy");
334	TEST_EQ(vbexlegacy_called, 1, "  try legacy");
335
336	/* Ctrl+U boots USB only if enabled */
337	ResetMocks();
338	mock_keypress[0] = 0x15;
339	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U normal");
340
341	/* Ctrl+U enabled, with good USB boot */
342	ResetMocks();
343	VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
344	mock_keypress[0] = 0x15;
345	vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
346	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U USB");
347
348	/* Ctrl+U enabled via GBB */
349	ResetMocks();
350	gbb.flags |= GBB_FLAG_FORCE_DEV_BOOT_USB;
351	mock_keypress[0] = 0x15;
352	vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
353	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 0, "Ctrl+U force USB");
354
355	/* If no USB, eventually times out and tries fixed disk */
356	ResetMocks();
357	VbNvSet(VbApiKernelGetVnc(), VBNV_DEV_BOOT_USB, 1);
358	mock_keypress[0] = 0x15;
359	TEST_EQ(VbBootDeveloper(&cparams, &lkp), 1002, "Ctrl+U enabled");
360	TEST_EQ(vbexlegacy_called, 0, "  not legacy");
361	VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
362	TEST_EQ(u, 0, "  recovery reason");
363	TEST_EQ(audio_looping_calls_left, 0, "  used up audio");
364
365	printf("...done.\n");
366}
367
368static void VbBootRecTest(void)
369{
370	uint32_t u;
371
372	printf("Testing VbBootRecovery()...\n");
373
374	/* Shutdown requested in loop */
375	ResetMocks();
376	shutdown_request_calls_left = 10;
377	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
378		"Shutdown requested");
379	VbNvGet(VbApiKernelGetVnc(), VBNV_RECOVERY_REQUEST, &u);
380	TEST_EQ(u, 0, "  recovery reason");
381	TEST_EQ(screens_displayed[0], VB_SCREEN_BLANK,
382		"  blank screen");
383	TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_NO_GOOD,
384		"  no good screen");
385
386	/* Disk inserted after start */
387	ResetMocks();
388	vbtlk_retval = VBERROR_SUCCESS - VB_DISK_FLAG_REMOVABLE;
389	TEST_EQ(VbBootRecovery(&cparams, &lkp), 0, "Good");
390
391	/* No disk inserted */
392	ResetMocks();
393	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
394	shutdown_request_calls_left = 10;
395	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
396		"Bad disk");
397	TEST_EQ(screens_displayed[0], VB_SCREEN_BLANK,
398		"  blank screen");
399	TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_INSERT,
400		"  insert screen");
401
402	/* Remove disks */
403	ResetMocks();
404	shutdown_request_calls_left = 100;
405	mock_num_disks[0] = 1;
406	mock_num_disks[1] = 1;
407	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
408	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
409		"Remove");
410	TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_REMOVE,
411		"  remove screen");
412	TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_REMOVE,
413		"  remove screen");
414	TEST_EQ(screens_displayed[2], VB_SCREEN_BLANK,
415		"  blank screen");
416	TEST_EQ(screens_displayed[3], VB_SCREEN_RECOVERY_INSERT,
417		"  insert screen");
418
419	/* No removal if dev switch is on */
420	ResetMocks();
421	shutdown_request_calls_left = 100;
422	mock_num_disks[0] = 1;
423	mock_num_disks[1] = 1;
424	shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
425	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
426	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
427		"No remove in dev");
428	TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
429		"  insert screen");
430
431	/* No removal if recovery button physically pressed */
432	ResetMocks();
433	shutdown_request_calls_left = 100;
434	mock_num_disks[0] = 1;
435	mock_num_disks[1] = 1;
436	shared->flags |= VBSD_BOOT_REC_SWITCH_ON;
437	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
438	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
439		"No remove in rec");
440	TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
441		"  insert screen");
442
443	/* Bad disk count doesn't require removal */
444	ResetMocks();
445	mock_num_disks[0] = -1;
446	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
447	shutdown_request_calls_left = 10;
448	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
449		"Bad disk count");
450	TEST_EQ(screens_displayed[0], VB_SCREEN_BLANK,
451		"  blank screen");
452	TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_INSERT,
453		"  insert screen");
454
455	/* Ctrl+D ignored for many reasons... */
456	ResetMocks();
457	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
458	shutdown_request_calls_left = 100;
459	mock_keypress[0] = 0x04;
460	trust_ec = 0;
461	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
462		"Ctrl+D ignored if EC not trusted");
463	TEST_EQ(virtdev_set, 0, "  virtual dev mode off");
464	TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
465		 "  todev screen");
466
467	ResetMocks();
468	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON |
469		VBSD_BOOT_DEV_SWITCH_ON;
470	trust_ec = 1;
471	shutdown_request_calls_left = 100;
472	mock_keypress[0] = 0x04;
473	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
474		"Ctrl+D ignored if already in dev mode");
475	TEST_EQ(virtdev_set, 0, "  virtual dev mode off");
476	TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
477		 "  todev screen");
478
479	ResetMocks();
480	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH;
481	trust_ec = 1;
482	shutdown_request_calls_left = 100;
483	mock_keypress[0] = 0x04;
484	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
485		"Ctrl+D ignored if recovery not manually triggered");
486	TEST_EQ(virtdev_set, 0, "  virtual dev mode off");
487	TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
488		 "  todev screen");
489
490	ResetMocks();
491	shared->flags = VBSD_BOOT_REC_SWITCH_ON;
492	trust_ec = 1;
493	shutdown_request_calls_left = 100;
494	mock_keypress[0] = 0x04;
495	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
496		"Ctrl+D ignored if no virtual dev switch");
497	TEST_EQ(virtdev_set, 0, "  virtual dev mode off");
498	TEST_NEQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
499		 "  todev screen");
500
501	/* Ctrl+D then space means don't enable */
502	ResetMocks();
503	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
504	shutdown_request_calls_left = 100;
505	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
506	trust_ec = 1;
507	mock_keypress[0] = 0x04;
508	mock_keypress[1] = ' ';
509	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_SHUTDOWN_REQUESTED,
510		"Ctrl+D todev abort");
511	TEST_EQ(screens_displayed[0], VB_SCREEN_RECOVERY_INSERT,
512		"  insert screen");
513	TEST_EQ(screens_displayed[1], VB_SCREEN_RECOVERY_TO_DEV,
514		"  todev screen");
515	TEST_EQ(screens_displayed[2], VB_SCREEN_RECOVERY_INSERT,
516		"  insert screen");
517	TEST_EQ(virtdev_set, 0, "  virtual dev mode off");
518
519	/* Ctrl+D then enter means enable */
520	ResetMocks();
521	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
522	shutdown_request_calls_left = 100;
523	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
524	trust_ec = 1;
525	mock_keypress[0] = 0x04;
526	mock_keypress[1] = '\r';
527	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED,
528		"Ctrl+D todev confirm");
529	TEST_EQ(virtdev_set, 1, "  virtual dev mode on");
530
531	/* Handle TPM error in enabling dev mode */
532	ResetMocks();
533	shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_REC_SWITCH_ON;
534	shutdown_request_calls_left = 100;
535	vbtlk_retval = VBERROR_NO_DISK_FOUND - VB_DISK_FLAG_REMOVABLE;
536	trust_ec = 1;
537	mock_keypress[0] = 0x04;
538	mock_keypress[1] = '\r';
539	virtdev_retval = VBERROR_SIMULATED;
540	TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_SET_BOOT_MODE_STATE,
541		"Ctrl+D todev failure");
542
543	printf("...done.\n");
544}
545
546
547int main(void)
548{
549	VbUserConfirmsTest();
550	VbBootTest();
551	VbBootDevTest();
552	VbBootRecTest();
553
554	return gTestSuccess ? 0 : 255;
555}
556