xref: /aosp_15_r20/external/vboot_reference/firmware/2lib/2misc.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2014 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  * Misc functions which need access to vb2_context but are not public APIs
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 "2recovery_reasons.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2secdata.h"
15*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
16*8617a60dSAndroid Build Coastguard Worker #include "2struct.h"
17*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
18*8617a60dSAndroid Build Coastguard Worker #include "vboot_api.h"
19*8617a60dSAndroid Build Coastguard Worker #include "vboot_struct.h"
20*8617a60dSAndroid Build Coastguard Worker 
vb2_validate_gbb_signature(uint8_t * sig)21*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_validate_gbb_signature(uint8_t *sig)
22*8617a60dSAndroid Build Coastguard Worker {
23*8617a60dSAndroid Build Coastguard Worker 	static const uint8_t sig_xor[VB2_GBB_SIGNATURE_SIZE] =
24*8617a60dSAndroid Build Coastguard Worker 			VB2_GBB_XOR_SIGNATURE;
25*8617a60dSAndroid Build Coastguard Worker 	int i;
26*8617a60dSAndroid Build Coastguard Worker 	for (i = 0; i < VB2_GBB_SIGNATURE_SIZE; i++) {
27*8617a60dSAndroid Build Coastguard Worker 		if (sig[i] != (sig_xor[i] ^ VB2_GBB_XOR_CHARS[i]))
28*8617a60dSAndroid Build Coastguard Worker 			return VB2_ERROR_GBB_MAGIC;
29*8617a60dSAndroid Build Coastguard Worker 	}
30*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
31*8617a60dSAndroid Build Coastguard Worker }
32*8617a60dSAndroid Build Coastguard Worker 
33*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_get_gbb(struct vb2_context * ctx)34*8617a60dSAndroid Build Coastguard Worker struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *ctx)
35*8617a60dSAndroid Build Coastguard Worker {
36*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
37*8617a60dSAndroid Build Coastguard Worker 	if (sd->gbb_offset == 0)
38*8617a60dSAndroid Build Coastguard Worker 		VB2_DIE("gbb_offset is not initialized\n");
39*8617a60dSAndroid Build Coastguard Worker 	return (struct vb2_gbb_header *)((void *)sd + sd->gbb_offset);
40*8617a60dSAndroid Build Coastguard Worker }
41*8617a60dSAndroid Build Coastguard Worker 
vb2api_get_firmware_size(struct vb2_context * ctx)42*8617a60dSAndroid Build Coastguard Worker uint32_t vb2api_get_firmware_size(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 	if (!sd->preamble_size)
46*8617a60dSAndroid Build Coastguard Worker 		VB2_DIE("Firmware preamble size is zero\n");
47*8617a60dSAndroid Build Coastguard Worker 
48*8617a60dSAndroid Build Coastguard Worker 	const struct vb2_fw_preamble *pre = (const struct vb2_fw_preamble *)
49*8617a60dSAndroid Build Coastguard Worker 		vb2_member_of(sd, sd->preamble_offset);
50*8617a60dSAndroid Build Coastguard Worker 
51*8617a60dSAndroid Build Coastguard Worker 	if (!pre->body_signature.data_size)
52*8617a60dSAndroid Build Coastguard Worker 		VB2_DIE("Firmware body data size in signature is zero\n");
53*8617a60dSAndroid Build Coastguard Worker 
54*8617a60dSAndroid Build Coastguard Worker 	return pre->body_signature.data_size;
55*8617a60dSAndroid Build Coastguard Worker }
56*8617a60dSAndroid Build Coastguard Worker 
57*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_read_gbb_header(struct vb2_context * ctx,struct vb2_gbb_header * gbb)58*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_read_gbb_header(struct vb2_context *ctx,
59*8617a60dSAndroid Build Coastguard Worker 				struct vb2_gbb_header *gbb)
60*8617a60dSAndroid Build Coastguard Worker {
61*8617a60dSAndroid Build Coastguard Worker 	/* Read the entire header */
62*8617a60dSAndroid Build Coastguard Worker 	VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, 0, gbb, sizeof(*gbb)));
63*8617a60dSAndroid Build Coastguard Worker 
64*8617a60dSAndroid Build Coastguard Worker 	/* Make sure it's really a GBB */
65*8617a60dSAndroid Build Coastguard Worker 	VB2_TRY(vb2_validate_gbb_signature(gbb->signature));
66*8617a60dSAndroid Build Coastguard Worker 
67*8617a60dSAndroid Build Coastguard Worker 	/* Check for compatible version */
68*8617a60dSAndroid Build Coastguard Worker 	if (gbb->major_version != VB2_GBB_MAJOR_VER)
69*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_GBB_VERSION;
70*8617a60dSAndroid Build Coastguard Worker 
71*8617a60dSAndroid Build Coastguard Worker 	/* Current code is not backwards-compatible to 1.1 headers or older */
72*8617a60dSAndroid Build Coastguard Worker 	if (gbb->minor_version < VB2_GBB_MINOR_VER)
73*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_GBB_TOO_OLD;
74*8617a60dSAndroid Build Coastguard Worker 
75*8617a60dSAndroid Build Coastguard Worker 	/*
76*8617a60dSAndroid Build Coastguard Worker 	 * Header size should be at least as big as we expect.  It could be
77*8617a60dSAndroid Build Coastguard Worker 	 * bigger, if the header has grown.
78*8617a60dSAndroid Build Coastguard Worker 	 */
79*8617a60dSAndroid Build Coastguard Worker 	if (gbb->header_size < sizeof(*gbb))
80*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_GBB_HEADER_SIZE;
81*8617a60dSAndroid Build Coastguard Worker 
82*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
83*8617a60dSAndroid Build Coastguard Worker }
84*8617a60dSAndroid Build Coastguard Worker 
fail_impl(struct vb2_context * ctx,uint8_t reason,uint8_t subcode,bool previous_boot)85*8617a60dSAndroid Build Coastguard Worker static void fail_impl(struct vb2_context *ctx,
86*8617a60dSAndroid Build Coastguard Worker 		      uint8_t reason, uint8_t subcode, bool previous_boot)
87*8617a60dSAndroid Build Coastguard Worker {
88*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
89*8617a60dSAndroid Build Coastguard Worker 	uint32_t last_fw_slot, last_fw_result, fw_slot;
90*8617a60dSAndroid Build Coastguard Worker 
91*8617a60dSAndroid Build Coastguard Worker 	/* If NV data hasn't been initialized, initialize it now */
92*8617a60dSAndroid Build Coastguard Worker 	if (!(sd->status & VB2_SD_STATUS_NV_INIT))
93*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_init(ctx);
94*8617a60dSAndroid Build Coastguard Worker 
95*8617a60dSAndroid Build Coastguard Worker 	/*
96*8617a60dSAndroid Build Coastguard Worker 	 * Donot overwrite any existing failure with a new failure reported
97*8617a60dSAndroid Build Coastguard Worker 	 * through vb2api_previous_boot_fail(). Existing failure might have
98*8617a60dSAndroid Build Coastguard Worker 	 * been set through vb2api_fail() in the previous boot and the new
99*8617a60dSAndroid Build Coastguard Worker 	 * failure can stand.
100*8617a60dSAndroid Build Coastguard Worker 	 */
101*8617a60dSAndroid Build Coastguard Worker 	if (previous_boot &&
102*8617a60dSAndroid Build Coastguard Worker 	    vb2_nv_get(ctx, VB2_NV_FW_RESULT) == VB2_FW_RESULT_FAILURE)
103*8617a60dSAndroid Build Coastguard Worker 		return;
104*8617a60dSAndroid Build Coastguard Worker 
105*8617a60dSAndroid Build Coastguard Worker 	/* See if we were far enough in the boot process to choose a slot */
106*8617a60dSAndroid Build Coastguard Worker 	if (previous_boot || (sd->status & VB2_SD_STATUS_CHOSE_SLOT)) {
107*8617a60dSAndroid Build Coastguard Worker 		last_fw_slot = vb2_nv_get(ctx, VB2_NV_FW_PREV_TRIED);
108*8617a60dSAndroid Build Coastguard Worker 		last_fw_result = vb2_nv_get(ctx, VB2_NV_FW_PREV_RESULT);
109*8617a60dSAndroid Build Coastguard Worker 		fw_slot = vb2_nv_get(ctx, VB2_NV_FW_TRIED);
110*8617a60dSAndroid Build Coastguard Worker 
111*8617a60dSAndroid Build Coastguard Worker 		/* Boot failed */
112*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_FAILURE);
113*8617a60dSAndroid Build Coastguard Worker 
114*8617a60dSAndroid Build Coastguard Worker 		/* Use up remaining tries */
115*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_TRY_COUNT, 0);
116*8617a60dSAndroid Build Coastguard Worker 
117*8617a60dSAndroid Build Coastguard Worker 		if (!(ctx->flags & VB2_CONTEXT_SLOT_A_ONLY)) {
118*8617a60dSAndroid Build Coastguard Worker 			/*
119*8617a60dSAndroid Build Coastguard Worker 			 * Try the other slot next time.  We'll alternate
120*8617a60dSAndroid Build Coastguard Worker 			 * between slots, which may help if one or both slots
121*8617a60dSAndroid Build Coastguard Worker 			 * is flaky.
122*8617a60dSAndroid Build Coastguard Worker 			 */
123*8617a60dSAndroid Build Coastguard Worker 			vb2_nv_set(ctx, VB2_NV_TRY_NEXT, 1 - fw_slot);
124*8617a60dSAndroid Build Coastguard Worker 
125*8617a60dSAndroid Build Coastguard Worker 			/*
126*8617a60dSAndroid Build Coastguard Worker 			 * If we didn't try the other slot last boot, or we
127*8617a60dSAndroid Build Coastguard Worker 			 * tried it and it didn't fail, try it next boot.
128*8617a60dSAndroid Build Coastguard Worker 			 */
129*8617a60dSAndroid Build Coastguard Worker 			if (last_fw_slot != 1 - fw_slot ||
130*8617a60dSAndroid Build Coastguard Worker 			    last_fw_result != VB2_FW_RESULT_FAILURE)
131*8617a60dSAndroid Build Coastguard Worker 				return;
132*8617a60dSAndroid Build Coastguard Worker 		}
133*8617a60dSAndroid Build Coastguard Worker 	}
134*8617a60dSAndroid Build Coastguard Worker 
135*8617a60dSAndroid Build Coastguard Worker 	/*
136*8617a60dSAndroid Build Coastguard Worker 	 * If we're still here, we failed before choosing a slot, or both
137*8617a60dSAndroid Build Coastguard Worker 	 * this slot and the other slot failed in successive boots.  So we
138*8617a60dSAndroid Build Coastguard Worker 	 * need to go to recovery.
139*8617a60dSAndroid Build Coastguard Worker 	 *
140*8617a60dSAndroid Build Coastguard Worker 	 * Set a recovery reason and subcode only if they're not already set.
141*8617a60dSAndroid Build Coastguard Worker 	 * If recovery is already requested, it's a more specific error code
142*8617a60dSAndroid Build Coastguard Worker 	 * than later code is providing and we shouldn't overwrite it.
143*8617a60dSAndroid Build Coastguard Worker 	 */
144*8617a60dSAndroid Build Coastguard Worker 	VB2_DEBUG("Need recovery, reason: %#x / %#x\n", reason, subcode);
145*8617a60dSAndroid Build Coastguard Worker 	if (!vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST)) {
146*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, reason);
147*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, subcode);
148*8617a60dSAndroid Build Coastguard Worker 	}
149*8617a60dSAndroid Build Coastguard Worker }
150*8617a60dSAndroid Build Coastguard Worker 
151*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2api_fail(struct vb2_context * ctx,uint8_t reason,uint8_t subcode)152*8617a60dSAndroid Build Coastguard Worker void vb2api_fail(struct vb2_context *ctx, uint8_t reason, uint8_t subcode)
153*8617a60dSAndroid Build Coastguard Worker {
154*8617a60dSAndroid Build Coastguard Worker 	fail_impl(ctx, reason, subcode, false);
155*8617a60dSAndroid Build Coastguard Worker }
156*8617a60dSAndroid Build Coastguard Worker 
157*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2api_previous_boot_fail(struct vb2_context * ctx,uint8_t reason,uint8_t subcode)158*8617a60dSAndroid Build Coastguard Worker void vb2api_previous_boot_fail(struct vb2_context *ctx,
159*8617a60dSAndroid Build Coastguard Worker 			       uint8_t reason, uint8_t subcode)
160*8617a60dSAndroid Build Coastguard Worker {
161*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
162*8617a60dSAndroid Build Coastguard Worker 
163*8617a60dSAndroid Build Coastguard Worker 	VB2_ASSERT(!(sd->status & VB2_SD_STATUS_NV_INIT) &&
164*8617a60dSAndroid Build Coastguard Worker 		   !(sd->status & VB2_SD_STATUS_CHOSE_SLOT));
165*8617a60dSAndroid Build Coastguard Worker 
166*8617a60dSAndroid Build Coastguard Worker 	fail_impl(ctx, reason, subcode, true);
167*8617a60dSAndroid Build Coastguard Worker }
168*8617a60dSAndroid Build Coastguard Worker 
vb2_check_recovery(struct vb2_context * ctx)169*8617a60dSAndroid Build Coastguard Worker void vb2_check_recovery(struct vb2_context *ctx)
170*8617a60dSAndroid Build Coastguard Worker {
171*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
172*8617a60dSAndroid Build Coastguard Worker 	uint32_t reason = vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST);
173*8617a60dSAndroid Build Coastguard Worker 	uint32_t subcode = vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE);
174*8617a60dSAndroid Build Coastguard Worker 
175*8617a60dSAndroid Build Coastguard Worker 	VB2_DEBUG("Recovery reason from previous boot: %#x / %#x\n",
176*8617a60dSAndroid Build Coastguard Worker 		  reason, subcode);
177*8617a60dSAndroid Build Coastguard Worker 
178*8617a60dSAndroid Build Coastguard Worker 	/*
179*8617a60dSAndroid Build Coastguard Worker 	 * Sets the current recovery request, unless there's already been a
180*8617a60dSAndroid Build Coastguard Worker 	 * failure earlier in the boot process.
181*8617a60dSAndroid Build Coastguard Worker 	 */
182*8617a60dSAndroid Build Coastguard Worker 	if (!sd->recovery_reason)
183*8617a60dSAndroid Build Coastguard Worker 		sd->recovery_reason = reason;
184*8617a60dSAndroid Build Coastguard Worker 
185*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_FORCE_RECOVERY_MODE) {
186*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("Recovery was requested manually\n");
187*8617a60dSAndroid Build Coastguard Worker 		if (subcode && !sd->recovery_reason &&
188*8617a60dSAndroid Build Coastguard Worker 		    subcode != VB2_RECOVERY_TRAIN_AND_REBOOT)
189*8617a60dSAndroid Build Coastguard Worker 			/*
190*8617a60dSAndroid Build Coastguard Worker 			 * Recovery was requested at 'broken' screen.
191*8617a60dSAndroid Build Coastguard Worker 			 * Promote subcode to reason.
192*8617a60dSAndroid Build Coastguard Worker 			 */
193*8617a60dSAndroid Build Coastguard Worker 			sd->recovery_reason = subcode;
194*8617a60dSAndroid Build Coastguard Worker 		else
195*8617a60dSAndroid Build Coastguard Worker 			/* Recovery was forced. Override recovery reason */
196*8617a60dSAndroid Build Coastguard Worker 			sd->recovery_reason = VB2_RECOVERY_RO_MANUAL;
197*8617a60dSAndroid Build Coastguard Worker 	}
198*8617a60dSAndroid Build Coastguard Worker 
199*8617a60dSAndroid Build Coastguard Worker 	/* If recovery reason is non-zero, tell caller we need recovery mode */
200*8617a60dSAndroid Build Coastguard Worker 	if (sd->recovery_reason) {
201*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
202*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("We have a recovery request: %#x / %#x\n",
203*8617a60dSAndroid Build Coastguard Worker 			  sd->recovery_reason,
204*8617a60dSAndroid Build Coastguard Worker 			  vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE));
205*8617a60dSAndroid Build Coastguard Worker 	}
206*8617a60dSAndroid Build Coastguard Worker 
207*8617a60dSAndroid Build Coastguard Worker 	sd->status |= VB2_SD_STATUS_RECOVERY_DECIDED;
208*8617a60dSAndroid Build Coastguard Worker }
209*8617a60dSAndroid Build Coastguard Worker 
210*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_fw_init_gbb(struct vb2_context * ctx)211*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_fw_init_gbb(struct vb2_context *ctx)
212*8617a60dSAndroid Build Coastguard Worker {
213*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
214*8617a60dSAndroid Build Coastguard Worker 	struct vb2_gbb_header *gbb;
215*8617a60dSAndroid Build Coastguard Worker 	struct vb2_workbuf wb;
216*8617a60dSAndroid Build Coastguard Worker 
217*8617a60dSAndroid Build Coastguard Worker 	vb2_workbuf_from_ctx(ctx, &wb);
218*8617a60dSAndroid Build Coastguard Worker 
219*8617a60dSAndroid Build Coastguard Worker 	/* Read GBB into next chunk of work buffer */
220*8617a60dSAndroid Build Coastguard Worker 	gbb = vb2_workbuf_alloc(&wb, sizeof(*gbb));
221*8617a60dSAndroid Build Coastguard Worker 	if (!gbb)
222*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_GBB_WORKBUF;
223*8617a60dSAndroid Build Coastguard Worker 
224*8617a60dSAndroid Build Coastguard Worker 	VB2_TRY(vb2_read_gbb_header(ctx, gbb));
225*8617a60dSAndroid Build Coastguard Worker 
226*8617a60dSAndroid Build Coastguard Worker 	/* Keep on the work buffer permanently */
227*8617a60dSAndroid Build Coastguard Worker 	sd->gbb_offset = vb2_offset_of(sd, gbb);
228*8617a60dSAndroid Build Coastguard Worker 	vb2_set_workbuf_used(ctx, vb2_offset_of(sd, wb.buf));
229*8617a60dSAndroid Build Coastguard Worker 
230*8617a60dSAndroid Build Coastguard Worker 	/* Set any context flags based on GBB flags */
231*8617a60dSAndroid Build Coastguard Worker 	if (gbb->flags & VB2_GBB_FLAG_DISABLE_FWMP)
232*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP;
233*8617a60dSAndroid Build Coastguard Worker 
234*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
235*8617a60dSAndroid Build Coastguard Worker }
236*8617a60dSAndroid Build Coastguard Worker 
237*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_check_dev_switch(struct vb2_context * ctx)238*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_check_dev_switch(struct vb2_context *ctx)
239*8617a60dSAndroid Build Coastguard Worker {
240*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
241*8617a60dSAndroid Build Coastguard Worker 	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
242*8617a60dSAndroid Build Coastguard Worker 	uint32_t flags = 0;
243*8617a60dSAndroid Build Coastguard Worker 	uint32_t old_flags;
244*8617a60dSAndroid Build Coastguard Worker 	int is_dev = 0;
245*8617a60dSAndroid Build Coastguard Worker 	int valid_secdata = 1;
246*8617a60dSAndroid Build Coastguard Worker 	vb2_error_t rv;
247*8617a60dSAndroid Build Coastguard Worker 
248*8617a60dSAndroid Build Coastguard Worker 	/* Check whether secdata_firmware is initialized */
249*8617a60dSAndroid Build Coastguard Worker 	if (!(sd->status & VB2_SD_STATUS_SECDATA_FIRMWARE_INIT))
250*8617a60dSAndroid Build Coastguard Worker 		valid_secdata = 0;
251*8617a60dSAndroid Build Coastguard Worker 
252*8617a60dSAndroid Build Coastguard Worker 	/* Read secure flags */
253*8617a60dSAndroid Build Coastguard Worker 	flags = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
254*8617a60dSAndroid Build Coastguard Worker 	old_flags = flags;
255*8617a60dSAndroid Build Coastguard Worker 
256*8617a60dSAndroid Build Coastguard Worker 	/* Handle dev disable request */
257*8617a60dSAndroid Build Coastguard Worker 	if (valid_secdata && vb2_nv_get(ctx, VB2_NV_DISABLE_DEV_REQUEST)) {
258*8617a60dSAndroid Build Coastguard Worker 		flags &= ~VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE;
259*8617a60dSAndroid Build Coastguard Worker 
260*8617a60dSAndroid Build Coastguard Worker 		/* Clear the request */
261*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 0);
262*8617a60dSAndroid Build Coastguard Worker 	}
263*8617a60dSAndroid Build Coastguard Worker 
264*8617a60dSAndroid Build Coastguard Worker 	/*
265*8617a60dSAndroid Build Coastguard Worker 	 * Check if we've been asked by the caller to disable dev mode.  Note
266*8617a60dSAndroid Build Coastguard Worker 	 * that GBB flag will take precedence over this.
267*8617a60dSAndroid Build Coastguard Worker 	 */
268*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_DISABLE_DEVELOPER_MODE)
269*8617a60dSAndroid Build Coastguard Worker 		flags &= ~VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE;
270*8617a60dSAndroid Build Coastguard Worker 
271*8617a60dSAndroid Build Coastguard Worker 	/* Check virtual dev switch */
272*8617a60dSAndroid Build Coastguard Worker 	if (flags & VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE)
273*8617a60dSAndroid Build Coastguard Worker 		is_dev = 1;
274*8617a60dSAndroid Build Coastguard Worker 
275*8617a60dSAndroid Build Coastguard Worker 	/* Check if GBB is forcing dev mode */
276*8617a60dSAndroid Build Coastguard Worker 	if (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON)
277*8617a60dSAndroid Build Coastguard Worker 		is_dev = 1;
278*8617a60dSAndroid Build Coastguard Worker 
279*8617a60dSAndroid Build Coastguard Worker 	/* Handle whichever mode we end up in */
280*8617a60dSAndroid Build Coastguard Worker 	if (is_dev) {
281*8617a60dSAndroid Build Coastguard Worker 		/* Developer mode */
282*8617a60dSAndroid Build Coastguard Worker 		sd->flags |= VB2_SD_FLAG_DEV_MODE_ENABLED;
283*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
284*8617a60dSAndroid Build Coastguard Worker 
285*8617a60dSAndroid Build Coastguard Worker 		flags |= VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER;
286*8617a60dSAndroid Build Coastguard Worker 	} else {
287*8617a60dSAndroid Build Coastguard Worker 		/* Normal mode */
288*8617a60dSAndroid Build Coastguard Worker 		flags &= ~VB2_SECDATA_FIRMWARE_FLAG_LAST_BOOT_DEVELOPER;
289*8617a60dSAndroid Build Coastguard Worker 
290*8617a60dSAndroid Build Coastguard Worker 		/*
291*8617a60dSAndroid Build Coastguard Worker 		 * Disable dev_boot_* flags.  This ensures they will be
292*8617a60dSAndroid Build Coastguard Worker 		 * initially disabled if the user later transitions back into
293*8617a60dSAndroid Build Coastguard Worker 		 * developer mode.
294*8617a60dSAndroid Build Coastguard Worker 		 */
295*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_DEV_BOOT_EXTERNAL, 0);
296*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_DEV_BOOT_ALTFW, 0);
297*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 0);
298*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_DEV_DEFAULT_BOOT, 0);
299*8617a60dSAndroid Build Coastguard Worker 	}
300*8617a60dSAndroid Build Coastguard Worker 
301*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_FORCE_WIPEOUT_MODE)
302*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_REQ_WIPEOUT, 1);
303*8617a60dSAndroid Build Coastguard Worker 
304*8617a60dSAndroid Build Coastguard Worker 	if (flags != old_flags) {
305*8617a60dSAndroid Build Coastguard Worker 		/*
306*8617a60dSAndroid Build Coastguard Worker 		 * Just changed dev mode state.  Clear TPM owner.  This must be
307*8617a60dSAndroid Build Coastguard Worker 		 * done here instead of simply passing a flag to
308*8617a60dSAndroid Build Coastguard Worker 		 * vb2_check_tpm_clear(), because we don't want to update
309*8617a60dSAndroid Build Coastguard Worker 		 * last_boot_developer and then fail to clear the TPM owner.
310*8617a60dSAndroid Build Coastguard Worker 		 *
311*8617a60dSAndroid Build Coastguard Worker 		 * Note that we do this even if secdata_firmware is having
312*8617a60dSAndroid Build Coastguard Worker 		 * issues, since the TPM owner and secdata_firmware may be
313*8617a60dSAndroid Build Coastguard Worker 		 * independent, and we want the owner to be cleared if *this
314*8617a60dSAndroid Build Coastguard Worker 		 * boot* is different than the last one (perhaps due to GBB flag
315*8617a60dSAndroid Build Coastguard Worker 		 * override).
316*8617a60dSAndroid Build Coastguard Worker 		 */
317*8617a60dSAndroid Build Coastguard Worker 		rv = vb2ex_tpm_clear_owner(ctx);
318*8617a60dSAndroid Build Coastguard Worker 		/* Check for failure to clear owner */
319*8617a60dSAndroid Build Coastguard Worker 		if (valid_secdata && rv) {
320*8617a60dSAndroid Build Coastguard Worker 			/*
321*8617a60dSAndroid Build Coastguard Worker 			 * Note that this truncates rv to 8 bit.  Which
322*8617a60dSAndroid Build Coastguard Worker 			 * is not as useful as the full error code, but
323*8617a60dSAndroid Build Coastguard Worker 			 * we don't have NVRAM space to store the full
324*8617a60dSAndroid Build Coastguard Worker 			 * 32-bit code.
325*8617a60dSAndroid Build Coastguard Worker 			 */
326*8617a60dSAndroid Build Coastguard Worker 			vb2api_fail(ctx, VB2_RECOVERY_TPM_CLEAR_OWNER, rv);
327*8617a60dSAndroid Build Coastguard Worker 			return rv;
328*8617a60dSAndroid Build Coastguard Worker 		}
329*8617a60dSAndroid Build Coastguard Worker 
330*8617a60dSAndroid Build Coastguard Worker 		/* Save new flags */
331*8617a60dSAndroid Build Coastguard Worker 		vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS,
332*8617a60dSAndroid Build Coastguard Worker 					 flags);
333*8617a60dSAndroid Build Coastguard Worker 	}
334*8617a60dSAndroid Build Coastguard Worker 
335*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
336*8617a60dSAndroid Build Coastguard Worker }
337*8617a60dSAndroid Build Coastguard Worker 
338*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_check_tpm_clear(struct vb2_context * ctx)339*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_check_tpm_clear(struct vb2_context *ctx)
340*8617a60dSAndroid Build Coastguard Worker {
341*8617a60dSAndroid Build Coastguard Worker 	vb2_error_t rv;
342*8617a60dSAndroid Build Coastguard Worker 
343*8617a60dSAndroid Build Coastguard Worker 	/* Check if we've been asked to clear the owner */
344*8617a60dSAndroid Build Coastguard Worker 	if (!vb2_nv_get(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST))
345*8617a60dSAndroid Build Coastguard Worker 		return VB2_SUCCESS;  /* No need to clear */
346*8617a60dSAndroid Build Coastguard Worker 
347*8617a60dSAndroid Build Coastguard Worker 	/* Request applies one time only */
348*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_CLEAR_TPM_OWNER_REQUEST, 0);
349*8617a60dSAndroid Build Coastguard Worker 
350*8617a60dSAndroid Build Coastguard Worker 	/* Try clearing */
351*8617a60dSAndroid Build Coastguard Worker 	rv = vb2ex_tpm_clear_owner(ctx);
352*8617a60dSAndroid Build Coastguard Worker 	if (rv) {
353*8617a60dSAndroid Build Coastguard Worker 		/*
354*8617a60dSAndroid Build Coastguard Worker 		 * Note that this truncates rv to 8 bit.  Which is not as
355*8617a60dSAndroid Build Coastguard Worker 		 * useful as the full error code, but we don't have NVRAM space
356*8617a60dSAndroid Build Coastguard Worker 		 * to store the full 32-bit code.
357*8617a60dSAndroid Build Coastguard Worker 		 */
358*8617a60dSAndroid Build Coastguard Worker 		vb2api_fail(ctx, VB2_RECOVERY_TPM_CLEAR_OWNER, rv);
359*8617a60dSAndroid Build Coastguard Worker 		return rv;
360*8617a60dSAndroid Build Coastguard Worker 	}
361*8617a60dSAndroid Build Coastguard Worker 
362*8617a60dSAndroid Build Coastguard Worker 	/* Clear successful */
363*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_CLEAR_TPM_OWNER_DONE, 1);
364*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
365*8617a60dSAndroid Build Coastguard Worker }
366*8617a60dSAndroid Build Coastguard Worker 
367*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_select_fw_slot(struct vb2_context * ctx)368*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_select_fw_slot(struct vb2_context *ctx)
369*8617a60dSAndroid Build Coastguard Worker {
370*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
371*8617a60dSAndroid Build Coastguard Worker 	uint32_t tries;
372*8617a60dSAndroid Build Coastguard Worker 
373*8617a60dSAndroid Build Coastguard Worker 	/* Get result of last boot */
374*8617a60dSAndroid Build Coastguard Worker 	sd->last_fw_slot = vb2_nv_get(ctx, VB2_NV_FW_TRIED);
375*8617a60dSAndroid Build Coastguard Worker 	sd->last_fw_result = vb2_nv_get(ctx, VB2_NV_FW_RESULT);
376*8617a60dSAndroid Build Coastguard Worker 
377*8617a60dSAndroid Build Coastguard Worker 	/* Save to the previous result fields in NV storage */
378*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_FW_PREV_TRIED, sd->last_fw_slot);
379*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_FW_PREV_RESULT, sd->last_fw_result);
380*8617a60dSAndroid Build Coastguard Worker 
381*8617a60dSAndroid Build Coastguard Worker 	/* Clear result, since we don't know what will happen this boot */
382*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_UNKNOWN);
383*8617a60dSAndroid Build Coastguard Worker 
384*8617a60dSAndroid Build Coastguard Worker 	/* If there is only one slot, next try should always be slot A */
385*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_SLOT_A_ONLY)
386*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_TRY_NEXT, 0);
387*8617a60dSAndroid Build Coastguard Worker 
388*8617a60dSAndroid Build Coastguard Worker 	/* Get slot to try */
389*8617a60dSAndroid Build Coastguard Worker 	sd->fw_slot = vb2_nv_get(ctx, VB2_NV_TRY_NEXT);
390*8617a60dSAndroid Build Coastguard Worker 
391*8617a60dSAndroid Build Coastguard Worker 	/* Check try count */
392*8617a60dSAndroid Build Coastguard Worker 	tries = vb2_nv_get(ctx, VB2_NV_TRY_COUNT);
393*8617a60dSAndroid Build Coastguard Worker 
394*8617a60dSAndroid Build Coastguard Worker 	if (sd->last_fw_result == VB2_FW_RESULT_TRYING &&
395*8617a60dSAndroid Build Coastguard Worker 	    sd->last_fw_slot == sd->fw_slot &&
396*8617a60dSAndroid Build Coastguard Worker 	    tries == 0) {
397*8617a60dSAndroid Build Coastguard Worker 		/*
398*8617a60dSAndroid Build Coastguard Worker 		 * If there is only RW A slot available, we have no other slot
399*8617a60dSAndroid Build Coastguard Worker 		 * to fall back to.
400*8617a60dSAndroid Build Coastguard Worker 		 */
401*8617a60dSAndroid Build Coastguard Worker 		if (ctx->flags & VB2_CONTEXT_SLOT_A_ONLY)
402*8617a60dSAndroid Build Coastguard Worker 			return VB2_ERROR_API_NEXT_SLOT_UNAVAILABLE;
403*8617a60dSAndroid Build Coastguard Worker 		/*
404*8617a60dSAndroid Build Coastguard Worker 		 * We used up our last try on the previous boot, so fall back
405*8617a60dSAndroid Build Coastguard Worker 		 * to the other slot this boot.
406*8617a60dSAndroid Build Coastguard Worker 		 */
407*8617a60dSAndroid Build Coastguard Worker 		sd->fw_slot = 1 - sd->fw_slot;
408*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_TRY_NEXT, sd->fw_slot);
409*8617a60dSAndroid Build Coastguard Worker 	}
410*8617a60dSAndroid Build Coastguard Worker 
411*8617a60dSAndroid Build Coastguard Worker 	if (tries > 0) {
412*8617a60dSAndroid Build Coastguard Worker 		/* Still trying this firmware */
413*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_FW_RESULT, VB2_FW_RESULT_TRYING);
414*8617a60dSAndroid Build Coastguard Worker 
415*8617a60dSAndroid Build Coastguard Worker 		/* Decrement non-zero try count, unless told not to */
416*8617a60dSAndroid Build Coastguard Worker 		if (!(ctx->flags & VB2_CONTEXT_NOFAIL_BOOT))
417*8617a60dSAndroid Build Coastguard Worker 			vb2_nv_set(ctx, VB2_NV_TRY_COUNT, tries - 1);
418*8617a60dSAndroid Build Coastguard Worker 	}
419*8617a60dSAndroid Build Coastguard Worker 
420*8617a60dSAndroid Build Coastguard Worker 	/* Store the slot we're trying */
421*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_FW_TRIED, sd->fw_slot);
422*8617a60dSAndroid Build Coastguard Worker 
423*8617a60dSAndroid Build Coastguard Worker 	/* Set context flag if we're using slot B */
424*8617a60dSAndroid Build Coastguard Worker 	if (sd->fw_slot)
425*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_FW_SLOT_B;
426*8617a60dSAndroid Build Coastguard Worker 
427*8617a60dSAndroid Build Coastguard Worker 	/* Set status flag */
428*8617a60dSAndroid Build Coastguard Worker 	sd->status |= VB2_SD_STATUS_CHOSE_SLOT;
429*8617a60dSAndroid Build Coastguard Worker 
430*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
431*8617a60dSAndroid Build Coastguard Worker }
432*8617a60dSAndroid Build Coastguard Worker 
vb2api_enable_developer_mode(struct vb2_context * ctx)433*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2api_enable_developer_mode(struct vb2_context *ctx)
434*8617a60dSAndroid Build Coastguard Worker {
435*8617a60dSAndroid Build Coastguard Worker 	if (ctx->boot_mode != VB2_BOOT_MODE_MANUAL_RECOVERY) {
436*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("ERROR: Can only enable developer mode from manual "
437*8617a60dSAndroid Build Coastguard Worker 			  "recovery mode\n");
438*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_API_ENABLE_DEV_NOT_ALLOWED;
439*8617a60dSAndroid Build Coastguard Worker 	}
440*8617a60dSAndroid Build Coastguard Worker 
441*8617a60dSAndroid Build Coastguard Worker 	uint32_t flags;
442*8617a60dSAndroid Build Coastguard Worker 
443*8617a60dSAndroid Build Coastguard Worker 	VB2_DEBUG("Enabling developer mode...\n");
444*8617a60dSAndroid Build Coastguard Worker 
445*8617a60dSAndroid Build Coastguard Worker 	flags = vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_FLAGS);
446*8617a60dSAndroid Build Coastguard Worker 	flags |= VB2_SECDATA_FIRMWARE_FLAG_DEV_MODE;
447*8617a60dSAndroid Build Coastguard Worker 	vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_FLAGS, flags);
448*8617a60dSAndroid Build Coastguard Worker 
449*8617a60dSAndroid Build Coastguard Worker 	VB2_DEBUG("Mode change will take effect on next reboot\n");
450*8617a60dSAndroid Build Coastguard Worker 
451*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
452*8617a60dSAndroid Build Coastguard Worker }
453*8617a60dSAndroid Build Coastguard Worker 
vb2api_disable_developer_mode(struct vb2_context * ctx)454*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2api_disable_developer_mode(struct vb2_context *ctx)
455*8617a60dSAndroid Build Coastguard Worker {
456*8617a60dSAndroid Build Coastguard Worker 	if (vb2api_gbb_get_flags(ctx) & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
457*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("ERROR: dev mode forced by GBB flag\n");
458*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_API_DISABLE_DEV_NOT_ALLOWED;
459*8617a60dSAndroid Build Coastguard Worker 	}
460*8617a60dSAndroid Build Coastguard Worker 
461*8617a60dSAndroid Build Coastguard Worker 	VB2_DEBUG("Leaving dev mode\n");
462*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
463*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
464*8617a60dSAndroid Build Coastguard Worker }
465*8617a60dSAndroid Build Coastguard Worker 
vb2api_request_diagnostics(struct vb2_context * ctx)466*8617a60dSAndroid Build Coastguard Worker void vb2api_request_diagnostics(struct vb2_context *ctx) {
467*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_DIAG_REQUEST, 1);
468*8617a60dSAndroid Build Coastguard Worker 	VB2_DEBUG("Diagnostics requested\n");
469*8617a60dSAndroid Build Coastguard Worker }
470*8617a60dSAndroid Build Coastguard Worker 
vb2api_clear_recovery(struct vb2_context * ctx)471*8617a60dSAndroid Build Coastguard Worker void vb2api_clear_recovery(struct vb2_context *ctx)
472*8617a60dSAndroid Build Coastguard Worker {
473*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
474*8617a60dSAndroid Build Coastguard Worker 	uint32_t reason = vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST);
475*8617a60dSAndroid Build Coastguard Worker 	uint32_t subcode = vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE);
476*8617a60dSAndroid Build Coastguard Worker 
477*8617a60dSAndroid Build Coastguard Worker 	if (reason || subcode)
478*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("Clearing recovery request: %#x / %#x  %s\n",
479*8617a60dSAndroid Build Coastguard Worker 			  reason, subcode,
480*8617a60dSAndroid Build Coastguard Worker 			  vb2_get_recovery_reason_string(reason));
481*8617a60dSAndroid Build Coastguard Worker 
482*8617a60dSAndroid Build Coastguard Worker 	/* Clear recovery request for both the manual recovery and the broken
483*8617a60dSAndroid Build Coastguard Worker 	   screen. */
484*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_NOT_REQUESTED);
485*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, 0);
486*8617a60dSAndroid Build Coastguard Worker 
487*8617a60dSAndroid Build Coastguard Worker 	/* But stow recovery reason as subcode for the broken screen. */
488*8617a60dSAndroid Build Coastguard Worker 	if (ctx->boot_mode == VB2_BOOT_MODE_BROKEN_SCREEN) {
489*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("Stow recovery reason as subcode (%#x)\n",
490*8617a60dSAndroid Build Coastguard Worker 			  sd->recovery_reason);
491*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, sd->recovery_reason);
492*8617a60dSAndroid Build Coastguard Worker 	}
493*8617a60dSAndroid Build Coastguard Worker }
494*8617a60dSAndroid Build Coastguard Worker 
495*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2api_need_reboot_for_display(struct vb2_context * ctx)496*8617a60dSAndroid Build Coastguard Worker int vb2api_need_reboot_for_display(struct vb2_context *ctx)
497*8617a60dSAndroid Build Coastguard Worker {
498*8617a60dSAndroid Build Coastguard Worker 	if (!(vb2_get_sd(ctx)->flags & VB2_SD_FLAG_DISPLAY_AVAILABLE)) {
499*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("Need reboot to initialize display\n");
500*8617a60dSAndroid Build Coastguard Worker 		vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 1);
501*8617a60dSAndroid Build Coastguard Worker 		return 1;
502*8617a60dSAndroid Build Coastguard Worker 	}
503*8617a60dSAndroid Build Coastguard Worker 	return 0;
504*8617a60dSAndroid Build Coastguard Worker }
505*8617a60dSAndroid Build Coastguard Worker 
vb2api_get_recovery_reason(struct vb2_context * ctx)506*8617a60dSAndroid Build Coastguard Worker uint32_t vb2api_get_recovery_reason(struct vb2_context *ctx)
507*8617a60dSAndroid Build Coastguard Worker {
508*8617a60dSAndroid Build Coastguard Worker 	return vb2_get_sd(ctx)->recovery_reason;
509*8617a60dSAndroid Build Coastguard Worker }
510*8617a60dSAndroid Build Coastguard Worker 
vb2api_get_locale_id(struct vb2_context * ctx)511*8617a60dSAndroid Build Coastguard Worker uint32_t vb2api_get_locale_id(struct vb2_context *ctx)
512*8617a60dSAndroid Build Coastguard Worker {
513*8617a60dSAndroid Build Coastguard Worker 	return vb2_nv_get(ctx, VB2_NV_LOCALIZATION_INDEX);
514*8617a60dSAndroid Build Coastguard Worker }
515*8617a60dSAndroid Build Coastguard Worker 
vb2api_set_locale_id(struct vb2_context * ctx,uint32_t locale_id)516*8617a60dSAndroid Build Coastguard Worker void vb2api_set_locale_id(struct vb2_context *ctx, uint32_t locale_id)
517*8617a60dSAndroid Build Coastguard Worker {
518*8617a60dSAndroid Build Coastguard Worker 	vb2_nv_set(ctx, VB2_NV_LOCALIZATION_INDEX, locale_id);
519*8617a60dSAndroid Build Coastguard Worker }
520*8617a60dSAndroid Build Coastguard Worker 
vb2api_export_vbsd(struct vb2_context * ctx,void * dest)521*8617a60dSAndroid Build Coastguard Worker void vb2api_export_vbsd(struct vb2_context *ctx, void *dest)
522*8617a60dSAndroid Build Coastguard Worker {
523*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
524*8617a60dSAndroid Build Coastguard Worker 	VbSharedDataHeader *vbsd = (void *)dest;
525*8617a60dSAndroid Build Coastguard Worker 
526*8617a60dSAndroid Build Coastguard Worker 	/* Initialize with boilerplate fields. */
527*8617a60dSAndroid Build Coastguard Worker 	memset(vbsd, 0, VB2_VBSD_SIZE);
528*8617a60dSAndroid Build Coastguard Worker 	vbsd->magic = VB_SHARED_DATA_MAGIC;
529*8617a60dSAndroid Build Coastguard Worker 	vbsd->struct_version = VB_SHARED_DATA_VERSION;
530*8617a60dSAndroid Build Coastguard Worker 	vbsd->struct_size = VB2_VBSD_SIZE;
531*8617a60dSAndroid Build Coastguard Worker 	vbsd->data_size = VB2_VBSD_SIZE;
532*8617a60dSAndroid Build Coastguard Worker 	vbsd->data_used = VB2_VBSD_SIZE;
533*8617a60dSAndroid Build Coastguard Worker 	vbsd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2;
534*8617a60dSAndroid Build Coastguard Worker 
535*8617a60dSAndroid Build Coastguard Worker 	/* Translate vboot2 flags and fields into vboot1. */
536*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_EC_SYNC_SUPPORTED)
537*8617a60dSAndroid Build Coastguard Worker 		vbsd->flags |= VBSD_EC_SOFTWARE_SYNC;
538*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_NVDATA_V2)
539*8617a60dSAndroid Build Coastguard Worker 		vbsd->flags |= VBSD_NVDATA_V2;
540*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_DEVELOPER_MODE)
541*8617a60dSAndroid Build Coastguard Worker 		vbsd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
542*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_FORCE_RECOVERY_MODE)
543*8617a60dSAndroid Build Coastguard Worker 		vbsd->flags |= VBSD_BOOT_REC_SWITCH_ON;
544*8617a60dSAndroid Build Coastguard Worker 	if (sd->flags & VB2_SD_FLAG_KERNEL_SIGNED)
545*8617a60dSAndroid Build Coastguard Worker 		vbsd->flags |= VBSD_KERNEL_KEY_VERIFIED;
546*8617a60dSAndroid Build Coastguard Worker 
547*8617a60dSAndroid Build Coastguard Worker 	vbsd->fw_version_tpm = sd->fw_version_secdata;
548*8617a60dSAndroid Build Coastguard Worker 	vbsd->fw_version_act = sd->fw_version;
549*8617a60dSAndroid Build Coastguard Worker 	vbsd->kernel_version_tpm = sd->kernel_version_secdata;
550*8617a60dSAndroid Build Coastguard Worker 	vbsd->kernel_version_act = sd->kernel_version;
551*8617a60dSAndroid Build Coastguard Worker 
552*8617a60dSAndroid Build Coastguard Worker 	vbsd->recovery_reason = sd->recovery_reason;
553*8617a60dSAndroid Build Coastguard Worker 	if (sd->recovery_reason)
554*8617a60dSAndroid Build Coastguard Worker 		vbsd->firmware_index = 0xff;
555*8617a60dSAndroid Build Coastguard Worker 	else
556*8617a60dSAndroid Build Coastguard Worker 		vbsd->firmware_index = sd->fw_slot;
557*8617a60dSAndroid Build Coastguard Worker }
558*8617a60dSAndroid Build Coastguard Worker _Static_assert(VB2_VBSD_SIZE == sizeof(VbSharedDataHeader),
559*8617a60dSAndroid Build Coastguard Worker 	       "VB2_VBSD_SIZE incorrect");
560*8617a60dSAndroid Build Coastguard Worker 
561*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2api_diagnostic_ui_enabled(struct vb2_context * ctx)562*8617a60dSAndroid Build Coastguard Worker int vb2api_diagnostic_ui_enabled(struct vb2_context *ctx)
563*8617a60dSAndroid Build Coastguard Worker {
564*8617a60dSAndroid Build Coastguard Worker 	return !(vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS) &
565*8617a60dSAndroid Build Coastguard Worker 		 VB2_SECDATA_KERNEL_FLAG_DIAGNOSTIC_UI_DISABLED);
566*8617a60dSAndroid Build Coastguard Worker }
567*8617a60dSAndroid Build Coastguard Worker 
vb2api_get_dev_default_boot_target(struct vb2_context * ctx)568*8617a60dSAndroid Build Coastguard Worker enum vb2_dev_default_boot_target vb2api_get_dev_default_boot_target(
569*8617a60dSAndroid Build Coastguard Worker 	struct vb2_context *ctx)
570*8617a60dSAndroid Build Coastguard Worker {
571*8617a60dSAndroid Build Coastguard Worker 	if (vb2api_gbb_get_flags(ctx) & VB2_GBB_FLAG_DEFAULT_DEV_BOOT_ALTFW)
572*8617a60dSAndroid Build Coastguard Worker 		return VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW;
573*8617a60dSAndroid Build Coastguard Worker 
574*8617a60dSAndroid Build Coastguard Worker 	switch (vb2_nv_get(ctx, VB2_NV_DEV_DEFAULT_BOOT)) {
575*8617a60dSAndroid Build Coastguard Worker 		case VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL:
576*8617a60dSAndroid Build Coastguard Worker 			if (ctx->flags & VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED)
577*8617a60dSAndroid Build Coastguard Worker 				return VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL;
578*8617a60dSAndroid Build Coastguard Worker 			break;
579*8617a60dSAndroid Build Coastguard Worker 
580*8617a60dSAndroid Build Coastguard Worker 		case VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW:
581*8617a60dSAndroid Build Coastguard Worker 			if (ctx->flags & VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED)
582*8617a60dSAndroid Build Coastguard Worker 				return VB2_DEV_DEFAULT_BOOT_TARGET_ALTFW;
583*8617a60dSAndroid Build Coastguard Worker 			break;
584*8617a60dSAndroid Build Coastguard Worker 	}
585*8617a60dSAndroid Build Coastguard Worker 
586*8617a60dSAndroid Build Coastguard Worker 	return VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL;
587*8617a60dSAndroid Build Coastguard Worker }
588*8617a60dSAndroid Build Coastguard Worker 
vb2_fill_dev_boot_flags(struct vb2_context * ctx)589*8617a60dSAndroid Build Coastguard Worker void vb2_fill_dev_boot_flags(struct vb2_context *ctx)
590*8617a60dSAndroid Build Coastguard Worker {
591*8617a60dSAndroid Build Coastguard Worker 	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
592*8617a60dSAndroid Build Coastguard Worker 
593*8617a60dSAndroid Build Coastguard Worker 	if (!vb2_secdata_fwmp_get_flag(ctx,
594*8617a60dSAndroid Build Coastguard Worker 				       VB2_SECDATA_FWMP_DEV_DISABLE_BOOT) ||
595*8617a60dSAndroid Build Coastguard Worker 	    (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON))
596*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_DEV_BOOT_ALLOWED;
597*8617a60dSAndroid Build Coastguard Worker 
598*8617a60dSAndroid Build Coastguard Worker 	if (vb2_nv_get(ctx, VB2_NV_DEV_BOOT_EXTERNAL) ||
599*8617a60dSAndroid Build Coastguard Worker 	    (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_USB) ||
600*8617a60dSAndroid Build Coastguard Worker 	    vb2_secdata_fwmp_get_flag(ctx,
601*8617a60dSAndroid Build Coastguard Worker 				      VB2_SECDATA_FWMP_DEV_ENABLE_EXTERNAL))
602*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_DEV_BOOT_EXTERNAL_ALLOWED;
603*8617a60dSAndroid Build Coastguard Worker 
604*8617a60dSAndroid Build Coastguard Worker 	if (vb2_nv_get(ctx, VB2_NV_DEV_BOOT_ALTFW) ||
605*8617a60dSAndroid Build Coastguard Worker 	    (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_ALTFW) ||
606*8617a60dSAndroid Build Coastguard Worker 	    vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_ALTFW))
607*8617a60dSAndroid Build Coastguard Worker 		ctx->flags |= VB2_CONTEXT_DEV_BOOT_ALTFW_ALLOWED;
608*8617a60dSAndroid Build Coastguard Worker }
609*8617a60dSAndroid Build Coastguard Worker 
vb2api_use_short_dev_screen_delay(struct vb2_context * ctx)610*8617a60dSAndroid Build Coastguard Worker int vb2api_use_short_dev_screen_delay(struct vb2_context *ctx)
611*8617a60dSAndroid Build Coastguard Worker {
612*8617a60dSAndroid Build Coastguard Worker 	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
613*8617a60dSAndroid Build Coastguard Worker 	return gbb->flags & VB2_GBB_FLAG_DEV_SCREEN_SHORT_DELAY;
614*8617a60dSAndroid Build Coastguard Worker }
615*8617a60dSAndroid Build Coastguard Worker 
snprint_sha1_sum(struct vb2_context * ctx,struct vb2_packed_key * key,char * dest,size_t dest_size)616*8617a60dSAndroid Build Coastguard Worker static void snprint_sha1_sum(struct vb2_context *ctx,
617*8617a60dSAndroid Build Coastguard Worker 			     struct vb2_packed_key *key,
618*8617a60dSAndroid Build Coastguard Worker 			     char *dest, size_t dest_size)
619*8617a60dSAndroid Build Coastguard Worker {
620*8617a60dSAndroid Build Coastguard Worker 	uint8_t *buf = ((uint8_t *)key) + key->key_offset;
621*8617a60dSAndroid Build Coastguard Worker 	uint64_t buflen = key->key_size;
622*8617a60dSAndroid Build Coastguard Worker 	struct vb2_hash hash;
623*8617a60dSAndroid Build Coastguard Worker 	int32_t used = 0;
624*8617a60dSAndroid Build Coastguard Worker 	int i;
625*8617a60dSAndroid Build Coastguard Worker 
626*8617a60dSAndroid Build Coastguard Worker 	vb2_hash_calculate(vb2api_hwcrypto_allowed(ctx), buf, buflen,
627*8617a60dSAndroid Build Coastguard Worker 			   VB2_HASH_SHA1, &hash);
628*8617a60dSAndroid Build Coastguard Worker 	for (i = 0; i < sizeof(hash.sha1); i++)
629*8617a60dSAndroid Build Coastguard Worker 		if (used < dest_size)
630*8617a60dSAndroid Build Coastguard Worker 			used += snprintf(dest + used, dest_size - used,
631*8617a60dSAndroid Build Coastguard Worker 					 "%02x", hash.sha1[i]);
632*8617a60dSAndroid Build Coastguard Worker 	dest[dest_size - 1] = '\0';
633*8617a60dSAndroid Build Coastguard Worker }
634*8617a60dSAndroid Build Coastguard Worker 
635*8617a60dSAndroid Build Coastguard Worker #define DEBUG_INFO_MAX_LENGTH 1024
636*8617a60dSAndroid Build Coastguard Worker 
637*8617a60dSAndroid Build Coastguard Worker #define DEBUG_INFO_APPEND(format, args...) do { \
638*8617a60dSAndroid Build Coastguard Worker 	if (used < DEBUG_INFO_MAX_LENGTH) \
639*8617a60dSAndroid Build Coastguard Worker 		used += snprintf(buf + used, DEBUG_INFO_MAX_LENGTH - used, \
640*8617a60dSAndroid Build Coastguard Worker 				 format, ## args); \
641*8617a60dSAndroid Build Coastguard Worker } while (0)
642*8617a60dSAndroid Build Coastguard Worker 
vb2api_get_debug_info(struct vb2_context * ctx)643*8617a60dSAndroid Build Coastguard Worker char *vb2api_get_debug_info(struct vb2_context *ctx)
644*8617a60dSAndroid Build Coastguard Worker {
645*8617a60dSAndroid Build Coastguard Worker 	char *buf;
646*8617a60dSAndroid Build Coastguard Worker 	uint32_t used = 0;
647*8617a60dSAndroid Build Coastguard Worker 
648*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
649*8617a60dSAndroid Build Coastguard Worker 	struct vb2_gbb_header *gbb = NULL;
650*8617a60dSAndroid Build Coastguard Worker 	struct vb2_workbuf wb;
651*8617a60dSAndroid Build Coastguard Worker 	char sha1sum[VB2_SHA1_DIGEST_SIZE * 2 + 1];
652*8617a60dSAndroid Build Coastguard Worker 
653*8617a60dSAndroid Build Coastguard Worker 	vb2_error_t rv;
654*8617a60dSAndroid Build Coastguard Worker 	uint32_t i;
655*8617a60dSAndroid Build Coastguard Worker 
656*8617a60dSAndroid Build Coastguard Worker 	buf = malloc(DEBUG_INFO_MAX_LENGTH + 1);
657*8617a60dSAndroid Build Coastguard Worker 	if (buf == NULL)
658*8617a60dSAndroid Build Coastguard Worker 		return NULL;
659*8617a60dSAndroid Build Coastguard Worker 
660*8617a60dSAndroid Build Coastguard Worker 	vb2_workbuf_from_ctx(ctx, &wb);
661*8617a60dSAndroid Build Coastguard Worker 
662*8617a60dSAndroid Build Coastguard Worker 	if (sd->gbb_offset == 0) {
663*8617a60dSAndroid Build Coastguard Worker 		DEBUG_INFO_APPEND("GBB: {INVALID}");
664*8617a60dSAndroid Build Coastguard Worker 	} else {
665*8617a60dSAndroid Build Coastguard Worker 		gbb = vb2_get_gbb(ctx);
666*8617a60dSAndroid Build Coastguard Worker 	}
667*8617a60dSAndroid Build Coastguard Worker 
668*8617a60dSAndroid Build Coastguard Worker 	/* Add hardware ID */
669*8617a60dSAndroid Build Coastguard Worker 	if (gbb) {
670*8617a60dSAndroid Build Coastguard Worker 		char hwid[VB2_GBB_HWID_MAX_SIZE];
671*8617a60dSAndroid Build Coastguard Worker 		uint32_t size = sizeof(hwid);
672*8617a60dSAndroid Build Coastguard Worker 		rv = vb2api_gbb_read_hwid(ctx, hwid, &size);
673*8617a60dSAndroid Build Coastguard Worker 		if (rv)
674*8617a60dSAndroid Build Coastguard Worker 			strcpy(hwid, "{INVALID}");
675*8617a60dSAndroid Build Coastguard Worker 		DEBUG_INFO_APPEND("HWID: %s", hwid);
676*8617a60dSAndroid Build Coastguard Worker 	}
677*8617a60dSAndroid Build Coastguard Worker 
678*8617a60dSAndroid Build Coastguard Worker 	/* Add recovery reason and subcode */
679*8617a60dSAndroid Build Coastguard Worker 	i = vb2_nv_get(ctx, VB2_NV_RECOVERY_SUBCODE);
680*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\nrecovery_reason: %#.2x / %#.2x  %s",
681*8617a60dSAndroid Build Coastguard Worker 			  sd->recovery_reason, i,
682*8617a60dSAndroid Build Coastguard Worker 			  vb2_get_recovery_reason_string(sd->recovery_reason));
683*8617a60dSAndroid Build Coastguard Worker 
684*8617a60dSAndroid Build Coastguard Worker 	/* Add vb2_context and vb2_shared_data flags */
685*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\ncontext.flags: %#.16" PRIx64, ctx->flags);
686*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\nshared_data.flags: %#.8x", sd->flags);
687*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\nshared_data.status: %#.8x", sd->status);
688*8617a60dSAndroid Build Coastguard Worker 
689*8617a60dSAndroid Build Coastguard Worker 	/* Add raw contents of nvdata */
690*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\nnvdata:");
691*8617a60dSAndroid Build Coastguard Worker 	if (vb2_nv_get_size(ctx) > 16)  /* Multi-line starts on next line */
692*8617a60dSAndroid Build Coastguard Worker 		DEBUG_INFO_APPEND("\n  ");
693*8617a60dSAndroid Build Coastguard Worker 	for (i = 0; i < vb2_nv_get_size(ctx); i++) {
694*8617a60dSAndroid Build Coastguard Worker 		/* Split into 16-byte blocks */
695*8617a60dSAndroid Build Coastguard Worker 		if (i > 0 && i % 16 == 0)
696*8617a60dSAndroid Build Coastguard Worker 			DEBUG_INFO_APPEND("\n  ");
697*8617a60dSAndroid Build Coastguard Worker 		DEBUG_INFO_APPEND(" %02x", ctx->nvdata[i]);
698*8617a60dSAndroid Build Coastguard Worker 	}
699*8617a60dSAndroid Build Coastguard Worker 
700*8617a60dSAndroid Build Coastguard Worker 	/* Add dev_boot_usb flag */
701*8617a60dSAndroid Build Coastguard Worker 	i = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_EXTERNAL);
702*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\ndev_boot_usb: %d", i);
703*8617a60dSAndroid Build Coastguard Worker 
704*8617a60dSAndroid Build Coastguard Worker 	/* Add dev_boot_altfw flag */
705*8617a60dSAndroid Build Coastguard Worker 	i = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_ALTFW);
706*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\ndev_boot_altfw: %d", i);
707*8617a60dSAndroid Build Coastguard Worker 
708*8617a60dSAndroid Build Coastguard Worker 	/* Add dev_default_boot flag */
709*8617a60dSAndroid Build Coastguard Worker 	i = vb2_nv_get(ctx, VB2_NV_DEV_DEFAULT_BOOT);
710*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\ndev_default_boot: %d", i);
711*8617a60dSAndroid Build Coastguard Worker 
712*8617a60dSAndroid Build Coastguard Worker 	/* Add dev_boot_signed_only flag */
713*8617a60dSAndroid Build Coastguard Worker 	i = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY);
714*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\ndev_boot_signed_only: %d", i);
715*8617a60dSAndroid Build Coastguard Worker 
716*8617a60dSAndroid Build Coastguard Worker 	/* Add TPM versions */
717*8617a60dSAndroid Build Coastguard Worker 	DEBUG_INFO_APPEND("\nTPM: fwver=%#.8x kernver=%#.8x",
718*8617a60dSAndroid Build Coastguard Worker 			  sd->fw_version_secdata, sd->kernel_version_secdata);
719*8617a60dSAndroid Build Coastguard Worker 
720*8617a60dSAndroid Build Coastguard Worker 	/* Add GBB flags */
721*8617a60dSAndroid Build Coastguard Worker 	if (gbb) {
722*8617a60dSAndroid Build Coastguard Worker 		DEBUG_INFO_APPEND("\ngbb.flags: %#.8x", gbb->flags);
723*8617a60dSAndroid Build Coastguard Worker 	}
724*8617a60dSAndroid Build Coastguard Worker 
725*8617a60dSAndroid Build Coastguard Worker 	/* Add sha1sum for Root & Recovery keys */
726*8617a60dSAndroid Build Coastguard Worker 	if (gbb) {
727*8617a60dSAndroid Build Coastguard Worker 		struct vb2_packed_key *key;
728*8617a60dSAndroid Build Coastguard Worker 		struct vb2_workbuf wblocal = wb;
729*8617a60dSAndroid Build Coastguard Worker 		rv = vb2_gbb_read_root_key(ctx, &key, NULL, &wblocal);
730*8617a60dSAndroid Build Coastguard Worker 		if (rv == VB2_SUCCESS) {
731*8617a60dSAndroid Build Coastguard Worker 			snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum));
732*8617a60dSAndroid Build Coastguard Worker 			DEBUG_INFO_APPEND("\ngbb.rootkey: %s", sha1sum);
733*8617a60dSAndroid Build Coastguard Worker 		}
734*8617a60dSAndroid Build Coastguard Worker 	}
735*8617a60dSAndroid Build Coastguard Worker 
736*8617a60dSAndroid Build Coastguard Worker 	if (gbb) {
737*8617a60dSAndroid Build Coastguard Worker 		struct vb2_packed_key *key;
738*8617a60dSAndroid Build Coastguard Worker 		struct vb2_workbuf wblocal = wb;
739*8617a60dSAndroid Build Coastguard Worker 		rv = vb2_gbb_read_recovery_key(ctx, &key, NULL, &wblocal);
740*8617a60dSAndroid Build Coastguard Worker 		if (rv == VB2_SUCCESS) {
741*8617a60dSAndroid Build Coastguard Worker 			snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum));
742*8617a60dSAndroid Build Coastguard Worker 			DEBUG_INFO_APPEND("\ngbb.recovery_key: %s", sha1sum);
743*8617a60dSAndroid Build Coastguard Worker 		}
744*8617a60dSAndroid Build Coastguard Worker 	}
745*8617a60dSAndroid Build Coastguard Worker 
746*8617a60dSAndroid Build Coastguard Worker 	/* If we're in dev-mode, show the kernel subkey that we expect, too. */
747*8617a60dSAndroid Build Coastguard Worker 	if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE) &&
748*8617a60dSAndroid Build Coastguard Worker 	    sd->kernel_key_offset) {
749*8617a60dSAndroid Build Coastguard Worker 		struct vb2_packed_key *key =
750*8617a60dSAndroid Build Coastguard Worker 			vb2_member_of(sd, sd->kernel_key_offset);
751*8617a60dSAndroid Build Coastguard Worker 		snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum));
752*8617a60dSAndroid Build Coastguard Worker 		DEBUG_INFO_APPEND("\nkernel_subkey: %s", sha1sum);
753*8617a60dSAndroid Build Coastguard Worker 	}
754*8617a60dSAndroid Build Coastguard Worker 
755*8617a60dSAndroid Build Coastguard Worker 	buf[DEBUG_INFO_MAX_LENGTH] = '\0';
756*8617a60dSAndroid Build Coastguard Worker 	return buf;
757*8617a60dSAndroid Build Coastguard Worker }
758*8617a60dSAndroid Build Coastguard Worker 
vb2_set_boot_mode(struct vb2_context * ctx)759*8617a60dSAndroid Build Coastguard Worker void vb2_set_boot_mode(struct vb2_context *ctx)
760*8617a60dSAndroid Build Coastguard Worker {
761*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
762*8617a60dSAndroid Build Coastguard Worker 
763*8617a60dSAndroid Build Coastguard Worker 	/* Cast boot mode to non-constant and assign */
764*8617a60dSAndroid Build Coastguard Worker 	enum vb2_boot_mode *boot_mode = (enum vb2_boot_mode *)&ctx->boot_mode;
765*8617a60dSAndroid Build Coastguard Worker 	*boot_mode = VB2_BOOT_MODE_NORMAL;
766*8617a60dSAndroid Build Coastguard Worker 
767*8617a60dSAndroid Build Coastguard Worker 	/*
768*8617a60dSAndroid Build Coastguard Worker 	 * The only way to pass this check and proceed to the recovery process
769*8617a60dSAndroid Build Coastguard Worker 	 * is to physically request a recovery (a.k.a. manual recovery).  All
770*8617a60dSAndroid Build Coastguard Worker 	 * other recovery requests including manual recovery requested by a
771*8617a60dSAndroid Build Coastguard Worker 	 * (compromised) host will end up with 'broken' screen.
772*8617a60dSAndroid Build Coastguard Worker 	 */
773*8617a60dSAndroid Build Coastguard Worker 	if ((ctx->flags & VB2_CONTEXT_FORCE_RECOVERY_MODE) &&
774*8617a60dSAndroid Build Coastguard Worker 	    !(ctx->flags & VB2_CONTEXT_NO_BOOT) &&
775*8617a60dSAndroid Build Coastguard Worker 	    (ctx->flags & VB2_CONTEXT_EC_TRUSTED)) {
776*8617a60dSAndroid Build Coastguard Worker 		*boot_mode = VB2_BOOT_MODE_MANUAL_RECOVERY;
777*8617a60dSAndroid Build Coastguard Worker 	} else if (sd->recovery_reason) {
778*8617a60dSAndroid Build Coastguard Worker 		vb2_gbb_flags_t gbb_flags = vb2api_gbb_get_flags(ctx);
779*8617a60dSAndroid Build Coastguard Worker 		if (gbb_flags & VB2_GBB_FLAG_FORCE_MANUAL_RECOVERY)
780*8617a60dSAndroid Build Coastguard Worker 			*boot_mode = VB2_BOOT_MODE_MANUAL_RECOVERY;
781*8617a60dSAndroid Build Coastguard Worker 		else
782*8617a60dSAndroid Build Coastguard Worker 			*boot_mode = VB2_BOOT_MODE_BROKEN_SCREEN;
783*8617a60dSAndroid Build Coastguard Worker 	} else if (vb2api_diagnostic_ui_enabled(ctx) &&
784*8617a60dSAndroid Build Coastguard Worker 		   vb2_nv_get(ctx, VB2_NV_DIAG_REQUEST)) {
785*8617a60dSAndroid Build Coastguard Worker 		*boot_mode = VB2_BOOT_MODE_DIAGNOSTICS;
786*8617a60dSAndroid Build Coastguard Worker 	} else if (ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) {
787*8617a60dSAndroid Build Coastguard Worker 		*boot_mode = VB2_BOOT_MODE_DEVELOPER;
788*8617a60dSAndroid Build Coastguard Worker 	}
789*8617a60dSAndroid Build Coastguard Worker }
790*8617a60dSAndroid Build Coastguard Worker 
791*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2api_hwcrypto_allowed(struct vb2_context * ctx)792*8617a60dSAndroid Build Coastguard Worker bool vb2api_hwcrypto_allowed(struct vb2_context *ctx)
793*8617a60dSAndroid Build Coastguard Worker {
794*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
795*8617a60dSAndroid Build Coastguard Worker 
796*8617a60dSAndroid Build Coastguard Worker 	/* disable hwcrypto in recovery mode */
797*8617a60dSAndroid Build Coastguard Worker 	if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
798*8617a60dSAndroid Build Coastguard Worker 		return 0;
799*8617a60dSAndroid Build Coastguard Worker 
800*8617a60dSAndroid Build Coastguard Worker 	/* disable hwcrypto if secdata isn't initialized */
801*8617a60dSAndroid Build Coastguard Worker 	if (!(sd->status & VB2_SD_STATUS_SECDATA_KERNEL_INIT))
802*8617a60dSAndroid Build Coastguard Worker 		return 0;
803*8617a60dSAndroid Build Coastguard Worker 
804*8617a60dSAndroid Build Coastguard Worker 	/* enable hwcrypto only if RW firmware set the flag */
805*8617a60dSAndroid Build Coastguard Worker 	return vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS) &
806*8617a60dSAndroid Build Coastguard Worker 		VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED;
807*8617a60dSAndroid Build Coastguard Worker }
808