1 /*
2  * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <string.h>
7 #include "hal/ecdsa_hal.h"
8 #include "esp_crypto_lock.h"
9 #include "esp_efuse.h"
10 #include "mbedtls/ecp.h"
11 #include "mbedtls/error.h"
12 #include "mbedtls/ecdsa.h"
13 #include "mbedtls/asn1.h"
14 #include "mbedtls/asn1write.h"
15 #include "mbedtls/platform_util.h"
16 #include "esp_private/periph_ctrl.h"
17 #include "ecdsa/ecdsa_alt.h"
18 #include "hal/ecc_ll.h"
19 
20 #define ECDSA_KEY_MAGIC             (short) 0xECD5A
21 #define ECDSA_SHA_LEN               32
22 #define MAX_ECDSA_COMPONENT_LEN     32
23 
24 #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
25 #include "esp_timer.h"
26 
27 #if CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH
28 /*
29  * This is the maximum time (in us) required for performing 1 ECDSA signature
30  * in this configuration along some additional margin considerations
31  */
32 #define ECDSA_MAX_SIG_TIME 24000
33 #else /* CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH */
34 #define ECDSA_MAX_SIG_TIME  17500
35 #endif /* !CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH */
36 
37 #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM
38 #define DUMMY_OP_COUNT ECDSA_SIGN_MAX_DUMMY_OP_COUNT
39 #else /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM */
40 #define DUMMY_OP_COUNT 0
41 #endif /* !CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM */
42 #define ECDSA_CM_FIXED_SIG_TIME ECDSA_MAX_SIG_TIME * (DUMMY_OP_COUNT + 1)
43 
44 #endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM */
45 
46 __attribute__((unused)) static const char *TAG = "ecdsa_alt";
47 
esp_ecdsa_acquire_hardware(void)48 static void esp_ecdsa_acquire_hardware(void)
49 {
50     esp_crypto_ecdsa_lock_acquire();
51 
52     periph_module_enable(PERIPH_ECDSA_MODULE);
53     ecc_ll_power_up();
54 }
55 
esp_ecdsa_release_hardware(void)56 static void esp_ecdsa_release_hardware(void)
57 {
58     periph_module_disable(PERIPH_ECDSA_MODULE);
59     ecc_ll_power_down();
60 
61     esp_crypto_ecdsa_lock_release();
62 }
63 
ecdsa_be_to_le(const uint8_t * be_point,uint8_t * le_point,uint8_t len)64 static void ecdsa_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len)
65 {
66     /* When the size is 24 bytes, it should be padded with 0 bytes*/
67     memset(le_point, 0x0, 32);
68 
69     for(int i = 0; i < len; i++) {
70         le_point[i] = be_point[len - i - 1];
71     }
72 }
73 
74 #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
esp_ecdsa_privkey_load_mpi(mbedtls_mpi * key,int efuse_blk)75 int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk)
76 {
77     if (!key) {
78         ESP_LOGE(TAG, "Invalid memory");
79         return -1;
80     }
81 
82     if (efuse_blk < EFUSE_BLK_KEY0 || efuse_blk >= EFUSE_BLK_KEY_MAX) {
83         ESP_LOGE(TAG, "Invalid efuse block");
84         return -1;
85     }
86 
87     mbedtls_mpi_init(key);
88 
89     /* We use the mbedtls_mpi struct to pass our own context to hardware ECDSA peripheral
90      * MPI struct expects `s` to be either 1 or -1, by setting it to 0xECD5A, we ensure that it does
91      * not collide with a valid MPI. This is done to differentiate between using the private key stored in efuse
92      * or using the private key provided by software
93      *
94      * `n` is used to store the efuse block which should be used as key
95      */
96     key->MBEDTLS_PRIVATE(s) = ECDSA_KEY_MAGIC;
97     key->MBEDTLS_PRIVATE(n) = efuse_blk;
98     key->MBEDTLS_PRIVATE(p) = NULL;
99 
100     return 0;
101 }
102 
esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context * key_ctx,int efuse_blk)103 int esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context *key_ctx, int efuse_blk)
104 {
105     const mbedtls_pk_info_t *pk_info;
106     mbedtls_ecp_keypair *keypair;
107 
108     if (!key_ctx) {
109         ESP_LOGE(TAG, "Invalid memory");
110         return -1;
111     }
112 
113     if (efuse_blk < EFUSE_BLK_KEY0 || efuse_blk >= EFUSE_BLK_KEY_MAX) {
114         ESP_LOGE(TAG, "Invalid efuse block");
115         return -1;
116     }
117 
118     mbedtls_pk_init(key_ctx);
119     pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
120     mbedtls_pk_setup(key_ctx, pk_info);
121     keypair = mbedtls_pk_ec(*key_ctx);
122 
123     return esp_ecdsa_privkey_load_mpi(&(keypair->MBEDTLS_PRIVATE(d)), efuse_blk);
124 }
125 
esp_ecdsa_sign(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * msg,size_t msg_len)126 static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s,
127                           const mbedtls_mpi *d, const unsigned char* msg, size_t msg_len)
128 {
129     ecdsa_curve_t curve;
130     esp_efuse_block_t blk;
131     uint16_t len;
132     uint8_t zeroes[MAX_ECDSA_COMPONENT_LEN] = {0};
133     uint8_t sha_le[ECDSA_SHA_LEN];
134     uint8_t r_le[MAX_ECDSA_COMPONENT_LEN];
135     uint8_t s_le[MAX_ECDSA_COMPONENT_LEN];
136 
137     if (!grp || !r || !s || !d || !msg) {
138         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
139     }
140 
141     if (msg_len != ECDSA_SHA_LEN) {
142         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
143     }
144 
145     if (grp->id == MBEDTLS_ECP_DP_SECP192R1) {
146         curve = ECDSA_CURVE_SECP192R1;
147         len = 24;
148     } else if (grp->id == MBEDTLS_ECP_DP_SECP256R1) {
149         curve = ECDSA_CURVE_SECP256R1;
150         len = 32;
151     } else {
152         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
153     }
154 
155     if (!esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, &blk)) {
156         ESP_LOGE(TAG, "No efuse block with purpose ECDSA_KEY found");
157         return MBEDTLS_ERR_ECP_INVALID_KEY;
158     }
159 
160     ecdsa_be_to_le(msg, sha_le, len);
161 
162     esp_ecdsa_acquire_hardware();
163 
164     bool process_again = false;
165 
166     do {
167         ecdsa_hal_config_t conf = {
168             .mode = ECDSA_MODE_SIGN_GEN,
169             .curve = curve,
170             .sha_mode = ECDSA_Z_USER_PROVIDED,
171             .efuse_key_blk = d->MBEDTLS_PRIVATE(n),
172         };
173 
174 #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
175         uint64_t sig_time = esp_timer_get_time();
176 #endif
177         ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len);
178 #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM
179         sig_time = esp_timer_get_time() - sig_time;
180         if (sig_time < ECDSA_CM_FIXED_SIG_TIME) {
181             esp_rom_delay_us(ECDSA_CM_FIXED_SIG_TIME - sig_time);
182         }
183 #endif
184         process_again = !ecdsa_hal_get_operation_result()
185                         || !memcmp(r_le, zeroes, len)
186                         || !memcmp(s_le, zeroes, len);
187 
188     } while (process_again);
189 
190     esp_ecdsa_release_hardware();
191 
192     mbedtls_mpi_read_binary_le(r, r_le, len);
193     mbedtls_mpi_read_binary_le(s, s_le, len);
194 
195     return 0;
196 }
197 
198 /*
199  * Compute ECDSA signature of a hashed message;
200  */
201 extern int __real_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
202                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
203                        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
204 
205 int __wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
206                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
207                        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
208 
__wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)209 int __wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
210                        const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
211                        int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
212 {
213     /*
214      * Check `d` whether it contains the hardware key
215      */
216     if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
217         // Use hardware ECDSA peripheral
218         return esp_ecdsa_sign(grp, r, s, d, buf, blen);
219     } else {
220         return __real_mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, f_rng, p_rng);
221     }
222 }
223 
224 extern int __real_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
225                                           const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
226                                           int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
227                                           int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind,
228                                           mbedtls_ecdsa_restart_ctx *rs_ctx);
229 
230 int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
231                                           const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
232                                           int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
233                                           int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind,
234                                           mbedtls_ecdsa_restart_ctx *rs_ctx);
235 
__wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group * grp,mbedtls_mpi * r,mbedtls_mpi * s,const mbedtls_mpi * d,const unsigned char * buf,size_t blen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int (* f_rng_blind)(void *,unsigned char *,size_t),void * p_rng_blind,mbedtls_ecdsa_restart_ctx * rs_ctx)236 int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
237                                           const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
238                                           int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
239                                           int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind,
240                                           mbedtls_ecdsa_restart_ctx *rs_ctx)
241 {
242     /*
243      * Check `d` whether it contains the hardware key
244      */
245     if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
246         // Use hardware ECDSA peripheral
247         return esp_ecdsa_sign(grp, r, s, d, buf, blen);
248     } else {
249         return __real_mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, f_rng, p_rng, f_rng_blind, p_rng_blind, rs_ctx);
250     }
251 }
252 
253 int __real_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
254                                               mbedtls_md_type_t md_alg,
255                                               const unsigned char *hash, size_t hlen,
256                                               unsigned char *sig, size_t sig_size, size_t *slen,
257                                               int (*f_rng)(void *, unsigned char *, size_t),
258                                               void *p_rng,
259                                               mbedtls_ecdsa_restart_ctx *rs_ctx);
260 
261 int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
262                                               mbedtls_md_type_t md_alg,
263                                               const unsigned char *hash, size_t hlen,
264                                               unsigned char *sig, size_t sig_size, size_t *slen,
265                                               int (*f_rng)(void *, unsigned char *, size_t),
266                                               void *p_rng,
267                                               mbedtls_ecdsa_restart_ctx *rs_ctx);
268 
269 /*
270  * Convert a signature (given by context) to ASN.1
271  */
ecdsa_signature_to_asn1(const mbedtls_mpi * r,const mbedtls_mpi * s,unsigned char * sig,size_t sig_size,size_t * slen)272 static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s,
273                                    unsigned char *sig, size_t sig_size,
274                                    size_t *slen)
275 {
276     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
277     unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 };
278     // Setting the pointer p to the end of the buffer as the functions used afterwards write in backwards manner in the given buffer.
279     unsigned char *p = buf + sizeof(buf);
280     size_t len = 0;
281 
282     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s));
283     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r));
284 
285     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
286     MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
287                                                      MBEDTLS_ASN1_CONSTRUCTED |
288                                                      MBEDTLS_ASN1_SEQUENCE));
289 
290     if (len > sig_size) {
291         return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
292     }
293 
294     memcpy(sig, p, len);
295     *slen = len;
296 
297     return 0;
298 }
299 
__wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hlen,unsigned char * sig,size_t sig_size,size_t * slen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecdsa_restart_ctx * rs_ctx)300 int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
301                                               mbedtls_md_type_t md_alg,
302                                               const unsigned char *hash, size_t hlen,
303                                               unsigned char *sig, size_t sig_size, size_t *slen,
304                                               int (*f_rng)(void *, unsigned char *, size_t),
305                                               void *p_rng,
306                                               mbedtls_ecdsa_restart_ctx *rs_ctx)
307 {
308     if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) != ECDSA_KEY_MAGIC) {
309         return __real_mbedtls_ecdsa_write_signature_restartable(ctx, md_alg, hash, hlen, sig, sig_size, slen, f_rng, p_rng, rs_ctx);
310     }
311 
312     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
313     mbedtls_mpi r, s;
314 
315     mbedtls_mpi_init(&r);
316     mbedtls_mpi_init(&s);
317 
318     /*
319      * Check `d` whether it contains the hardware key
320      */
321     if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
322         // Use hardware ECDSA peripheral
323 
324         MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen));
325     }
326 
327     MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen));
328 
329 cleanup:
330     mbedtls_mpi_free(&r);
331     mbedtls_mpi_free(&s);
332 
333     return ret;
334 }
335 
336 int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
337                                   mbedtls_md_type_t md_alg,
338                                   const unsigned char *hash, size_t hlen,
339                                   unsigned char *sig, size_t sig_size, size_t *slen,
340                                   int (*f_rng)(void *, unsigned char *, size_t),
341                                   void *p_rng);
342 
__wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context * ctx,mbedtls_md_type_t md_alg,const unsigned char * hash,size_t hlen,unsigned char * sig,size_t sig_size,size_t * slen,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)343 int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
344                                   mbedtls_md_type_t md_alg,
345                                   const unsigned char *hash, size_t hlen,
346                                   unsigned char *sig, size_t sig_size, size_t *slen,
347                                   int (*f_rng)(void *, unsigned char *, size_t),
348                                   void *p_rng)
349 {
350     return __wrap_mbedtls_ecdsa_write_signature_restartable(
351         ctx, md_alg, hash, hlen, sig, sig_size, slen,
352         f_rng, p_rng, NULL);
353 }
354 #endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */
355 
356 #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
esp_ecdsa_verify(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s)357 static int esp_ecdsa_verify(mbedtls_ecp_group *grp,
358                             const unsigned char *buf, size_t blen,
359                             const mbedtls_ecp_point *Q,
360                             const mbedtls_mpi *r,
361                             const mbedtls_mpi *s)
362 {
363     ecdsa_curve_t curve;
364     uint16_t len;
365     uint8_t r_le[MAX_ECDSA_COMPONENT_LEN];
366     uint8_t s_le[MAX_ECDSA_COMPONENT_LEN];
367     uint8_t qx_le[MAX_ECDSA_COMPONENT_LEN];
368     uint8_t qy_le[MAX_ECDSA_COMPONENT_LEN];
369     uint8_t sha_le[ECDSA_SHA_LEN];
370 
371     if (!grp || !buf || !Q || !r || !s) {
372         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
373     }
374 
375     if (blen != ECDSA_SHA_LEN) {
376         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
377     }
378 
379     if (grp->id == MBEDTLS_ECP_DP_SECP192R1) {
380         curve = ECDSA_CURVE_SECP192R1;
381         len = 24;
382     } else if (grp->id == MBEDTLS_ECP_DP_SECP256R1) {
383         curve = ECDSA_CURVE_SECP256R1;
384         len = 32;
385     } else {
386         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
387     }
388 
389     if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 ||
390        mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0 )
391     {
392         return MBEDTLS_ERR_ECP_VERIFY_FAILED;
393     }
394 
395     ecdsa_be_to_le(buf, sha_le, len);
396 
397     mbedtls_mpi_write_binary_le(&Q->MBEDTLS_PRIVATE(X), qx_le, len);
398     mbedtls_mpi_write_binary_le(&Q->MBEDTLS_PRIVATE(Y), qy_le, len);
399     mbedtls_mpi_write_binary_le(r, r_le, len);
400     mbedtls_mpi_write_binary_le(s, s_le, len);
401 
402     esp_ecdsa_acquire_hardware();
403 
404     ecdsa_hal_config_t conf = {
405         .mode = ECDSA_MODE_SIGN_VERIFY,
406         .curve = curve,
407         .sha_mode = ECDSA_Z_USER_PROVIDED,
408     };
409 
410     int ret = ecdsa_hal_verify_signature(&conf, sha_le, r_le, s_le, qx_le, qy_le, len);
411 
412     esp_ecdsa_release_hardware();
413 
414     if (ret != 0) {
415         return MBEDTLS_ERR_ECP_VERIFY_FAILED;
416     }
417 
418     return ret;
419 }
420 
421 /*
422  * Verify ECDSA signature of hashed message
423  */
424 extern int __real_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
425                          const unsigned char *buf, size_t blen,
426                          const mbedtls_ecp_point *Q,
427                          const mbedtls_mpi *r,
428                          const mbedtls_mpi *s,
429                          mbedtls_ecdsa_restart_ctx *rs_ctx);
430 
431 int __wrap_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
432                          const unsigned char *buf, size_t blen,
433                          const mbedtls_ecp_point *Q,
434                          const mbedtls_mpi *r,
435                          const mbedtls_mpi *s,
436                          mbedtls_ecdsa_restart_ctx *rs_ctx);
437 
__wrap_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s,mbedtls_ecdsa_restart_ctx * rs_ctx)438 int __wrap_mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
439                          const unsigned char *buf, size_t blen,
440                          const mbedtls_ecp_point *Q,
441                          const mbedtls_mpi *r,
442                          const mbedtls_mpi *s,
443                          mbedtls_ecdsa_restart_ctx *rs_ctx)
444 {
445     if ((grp->id == MBEDTLS_ECP_DP_SECP192R1 || grp->id == MBEDTLS_ECP_DP_SECP256R1) && blen == ECDSA_SHA_LEN) {
446         return esp_ecdsa_verify(grp, buf, blen, Q, r, s);
447     } else {
448         return __real_mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, rs_ctx);
449     }
450 }
451 
452 /*
453  * Verify ECDSA signature of hashed message
454  */
455 extern int __real_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
456                          const unsigned char *buf, size_t blen,
457                          const mbedtls_ecp_point *Q,
458                          const mbedtls_mpi *r,
459                          const mbedtls_mpi *s);
460 
461 int __wrap_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
462                          const unsigned char *buf, size_t blen,
463                          const mbedtls_ecp_point *Q,
464                          const mbedtls_mpi *r,
465                          const mbedtls_mpi *s);
466 
__wrap_mbedtls_ecdsa_verify(mbedtls_ecp_group * grp,const unsigned char * buf,size_t blen,const mbedtls_ecp_point * Q,const mbedtls_mpi * r,const mbedtls_mpi * s)467 int __wrap_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
468                          const unsigned char *buf, size_t blen,
469                          const mbedtls_ecp_point *Q,
470                          const mbedtls_mpi *r,
471                          const mbedtls_mpi *s)
472 {
473     return __wrap_mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL);
474 }
475 
476 
477 int __real_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
478                                              const unsigned char *hash, size_t hlen,
479                                              const unsigned char *sig, size_t slen,
480                                              mbedtls_ecdsa_restart_ctx *rs_ctx);
481 
482 int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
483                                              const unsigned char *hash, size_t hlen,
484                                              const unsigned char *sig, size_t slen,
485                                              mbedtls_ecdsa_restart_ctx *rs_ctx);
486 
__wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context * ctx,const unsigned char * hash,size_t hlen,const unsigned char * sig,size_t slen,mbedtls_ecdsa_restart_ctx * rs_ctx)487 int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
488                                              const unsigned char *hash, size_t hlen,
489                                              const unsigned char *sig, size_t slen,
490                                              mbedtls_ecdsa_restart_ctx *rs_ctx)
491 {
492     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
493     unsigned char *p = (unsigned char *) sig;
494     const unsigned char *end = sig + slen;
495     size_t len;
496     mbedtls_mpi r, s;
497     mbedtls_mpi_init(&r);
498     mbedtls_mpi_init(&s);
499 
500     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
501                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
502         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
503         goto cleanup;
504     }
505 
506     if (p + len != end) {
507         ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
508                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
509         goto cleanup;
510     }
511 
512     if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
513         (ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) {
514         ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
515         goto cleanup;
516     }
517 
518     if ((ret = __wrap_mbedtls_ecdsa_verify_restartable(&ctx->MBEDTLS_PRIVATE(grp), hash, hlen,
519                                                     &ctx->MBEDTLS_PRIVATE(Q), &r, &s, NULL)) != 0) {
520         goto cleanup;
521     }
522 
523     /* At this point we know that the buffer starts with a valid signature.
524      * Return 0 if the buffer just contains the signature, and a specific
525      * error code if the valid signature is followed by more data. */
526     if (p != end) {
527         ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
528     }
529 
530 cleanup:
531     mbedtls_mpi_free(&r);
532     mbedtls_mpi_free(&s);
533 
534     return ret;
535 }
536 
537 
538 int __real_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
539                                     const unsigned char *hash, size_t hlen,
540                                     const unsigned char *sig, size_t slen);
541 
542 int __wrap_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
543                                     const unsigned char *hash, size_t hlen,
544                                     const unsigned char *sig, size_t slen);
545 
__wrap_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context * ctx,const unsigned char * hash,size_t hlen,const unsigned char * sig,size_t slen)546 int __wrap_mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
547                                     const unsigned char *hash, size_t hlen,
548                                     const unsigned char *sig, size_t slen)
549 {
550     return __wrap_mbedtls_ecdsa_read_signature_restartable(
551             ctx, hash, hlen, sig, slen, NULL);
552 }
553 #endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY */
554