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