1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Externally-callable APIs
6 * (Firmware portion)
7 */
8
9 #include "2sysincludes.h"
10 #include "2api.h"
11 #include "2misc.h"
12 #include "2nvstorage.h"
13 #include "2secdata.h"
14 #include "2sha.h"
15 #include "2rsa.h"
16 #include "vb2_common.h"
17
vb2api_fw_phase3(struct vb2_context * ctx)18 int vb2api_fw_phase3(struct vb2_context *ctx)
19 {
20 int rv;
21
22 /* Verify firmware keyblock */
23 rv = vb2_load_fw_keyblock(ctx);
24 if (rv) {
25 vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
26 return rv;
27 }
28
29 /* Verify firmware preamble */
30 rv = vb2_load_fw_preamble(ctx);
31 if (rv) {
32 vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
33 return rv;
34 }
35
36 return VB2_SUCCESS;
37 }
38
vb2api_init_hash(struct vb2_context * ctx,uint32_t tag,uint32_t * size)39 int vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, uint32_t *size)
40 {
41 struct vb2_shared_data *sd = vb2_get_sd(ctx);
42 const struct vb2_fw_preamble *pre;
43 struct vb2_digest_context *dc;
44 struct vb2_public_key key;
45 struct vb2_workbuf wb;
46 int rv;
47
48 vb2_workbuf_from_ctx(ctx, &wb);
49
50 if (tag == VB2_HASH_TAG_INVALID)
51 return VB2_ERROR_API_INIT_HASH_TAG;
52
53 /* Get preamble pointer */
54 if (!sd->workbuf_preamble_size)
55 return VB2_ERROR_API_INIT_HASH_PREAMBLE;
56 pre = (const struct vb2_fw_preamble *)
57 (ctx->workbuf + sd->workbuf_preamble_offset);
58
59 /* For now, we only support the firmware body tag */
60 if (tag != VB2_HASH_TAG_FW_BODY)
61 return VB2_ERROR_API_INIT_HASH_TAG;
62
63 /* Allocate workbuf space for the hash */
64 if (sd->workbuf_hash_size) {
65 dc = (struct vb2_digest_context *)
66 (ctx->workbuf + sd->workbuf_hash_offset);
67 } else {
68 uint32_t dig_size = sizeof(*dc);
69
70 dc = vb2_workbuf_alloc(&wb, dig_size);
71 if (!dc)
72 return VB2_ERROR_API_INIT_HASH_WORKBUF;
73
74 sd->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc);
75 sd->workbuf_hash_size = dig_size;
76 ctx->workbuf_used = sd->workbuf_hash_offset + dig_size;
77 }
78
79 /*
80 * Unpack the firmware data key to see which hashing algorithm we
81 * should use.
82 *
83 * TODO: really, the firmware body should be hashed, and not signed,
84 * because the signature we're checking is already signed as part of
85 * the firmware preamble. But until we can change the signing scripts,
86 * we're stuck with a signature here instead of a hash.
87 */
88 if (!sd->workbuf_data_key_size)
89 return VB2_ERROR_API_INIT_HASH_DATA_KEY;
90
91 rv = vb2_unpack_key(&key,
92 ctx->workbuf + sd->workbuf_data_key_offset,
93 sd->workbuf_data_key_size);
94 if (rv)
95 return rv;
96
97 sd->hash_tag = tag;
98 sd->hash_remaining_size = pre->body_signature.data_size;
99
100 if (size)
101 *size = pre->body_signature.data_size;
102
103 if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) {
104 rv = vb2ex_hwcrypto_digest_init(key.hash_alg,
105 pre->body_signature.data_size);
106 if (!rv) {
107 VB2_DEBUG("Using HW crypto engine for hash_alg %d\n",
108 key.hash_alg);
109 dc->hash_alg = key.hash_alg;
110 dc->using_hwcrypto = 1;
111 return VB2_SUCCESS;
112 }
113 if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED)
114 return rv;
115 VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n",
116 key.hash_alg);
117 } else {
118 VB2_DEBUG("HW crypto forbidden by preamble, using SW\n");
119 }
120
121 return vb2_digest_init(dc, key.hash_alg);
122 }
123
vb2api_check_hash(struct vb2_context * ctx)124 int vb2api_check_hash(struct vb2_context *ctx)
125 {
126 struct vb2_shared_data *sd = vb2_get_sd(ctx);
127 struct vb2_digest_context *dc = (struct vb2_digest_context *)
128 (ctx->workbuf + sd->workbuf_hash_offset);
129 struct vb2_workbuf wb;
130
131 uint8_t *digest;
132 uint32_t digest_size = vb2_digest_size(dc->hash_alg);
133
134 struct vb2_fw_preamble *pre;
135 struct vb2_public_key key;
136 int rv;
137
138 vb2_workbuf_from_ctx(ctx, &wb);
139
140 /* Get preamble pointer */
141 if (!sd->workbuf_preamble_size)
142 return VB2_ERROR_API_CHECK_HASH_PREAMBLE;
143 pre = (struct vb2_fw_preamble *)
144 (ctx->workbuf + sd->workbuf_preamble_offset);
145
146 /* Must have initialized hash digest work area */
147 if (!sd->workbuf_hash_size)
148 return VB2_ERROR_API_CHECK_HASH_WORKBUF;
149
150 /* Should have hashed the right amount of data */
151 if (sd->hash_remaining_size)
152 return VB2_ERROR_API_CHECK_HASH_SIZE;
153
154 /* Allocate the digest */
155 digest = vb2_workbuf_alloc(&wb, digest_size);
156 if (!digest)
157 return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
158
159 /* Finalize the digest */
160 if (dc->using_hwcrypto)
161 rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size);
162 else
163 rv = vb2_digest_finalize(dc, digest, digest_size);
164 if (rv)
165 return rv;
166
167 /* The code below is specific to the body signature */
168 if (sd->hash_tag != VB2_HASH_TAG_FW_BODY)
169 return VB2_ERROR_API_CHECK_HASH_TAG;
170
171 /*
172 * The body signature is currently a *signature* of the body data, not
173 * just its hash. So we need to verify the signature.
174 */
175
176 /* Unpack the data key */
177 if (!sd->workbuf_data_key_size)
178 return VB2_ERROR_API_CHECK_HASH_DATA_KEY;
179
180 rv = vb2_unpack_key(&key,
181 ctx->workbuf + sd->workbuf_data_key_offset,
182 sd->workbuf_data_key_size);
183 if (rv)
184 return rv;
185
186 /*
187 * Check digest vs. signature. Note that this destroys the signature.
188 * That's ok, because we only check each signature once per boot.
189 */
190 rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb);
191 if (rv)
192 vb2_fail(ctx, VB2_RECOVERY_FW_BODY, rv);
193
194 return rv;
195 }
196