xref: /aosp_15_r20/external/vboot_reference/firmware/2lib/2secdata_firmware.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  * Secure storage APIs
6*8617a60dSAndroid Build Coastguard Worker  */
7*8617a60dSAndroid Build Coastguard Worker 
8*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
9*8617a60dSAndroid Build Coastguard Worker #include "2crc8.h"
10*8617a60dSAndroid Build Coastguard Worker #include "2misc.h"
11*8617a60dSAndroid Build Coastguard Worker #include "2secdata.h"
12*8617a60dSAndroid Build Coastguard Worker #include "2secdata_struct.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
14*8617a60dSAndroid Build Coastguard Worker 
vb2api_secdata_firmware_check(struct vb2_context * ctx)15*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2api_secdata_firmware_check(struct vb2_context *ctx)
16*8617a60dSAndroid Build Coastguard Worker {
17*8617a60dSAndroid Build Coastguard Worker 	struct vb2_secdata_firmware *sec =
18*8617a60dSAndroid Build Coastguard Worker 		(struct vb2_secdata_firmware *)ctx->secdata_firmware;
19*8617a60dSAndroid Build Coastguard Worker 
20*8617a60dSAndroid Build Coastguard Worker 	/* Verify CRC */
21*8617a60dSAndroid Build Coastguard Worker 	if (sec->crc8 != vb2_crc8(sec, offsetof(struct vb2_secdata_firmware,
22*8617a60dSAndroid Build Coastguard Worker 						crc8))) {
23*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("secdata_firmware: bad CRC\n");
24*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_SECDATA_FIRMWARE_CRC;
25*8617a60dSAndroid Build Coastguard Worker 	}
26*8617a60dSAndroid Build Coastguard Worker 
27*8617a60dSAndroid Build Coastguard Worker 	/* Verify version */
28*8617a60dSAndroid Build Coastguard Worker 	if (sec->struct_version < VB2_SECDATA_FIRMWARE_VERSION) {
29*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("secdata_firmware: version incompatible\n");
30*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_SECDATA_FIRMWARE_VERSION;
31*8617a60dSAndroid Build Coastguard Worker 	}
32*8617a60dSAndroid Build Coastguard Worker 
33*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
34*8617a60dSAndroid Build Coastguard Worker }
35*8617a60dSAndroid Build Coastguard Worker 
vb2api_secdata_firmware_create(struct vb2_context * ctx)36*8617a60dSAndroid Build Coastguard Worker uint32_t vb2api_secdata_firmware_create(struct vb2_context *ctx)
37*8617a60dSAndroid Build Coastguard Worker {
38*8617a60dSAndroid Build Coastguard Worker 	struct vb2_secdata_firmware *sec =
39*8617a60dSAndroid Build Coastguard Worker 		(struct vb2_secdata_firmware *)ctx->secdata_firmware;
40*8617a60dSAndroid Build Coastguard Worker 
41*8617a60dSAndroid Build Coastguard Worker 	/* Clear the entire struct */
42*8617a60dSAndroid Build Coastguard Worker 	memset(sec, 0, sizeof(*sec));
43*8617a60dSAndroid Build Coastguard Worker 
44*8617a60dSAndroid Build Coastguard Worker 	/* Set to current version */
45*8617a60dSAndroid Build Coastguard Worker 	sec->struct_version = VB2_SECDATA_FIRMWARE_VERSION;
46*8617a60dSAndroid Build Coastguard Worker 
47*8617a60dSAndroid Build Coastguard Worker 	/* Calculate initial CRC */
48*8617a60dSAndroid Build Coastguard Worker 	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata_firmware, crc8));
49*8617a60dSAndroid Build Coastguard Worker 
50*8617a60dSAndroid Build Coastguard Worker 	/* Mark as changed */
51*8617a60dSAndroid Build Coastguard Worker 	ctx->flags |= VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
52*8617a60dSAndroid Build Coastguard Worker 
53*8617a60dSAndroid Build Coastguard Worker 	return sizeof(*sec);
54*8617a60dSAndroid Build Coastguard Worker }
55*8617a60dSAndroid Build Coastguard Worker 
vb2_secdata_firmware_init(struct vb2_context * ctx)56*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_secdata_firmware_init(struct vb2_context *ctx)
57*8617a60dSAndroid Build Coastguard Worker {
58*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
59*8617a60dSAndroid Build Coastguard Worker 
60*8617a60dSAndroid Build Coastguard Worker 	VB2_TRY(vb2api_secdata_firmware_check(ctx));
61*8617a60dSAndroid Build Coastguard Worker 
62*8617a60dSAndroid Build Coastguard Worker 	/* Set status flag */
63*8617a60dSAndroid Build Coastguard Worker 	sd->status |= VB2_SD_STATUS_SECDATA_FIRMWARE_INIT;
64*8617a60dSAndroid Build Coastguard Worker 
65*8617a60dSAndroid Build Coastguard Worker 	/* Read this now to make sure crossystem has it even in rec mode */
66*8617a60dSAndroid Build Coastguard Worker 	sd->fw_version_secdata =
67*8617a60dSAndroid Build Coastguard Worker 		vb2_secdata_firmware_get(ctx, VB2_SECDATA_FIRMWARE_VERSIONS);
68*8617a60dSAndroid Build Coastguard Worker 
69*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
70*8617a60dSAndroid Build Coastguard Worker }
71*8617a60dSAndroid Build Coastguard Worker 
vb2_secdata_firmware_get(struct vb2_context * ctx,enum vb2_secdata_firmware_param param)72*8617a60dSAndroid Build Coastguard Worker uint32_t vb2_secdata_firmware_get(struct vb2_context *ctx,
73*8617a60dSAndroid Build Coastguard Worker 				  enum vb2_secdata_firmware_param param)
74*8617a60dSAndroid Build Coastguard Worker {
75*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
76*8617a60dSAndroid Build Coastguard Worker 	struct vb2_secdata_firmware *sec =
77*8617a60dSAndroid Build Coastguard Worker 		(struct vb2_secdata_firmware *)ctx->secdata_firmware;
78*8617a60dSAndroid Build Coastguard Worker 	const char *msg;
79*8617a60dSAndroid Build Coastguard Worker 
80*8617a60dSAndroid Build Coastguard Worker 	if (!(sd->status & VB2_SD_STATUS_SECDATA_FIRMWARE_INIT)) {
81*8617a60dSAndroid Build Coastguard Worker 		msg = "get before init";
82*8617a60dSAndroid Build Coastguard Worker 		goto fail;
83*8617a60dSAndroid Build Coastguard Worker 	}
84*8617a60dSAndroid Build Coastguard Worker 
85*8617a60dSAndroid Build Coastguard Worker 	switch (param) {
86*8617a60dSAndroid Build Coastguard Worker 	case VB2_SECDATA_FIRMWARE_FLAGS:
87*8617a60dSAndroid Build Coastguard Worker 		return sec->flags;
88*8617a60dSAndroid Build Coastguard Worker 
89*8617a60dSAndroid Build Coastguard Worker 	case VB2_SECDATA_FIRMWARE_VERSIONS:
90*8617a60dSAndroid Build Coastguard Worker 		return sec->fw_versions;
91*8617a60dSAndroid Build Coastguard Worker 
92*8617a60dSAndroid Build Coastguard Worker 	default:
93*8617a60dSAndroid Build Coastguard Worker 		msg = "invalid param";
94*8617a60dSAndroid Build Coastguard Worker 	}
95*8617a60dSAndroid Build Coastguard Worker 
96*8617a60dSAndroid Build Coastguard Worker  fail:
97*8617a60dSAndroid Build Coastguard Worker 	VB2_REC_OR_DIE(ctx, "%s\n", msg);
98*8617a60dSAndroid Build Coastguard Worker 	return 0;
99*8617a60dSAndroid Build Coastguard Worker }
100*8617a60dSAndroid Build Coastguard Worker 
vb2_secdata_firmware_set(struct vb2_context * ctx,enum vb2_secdata_firmware_param param,uint32_t value)101*8617a60dSAndroid Build Coastguard Worker void vb2_secdata_firmware_set(struct vb2_context *ctx,
102*8617a60dSAndroid Build Coastguard Worker 			      enum vb2_secdata_firmware_param param,
103*8617a60dSAndroid Build Coastguard Worker 			      uint32_t value)
104*8617a60dSAndroid Build Coastguard Worker {
105*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
106*8617a60dSAndroid Build Coastguard Worker 	struct vb2_secdata_firmware *sec =
107*8617a60dSAndroid Build Coastguard Worker 		(struct vb2_secdata_firmware *)ctx->secdata_firmware;
108*8617a60dSAndroid Build Coastguard Worker 	const char *msg;
109*8617a60dSAndroid Build Coastguard Worker 
110*8617a60dSAndroid Build Coastguard Worker 	if (!(sd->status & VB2_SD_STATUS_SECDATA_FIRMWARE_INIT)) {
111*8617a60dSAndroid Build Coastguard Worker 		msg = "set before init";
112*8617a60dSAndroid Build Coastguard Worker 		goto fail;
113*8617a60dSAndroid Build Coastguard Worker 	}
114*8617a60dSAndroid Build Coastguard Worker 
115*8617a60dSAndroid Build Coastguard Worker 	/* If not changing the value, just return early */
116*8617a60dSAndroid Build Coastguard Worker 	if (value == vb2_secdata_firmware_get(ctx, param))
117*8617a60dSAndroid Build Coastguard Worker 		return;
118*8617a60dSAndroid Build Coastguard Worker 
119*8617a60dSAndroid Build Coastguard Worker 	switch (param) {
120*8617a60dSAndroid Build Coastguard Worker 	case VB2_SECDATA_FIRMWARE_FLAGS:
121*8617a60dSAndroid Build Coastguard Worker 		/* Make sure flags is in valid range */
122*8617a60dSAndroid Build Coastguard Worker 		if (value > 0xff) {
123*8617a60dSAndroid Build Coastguard Worker 			msg = "flags out of range";
124*8617a60dSAndroid Build Coastguard Worker 			goto fail;
125*8617a60dSAndroid Build Coastguard Worker 		}
126*8617a60dSAndroid Build Coastguard Worker 
127*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("secdata_firmware flags updated from %#x to %#x\n",
128*8617a60dSAndroid Build Coastguard Worker 			  sec->flags, value);
129*8617a60dSAndroid Build Coastguard Worker 		sec->flags = value;
130*8617a60dSAndroid Build Coastguard Worker 		break;
131*8617a60dSAndroid Build Coastguard Worker 
132*8617a60dSAndroid Build Coastguard Worker 	case VB2_SECDATA_FIRMWARE_VERSIONS:
133*8617a60dSAndroid Build Coastguard Worker 		VB2_DEBUG("secdata_firmware versions updated from "
134*8617a60dSAndroid Build Coastguard Worker 			  "%#x to %#x\n",
135*8617a60dSAndroid Build Coastguard Worker 			  sec->fw_versions, value);
136*8617a60dSAndroid Build Coastguard Worker 		sec->fw_versions = value;
137*8617a60dSAndroid Build Coastguard Worker 		break;
138*8617a60dSAndroid Build Coastguard Worker 
139*8617a60dSAndroid Build Coastguard Worker 	default:
140*8617a60dSAndroid Build Coastguard Worker 		msg = "invalid param";
141*8617a60dSAndroid Build Coastguard Worker 		goto fail;
142*8617a60dSAndroid Build Coastguard Worker 	}
143*8617a60dSAndroid Build Coastguard Worker 
144*8617a60dSAndroid Build Coastguard Worker 	/* Regenerate CRC */
145*8617a60dSAndroid Build Coastguard Worker 	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata_firmware, crc8));
146*8617a60dSAndroid Build Coastguard Worker 	ctx->flags |= VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
147*8617a60dSAndroid Build Coastguard Worker 	return;
148*8617a60dSAndroid Build Coastguard Worker 
149*8617a60dSAndroid Build Coastguard Worker  fail:
150*8617a60dSAndroid Build Coastguard Worker 	VB2_REC_OR_DIE(ctx, "%s\n", msg);
151*8617a60dSAndroid Build Coastguard Worker }
152