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
18int 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
39int 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
124int 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