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 "2rsa.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2secdata.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
15*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
16*8617a60dSAndroid Build Coastguard Worker
vb2_load_fw_keyblock(struct vb2_context * ctx)17*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
18*8617a60dSAndroid Build Coastguard Worker {
19*8617a60dSAndroid Build Coastguard Worker struct vb2_shared_data *sd = vb2_get_sd(ctx);
20*8617a60dSAndroid Build Coastguard Worker struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
21*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
22*8617a60dSAndroid Build Coastguard Worker
23*8617a60dSAndroid Build Coastguard Worker uint8_t *key_data;
24*8617a60dSAndroid Build Coastguard Worker uint32_t key_size;
25*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key root_key;
26*8617a60dSAndroid Build Coastguard Worker
27*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *kb;
28*8617a60dSAndroid Build Coastguard Worker uint32_t block_size;
29*8617a60dSAndroid Build Coastguard Worker
30*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv = VB2_SUCCESS;
31*8617a60dSAndroid Build Coastguard Worker
32*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_from_ctx(ctx, &wb);
33*8617a60dSAndroid Build Coastguard Worker
34*8617a60dSAndroid Build Coastguard Worker /* Read the root key */
35*8617a60dSAndroid Build Coastguard Worker key_size = gbb->rootkey_size;
36*8617a60dSAndroid Build Coastguard Worker key_data = vb2_workbuf_alloc(&wb, key_size);
37*8617a60dSAndroid Build Coastguard Worker if (!key_data)
38*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;
39*8617a60dSAndroid Build Coastguard Worker
40*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->rootkey_offset,
41*8617a60dSAndroid Build Coastguard Worker key_data, key_size));
42*8617a60dSAndroid Build Coastguard Worker
43*8617a60dSAndroid Build Coastguard Worker /* Unpack the root key */
44*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_unpack_key_buffer(&root_key, key_data, key_size));
45*8617a60dSAndroid Build Coastguard Worker
46*8617a60dSAndroid Build Coastguard Worker root_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
47*8617a60dSAndroid Build Coastguard Worker
48*8617a60dSAndroid Build Coastguard Worker /* Load the firmware keyblock header after the root key */
49*8617a60dSAndroid Build Coastguard Worker kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
50*8617a60dSAndroid Build Coastguard Worker if (!kb)
51*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER;
52*8617a60dSAndroid Build Coastguard Worker
53*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0,
54*8617a60dSAndroid Build Coastguard Worker kb, sizeof(*kb)));
55*8617a60dSAndroid Build Coastguard Worker
56*8617a60dSAndroid Build Coastguard Worker block_size = kb->keyblock_size;
57*8617a60dSAndroid Build Coastguard Worker
58*8617a60dSAndroid Build Coastguard Worker /*
59*8617a60dSAndroid Build Coastguard Worker * Load the entire keyblock, now that we know how big it is. Note that
60*8617a60dSAndroid Build Coastguard Worker * we're loading the entire keyblock instead of just the piece after
61*8617a60dSAndroid Build Coastguard Worker * the header. That means we re-read the header. But that's a tiny
62*8617a60dSAndroid Build Coastguard Worker * amount of data, and it makes the code much more straightforward.
63*8617a60dSAndroid Build Coastguard Worker */
64*8617a60dSAndroid Build Coastguard Worker kb = vb2_workbuf_realloc(&wb, sizeof(*kb), block_size);
65*8617a60dSAndroid Build Coastguard Worker if (!kb)
66*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_FW_KEYBLOCK_WORKBUF;
67*8617a60dSAndroid Build Coastguard Worker
68*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size));
69*8617a60dSAndroid Build Coastguard Worker
70*8617a60dSAndroid Build Coastguard Worker /* Verify the keyblock */
71*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_verify_keyblock(kb, block_size, &root_key, &wb),
72*8617a60dSAndroid Build Coastguard Worker ctx, VB2_RECOVERY_FW_KEYBLOCK);
73*8617a60dSAndroid Build Coastguard Worker
74*8617a60dSAndroid Build Coastguard Worker /* Key version is the upper 16 bits of the composite firmware version */
75*8617a60dSAndroid Build Coastguard Worker if (kb->data_key.key_version > VB2_MAX_KEY_VERSION)
76*8617a60dSAndroid Build Coastguard Worker rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
77*8617a60dSAndroid Build Coastguard Worker if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16)) {
78*8617a60dSAndroid Build Coastguard Worker if (gbb->flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
79*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Ignoring FW key rollback due to GBB flag\n");
80*8617a60dSAndroid Build Coastguard Worker else
81*8617a60dSAndroid Build Coastguard Worker rv = VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
82*8617a60dSAndroid Build Coastguard Worker }
83*8617a60dSAndroid Build Coastguard Worker if (rv) {
84*8617a60dSAndroid Build Coastguard Worker vb2api_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
85*8617a60dSAndroid Build Coastguard Worker return rv;
86*8617a60dSAndroid Build Coastguard Worker }
87*8617a60dSAndroid Build Coastguard Worker
88*8617a60dSAndroid Build Coastguard Worker sd->fw_version = kb->data_key.key_version << 16;
89*8617a60dSAndroid Build Coastguard Worker
90*8617a60dSAndroid Build Coastguard Worker /* Preamble follows the keyblock in the vblock. */
91*8617a60dSAndroid Build Coastguard Worker sd->vblock_preamble_offset = kb->keyblock_size;
92*8617a60dSAndroid Build Coastguard Worker
93*8617a60dSAndroid Build Coastguard Worker /*
94*8617a60dSAndroid Build Coastguard Worker * Save the data key in the work buffer. We'll overwrite the root key
95*8617a60dSAndroid Build Coastguard Worker * we read above. That's ok, because now that we have the data key we
96*8617a60dSAndroid Build Coastguard Worker * no longer need the root key. First, let's double-check that it is
97*8617a60dSAndroid Build Coastguard Worker * well-formed though (although the keyblock was signed anyway).
98*8617a60dSAndroid Build Coastguard Worker */
99*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_verify_packed_key_inside(kb, block_size, &kb->data_key));
100*8617a60dSAndroid Build Coastguard Worker
101*8617a60dSAndroid Build Coastguard Worker /* Save the future offset and size while kb->data_key is still valid.
102*8617a60dSAndroid Build Coastguard Worker The check above made sure that key_offset and key_size are valid. */
103*8617a60dSAndroid Build Coastguard Worker sd->data_key_offset = vb2_offset_of(sd, key_data);
104*8617a60dSAndroid Build Coastguard Worker sd->data_key_size = kb->data_key.key_offset + kb->data_key.key_size;
105*8617a60dSAndroid Build Coastguard Worker
106*8617a60dSAndroid Build Coastguard Worker /*
107*8617a60dSAndroid Build Coastguard Worker * Use memmove() instead of memcpy(). In theory, the destination will
108*8617a60dSAndroid Build Coastguard Worker * never overlap because with the source because the root key is likely
109*8617a60dSAndroid Build Coastguard Worker * to be at least as large as the data key, but there's no harm here in
110*8617a60dSAndroid Build Coastguard Worker * being paranoid. Make sure we immediately invalidate 'kb' after the
111*8617a60dSAndroid Build Coastguard Worker * move to guarantee we won't try to access it anymore.
112*8617a60dSAndroid Build Coastguard Worker */
113*8617a60dSAndroid Build Coastguard Worker memmove(key_data, &kb->data_key, sd->data_key_size);
114*8617a60dSAndroid Build Coastguard Worker kb = NULL;
115*8617a60dSAndroid Build Coastguard Worker
116*8617a60dSAndroid Build Coastguard Worker /*
117*8617a60dSAndroid Build Coastguard Worker * Data key will persist in the workbuf after we return.
118*8617a60dSAndroid Build Coastguard Worker *
119*8617a60dSAndroid Build Coastguard Worker * Work buffer now contains:
120*8617a60dSAndroid Build Coastguard Worker * - vb2_shared_data
121*8617a60dSAndroid Build Coastguard Worker * - packed firmware data key
122*8617a60dSAndroid Build Coastguard Worker */
123*8617a60dSAndroid Build Coastguard Worker vb2_set_workbuf_used(ctx, sd->data_key_offset + sd->data_key_size);
124*8617a60dSAndroid Build Coastguard Worker
125*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
126*8617a60dSAndroid Build Coastguard Worker }
127*8617a60dSAndroid Build Coastguard Worker
vb2_load_fw_preamble(struct vb2_context * ctx)128*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx)
129*8617a60dSAndroid Build Coastguard Worker {
130*8617a60dSAndroid Build Coastguard Worker struct vb2_shared_data *sd = vb2_get_sd(ctx);
131*8617a60dSAndroid Build Coastguard Worker struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
132*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
133*8617a60dSAndroid Build Coastguard Worker
134*8617a60dSAndroid Build Coastguard Worker uint8_t *key_data = vb2_member_of(sd, sd->data_key_offset);
135*8617a60dSAndroid Build Coastguard Worker uint32_t key_size = sd->data_key_size;
136*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key data_key;
137*8617a60dSAndroid Build Coastguard Worker
138*8617a60dSAndroid Build Coastguard Worker /* Preamble goes in the next unused chunk of work buffer */
139*8617a60dSAndroid Build Coastguard Worker struct vb2_fw_preamble *pre;
140*8617a60dSAndroid Build Coastguard Worker uint32_t pre_size;
141*8617a60dSAndroid Build Coastguard Worker
142*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv = VB2_SUCCESS;
143*8617a60dSAndroid Build Coastguard Worker
144*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_from_ctx(ctx, &wb);
145*8617a60dSAndroid Build Coastguard Worker
146*8617a60dSAndroid Build Coastguard Worker /* Unpack the firmware data key */
147*8617a60dSAndroid Build Coastguard Worker if (!sd->data_key_size)
148*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;
149*8617a60dSAndroid Build Coastguard Worker
150*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_unpack_key_buffer(&data_key, key_data, key_size));
151*8617a60dSAndroid Build Coastguard Worker
152*8617a60dSAndroid Build Coastguard Worker data_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
153*8617a60dSAndroid Build Coastguard Worker
154*8617a60dSAndroid Build Coastguard Worker /* Load the firmware preamble header */
155*8617a60dSAndroid Build Coastguard Worker pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
156*8617a60dSAndroid Build Coastguard Worker if (!pre)
157*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER;
158*8617a60dSAndroid Build Coastguard Worker
159*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
160*8617a60dSAndroid Build Coastguard Worker sd->vblock_preamble_offset,
161*8617a60dSAndroid Build Coastguard Worker pre, sizeof(*pre)));
162*8617a60dSAndroid Build Coastguard Worker
163*8617a60dSAndroid Build Coastguard Worker pre_size = pre->preamble_size;
164*8617a60dSAndroid Build Coastguard Worker
165*8617a60dSAndroid Build Coastguard Worker /* Load the entire firmware preamble, now that we know how big it is */
166*8617a60dSAndroid Build Coastguard Worker pre = vb2_workbuf_realloc(&wb, sizeof(*pre), pre_size);
167*8617a60dSAndroid Build Coastguard Worker if (!pre)
168*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_FW_PREAMBLE2_WORKBUF;
169*8617a60dSAndroid Build Coastguard Worker
170*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
171*8617a60dSAndroid Build Coastguard Worker sd->vblock_preamble_offset,
172*8617a60dSAndroid Build Coastguard Worker pre, pre_size));
173*8617a60dSAndroid Build Coastguard Worker
174*8617a60dSAndroid Build Coastguard Worker /* Work buffer now contains the data subkey data and the preamble */
175*8617a60dSAndroid Build Coastguard Worker
176*8617a60dSAndroid Build Coastguard Worker /* Verify the preamble */
177*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb),
178*8617a60dSAndroid Build Coastguard Worker ctx, VB2_RECOVERY_FW_PREAMBLE);
179*8617a60dSAndroid Build Coastguard Worker
180*8617a60dSAndroid Build Coastguard Worker /*
181*8617a60dSAndroid Build Coastguard Worker * Firmware version is the lower 16 bits of the composite firmware
182*8617a60dSAndroid Build Coastguard Worker * version.
183*8617a60dSAndroid Build Coastguard Worker */
184*8617a60dSAndroid Build Coastguard Worker if (pre->firmware_version > VB2_MAX_PREAMBLE_VERSION)
185*8617a60dSAndroid Build Coastguard Worker rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
186*8617a60dSAndroid Build Coastguard Worker /* Combine with the key version from vb2_load_fw_keyblock() */
187*8617a60dSAndroid Build Coastguard Worker sd->fw_version |= pre->firmware_version;
188*8617a60dSAndroid Build Coastguard Worker if (!rv && sd->fw_version < sd->fw_version_secdata) {
189*8617a60dSAndroid Build Coastguard Worker if (gbb->flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
190*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Ignoring FW rollback due to GBB flag\n");
191*8617a60dSAndroid Build Coastguard Worker else
192*8617a60dSAndroid Build Coastguard Worker rv = VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
193*8617a60dSAndroid Build Coastguard Worker }
194*8617a60dSAndroid Build Coastguard Worker if (rv) {
195*8617a60dSAndroid Build Coastguard Worker vb2api_fail(ctx, VB2_RECOVERY_FW_ROLLBACK, rv);
196*8617a60dSAndroid Build Coastguard Worker return rv;
197*8617a60dSAndroid Build Coastguard Worker }
198*8617a60dSAndroid Build Coastguard Worker
199*8617a60dSAndroid Build Coastguard Worker /*
200*8617a60dSAndroid Build Coastguard Worker * If this is a newer version than in secure storage, and we
201*8617a60dSAndroid Build Coastguard Worker * successfully booted the same slot last boot, roll forward the
202*8617a60dSAndroid Build Coastguard Worker * version in secure storage.
203*8617a60dSAndroid Build Coastguard Worker *
204*8617a60dSAndroid Build Coastguard Worker * Note that this happens before we've verified the firmware data this
205*8617a60dSAndroid Build Coastguard Worker * boot; we're relying on the indicator that the last boot was
206*8617a60dSAndroid Build Coastguard Worker * successful. That's ok, because even if the firmware data has a
207*8617a60dSAndroid Build Coastguard Worker * valid hash, the only way we can know if it's functional is to trust
208*8617a60dSAndroid Build Coastguard Worker * the status from the last boot.
209*8617a60dSAndroid Build Coastguard Worker */
210*8617a60dSAndroid Build Coastguard Worker if (sd->fw_version > sd->fw_version_secdata &&
211*8617a60dSAndroid Build Coastguard Worker sd->last_fw_slot == sd->fw_slot &&
212*8617a60dSAndroid Build Coastguard Worker sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
213*8617a60dSAndroid Build Coastguard Worker sd->fw_version_secdata = sd->fw_version;
214*8617a60dSAndroid Build Coastguard Worker vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
215*8617a60dSAndroid Build Coastguard Worker sd->fw_version);
216*8617a60dSAndroid Build Coastguard Worker }
217*8617a60dSAndroid Build Coastguard Worker
218*8617a60dSAndroid Build Coastguard Worker /* Keep track of where we put the preamble */
219*8617a60dSAndroid Build Coastguard Worker sd->preamble_offset = vb2_offset_of(sd, pre);
220*8617a60dSAndroid Build Coastguard Worker sd->preamble_size = pre_size;
221*8617a60dSAndroid Build Coastguard Worker
222*8617a60dSAndroid Build Coastguard Worker /*
223*8617a60dSAndroid Build Coastguard Worker * Preamble will persist in work buffer after we return.
224*8617a60dSAndroid Build Coastguard Worker *
225*8617a60dSAndroid Build Coastguard Worker * Work buffer now contains:
226*8617a60dSAndroid Build Coastguard Worker * - vb2_shared_data
227*8617a60dSAndroid Build Coastguard Worker * - vb2_gbb_header
228*8617a60dSAndroid Build Coastguard Worker * - packed firmware data key
229*8617a60dSAndroid Build Coastguard Worker * - firmware preamble
230*8617a60dSAndroid Build Coastguard Worker *
231*8617a60dSAndroid Build Coastguard Worker * TODO: we could move the preamble down over the firmware data key
232*8617a60dSAndroid Build Coastguard Worker * since we don't need it anymore.
233*8617a60dSAndroid Build Coastguard Worker */
234*8617a60dSAndroid Build Coastguard Worker vb2_set_workbuf_used(ctx, sd->preamble_offset + pre_size);
235*8617a60dSAndroid Build Coastguard Worker
236*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
237*8617a60dSAndroid Build Coastguard Worker }
238