1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2020 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * Kernel selection, loading, verification, and booting.
6*8617a60dSAndroid Build Coastguard Worker */
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include "2api.h"
9*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
10*8617a60dSAndroid Build Coastguard Worker #include "2misc.h"
11*8617a60dSAndroid Build Coastguard Worker #include "2nvstorage.h"
12*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2secdata.h"
14*8617a60dSAndroid Build Coastguard Worker
vb2api_is_developer_signed(struct vb2_context * ctx)15*8617a60dSAndroid Build Coastguard Worker int vb2api_is_developer_signed(struct vb2_context *ctx)
16*8617a60dSAndroid Build Coastguard Worker {
17*8617a60dSAndroid Build Coastguard Worker struct vb2_shared_data *sd = vb2_get_sd(ctx);
18*8617a60dSAndroid Build Coastguard Worker
19*8617a60dSAndroid Build Coastguard Worker if (!sd->kernel_key_offset || !sd->kernel_key_size) {
20*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("ERROR: Cannot call this before kernel_phase1!\n");
21*8617a60dSAndroid Build Coastguard Worker return 0;
22*8617a60dSAndroid Build Coastguard Worker }
23*8617a60dSAndroid Build Coastguard Worker
24*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key key;
25*8617a60dSAndroid Build Coastguard Worker if (vb2_unpack_key(&key, vb2_member_of(sd, sd->kernel_key_offset)))
26*8617a60dSAndroid Build Coastguard Worker return 0;
27*8617a60dSAndroid Build Coastguard Worker
28*8617a60dSAndroid Build Coastguard Worker /* This is a debugging aid, not a security-relevant feature. There's no
29*8617a60dSAndroid Build Coastguard Worker reason to hardcode the whole key or waste time computing a hash. Just
30*8617a60dSAndroid Build Coastguard Worker spot check the starting bytes of the pseudorandom part of the key. */
31*8617a60dSAndroid Build Coastguard Worker uint32_t devkey_n0inv = ctx->flags & VB2_CONTEXT_RECOVERY_MODE ?
32*8617a60dSAndroid Build Coastguard Worker 0x18cebcf5 : /* recovery_key.vbpubk @0x24 */
33*8617a60dSAndroid Build Coastguard Worker 0xe0cd87d9; /* kernel_subkey.vbpubk @0x24 */
34*8617a60dSAndroid Build Coastguard Worker
35*8617a60dSAndroid Build Coastguard Worker if (key.n0inv == devkey_n0inv)
36*8617a60dSAndroid Build Coastguard Worker return 1;
37*8617a60dSAndroid Build Coastguard Worker
38*8617a60dSAndroid Build Coastguard Worker return 0;
39*8617a60dSAndroid Build Coastguard Worker }
40*8617a60dSAndroid Build Coastguard Worker
41*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2api_kernel_phase1(struct vb2_context * ctx)42*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx)
43*8617a60dSAndroid Build Coastguard Worker {
44*8617a60dSAndroid Build Coastguard Worker struct vb2_shared_data *sd = vb2_get_sd(ctx);
45*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
46*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *packed_key;
47*8617a60dSAndroid Build Coastguard Worker uint32_t flags;
48*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
49*8617a60dSAndroid Build Coastguard Worker
50*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_from_ctx(ctx, &wb);
51*8617a60dSAndroid Build Coastguard Worker
52*8617a60dSAndroid Build Coastguard Worker /*
53*8617a60dSAndroid Build Coastguard Worker * Init secdata_fwmp spaces. No need to init secdata_firmware or
54*8617a60dSAndroid Build Coastguard Worker * secdata_kernel, since they were already read during firmware
55*8617a60dSAndroid Build Coastguard Worker * verification. Ignore errors in recovery mode.
56*8617a60dSAndroid Build Coastguard Worker */
57*8617a60dSAndroid Build Coastguard Worker rv = vb2_secdata_fwmp_init(ctx);
58*8617a60dSAndroid Build Coastguard Worker if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
59*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("TPM: init secdata_fwmp returned %#x\n", rv);
60*8617a60dSAndroid Build Coastguard Worker vb2api_fail(ctx, VB2_RECOVERY_SECDATA_FWMP_INIT, rv);
61*8617a60dSAndroid Build Coastguard Worker return rv;
62*8617a60dSAndroid Build Coastguard Worker }
63*8617a60dSAndroid Build Coastguard Worker
64*8617a60dSAndroid Build Coastguard Worker /* Initialize experimental feature flags while in normal RW path. */
65*8617a60dSAndroid Build Coastguard Worker if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
66*8617a60dSAndroid Build Coastguard Worker flags = vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS);
67*8617a60dSAndroid Build Coastguard Worker flags &= ~VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED;
68*8617a60dSAndroid Build Coastguard Worker flags |= VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED;
69*8617a60dSAndroid Build Coastguard Worker vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS, flags);
70*8617a60dSAndroid Build Coastguard Worker }
71*8617a60dSAndroid Build Coastguard Worker
72*8617a60dSAndroid Build Coastguard Worker /* Read kernel version from secdata. */
73*8617a60dSAndroid Build Coastguard Worker sd->kernel_version_secdata =
74*8617a60dSAndroid Build Coastguard Worker vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS);
75*8617a60dSAndroid Build Coastguard Worker
76*8617a60dSAndroid Build Coastguard Worker vb2_fill_dev_boot_flags(ctx);
77*8617a60dSAndroid Build Coastguard Worker
78*8617a60dSAndroid Build Coastguard Worker /* Find the key to use to verify the kernel keyblock */
79*8617a60dSAndroid Build Coastguard Worker if ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
80*8617a60dSAndroid Build Coastguard Worker /* Load recovery key from GBB. */
81*8617a60dSAndroid Build Coastguard Worker rv = vb2_gbb_read_recovery_key(ctx, &packed_key, NULL, &wb);
82*8617a60dSAndroid Build Coastguard Worker if (rv) {
83*8617a60dSAndroid Build Coastguard Worker if (ctx->boot_mode != VB2_BOOT_MODE_BROKEN_SCREEN)
84*8617a60dSAndroid Build Coastguard Worker VB2_DIE("GBB read recovery key failed.\n");
85*8617a60dSAndroid Build Coastguard Worker else
86*8617a60dSAndroid Build Coastguard Worker /*
87*8617a60dSAndroid Build Coastguard Worker * If we're headed for the BROKEN screen,
88*8617a60dSAndroid Build Coastguard Worker * we won't need the recovery key. Just
89*8617a60dSAndroid Build Coastguard Worker * short-circuit with success.
90*8617a60dSAndroid Build Coastguard Worker */
91*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
92*8617a60dSAndroid Build Coastguard Worker }
93*8617a60dSAndroid Build Coastguard Worker } else {
94*8617a60dSAndroid Build Coastguard Worker /* Kernel subkey from firmware preamble */
95*8617a60dSAndroid Build Coastguard Worker struct vb2_fw_preamble *pre;
96*8617a60dSAndroid Build Coastguard Worker
97*8617a60dSAndroid Build Coastguard Worker /* Make sure we have a firmware preamble loaded */
98*8617a60dSAndroid Build Coastguard Worker if (!sd->preamble_size)
99*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_API_KPHASE1_PREAMBLE;
100*8617a60dSAndroid Build Coastguard Worker
101*8617a60dSAndroid Build Coastguard Worker pre = (struct vb2_fw_preamble *)
102*8617a60dSAndroid Build Coastguard Worker vb2_member_of(sd, sd->preamble_offset);
103*8617a60dSAndroid Build Coastguard Worker packed_key = &pre->kernel_subkey;
104*8617a60dSAndroid Build Coastguard Worker }
105*8617a60dSAndroid Build Coastguard Worker
106*8617a60dSAndroid Build Coastguard Worker sd->kernel_key_offset = vb2_offset_of(sd, packed_key);
107*8617a60dSAndroid Build Coastguard Worker sd->kernel_key_size = packed_key->key_offset + packed_key->key_size;
108*8617a60dSAndroid Build Coastguard Worker
109*8617a60dSAndroid Build Coastguard Worker vb2_set_workbuf_used(ctx, vb2_offset_of(sd, wb.buf));
110*8617a60dSAndroid Build Coastguard Worker
111*8617a60dSAndroid Build Coastguard Worker if (vb2api_is_developer_signed(ctx))
112*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("This is developer-signed firmware.\n");
113*8617a60dSAndroid Build Coastguard Worker
114*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
115*8617a60dSAndroid Build Coastguard Worker }
116*8617a60dSAndroid Build Coastguard Worker
handle_battery_cutoff(struct vb2_context * ctx)117*8617a60dSAndroid Build Coastguard Worker static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx)
118*8617a60dSAndroid Build Coastguard Worker {
119*8617a60dSAndroid Build Coastguard Worker /*
120*8617a60dSAndroid Build Coastguard Worker * Check if we need to cut-off battery. This should be done after EC
121*8617a60dSAndroid Build Coastguard Worker * FW and auxfw are updated, and before the kernel is started. This
122*8617a60dSAndroid Build Coastguard Worker * is to make sure all firmware is up-to-date before shipping (which
123*8617a60dSAndroid Build Coastguard Worker * is the typical use-case for cutoff).
124*8617a60dSAndroid Build Coastguard Worker */
125*8617a60dSAndroid Build Coastguard Worker if (vb2_nv_get(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST)) {
126*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Request to cut-off battery\n");
127*8617a60dSAndroid Build Coastguard Worker vb2_nv_set(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST, 0);
128*8617a60dSAndroid Build Coastguard Worker
129*8617a60dSAndroid Build Coastguard Worker /* May lose power immediately, so commit our update now. */
130*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2ex_commit_data(ctx));
131*8617a60dSAndroid Build Coastguard Worker
132*8617a60dSAndroid Build Coastguard Worker vb2ex_ec_battery_cutoff();
133*8617a60dSAndroid Build Coastguard Worker return VB2_REQUEST_SHUTDOWN;
134*8617a60dSAndroid Build Coastguard Worker }
135*8617a60dSAndroid Build Coastguard Worker
136*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
137*8617a60dSAndroid Build Coastguard Worker }
138*8617a60dSAndroid Build Coastguard Worker
vb2api_kernel_phase2(struct vb2_context * ctx)139*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2api_kernel_phase2(struct vb2_context *ctx)
140*8617a60dSAndroid Build Coastguard Worker {
141*8617a60dSAndroid Build Coastguard Worker struct vb2_shared_data *sd = vb2_get_sd(ctx);
142*8617a60dSAndroid Build Coastguard Worker vb2_gbb_flags_t gbb_flags = vb2api_gbb_get_flags(ctx);
143*8617a60dSAndroid Build Coastguard Worker
144*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("GBB flags are %#x\n", gbb_flags);
145*8617a60dSAndroid Build Coastguard Worker
146*8617a60dSAndroid Build Coastguard Worker /*
147*8617a60dSAndroid Build Coastguard Worker * Do EC and auxfw software sync unless we're in recovery mode. This
148*8617a60dSAndroid Build Coastguard Worker * has UI but it's just a single non-interactive WAIT screen.
149*8617a60dSAndroid Build Coastguard Worker */
150*8617a60dSAndroid Build Coastguard Worker if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) {
151*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2api_ec_sync(ctx));
152*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2api_auxfw_sync(ctx));
153*8617a60dSAndroid Build Coastguard Worker VB2_TRY(handle_battery_cutoff(ctx));
154*8617a60dSAndroid Build Coastguard Worker }
155*8617a60dSAndroid Build Coastguard Worker
156*8617a60dSAndroid Build Coastguard Worker /*
157*8617a60dSAndroid Build Coastguard Worker * If in the broken screen, save the recovery reason as subcode.
158*8617a60dSAndroid Build Coastguard Worker * Otherwise, clear any leftover recovery requests or subcodes.
159*8617a60dSAndroid Build Coastguard Worker */
160*8617a60dSAndroid Build Coastguard Worker vb2api_clear_recovery(ctx);
161*8617a60dSAndroid Build Coastguard Worker
162*8617a60dSAndroid Build Coastguard Worker /*
163*8617a60dSAndroid Build Coastguard Worker * Clear the diagnostic request flag and commit nvdata to prevent
164*8617a60dSAndroid Build Coastguard Worker * booting back into diagnostic mode when a forced system reset occurs.
165*8617a60dSAndroid Build Coastguard Worker */
166*8617a60dSAndroid Build Coastguard Worker if (vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST)) {
167*8617a60dSAndroid Build Coastguard Worker vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 0);
168*8617a60dSAndroid Build Coastguard Worker /*
169*8617a60dSAndroid Build Coastguard Worker * According to current FAFT design (firmware_MiniDiag), we
170*8617a60dSAndroid Build Coastguard Worker * need an AP reset after MiniDiag test items to preserve the
171*8617a60dSAndroid Build Coastguard Worker * CBMEM console logs. So we need to commit nvdata immediately
172*8617a60dSAndroid Build Coastguard Worker * to prevent booting back to VB2_BOOT_MODE_DIAGNOSTICS.
173*8617a60dSAndroid Build Coastguard Worker */
174*8617a60dSAndroid Build Coastguard Worker vb2ex_commit_data(ctx);
175*8617a60dSAndroid Build Coastguard Worker }
176*8617a60dSAndroid Build Coastguard Worker
177*8617a60dSAndroid Build Coastguard Worker /* Select boot path */
178*8617a60dSAndroid Build Coastguard Worker switch (ctx->boot_mode) {
179*8617a60dSAndroid Build Coastguard Worker case VB2_BOOT_MODE_MANUAL_RECOVERY:
180*8617a60dSAndroid Build Coastguard Worker case VB2_BOOT_MODE_BROKEN_SCREEN:
181*8617a60dSAndroid Build Coastguard Worker /* If we're in recovery mode just to do memory retraining, all
182*8617a60dSAndroid Build Coastguard Worker we need to do is reboot. */
183*8617a60dSAndroid Build Coastguard Worker if (sd->recovery_reason == VB2_RECOVERY_TRAIN_AND_REBOOT) {
184*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Reboot after retraining in recovery\n");
185*8617a60dSAndroid Build Coastguard Worker return VB2_REQUEST_REBOOT;
186*8617a60dSAndroid Build Coastguard Worker }
187*8617a60dSAndroid Build Coastguard Worker
188*8617a60dSAndroid Build Coastguard Worker /*
189*8617a60dSAndroid Build Coastguard Worker * Need to commit nvdata changes immediately, since we will be
190*8617a60dSAndroid Build Coastguard Worker * entering either manual recovery UI or BROKEN screen shortly.
191*8617a60dSAndroid Build Coastguard Worker */
192*8617a60dSAndroid Build Coastguard Worker vb2ex_commit_data(ctx);
193*8617a60dSAndroid Build Coastguard Worker break;
194*8617a60dSAndroid Build Coastguard Worker case VB2_BOOT_MODE_DIAGNOSTICS:
195*8617a60dSAndroid Build Coastguard Worker case VB2_BOOT_MODE_DEVELOPER:
196*8617a60dSAndroid Build Coastguard Worker break;
197*8617a60dSAndroid Build Coastguard Worker case VB2_BOOT_MODE_NORMAL:
198*8617a60dSAndroid Build Coastguard Worker if (vb2_nv_get(ctx, VB2_NV_DISPLAY_REQUEST)) {
199*8617a60dSAndroid Build Coastguard Worker vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 0);
200*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Normal mode: "
201*8617a60dSAndroid Build Coastguard Worker "reboot to unset display request\n");
202*8617a60dSAndroid Build Coastguard Worker return VB2_REQUEST_REBOOT;
203*8617a60dSAndroid Build Coastguard Worker }
204*8617a60dSAndroid Build Coastguard Worker break;
205*8617a60dSAndroid Build Coastguard Worker default:
206*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_ESCAPE_NO_BOOT;
207*8617a60dSAndroid Build Coastguard Worker }
208*8617a60dSAndroid Build Coastguard Worker
209*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
210*8617a60dSAndroid Build Coastguard Worker }
211*8617a60dSAndroid Build Coastguard Worker
update_kernel_version(struct vb2_context * ctx)212*8617a60dSAndroid Build Coastguard Worker static void update_kernel_version(struct vb2_context *ctx)
213*8617a60dSAndroid Build Coastguard Worker {
214*8617a60dSAndroid Build Coastguard Worker struct vb2_shared_data *sd = vb2_get_sd(ctx);
215*8617a60dSAndroid Build Coastguard Worker uint32_t max_rollforward =
216*8617a60dSAndroid Build Coastguard Worker vb2_nv_get(ctx, VB2_NV_KERNEL_MAX_ROLLFORWARD);
217*8617a60dSAndroid Build Coastguard Worker
218*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Checking if TPM kernel version needs advancing\n");
219*8617a60dSAndroid Build Coastguard Worker
220*8617a60dSAndroid Build Coastguard Worker /*
221*8617a60dSAndroid Build Coastguard Worker * Special case for when we're trying a slot with new firmware.
222*8617a60dSAndroid Build Coastguard Worker * Firmware updates also usually change the kernel key, which means
223*8617a60dSAndroid Build Coastguard Worker * that the new firmware can only boot a new kernel, and the old
224*8617a60dSAndroid Build Coastguard Worker * firmware in the previous slot can only boot the previous kernel.
225*8617a60dSAndroid Build Coastguard Worker *
226*8617a60dSAndroid Build Coastguard Worker * Don't roll-forward the kernel version, because we don't yet know if
227*8617a60dSAndroid Build Coastguard Worker * the new kernel will successfully boot.
228*8617a60dSAndroid Build Coastguard Worker */
229*8617a60dSAndroid Build Coastguard Worker if (vb2_nv_get(ctx, VB2_NV_FW_RESULT) == VB2_FW_RESULT_TRYING) {
230*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Trying new FW; "
231*8617a60dSAndroid Build Coastguard Worker "skip kernel version roll-forward.\n");
232*8617a60dSAndroid Build Coastguard Worker return;
233*8617a60dSAndroid Build Coastguard Worker }
234*8617a60dSAndroid Build Coastguard Worker
235*8617a60dSAndroid Build Coastguard Worker /*
236*8617a60dSAndroid Build Coastguard Worker * Limit kernel version rollforward if needed. Can't limit kernel
237*8617a60dSAndroid Build Coastguard Worker * version to less than the version currently in the TPM. That is,
238*8617a60dSAndroid Build Coastguard Worker * we're limiting rollforward, not allowing rollback.
239*8617a60dSAndroid Build Coastguard Worker */
240*8617a60dSAndroid Build Coastguard Worker uint32_t original_kernel_version =
241*8617a60dSAndroid Build Coastguard Worker vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS);
242*8617a60dSAndroid Build Coastguard Worker
243*8617a60dSAndroid Build Coastguard Worker if (max_rollforward < original_kernel_version)
244*8617a60dSAndroid Build Coastguard Worker max_rollforward = original_kernel_version;
245*8617a60dSAndroid Build Coastguard Worker
246*8617a60dSAndroid Build Coastguard Worker if (sd->kernel_version_secdata > max_rollforward) {
247*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Limiting TPM kernel version roll-forward "
248*8617a60dSAndroid Build Coastguard Worker "to %#x < %#x\n",
249*8617a60dSAndroid Build Coastguard Worker max_rollforward, sd->kernel_version_secdata);
250*8617a60dSAndroid Build Coastguard Worker
251*8617a60dSAndroid Build Coastguard Worker sd->kernel_version_secdata = max_rollforward;
252*8617a60dSAndroid Build Coastguard Worker }
253*8617a60dSAndroid Build Coastguard Worker
254*8617a60dSAndroid Build Coastguard Worker if (sd->kernel_version_secdata > original_kernel_version) {
255*8617a60dSAndroid Build Coastguard Worker vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_VERSIONS,
256*8617a60dSAndroid Build Coastguard Worker sd->kernel_version_secdata);
257*8617a60dSAndroid Build Coastguard Worker } else {
258*8617a60dSAndroid Build Coastguard Worker sd->kernel_version_secdata = original_kernel_version;
259*8617a60dSAndroid Build Coastguard Worker }
260*8617a60dSAndroid Build Coastguard Worker }
261*8617a60dSAndroid Build Coastguard Worker
vb2api_kernel_finalize(struct vb2_context * ctx)262*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2api_kernel_finalize(struct vb2_context *ctx)
263*8617a60dSAndroid Build Coastguard Worker {
264*8617a60dSAndroid Build Coastguard Worker vb2_gbb_flags_t gbb_flags = vb2api_gbb_get_flags(ctx);
265*8617a60dSAndroid Build Coastguard Worker
266*8617a60dSAndroid Build Coastguard Worker /*
267*8617a60dSAndroid Build Coastguard Worker * Disallow booting to kernel when NO_BOOT flag is set, except when
268*8617a60dSAndroid Build Coastguard Worker * GBB flag disables software sync.
269*8617a60dSAndroid Build Coastguard Worker */
270*8617a60dSAndroid Build Coastguard Worker if (!(gbb_flags & VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC)
271*8617a60dSAndroid Build Coastguard Worker && (ctx->flags & VB2_CONTEXT_EC_SYNC_SUPPORTED)
272*8617a60dSAndroid Build Coastguard Worker && (ctx->flags & VB2_CONTEXT_NO_BOOT)) {
273*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Blocking escape from NO_BOOT mode.\n");
274*8617a60dSAndroid Build Coastguard Worker vb2api_fail(ctx, VB2_RECOVERY_ESCAPE_NO_BOOT, 0);
275*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_ESCAPE_NO_BOOT;
276*8617a60dSAndroid Build Coastguard Worker }
277*8617a60dSAndroid Build Coastguard Worker
278*8617a60dSAndroid Build Coastguard Worker if (ctx->boot_mode == VB2_BOOT_MODE_NORMAL)
279*8617a60dSAndroid Build Coastguard Worker update_kernel_version(ctx);
280*8617a60dSAndroid Build Coastguard Worker
281*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
282*8617a60dSAndroid Build Coastguard Worker }
283