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 "2common.h"
12 #include "2misc.h"
13 #include "2nvstorage.h"
14 #include "2secdata.h"
15 #include "2sha.h"
16 #include "2rsa.h"
17 #include "vb2_common.h"
18
vb2api_fw_phase3(struct vb2_context * ctx)19 int vb2api_fw_phase3(struct vb2_context *ctx)
20 {
21 int rv;
22
23 /* Verify firmware keyblock */
24 rv = vb2_load_fw_keyblock(ctx);
25 if (rv) {
26 vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
27 return rv;
28 }
29
30 /* Verify firmware preamble */
31 rv = vb2_load_fw_preamble(ctx);
32 if (rv) {
33 vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
34 return rv;
35 }
36
37 return VB2_SUCCESS;
38 }
39
vb2api_init_hash2(struct vb2_context * ctx,const struct vb2_guid * guid,uint32_t * size)40 int vb2api_init_hash2(struct vb2_context *ctx,
41 const struct vb2_guid *guid,
42 uint32_t *size)
43 {
44 struct vb2_shared_data *sd = vb2_get_sd(ctx);
45 const struct vb2_fw_preamble *pre;
46 const struct vb2_signature *sig = NULL;
47 struct vb2_digest_context *dc;
48 struct vb2_workbuf wb;
49 uint32_t hash_offset;
50 int i, rv;
51
52 vb2_workbuf_from_ctx(ctx, &wb);
53
54 /* Get preamble pointer */
55 if (!sd->workbuf_preamble_size)
56 return VB2_ERROR_API_INIT_HASH_PREAMBLE;
57 pre = (const struct vb2_fw_preamble *)
58 (ctx->workbuf + sd->workbuf_preamble_offset);
59
60 /* Find the matching signature */
61 hash_offset = pre->hash_offset;
62 for (i = 0; i < pre->hash_count; i++) {
63 sig = (const struct vb2_signature *)
64 ((uint8_t *)pre + hash_offset);
65
66 if (!memcmp(guid, &sig->guid, sizeof(*guid)))
67 break;
68
69 hash_offset += sig->c.total_size;
70 }
71 if (i >= pre->hash_count)
72 return VB2_ERROR_API_INIT_HASH_GUID; /* No match */
73
74 /* Allocate workbuf space for the hash */
75 if (sd->workbuf_hash_size) {
76 dc = (struct vb2_digest_context *)
77 (ctx->workbuf + sd->workbuf_hash_offset);
78 } else {
79 uint32_t dig_size = sizeof(*dc);
80
81 dc = vb2_workbuf_alloc(&wb, dig_size);
82 if (!dc)
83 return VB2_ERROR_API_INIT_HASH_WORKBUF;
84
85 sd->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc);
86 sd->workbuf_hash_size = dig_size;
87 ctx->workbuf_used = sd->workbuf_hash_offset + dig_size;
88 }
89
90 sd->hash_tag = vb2_offset_of(ctx->workbuf, sig);
91 sd->hash_remaining_size = sig->data_size;
92
93 if (size)
94 *size = sig->data_size;
95
96 if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) {
97 rv = vb2ex_hwcrypto_digest_init(sig->hash_alg, sig->data_size);
98 if (!rv) {
99 VB2_DEBUG("Using HW crypto engine for hash_alg %d\n",
100 sig->hash_alg);
101 dc->hash_alg = sig->hash_alg;
102 dc->using_hwcrypto = 1;
103 return VB2_SUCCESS;
104 }
105 if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED)
106 return rv;
107 VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n",
108 sig->hash_alg);
109 } else {
110 VB2_DEBUG("HW crypto forbidden by preamble, using SW\n");
111 }
112
113 return vb2_digest_init(dc, sig->hash_alg);
114 }
115
vb2api_check_hash(struct vb2_context * ctx)116 int vb2api_check_hash(struct vb2_context *ctx)
117 {
118 struct vb2_shared_data *sd = vb2_get_sd(ctx);
119 struct vb2_digest_context *dc = (struct vb2_digest_context *)
120 (ctx->workbuf + sd->workbuf_hash_offset);
121 struct vb2_workbuf wb;
122
123 uint8_t *digest;
124 uint32_t digest_size = vb2_digest_size(dc->hash_alg);
125
126 const struct vb2_signature *sig;
127
128 int rv;
129
130 vb2_workbuf_from_ctx(ctx, &wb);
131
132 /* Get signature pointer */
133 if (!sd->hash_tag)
134 return VB2_ERROR_API_CHECK_HASH_TAG;
135 sig = (const struct vb2_signature *)(ctx->workbuf + sd->hash_tag);
136
137 /* Must have initialized hash digest work area */
138 if (!sd->workbuf_hash_size)
139 return VB2_ERROR_API_CHECK_HASH_WORKBUF;
140
141 /* Should have hashed the right amount of data */
142 if (sd->hash_remaining_size)
143 return VB2_ERROR_API_CHECK_HASH_SIZE;
144
145 /* Allocate the digest */
146 digest = vb2_workbuf_alloc(&wb, digest_size);
147 if (!digest)
148 return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
149
150 /* Finalize the digest */
151 if (dc->using_hwcrypto)
152 rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size);
153 else
154 rv = vb2_digest_finalize(dc, digest, digest_size);
155 if (rv)
156 return rv;
157
158 /* Compare with the signature */
159 if (vb2_safe_memcmp(digest, (const uint8_t *)sig + sig->sig_offset,
160 digest_size))
161 return VB2_ERROR_API_CHECK_HASH_SIG;
162
163 // TODO: the old check-hash function called vb2_fail() on any mismatch.
164 // I don't think it should do that; the caller should.
165
166 return VB2_SUCCESS;
167 }
168