1 /* Copyright 2022 The ChromiumOS Authors
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 vb2_set_boot_mode.
6 */
7
8 #include "2api.h"
9 #include "2common.h"
10 #include "2misc.h"
11 #include "2nvstorage.h"
12 #include "common/tests.h"
13
14 /* Mock data */
15
16 static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
17 __attribute__((aligned(VB2_WORKBUF_ALIGN)));
18 static struct vb2_context *ctx;
19 static struct vb2_shared_data *sd;
20 static struct vb2_gbb_header gbb;
21
22 static int mock_diagnostic_ui_enabled;
23
24 /* Mock functions */
25
vb2_get_gbb(struct vb2_context * c)26 struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
27 {
28 return &gbb;
29 }
30
vb2api_diagnostic_ui_enabled(struct vb2_context * c)31 int vb2api_diagnostic_ui_enabled(struct vb2_context *c)
32 {
33 return mock_diagnostic_ui_enabled;
34 }
35
reset_common_data(void)36 static void reset_common_data(void)
37 {
38 memset(workbuf, 0xaa, sizeof(workbuf));
39
40 memset(&gbb, 0, sizeof(gbb));
41
42 TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
43 "vb2api_init failed");
44 sd = vb2_get_sd(ctx);
45
46 vb2_nv_init(ctx);
47
48 mock_diagnostic_ui_enabled = 0;
49 }
50
set_boot_mode_tests(void)51 static void set_boot_mode_tests(void)
52 {
53 /* Normal boot */
54 reset_common_data();
55 vb2_set_boot_mode(ctx);
56 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_NORMAL, "Normal boot");
57
58 /* Check that NV_DIAG_REQUEST triggers diagnostic mode */
59 reset_common_data();
60 mock_diagnostic_ui_enabled = 1;
61 vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
62 vb2_set_boot_mode(ctx);
63 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_DIAGNOSTICS,
64 "Normal boot with diag UI enabled");
65
66 reset_common_data();
67 vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
68 vb2_set_boot_mode(ctx);
69 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_NORMAL,
70 "Normal boot with diag UI disabled");
71
72 /* Developer boot */
73 reset_common_data();
74 ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
75 sd->flags |= VB2_SD_FLAG_DEV_MODE_ENABLED;
76 vb2_set_boot_mode(ctx);
77 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_DEVELOPER, "Dev boot");
78
79 /* Recovery boot */
80 reset_common_data();
81 sd->recovery_reason = 123;
82 ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
83 vb2_set_boot_mode(ctx);
84 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_BROKEN_SCREEN, "Broken screen");
85
86 reset_common_data();
87 sd->recovery_reason = VB2_RECOVERY_RO_MANUAL;
88 ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
89 gbb.flags |= VB2_GBB_FLAG_FORCE_MANUAL_RECOVERY;
90 vb2_set_boot_mode(ctx);
91 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_MANUAL_RECOVERY,
92 "Manual recovery: forced by GBB flags");
93
94 reset_common_data();
95 sd->recovery_reason = VB2_RECOVERY_RO_MANUAL;
96 ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
97 ctx->flags |= VB2_CONTEXT_EC_TRUSTED;
98 vb2_set_boot_mode(ctx);
99 TEST_EQ(ctx->boot_mode, VB2_BOOT_MODE_MANUAL_RECOVERY,
100 "Manual recovery: physical rec switch");
101
102 reset_common_data();
103 ctx->flags |= VB2_CONTEXT_EC_TRUSTED;
104 vb2_set_boot_mode(ctx);
105 TEST_NEQ(ctx->boot_mode, VB2_BOOT_MODE_MANUAL_RECOVERY,
106 "VB2_CONTEXT_FORCE_RECOVERY_MODE is not set");
107
108 reset_common_data();
109 ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
110 ctx->flags |= VB2_CONTEXT_NO_BOOT;
111 ctx->flags |= VB2_CONTEXT_EC_TRUSTED;
112 vb2_set_boot_mode(ctx);
113 TEST_NEQ(ctx->boot_mode, VB2_BOOT_MODE_MANUAL_RECOVERY,
114 "Block manual recovery if NO_BOOT");
115
116 reset_common_data();
117 ctx->flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
118 vb2_set_boot_mode(ctx);
119 TEST_NEQ(ctx->boot_mode, VB2_BOOT_MODE_MANUAL_RECOVERY,
120 "Block manual recovery for untrusted EC");
121 }
122
main(void)123 int main(void)
124 {
125 set_boot_mode_tests();
126
127 return gTestSuccess ? 0 : 255;
128 }
129