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 * Signature validation functions
6*8617a60dSAndroid Build Coastguard Worker */
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
9*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
10*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
11*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
12*8617a60dSAndroid Build Coastguard Worker #include "host_common21.h"
13*8617a60dSAndroid Build Coastguard Worker
vb21_common_desc(const void * buf)14*8617a60dSAndroid Build Coastguard Worker const char *vb21_common_desc(const void *buf)
15*8617a60dSAndroid Build Coastguard Worker {
16*8617a60dSAndroid Build Coastguard Worker const struct vb21_struct_common *c = buf;
17*8617a60dSAndroid Build Coastguard Worker
18*8617a60dSAndroid Build Coastguard Worker return c->desc_size ? (const char *)c + c->fixed_size : "";
19*8617a60dSAndroid Build Coastguard Worker }
20*8617a60dSAndroid Build Coastguard Worker
vb21_verify_common_header(const void * parent,uint32_t parent_size)21*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb21_verify_common_header(const void *parent, uint32_t parent_size)
22*8617a60dSAndroid Build Coastguard Worker {
23*8617a60dSAndroid Build Coastguard Worker const struct vb21_struct_common *c = parent;
24*8617a60dSAndroid Build Coastguard Worker
25*8617a60dSAndroid Build Coastguard Worker /* Parent buffer size must be at least the claimed total size */
26*8617a60dSAndroid Build Coastguard Worker if (parent_size < c->total_size)
27*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_TOTAL_SIZE;
28*8617a60dSAndroid Build Coastguard Worker
29*8617a60dSAndroid Build Coastguard Worker /*
30*8617a60dSAndroid Build Coastguard Worker * And big enough for the fixed size, which itself must be at least as
31*8617a60dSAndroid Build Coastguard Worker * big as the common struct header.
32*8617a60dSAndroid Build Coastguard Worker */
33*8617a60dSAndroid Build Coastguard Worker if (c->total_size < c->fixed_size || c->fixed_size < sizeof(*c))
34*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_FIXED_SIZE;
35*8617a60dSAndroid Build Coastguard Worker
36*8617a60dSAndroid Build Coastguard Worker /* Make sure sizes are all multiples of 32 bits */
37*8617a60dSAndroid Build Coastguard Worker if (!vb2_aligned(c->total_size, sizeof(uint32_t)))
38*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_TOTAL_UNALIGNED;
39*8617a60dSAndroid Build Coastguard Worker if (!vb2_aligned(c->fixed_size, sizeof(uint32_t)))
40*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_FIXED_UNALIGNED;
41*8617a60dSAndroid Build Coastguard Worker if (!vb2_aligned(c->desc_size, sizeof(uint32_t)))
42*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_DESC_UNALIGNED;
43*8617a60dSAndroid Build Coastguard Worker
44*8617a60dSAndroid Build Coastguard Worker /* Check description */
45*8617a60dSAndroid Build Coastguard Worker if (c->desc_size > 0) {
46*8617a60dSAndroid Build Coastguard Worker /* Make sure description fits and doesn't wrap */
47*8617a60dSAndroid Build Coastguard Worker if (c->fixed_size + c->desc_size < c->fixed_size)
48*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_DESC_WRAPS;
49*8617a60dSAndroid Build Coastguard Worker if (c->fixed_size + c->desc_size > c->total_size)
50*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_DESC_SIZE;
51*8617a60dSAndroid Build Coastguard Worker
52*8617a60dSAndroid Build Coastguard Worker /* Description must be null-terminated */
53*8617a60dSAndroid Build Coastguard Worker if (vb21_common_desc(c)[c->desc_size - 1] != 0)
54*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_DESC_TERMINATOR;
55*8617a60dSAndroid Build Coastguard Worker }
56*8617a60dSAndroid Build Coastguard Worker
57*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
58*8617a60dSAndroid Build Coastguard Worker }
59*8617a60dSAndroid Build Coastguard Worker
vb21_verify_common_member(const void * parent,uint32_t * min_offset,uint32_t member_offset,uint32_t member_size)60*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb21_verify_common_member(const void *parent, uint32_t *min_offset,
61*8617a60dSAndroid Build Coastguard Worker uint32_t member_offset,
62*8617a60dSAndroid Build Coastguard Worker uint32_t member_size)
63*8617a60dSAndroid Build Coastguard Worker {
64*8617a60dSAndroid Build Coastguard Worker const struct vb21_struct_common *c = parent;
65*8617a60dSAndroid Build Coastguard Worker uint32_t member_end = member_offset + member_size;
66*8617a60dSAndroid Build Coastguard Worker
67*8617a60dSAndroid Build Coastguard Worker /* Make sure member doesn't wrap */
68*8617a60dSAndroid Build Coastguard Worker if (member_end < member_offset)
69*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_MEMBER_WRAPS;
70*8617a60dSAndroid Build Coastguard Worker
71*8617a60dSAndroid Build Coastguard Worker /* Member offset and size must be 32-bit aligned */
72*8617a60dSAndroid Build Coastguard Worker if (!vb2_aligned(member_offset, sizeof(uint32_t)) ||
73*8617a60dSAndroid Build Coastguard Worker !vb2_aligned(member_size, sizeof(uint32_t)))
74*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_MEMBER_UNALIGNED;
75*8617a60dSAndroid Build Coastguard Worker
76*8617a60dSAndroid Build Coastguard Worker /* Initialize minimum offset if necessary */
77*8617a60dSAndroid Build Coastguard Worker if (!*min_offset)
78*8617a60dSAndroid Build Coastguard Worker *min_offset = c->fixed_size + c->desc_size;
79*8617a60dSAndroid Build Coastguard Worker
80*8617a60dSAndroid Build Coastguard Worker /* Member must be after minimum offset */
81*8617a60dSAndroid Build Coastguard Worker if (member_offset < *min_offset)
82*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_MEMBER_OVERLAP;
83*8617a60dSAndroid Build Coastguard Worker
84*8617a60dSAndroid Build Coastguard Worker /* Member must end before total size */
85*8617a60dSAndroid Build Coastguard Worker if (member_end > c->total_size)
86*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_COMMON_MEMBER_SIZE;
87*8617a60dSAndroid Build Coastguard Worker
88*8617a60dSAndroid Build Coastguard Worker /* Update minimum offset for subsequent checks */
89*8617a60dSAndroid Build Coastguard Worker *min_offset = member_end;
90*8617a60dSAndroid Build Coastguard Worker
91*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
92*8617a60dSAndroid Build Coastguard Worker }
93*8617a60dSAndroid Build Coastguard Worker
vb21_verify_common_subobject(const void * parent,uint32_t * min_offset,uint32_t member_offset)94*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb21_verify_common_subobject(const void *parent,
95*8617a60dSAndroid Build Coastguard Worker uint32_t *min_offset,
96*8617a60dSAndroid Build Coastguard Worker uint32_t member_offset)
97*8617a60dSAndroid Build Coastguard Worker {
98*8617a60dSAndroid Build Coastguard Worker const struct vb21_struct_common *p = parent;
99*8617a60dSAndroid Build Coastguard Worker const struct vb21_struct_common *m =
100*8617a60dSAndroid Build Coastguard Worker (const struct vb21_struct_common *)
101*8617a60dSAndroid Build Coastguard Worker ((const uint8_t *)parent + member_offset);
102*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
103*8617a60dSAndroid Build Coastguard Worker
104*8617a60dSAndroid Build Coastguard Worker /*
105*8617a60dSAndroid Build Coastguard Worker * Verify the parent has space at the member offset for the common
106*8617a60dSAndroid Build Coastguard Worker * header.
107*8617a60dSAndroid Build Coastguard Worker */
108*8617a60dSAndroid Build Coastguard Worker rv = vb21_verify_common_member(parent, min_offset, member_offset,
109*8617a60dSAndroid Build Coastguard Worker sizeof(*m));
110*8617a60dSAndroid Build Coastguard Worker if (rv)
111*8617a60dSAndroid Build Coastguard Worker return rv;
112*8617a60dSAndroid Build Coastguard Worker
113*8617a60dSAndroid Build Coastguard Worker /*
114*8617a60dSAndroid Build Coastguard Worker * Now it's safe to look at the member's header, and verify any
115*8617a60dSAndroid Build Coastguard Worker * additional data for the object past its common header fits in the
116*8617a60dSAndroid Build Coastguard Worker * parent.
117*8617a60dSAndroid Build Coastguard Worker */
118*8617a60dSAndroid Build Coastguard Worker rv = vb21_verify_common_header(m, p->total_size - member_offset);
119*8617a60dSAndroid Build Coastguard Worker if (rv)
120*8617a60dSAndroid Build Coastguard Worker return rv;
121*8617a60dSAndroid Build Coastguard Worker
122*8617a60dSAndroid Build Coastguard Worker /* Advance the min offset to the end of the subobject */
123*8617a60dSAndroid Build Coastguard Worker *min_offset = member_offset + m->total_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_sig_size(enum vb2_signature_algorithm sig_alg,enum vb2_hash_algorithm hash_alg)128*8617a60dSAndroid Build Coastguard Worker uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg,
129*8617a60dSAndroid Build Coastguard Worker enum vb2_hash_algorithm hash_alg)
130*8617a60dSAndroid Build Coastguard Worker {
131*8617a60dSAndroid Build Coastguard Worker uint32_t digest_size = vb2_digest_size(hash_alg);
132*8617a60dSAndroid Build Coastguard Worker
133*8617a60dSAndroid Build Coastguard Worker /* Fail if we don't support the hash algorithm */
134*8617a60dSAndroid Build Coastguard Worker if (!digest_size)
135*8617a60dSAndroid Build Coastguard Worker return 0;
136*8617a60dSAndroid Build Coastguard Worker
137*8617a60dSAndroid Build Coastguard Worker /* Handle unsigned hashes */
138*8617a60dSAndroid Build Coastguard Worker if (sig_alg == VB2_SIG_NONE)
139*8617a60dSAndroid Build Coastguard Worker return digest_size;
140*8617a60dSAndroid Build Coastguard Worker
141*8617a60dSAndroid Build Coastguard Worker return vb2_rsa_sig_size(sig_alg);
142*8617a60dSAndroid Build Coastguard Worker }
143*8617a60dSAndroid Build Coastguard Worker
vb2_hash_id(enum vb2_hash_algorithm hash_alg)144*8617a60dSAndroid Build Coastguard Worker const struct vb2_id *vb2_hash_id(enum vb2_hash_algorithm hash_alg)
145*8617a60dSAndroid Build Coastguard Worker {
146*8617a60dSAndroid Build Coastguard Worker switch(hash_alg) {
147*8617a60dSAndroid Build Coastguard Worker #ifdef VB2_SUPPORT_SHA1
148*8617a60dSAndroid Build Coastguard Worker case VB2_HASH_SHA1:
149*8617a60dSAndroid Build Coastguard Worker {
150*8617a60dSAndroid Build Coastguard Worker static const struct vb2_id id = VB2_ID_NONE_SHA1;
151*8617a60dSAndroid Build Coastguard Worker return &id;
152*8617a60dSAndroid Build Coastguard Worker }
153*8617a60dSAndroid Build Coastguard Worker #endif
154*8617a60dSAndroid Build Coastguard Worker #ifdef VB2_SUPPORT_SHA256
155*8617a60dSAndroid Build Coastguard Worker case VB2_HASH_SHA256:
156*8617a60dSAndroid Build Coastguard Worker {
157*8617a60dSAndroid Build Coastguard Worker static const struct vb2_id id = VB2_ID_NONE_SHA256;
158*8617a60dSAndroid Build Coastguard Worker return &id;
159*8617a60dSAndroid Build Coastguard Worker }
160*8617a60dSAndroid Build Coastguard Worker #endif
161*8617a60dSAndroid Build Coastguard Worker #ifdef VB2_SUPPORT_SHA512
162*8617a60dSAndroid Build Coastguard Worker case VB2_HASH_SHA512:
163*8617a60dSAndroid Build Coastguard Worker {
164*8617a60dSAndroid Build Coastguard Worker static const struct vb2_id id = VB2_ID_NONE_SHA512;
165*8617a60dSAndroid Build Coastguard Worker return &id;
166*8617a60dSAndroid Build Coastguard Worker }
167*8617a60dSAndroid Build Coastguard Worker #endif
168*8617a60dSAndroid Build Coastguard Worker default:
169*8617a60dSAndroid Build Coastguard Worker return NULL;
170*8617a60dSAndroid Build Coastguard Worker }
171*8617a60dSAndroid Build Coastguard Worker }
172*8617a60dSAndroid Build Coastguard Worker
vb21_verify_signature(const struct vb21_signature * sig,uint32_t size)173*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb21_verify_signature(const struct vb21_signature *sig,
174*8617a60dSAndroid Build Coastguard Worker uint32_t size)
175*8617a60dSAndroid Build Coastguard Worker {
176*8617a60dSAndroid Build Coastguard Worker uint32_t min_offset = 0;
177*8617a60dSAndroid Build Coastguard Worker uint32_t expect_sig_size;
178*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
179*8617a60dSAndroid Build Coastguard Worker
180*8617a60dSAndroid Build Coastguard Worker /* Check magic number */
181*8617a60dSAndroid Build Coastguard Worker if (sig->c.magic != VB21_MAGIC_SIGNATURE)
182*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_SIG_MAGIC;
183*8617a60dSAndroid Build Coastguard Worker
184*8617a60dSAndroid Build Coastguard Worker /* Make sure common header is good */
185*8617a60dSAndroid Build Coastguard Worker rv = vb21_verify_common_header(sig, size);
186*8617a60dSAndroid Build Coastguard Worker if (rv)
187*8617a60dSAndroid Build Coastguard Worker return rv;
188*8617a60dSAndroid Build Coastguard Worker
189*8617a60dSAndroid Build Coastguard Worker /*
190*8617a60dSAndroid Build Coastguard Worker * Check for compatible version. No need to check minor version, since
191*8617a60dSAndroid Build Coastguard Worker * that's compatible across readers matching the major version, and we
192*8617a60dSAndroid Build Coastguard Worker * haven't added any new fields.
193*8617a60dSAndroid Build Coastguard Worker */
194*8617a60dSAndroid Build Coastguard Worker if (sig->c.struct_version_major != VB21_SIGNATURE_VERSION_MAJOR)
195*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_SIG_VERSION;
196*8617a60dSAndroid Build Coastguard Worker
197*8617a60dSAndroid Build Coastguard Worker /* Make sure header is big enough for signature */
198*8617a60dSAndroid Build Coastguard Worker if (sig->c.fixed_size < sizeof(*sig))
199*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_SIG_HEADER_SIZE;
200*8617a60dSAndroid Build Coastguard Worker
201*8617a60dSAndroid Build Coastguard Worker /* Make sure signature data is inside */
202*8617a60dSAndroid Build Coastguard Worker rv = vb21_verify_common_member(sig, &min_offset,
203*8617a60dSAndroid Build Coastguard Worker sig->sig_offset, sig->sig_size);
204*8617a60dSAndroid Build Coastguard Worker if (rv)
205*8617a60dSAndroid Build Coastguard Worker return rv;
206*8617a60dSAndroid Build Coastguard Worker
207*8617a60dSAndroid Build Coastguard Worker /* Make sure signature size is correct for the algorithm */
208*8617a60dSAndroid Build Coastguard Worker expect_sig_size = vb2_sig_size(sig->sig_alg, sig->hash_alg);
209*8617a60dSAndroid Build Coastguard Worker if (!expect_sig_size)
210*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_SIG_ALGORITHM;
211*8617a60dSAndroid Build Coastguard Worker if (sig->sig_size != expect_sig_size)
212*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_SIG_SIZE;
213*8617a60dSAndroid Build Coastguard Worker
214*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
215*8617a60dSAndroid Build Coastguard Worker }
216*8617a60dSAndroid Build Coastguard Worker
217*8617a60dSAndroid Build Coastguard Worker /**
218*8617a60dSAndroid Build Coastguard Worker * Return the signature data for a signature
219*8617a60dSAndroid Build Coastguard Worker */
vb21_signature_data(struct vb21_signature * sig)220*8617a60dSAndroid Build Coastguard Worker static uint8_t *vb21_signature_data(struct vb21_signature *sig)
221*8617a60dSAndroid Build Coastguard Worker {
222*8617a60dSAndroid Build Coastguard Worker return (uint8_t *)sig + sig->sig_offset;
223*8617a60dSAndroid Build Coastguard Worker }
224*8617a60dSAndroid Build Coastguard Worker
vb21_verify_digest(const struct vb2_public_key * key,struct vb21_signature * sig,const uint8_t * digest,const struct vb2_workbuf * wb)225*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb21_verify_digest(const struct vb2_public_key *key,
226*8617a60dSAndroid Build Coastguard Worker struct vb21_signature *sig,
227*8617a60dSAndroid Build Coastguard Worker const uint8_t *digest,
228*8617a60dSAndroid Build Coastguard Worker const struct vb2_workbuf *wb)
229*8617a60dSAndroid Build Coastguard Worker {
230*8617a60dSAndroid Build Coastguard Worker uint32_t key_sig_size = vb2_sig_size(key->sig_alg, key->hash_alg);
231*8617a60dSAndroid Build Coastguard Worker
232*8617a60dSAndroid Build Coastguard Worker /* If we can't figure out the signature size, key algorithm was bad */
233*8617a60dSAndroid Build Coastguard Worker if (!key_sig_size)
234*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_ALGORITHM;
235*8617a60dSAndroid Build Coastguard Worker
236*8617a60dSAndroid Build Coastguard Worker /* Make sure the signature and key algorithms match */
237*8617a60dSAndroid Build Coastguard Worker if (key->sig_alg != sig->sig_alg || key->hash_alg != sig->hash_alg)
238*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_ALGORITHM_MISMATCH;
239*8617a60dSAndroid Build Coastguard Worker
240*8617a60dSAndroid Build Coastguard Worker if (sig->sig_size != key_sig_size)
241*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_SIG_SIZE;
242*8617a60dSAndroid Build Coastguard Worker
243*8617a60dSAndroid Build Coastguard Worker if (key->sig_alg == VB2_SIG_NONE) {
244*8617a60dSAndroid Build Coastguard Worker /* Bare hash */
245*8617a60dSAndroid Build Coastguard Worker if (vb2_safe_memcmp(vb21_signature_data(sig),
246*8617a60dSAndroid Build Coastguard Worker digest, key_sig_size))
247*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_VERIFY_DIGEST;
248*8617a60dSAndroid Build Coastguard Worker
249*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
250*8617a60dSAndroid Build Coastguard Worker } else {
251*8617a60dSAndroid Build Coastguard Worker /* RSA-signed digest */
252*8617a60dSAndroid Build Coastguard Worker return vb2_rsa_verify_digest(key,
253*8617a60dSAndroid Build Coastguard Worker vb21_signature_data(sig),
254*8617a60dSAndroid Build Coastguard Worker digest, wb);
255*8617a60dSAndroid Build Coastguard Worker }
256*8617a60dSAndroid Build Coastguard Worker }
257*8617a60dSAndroid Build Coastguard Worker
vb21_verify_data(const void * data,uint32_t size,struct vb21_signature * sig,const struct vb2_public_key * key,const struct vb2_workbuf * wb)258*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb21_verify_data(const void *data, uint32_t size,
259*8617a60dSAndroid Build Coastguard Worker struct vb21_signature *sig,
260*8617a60dSAndroid Build Coastguard Worker const struct vb2_public_key *key,
261*8617a60dSAndroid Build Coastguard Worker const struct vb2_workbuf *wb)
262*8617a60dSAndroid Build Coastguard Worker {
263*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wblocal = *wb;
264*8617a60dSAndroid Build Coastguard Worker struct vb2_digest_context *dc;
265*8617a60dSAndroid Build Coastguard Worker uint8_t *digest;
266*8617a60dSAndroid Build Coastguard Worker uint32_t digest_size;
267*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
268*8617a60dSAndroid Build Coastguard Worker
269*8617a60dSAndroid Build Coastguard Worker if (sig->data_size != size) {
270*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Wrong amount of data signed.\n");
271*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_SIZE;
272*8617a60dSAndroid Build Coastguard Worker }
273*8617a60dSAndroid Build Coastguard Worker
274*8617a60dSAndroid Build Coastguard Worker /* Digest goes at start of work buffer */
275*8617a60dSAndroid Build Coastguard Worker digest_size = vb2_digest_size(key->hash_alg);
276*8617a60dSAndroid Build Coastguard Worker if (!digest_size)
277*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_DIGEST_SIZE;
278*8617a60dSAndroid Build Coastguard Worker
279*8617a60dSAndroid Build Coastguard Worker digest = vb2_workbuf_alloc(&wblocal, digest_size);
280*8617a60dSAndroid Build Coastguard Worker if (!digest)
281*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_WORKBUF_DIGEST;
282*8617a60dSAndroid Build Coastguard Worker
283*8617a60dSAndroid Build Coastguard Worker /* Hashing requires temp space for the context */
284*8617a60dSAndroid Build Coastguard Worker dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
285*8617a60dSAndroid Build Coastguard Worker if (!dc)
286*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_VDATA_WORKBUF_HASHING;
287*8617a60dSAndroid Build Coastguard Worker
288*8617a60dSAndroid Build Coastguard Worker rv = vb2_digest_init(dc, false, key->hash_alg, 0);
289*8617a60dSAndroid Build Coastguard Worker if (rv)
290*8617a60dSAndroid Build Coastguard Worker return rv;
291*8617a60dSAndroid Build Coastguard Worker
292*8617a60dSAndroid Build Coastguard Worker rv = vb2_digest_extend(dc, data, size);
293*8617a60dSAndroid Build Coastguard Worker if (rv)
294*8617a60dSAndroid Build Coastguard Worker return rv;
295*8617a60dSAndroid Build Coastguard Worker
296*8617a60dSAndroid Build Coastguard Worker rv = vb2_digest_finalize(dc, digest, digest_size);
297*8617a60dSAndroid Build Coastguard Worker if (rv)
298*8617a60dSAndroid Build Coastguard Worker return rv;
299*8617a60dSAndroid Build Coastguard Worker
300*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_free(&wblocal, sizeof(*dc));
301*8617a60dSAndroid Build Coastguard Worker
302*8617a60dSAndroid Build Coastguard Worker return vb21_verify_digest(key, sig, digest, &wblocal);
303*8617a60dSAndroid Build Coastguard Worker }
304