xref: /aosp_15_r20/external/avb/libavb/avb_rsa.c (revision d289c2ba6de359471b23d594623b906876bc48a0)
1*d289c2baSAndroid Build Coastguard Worker /*
2*d289c2baSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*d289c2baSAndroid Build Coastguard Worker  *
4*d289c2baSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person
5*d289c2baSAndroid Build Coastguard Worker  * obtaining a copy of this software and associated documentation
6*d289c2baSAndroid Build Coastguard Worker  * files (the "Software"), to deal in the Software without
7*d289c2baSAndroid Build Coastguard Worker  * restriction, including without limitation the rights to use, copy,
8*d289c2baSAndroid Build Coastguard Worker  * modify, merge, publish, distribute, sublicense, and/or sell copies
9*d289c2baSAndroid Build Coastguard Worker  * of the Software, and to permit persons to whom the Software is
10*d289c2baSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
11*d289c2baSAndroid Build Coastguard Worker  *
12*d289c2baSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be
13*d289c2baSAndroid Build Coastguard Worker  * included in all copies or substantial portions of the Software.
14*d289c2baSAndroid Build Coastguard Worker  *
15*d289c2baSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*d289c2baSAndroid Build Coastguard Worker  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*d289c2baSAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*d289c2baSAndroid Build Coastguard Worker  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*d289c2baSAndroid Build Coastguard Worker  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*d289c2baSAndroid Build Coastguard Worker  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*d289c2baSAndroid Build Coastguard Worker  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*d289c2baSAndroid Build Coastguard Worker  * SOFTWARE.
23*d289c2baSAndroid Build Coastguard Worker  */
24*d289c2baSAndroid Build Coastguard Worker 
25*d289c2baSAndroid Build Coastguard Worker /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
26*d289c2baSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
27*d289c2baSAndroid Build Coastguard Worker  * found in the LICENSE file.
28*d289c2baSAndroid Build Coastguard Worker  */
29*d289c2baSAndroid Build Coastguard Worker 
30*d289c2baSAndroid Build Coastguard Worker /* Implementation of RSA signature verification which uses a pre-processed
31*d289c2baSAndroid Build Coastguard Worker  * key for computation. The code extends libmincrypt RSA verification code to
32*d289c2baSAndroid Build Coastguard Worker  * support multiple RSA key lengths and hash digest algorithms.
33*d289c2baSAndroid Build Coastguard Worker  */
34*d289c2baSAndroid Build Coastguard Worker 
35*d289c2baSAndroid Build Coastguard Worker #include "avb_rsa.h"
36*d289c2baSAndroid Build Coastguard Worker #include "avb_sha.h"
37*d289c2baSAndroid Build Coastguard Worker #include "avb_util.h"
38*d289c2baSAndroid Build Coastguard Worker #include "avb_vbmeta_image.h"
39*d289c2baSAndroid Build Coastguard Worker 
40*d289c2baSAndroid Build Coastguard Worker typedef struct IAvbKey {
41*d289c2baSAndroid Build Coastguard Worker   unsigned int len; /* Length of n[] in number of uint32_t */
42*d289c2baSAndroid Build Coastguard Worker   uint32_t n0inv;   /* -1 / n[0] mod 2^32 */
43*d289c2baSAndroid Build Coastguard Worker   uint32_t* n;      /* modulus as array (host-byte order) */
44*d289c2baSAndroid Build Coastguard Worker   uint32_t* rr;     /* R^2 as array (host-byte order) */
45*d289c2baSAndroid Build Coastguard Worker } IAvbKey;
46*d289c2baSAndroid Build Coastguard Worker 
iavb_parse_key_data(const uint8_t * data,size_t length)47*d289c2baSAndroid Build Coastguard Worker static IAvbKey* iavb_parse_key_data(const uint8_t* data, size_t length) {
48*d289c2baSAndroid Build Coastguard Worker   AvbRSAPublicKeyHeader h;
49*d289c2baSAndroid Build Coastguard Worker   IAvbKey* key = NULL;
50*d289c2baSAndroid Build Coastguard Worker   size_t expected_length;
51*d289c2baSAndroid Build Coastguard Worker   unsigned int i;
52*d289c2baSAndroid Build Coastguard Worker   const uint8_t* n;
53*d289c2baSAndroid Build Coastguard Worker   const uint8_t* rr;
54*d289c2baSAndroid Build Coastguard Worker 
55*d289c2baSAndroid Build Coastguard Worker   if (!avb_rsa_public_key_header_validate_and_byteswap(
56*d289c2baSAndroid Build Coastguard Worker           (const AvbRSAPublicKeyHeader*)data, &h)) {
57*d289c2baSAndroid Build Coastguard Worker     avb_error("Invalid key.\n");
58*d289c2baSAndroid Build Coastguard Worker     goto fail;
59*d289c2baSAndroid Build Coastguard Worker   }
60*d289c2baSAndroid Build Coastguard Worker 
61*d289c2baSAndroid Build Coastguard Worker   if (!(h.key_num_bits == 2048 || h.key_num_bits == 4096 ||
62*d289c2baSAndroid Build Coastguard Worker         h.key_num_bits == 8192)) {
63*d289c2baSAndroid Build Coastguard Worker     avb_error("Unexpected key length.\n");
64*d289c2baSAndroid Build Coastguard Worker     goto fail;
65*d289c2baSAndroid Build Coastguard Worker   }
66*d289c2baSAndroid Build Coastguard Worker 
67*d289c2baSAndroid Build Coastguard Worker   expected_length = sizeof(AvbRSAPublicKeyHeader) + 2 * h.key_num_bits / 8;
68*d289c2baSAndroid Build Coastguard Worker   if (length != expected_length) {
69*d289c2baSAndroid Build Coastguard Worker     avb_error("Key does not match expected length.\n");
70*d289c2baSAndroid Build Coastguard Worker     goto fail;
71*d289c2baSAndroid Build Coastguard Worker   }
72*d289c2baSAndroid Build Coastguard Worker 
73*d289c2baSAndroid Build Coastguard Worker   n = data + sizeof(AvbRSAPublicKeyHeader);
74*d289c2baSAndroid Build Coastguard Worker   rr = data + sizeof(AvbRSAPublicKeyHeader) + h.key_num_bits / 8;
75*d289c2baSAndroid Build Coastguard Worker 
76*d289c2baSAndroid Build Coastguard Worker   /* Store n and rr following the key header so we only have to do one
77*d289c2baSAndroid Build Coastguard Worker    * allocation.
78*d289c2baSAndroid Build Coastguard Worker    */
79*d289c2baSAndroid Build Coastguard Worker   key = (IAvbKey*)(avb_malloc(sizeof(IAvbKey) + 2 * h.key_num_bits / 8));
80*d289c2baSAndroid Build Coastguard Worker   if (key == NULL) {
81*d289c2baSAndroid Build Coastguard Worker     goto fail;
82*d289c2baSAndroid Build Coastguard Worker   }
83*d289c2baSAndroid Build Coastguard Worker 
84*d289c2baSAndroid Build Coastguard Worker   key->len = h.key_num_bits / 32;
85*d289c2baSAndroid Build Coastguard Worker   key->n0inv = h.n0inv;
86*d289c2baSAndroid Build Coastguard Worker   key->n = (uint32_t*)(key + 1); /* Skip ahead sizeof(IAvbKey) bytes. */
87*d289c2baSAndroid Build Coastguard Worker   key->rr = key->n + key->len;
88*d289c2baSAndroid Build Coastguard Worker 
89*d289c2baSAndroid Build Coastguard Worker   /* Crypto-code below (modpowF4() and friends) expects the key in
90*d289c2baSAndroid Build Coastguard Worker    * little-endian format (rather than the format we're storing the
91*d289c2baSAndroid Build Coastguard Worker    * key in), so convert it.
92*d289c2baSAndroid Build Coastguard Worker    */
93*d289c2baSAndroid Build Coastguard Worker   for (i = 0; i < key->len; i++) {
94*d289c2baSAndroid Build Coastguard Worker     key->n[i] = avb_be32toh(((uint32_t*)n)[key->len - i - 1]);
95*d289c2baSAndroid Build Coastguard Worker     key->rr[i] = avb_be32toh(((uint32_t*)rr)[key->len - i - 1]);
96*d289c2baSAndroid Build Coastguard Worker   }
97*d289c2baSAndroid Build Coastguard Worker   return key;
98*d289c2baSAndroid Build Coastguard Worker 
99*d289c2baSAndroid Build Coastguard Worker fail:
100*d289c2baSAndroid Build Coastguard Worker   if (key != NULL) {
101*d289c2baSAndroid Build Coastguard Worker     avb_free(key);
102*d289c2baSAndroid Build Coastguard Worker   }
103*d289c2baSAndroid Build Coastguard Worker   return NULL;
104*d289c2baSAndroid Build Coastguard Worker }
105*d289c2baSAndroid Build Coastguard Worker 
iavb_free_parsed_key(IAvbKey * key)106*d289c2baSAndroid Build Coastguard Worker static void iavb_free_parsed_key(IAvbKey* key) {
107*d289c2baSAndroid Build Coastguard Worker   avb_free(key);
108*d289c2baSAndroid Build Coastguard Worker }
109*d289c2baSAndroid Build Coastguard Worker 
110*d289c2baSAndroid Build Coastguard Worker /* a[] -= mod */
subM(const IAvbKey * key,uint32_t * a)111*d289c2baSAndroid Build Coastguard Worker static void subM(const IAvbKey* key, uint32_t* a) {
112*d289c2baSAndroid Build Coastguard Worker   int64_t A = 0;
113*d289c2baSAndroid Build Coastguard Worker   uint32_t i;
114*d289c2baSAndroid Build Coastguard Worker   for (i = 0; i < key->len; ++i) {
115*d289c2baSAndroid Build Coastguard Worker     A += (uint64_t)a[i] - key->n[i];
116*d289c2baSAndroid Build Coastguard Worker     a[i] = (uint32_t)A;
117*d289c2baSAndroid Build Coastguard Worker     A >>= 32;
118*d289c2baSAndroid Build Coastguard Worker   }
119*d289c2baSAndroid Build Coastguard Worker }
120*d289c2baSAndroid Build Coastguard Worker 
121*d289c2baSAndroid Build Coastguard Worker /* return a[] >= mod */
geM(const IAvbKey * key,uint32_t * a)122*d289c2baSAndroid Build Coastguard Worker static int geM(const IAvbKey* key, uint32_t* a) {
123*d289c2baSAndroid Build Coastguard Worker   uint32_t i;
124*d289c2baSAndroid Build Coastguard Worker   for (i = key->len; i;) {
125*d289c2baSAndroid Build Coastguard Worker     --i;
126*d289c2baSAndroid Build Coastguard Worker     if (a[i] < key->n[i]) {
127*d289c2baSAndroid Build Coastguard Worker       return 0;
128*d289c2baSAndroid Build Coastguard Worker     }
129*d289c2baSAndroid Build Coastguard Worker     if (a[i] > key->n[i]) {
130*d289c2baSAndroid Build Coastguard Worker       return 1;
131*d289c2baSAndroid Build Coastguard Worker     }
132*d289c2baSAndroid Build Coastguard Worker   }
133*d289c2baSAndroid Build Coastguard Worker   return 1; /* equal */
134*d289c2baSAndroid Build Coastguard Worker }
135*d289c2baSAndroid Build Coastguard Worker 
136*d289c2baSAndroid Build Coastguard Worker /* montgomery c[] += a * b[] / R % mod */
montMulAdd(const IAvbKey * key,uint32_t * c,const uint32_t a,const uint32_t * b)137*d289c2baSAndroid Build Coastguard Worker static void montMulAdd(const IAvbKey* key,
138*d289c2baSAndroid Build Coastguard Worker                        uint32_t* c,
139*d289c2baSAndroid Build Coastguard Worker                        const uint32_t a,
140*d289c2baSAndroid Build Coastguard Worker                        const uint32_t* b) {
141*d289c2baSAndroid Build Coastguard Worker   uint64_t A = (uint64_t)a * b[0] + c[0];
142*d289c2baSAndroid Build Coastguard Worker   uint32_t d0 = (uint32_t)A * key->n0inv;
143*d289c2baSAndroid Build Coastguard Worker   uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A;
144*d289c2baSAndroid Build Coastguard Worker   uint32_t i;
145*d289c2baSAndroid Build Coastguard Worker 
146*d289c2baSAndroid Build Coastguard Worker   for (i = 1; i < key->len; ++i) {
147*d289c2baSAndroid Build Coastguard Worker     A = (A >> 32) + (uint64_t)a * b[i] + c[i];
148*d289c2baSAndroid Build Coastguard Worker     B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A;
149*d289c2baSAndroid Build Coastguard Worker     c[i - 1] = (uint32_t)B;
150*d289c2baSAndroid Build Coastguard Worker   }
151*d289c2baSAndroid Build Coastguard Worker 
152*d289c2baSAndroid Build Coastguard Worker   A = (A >> 32) + (B >> 32);
153*d289c2baSAndroid Build Coastguard Worker 
154*d289c2baSAndroid Build Coastguard Worker   c[i - 1] = (uint32_t)A;
155*d289c2baSAndroid Build Coastguard Worker 
156*d289c2baSAndroid Build Coastguard Worker   if (A >> 32) {
157*d289c2baSAndroid Build Coastguard Worker     subM(key, c);
158*d289c2baSAndroid Build Coastguard Worker   }
159*d289c2baSAndroid Build Coastguard Worker }
160*d289c2baSAndroid Build Coastguard Worker 
161*d289c2baSAndroid Build Coastguard Worker /* montgomery c[] = a[] * b[] / R % mod */
montMul(const IAvbKey * key,uint32_t * c,uint32_t * a,uint32_t * b)162*d289c2baSAndroid Build Coastguard Worker static void montMul(const IAvbKey* key, uint32_t* c, uint32_t* a, uint32_t* b) {
163*d289c2baSAndroid Build Coastguard Worker   uint32_t i;
164*d289c2baSAndroid Build Coastguard Worker   for (i = 0; i < key->len; ++i) {
165*d289c2baSAndroid Build Coastguard Worker     c[i] = 0;
166*d289c2baSAndroid Build Coastguard Worker   }
167*d289c2baSAndroid Build Coastguard Worker   for (i = 0; i < key->len; ++i) {
168*d289c2baSAndroid Build Coastguard Worker     montMulAdd(key, c, a[i], b);
169*d289c2baSAndroid Build Coastguard Worker   }
170*d289c2baSAndroid Build Coastguard Worker }
171*d289c2baSAndroid Build Coastguard Worker 
172*d289c2baSAndroid Build Coastguard Worker /* In-place public exponentiation. (65537}
173*d289c2baSAndroid Build Coastguard Worker  * Input and output big-endian byte array in inout.
174*d289c2baSAndroid Build Coastguard Worker  */
modpowF4(const IAvbKey * key,uint8_t * inout)175*d289c2baSAndroid Build Coastguard Worker static void modpowF4(const IAvbKey* key, uint8_t* inout) {
176*d289c2baSAndroid Build Coastguard Worker   uint32_t* a = (uint32_t*)avb_malloc(key->len * sizeof(uint32_t));
177*d289c2baSAndroid Build Coastguard Worker   uint32_t* aR = (uint32_t*)avb_malloc(key->len * sizeof(uint32_t));
178*d289c2baSAndroid Build Coastguard Worker   uint32_t* aaR = (uint32_t*)avb_malloc(key->len * sizeof(uint32_t));
179*d289c2baSAndroid Build Coastguard Worker   if (a == NULL || aR == NULL || aaR == NULL) {
180*d289c2baSAndroid Build Coastguard Worker     goto out;
181*d289c2baSAndroid Build Coastguard Worker   }
182*d289c2baSAndroid Build Coastguard Worker 
183*d289c2baSAndroid Build Coastguard Worker   uint32_t* aaa = aaR; /* Re-use location. */
184*d289c2baSAndroid Build Coastguard Worker   int i;
185*d289c2baSAndroid Build Coastguard Worker 
186*d289c2baSAndroid Build Coastguard Worker   /* Convert from big endian byte array to little endian word array. */
187*d289c2baSAndroid Build Coastguard Worker   for (i = 0; i < (int)key->len; ++i) {
188*d289c2baSAndroid Build Coastguard Worker     uint32_t tmp = (inout[((key->len - 1 - i) * 4) + 0] << 24) |
189*d289c2baSAndroid Build Coastguard Worker                    (inout[((key->len - 1 - i) * 4) + 1] << 16) |
190*d289c2baSAndroid Build Coastguard Worker                    (inout[((key->len - 1 - i) * 4) + 2] << 8) |
191*d289c2baSAndroid Build Coastguard Worker                    (inout[((key->len - 1 - i) * 4) + 3] << 0);
192*d289c2baSAndroid Build Coastguard Worker     a[i] = tmp;
193*d289c2baSAndroid Build Coastguard Worker   }
194*d289c2baSAndroid Build Coastguard Worker 
195*d289c2baSAndroid Build Coastguard Worker   montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M   */
196*d289c2baSAndroid Build Coastguard Worker   for (i = 0; i < 16; i += 2) {
197*d289c2baSAndroid Build Coastguard Worker     montMul(key, aaR, aR, aR);  /* aaR = aR * aR / R mod M */
198*d289c2baSAndroid Build Coastguard Worker     montMul(key, aR, aaR, aaR); /* aR = aaR * aaR / R mod M */
199*d289c2baSAndroid Build Coastguard Worker   }
200*d289c2baSAndroid Build Coastguard Worker   montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */
201*d289c2baSAndroid Build Coastguard Worker 
202*d289c2baSAndroid Build Coastguard Worker   /* Make sure aaa < mod; aaa is at most 1x mod too large. */
203*d289c2baSAndroid Build Coastguard Worker   if (geM(key, aaa)) {
204*d289c2baSAndroid Build Coastguard Worker     subM(key, aaa);
205*d289c2baSAndroid Build Coastguard Worker   }
206*d289c2baSAndroid Build Coastguard Worker 
207*d289c2baSAndroid Build Coastguard Worker   /* Convert to bigendian byte array */
208*d289c2baSAndroid Build Coastguard Worker   for (i = (int)key->len - 1; i >= 0; --i) {
209*d289c2baSAndroid Build Coastguard Worker     uint32_t tmp = aaa[i];
210*d289c2baSAndroid Build Coastguard Worker     *inout++ = (uint8_t)(tmp >> 24);
211*d289c2baSAndroid Build Coastguard Worker     *inout++ = (uint8_t)(tmp >> 16);
212*d289c2baSAndroid Build Coastguard Worker     *inout++ = (uint8_t)(tmp >> 8);
213*d289c2baSAndroid Build Coastguard Worker     *inout++ = (uint8_t)(tmp >> 0);
214*d289c2baSAndroid Build Coastguard Worker   }
215*d289c2baSAndroid Build Coastguard Worker 
216*d289c2baSAndroid Build Coastguard Worker out:
217*d289c2baSAndroid Build Coastguard Worker   if (a != NULL) {
218*d289c2baSAndroid Build Coastguard Worker     avb_free(a);
219*d289c2baSAndroid Build Coastguard Worker   }
220*d289c2baSAndroid Build Coastguard Worker   if (aR != NULL) {
221*d289c2baSAndroid Build Coastguard Worker     avb_free(aR);
222*d289c2baSAndroid Build Coastguard Worker   }
223*d289c2baSAndroid Build Coastguard Worker   if (aaR != NULL) {
224*d289c2baSAndroid Build Coastguard Worker     avb_free(aaR);
225*d289c2baSAndroid Build Coastguard Worker   }
226*d289c2baSAndroid Build Coastguard Worker }
227*d289c2baSAndroid Build Coastguard Worker 
228*d289c2baSAndroid Build Coastguard Worker /* Verify a RSA PKCS1.5 signature against an expected hash.
229*d289c2baSAndroid Build Coastguard Worker  * Returns false on failure, true on success.
230*d289c2baSAndroid Build Coastguard Worker  */
avb_rsa_verify(const uint8_t * key,size_t key_num_bytes,const uint8_t * sig,size_t sig_num_bytes,const uint8_t * hash,size_t hash_num_bytes,const uint8_t * padding,size_t padding_num_bytes)231*d289c2baSAndroid Build Coastguard Worker bool avb_rsa_verify(const uint8_t* key,
232*d289c2baSAndroid Build Coastguard Worker                     size_t key_num_bytes,
233*d289c2baSAndroid Build Coastguard Worker                     const uint8_t* sig,
234*d289c2baSAndroid Build Coastguard Worker                     size_t sig_num_bytes,
235*d289c2baSAndroid Build Coastguard Worker                     const uint8_t* hash,
236*d289c2baSAndroid Build Coastguard Worker                     size_t hash_num_bytes,
237*d289c2baSAndroid Build Coastguard Worker                     const uint8_t* padding,
238*d289c2baSAndroid Build Coastguard Worker                     size_t padding_num_bytes) {
239*d289c2baSAndroid Build Coastguard Worker   uint8_t* buf = NULL;
240*d289c2baSAndroid Build Coastguard Worker   IAvbKey* parsed_key = NULL;
241*d289c2baSAndroid Build Coastguard Worker   bool success = false;
242*d289c2baSAndroid Build Coastguard Worker 
243*d289c2baSAndroid Build Coastguard Worker   if (key == NULL || sig == NULL || hash == NULL || padding == NULL) {
244*d289c2baSAndroid Build Coastguard Worker     avb_error("Invalid input.\n");
245*d289c2baSAndroid Build Coastguard Worker     goto out;
246*d289c2baSAndroid Build Coastguard Worker   }
247*d289c2baSAndroid Build Coastguard Worker 
248*d289c2baSAndroid Build Coastguard Worker   parsed_key = iavb_parse_key_data(key, key_num_bytes);
249*d289c2baSAndroid Build Coastguard Worker   if (parsed_key == NULL) {
250*d289c2baSAndroid Build Coastguard Worker     avb_error("Error parsing key.\n");
251*d289c2baSAndroid Build Coastguard Worker     goto out;
252*d289c2baSAndroid Build Coastguard Worker   }
253*d289c2baSAndroid Build Coastguard Worker 
254*d289c2baSAndroid Build Coastguard Worker   if (sig_num_bytes != (parsed_key->len * sizeof(uint32_t))) {
255*d289c2baSAndroid Build Coastguard Worker     avb_error("Signature length does not match key length.\n");
256*d289c2baSAndroid Build Coastguard Worker     goto out;
257*d289c2baSAndroid Build Coastguard Worker   }
258*d289c2baSAndroid Build Coastguard Worker 
259*d289c2baSAndroid Build Coastguard Worker   if (padding_num_bytes != sig_num_bytes - hash_num_bytes) {
260*d289c2baSAndroid Build Coastguard Worker     avb_error("Padding length does not match hash and signature lengths.\n");
261*d289c2baSAndroid Build Coastguard Worker     goto out;
262*d289c2baSAndroid Build Coastguard Worker   }
263*d289c2baSAndroid Build Coastguard Worker 
264*d289c2baSAndroid Build Coastguard Worker   buf = (uint8_t*)avb_malloc(sig_num_bytes);
265*d289c2baSAndroid Build Coastguard Worker   if (buf == NULL) {
266*d289c2baSAndroid Build Coastguard Worker     avb_error("Error allocating memory.\n");
267*d289c2baSAndroid Build Coastguard Worker     goto out;
268*d289c2baSAndroid Build Coastguard Worker   }
269*d289c2baSAndroid Build Coastguard Worker   avb_memcpy(buf, sig, sig_num_bytes);
270*d289c2baSAndroid Build Coastguard Worker 
271*d289c2baSAndroid Build Coastguard Worker   modpowF4(parsed_key, buf);
272*d289c2baSAndroid Build Coastguard Worker 
273*d289c2baSAndroid Build Coastguard Worker   /* Check padding bytes.
274*d289c2baSAndroid Build Coastguard Worker    *
275*d289c2baSAndroid Build Coastguard Worker    * Even though there are probably no timing issues here, we use
276*d289c2baSAndroid Build Coastguard Worker    * avb_safe_memcmp() just to be on the safe side.
277*d289c2baSAndroid Build Coastguard Worker    */
278*d289c2baSAndroid Build Coastguard Worker   if (avb_safe_memcmp(buf, padding, padding_num_bytes)) {
279*d289c2baSAndroid Build Coastguard Worker     avb_error("Padding check failed.\n");
280*d289c2baSAndroid Build Coastguard Worker     goto out;
281*d289c2baSAndroid Build Coastguard Worker   }
282*d289c2baSAndroid Build Coastguard Worker 
283*d289c2baSAndroid Build Coastguard Worker   /* Check hash. */
284*d289c2baSAndroid Build Coastguard Worker   if (avb_safe_memcmp(buf + padding_num_bytes, hash, hash_num_bytes)) {
285*d289c2baSAndroid Build Coastguard Worker     avb_error("Hash check failed.\n");
286*d289c2baSAndroid Build Coastguard Worker     goto out;
287*d289c2baSAndroid Build Coastguard Worker   }
288*d289c2baSAndroid Build Coastguard Worker 
289*d289c2baSAndroid Build Coastguard Worker   success = true;
290*d289c2baSAndroid Build Coastguard Worker 
291*d289c2baSAndroid Build Coastguard Worker out:
292*d289c2baSAndroid Build Coastguard Worker   if (parsed_key != NULL) {
293*d289c2baSAndroid Build Coastguard Worker     iavb_free_parsed_key(parsed_key);
294*d289c2baSAndroid Build Coastguard Worker   }
295*d289c2baSAndroid Build Coastguard Worker   if (buf != NULL) {
296*d289c2baSAndroid Build Coastguard Worker     avb_free(buf);
297*d289c2baSAndroid Build Coastguard Worker   }
298*d289c2baSAndroid Build Coastguard Worker   return success;
299*d289c2baSAndroid Build Coastguard Worker }
300