• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/ecdsa.h"
3#include "hash_info.h"
4#include "mbedtls/legacy_or_psa.h"
5#if (defined(MBEDTLS_ECDSA_DETERMINISTIC) && defined(MBEDTLS_SHA256_C)) || \
6    (!defined(MBEDTLS_ECDSA_DETERMINISTIC) && defined(MBEDTLS_HAS_ALG_SHA_256_VIA_LOWLEVEL_OR_PSA))
7#define MBEDTLS_HAS_ALG_SHA_256_VIA_MD_IF_DETERMINISTIC
8#endif
9/* END_HEADER */
10
11/* BEGIN_DEPENDENCIES
12 * depends_on:MBEDTLS_ECDSA_C
13 * END_DEPENDENCIES
14 */
15
16/* BEGIN_CASE */
17void ecdsa_prim_zero(int id)
18{
19    mbedtls_ecp_group grp;
20    mbedtls_ecp_point Q;
21    mbedtls_mpi d, r, s;
22    mbedtls_test_rnd_pseudo_info rnd_info;
23    unsigned char buf[MBEDTLS_HASH_MAX_SIZE];
24
25    mbedtls_ecp_group_init(&grp);
26    mbedtls_ecp_point_init(&Q);
27    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
28    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
29    memset(buf, 0, sizeof(buf));
30
31    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
32    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
33                                        &mbedtls_test_rnd_pseudo_rand,
34                                        &rnd_info) == 0);
35
36    TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, buf, sizeof(buf),
37                                   &mbedtls_test_rnd_pseudo_rand,
38                                   &rnd_info) == 0);
39    TEST_ASSERT(mbedtls_ecdsa_verify(&grp, buf, sizeof(buf), &Q, &r, &s) == 0);
40
41exit:
42    mbedtls_ecp_group_free(&grp);
43    mbedtls_ecp_point_free(&Q);
44    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
45}
46/* END_CASE */
47
48/* BEGIN_CASE */
49void ecdsa_prim_random(int id)
50{
51    mbedtls_ecp_group grp;
52    mbedtls_ecp_point Q;
53    mbedtls_mpi d, r, s;
54    mbedtls_test_rnd_pseudo_info rnd_info;
55    unsigned char buf[MBEDTLS_HASH_MAX_SIZE];
56
57    mbedtls_ecp_group_init(&grp);
58    mbedtls_ecp_point_init(&Q);
59    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
60    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
61    memset(buf, 0, sizeof(buf));
62
63    /* prepare material for signature */
64    TEST_ASSERT(mbedtls_test_rnd_pseudo_rand(&rnd_info,
65                                             buf, sizeof(buf)) == 0);
66    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
67    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
68                                        &mbedtls_test_rnd_pseudo_rand,
69                                        &rnd_info) == 0);
70
71    TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, buf, sizeof(buf),
72                                   &mbedtls_test_rnd_pseudo_rand,
73                                   &rnd_info) == 0);
74    TEST_ASSERT(mbedtls_ecdsa_verify(&grp, buf, sizeof(buf), &Q, &r, &s) == 0);
75
76exit:
77    mbedtls_ecp_group_free(&grp);
78    mbedtls_ecp_point_free(&Q);
79    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
80}
81/* END_CASE */
82
83/* BEGIN_CASE */
84void ecdsa_prim_test_vectors(int id, char *d_str, char *xQ_str,
85                             char *yQ_str, data_t *rnd_buf,
86                             data_t *hash, char *r_str, char *s_str,
87                             int result)
88{
89    mbedtls_ecp_group grp;
90    mbedtls_ecp_point Q;
91    mbedtls_mpi d, r, s, r_check, s_check, zero;
92    mbedtls_test_rnd_buf_info rnd_info;
93
94    mbedtls_ecp_group_init(&grp);
95    mbedtls_ecp_point_init(&Q);
96    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
97    mbedtls_mpi_init(&r_check); mbedtls_mpi_init(&s_check);
98    mbedtls_mpi_init(&zero);
99
100    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
101    TEST_ASSERT(mbedtls_ecp_point_read_string(&Q, 16, xQ_str, yQ_str) == 0);
102    TEST_ASSERT(mbedtls_test_read_mpi(&d, d_str) == 0);
103    TEST_ASSERT(mbedtls_test_read_mpi(&r_check, r_str) == 0);
104    TEST_ASSERT(mbedtls_test_read_mpi(&s_check, s_str) == 0);
105    rnd_info.fallback_f_rng = mbedtls_test_rnd_std_rand;
106    rnd_info.fallback_p_rng = NULL;
107    rnd_info.buf = rnd_buf->x;
108    rnd_info.length = rnd_buf->len;
109
110    /* Fix rnd_buf->x by shifting it left if necessary */
111    if (grp.nbits % 8 != 0) {
112        unsigned char shift = 8 - (grp.nbits % 8);
113        size_t i;
114
115        for (i = 0; i < rnd_info.length - 1; i++) {
116            rnd_buf->x[i] = rnd_buf->x[i] << shift | rnd_buf->x[i+1] >> (8 - shift);
117        }
118
119        rnd_buf->x[rnd_info.length-1] <<= shift;
120    }
121
122    TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, hash->x, hash->len,
123                                   mbedtls_test_rnd_buffer_rand, &rnd_info) == result);
124
125    if (result == 0) {
126        /* Check we generated the expected values */
127        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&r, &r_check), 0);
128        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&s, &s_check), 0);
129
130        /* Valid signature */
131        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len,
132                                        &Q, &r_check, &s_check), 0);
133
134        /* Invalid signature: wrong public key (G instead of Q) */
135        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len,
136                                        &grp.G, &r_check, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
137
138        /* Invalid signatures: r or s or both one off */
139        TEST_EQUAL(mbedtls_mpi_sub_int(&r, &r_check, 1), 0);
140        TEST_EQUAL(mbedtls_mpi_add_int(&s, &s_check, 1), 0);
141
142        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
143                                        &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
144        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
145                                        &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
146        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
147                                        &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
148
149        /* Invalid signatures: r, s or both (CVE-2022-21449) are zero */
150        TEST_EQUAL(mbedtls_mpi_lset(&zero, 0), 0);
151
152        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
153                                        &zero, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
154        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
155                                        &r_check, &zero), MBEDTLS_ERR_ECP_VERIFY_FAILED);
156        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
157                                        &zero, &zero), MBEDTLS_ERR_ECP_VERIFY_FAILED);
158
159        /* Invalid signatures: r, s or both are == N */
160        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
161                                        &grp.N, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
162        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
163                                        &r_check, &grp.N), MBEDTLS_ERR_ECP_VERIFY_FAILED);
164        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
165                                        &grp.N, &grp.N), MBEDTLS_ERR_ECP_VERIFY_FAILED);
166
167        /* Invalid signatures: r, s or both are negative */
168        TEST_EQUAL(mbedtls_mpi_sub_mpi(&r, &r_check, &grp.N), 0);
169        TEST_EQUAL(mbedtls_mpi_sub_mpi(&s, &s_check, &grp.N), 0);
170
171        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
172                                        &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
173        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
174                                        &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
175        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
176                                        &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
177
178        /* Invalid signatures: r or s or both are > N */
179        TEST_EQUAL(mbedtls_mpi_add_mpi(&r, &r_check, &grp.N), 0);
180        TEST_EQUAL(mbedtls_mpi_add_mpi(&s, &s_check, &grp.N), 0);
181
182        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
183                                        &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
184        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
185                                        &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
186        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
187                                        &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
188    }
189
190exit:
191    mbedtls_ecp_group_free(&grp);
192    mbedtls_ecp_point_free(&Q);
193    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
194    mbedtls_mpi_free(&r_check); mbedtls_mpi_free(&s_check);
195    mbedtls_mpi_free(&zero);
196}
197/* END_CASE */
198
199/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
200void ecdsa_det_test_vectors(int id, char *d_str, int md_alg, data_t *hash,
201                            char *r_str, char *s_str)
202{
203    mbedtls_ecp_group grp;
204    mbedtls_mpi d, r, s, r_check, s_check;
205
206    mbedtls_ecp_group_init(&grp);
207    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
208    mbedtls_mpi_init(&r_check); mbedtls_mpi_init(&s_check);
209
210    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
211    TEST_ASSERT(mbedtls_test_read_mpi(&d, d_str) == 0);
212    TEST_ASSERT(mbedtls_test_read_mpi(&r_check, r_str) == 0);
213    TEST_ASSERT(mbedtls_test_read_mpi(&s_check, s_str) == 0);
214
215    TEST_ASSERT(
216        mbedtls_ecdsa_sign_det_ext(&grp, &r, &s, &d,
217                                   hash->x, hash->len, md_alg,
218                                   mbedtls_test_rnd_std_rand,
219                                   NULL)
220        == 0);
221
222    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&r, &r_check) == 0);
223    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&s, &s_check) == 0);
224
225exit:
226    mbedtls_ecp_group_free(&grp);
227    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
228    mbedtls_mpi_free(&r_check); mbedtls_mpi_free(&s_check);
229}
230/* END_CASE */
231
232/* BEGIN_CASE depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_IF_DETERMINISTIC */
233void ecdsa_write_read_zero(int id)
234{
235    mbedtls_ecdsa_context ctx;
236    mbedtls_test_rnd_pseudo_info rnd_info;
237    unsigned char hash[32];
238    unsigned char sig[200];
239    size_t sig_len, i;
240
241    mbedtls_ecdsa_init(&ctx);
242    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
243    memset(hash, 0, sizeof(hash));
244    memset(sig, 0x2a, sizeof(sig));
245
246    /* generate signing key */
247    TEST_ASSERT(mbedtls_ecdsa_genkey(&ctx, id,
248                                     &mbedtls_test_rnd_pseudo_rand,
249                                     &rnd_info) == 0);
250
251    /* generate and write signature, then read and verify it */
252    TEST_ASSERT(mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256,
253                                              hash, sizeof(hash),
254                                              sig, sizeof(sig), &sig_len,
255                                              &mbedtls_test_rnd_pseudo_rand,
256                                              &rnd_info) == 0);
257    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
258                                             sig, sig_len) == 0);
259
260    /* check we didn't write past the announced length */
261    for (i = sig_len; i < sizeof(sig); i++) {
262        TEST_ASSERT(sig[i] == 0x2a);
263    }
264
265    /* try verification with invalid length */
266    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
267                                             sig, sig_len - 1) != 0);
268    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
269                                             sig, sig_len + 1) != 0);
270
271    /* try invalid sequence tag */
272    sig[0]++;
273    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
274                                             sig, sig_len) != 0);
275    sig[0]--;
276
277    /* try modifying r */
278    sig[10]++;
279    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
280                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
281    sig[10]--;
282
283    /* try modifying s */
284    sig[sig_len - 1]++;
285    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
286                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
287    sig[sig_len - 1]--;
288
289exit:
290    mbedtls_ecdsa_free(&ctx);
291}
292/* END_CASE */
293
294/* BEGIN_CASE depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_IF_DETERMINISTIC */
295void ecdsa_write_read_random(int id)
296{
297    mbedtls_ecdsa_context ctx;
298    mbedtls_test_rnd_pseudo_info rnd_info;
299    unsigned char hash[32];
300    unsigned char sig[200];
301    size_t sig_len, i;
302
303    mbedtls_ecdsa_init(&ctx);
304    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
305    memset(hash, 0, sizeof(hash));
306    memset(sig, 0x2a, sizeof(sig));
307
308    /* prepare material for signature */
309    TEST_ASSERT(mbedtls_test_rnd_pseudo_rand(&rnd_info,
310                                             hash, sizeof(hash)) == 0);
311
312    /* generate signing key */
313    TEST_ASSERT(mbedtls_ecdsa_genkey(&ctx, id,
314                                     &mbedtls_test_rnd_pseudo_rand,
315                                     &rnd_info) == 0);
316
317    /* generate and write signature, then read and verify it */
318    TEST_ASSERT(mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256,
319                                              hash, sizeof(hash),
320                                              sig, sizeof(sig), &sig_len,
321                                              &mbedtls_test_rnd_pseudo_rand,
322                                              &rnd_info) == 0);
323    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
324                                             sig, sig_len) == 0);
325
326    /* check we didn't write past the announced length */
327    for (i = sig_len; i < sizeof(sig); i++) {
328        TEST_ASSERT(sig[i] == 0x2a);
329    }
330
331    /* try verification with invalid length */
332    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
333                                             sig, sig_len - 1) != 0);
334    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
335                                             sig, sig_len + 1) != 0);
336
337    /* try invalid sequence tag */
338    sig[0]++;
339    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
340                                             sig, sig_len) != 0);
341    sig[0]--;
342
343    /* try modifying r */
344    sig[10]++;
345    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
346                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
347    sig[10]--;
348
349    /* try modifying s */
350    sig[sig_len - 1]++;
351    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
352                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
353    sig[sig_len - 1]--;
354
355exit:
356    mbedtls_ecdsa_free(&ctx);
357}
358/* END_CASE */
359
360/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
361void ecdsa_read_restart(int id, data_t *pk, data_t *hash, data_t *sig,
362                        int max_ops, int min_restart, int max_restart)
363{
364    mbedtls_ecdsa_context ctx;
365    mbedtls_ecdsa_restart_ctx rs_ctx;
366    int ret, cnt_restart;
367
368    mbedtls_ecdsa_init(&ctx);
369    mbedtls_ecdsa_restart_init(&rs_ctx);
370
371    TEST_ASSERT(mbedtls_ecp_group_load(&ctx.grp, id) == 0);
372    TEST_ASSERT(mbedtls_ecp_point_read_binary(&ctx.grp, &ctx.Q,
373                                              pk->x, pk->len) == 0);
374
375    mbedtls_ecp_set_max_ops(max_ops);
376
377    cnt_restart = 0;
378    do {
379        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
380                                                       hash->x, hash->len, sig->x, sig->len,
381                                                       &rs_ctx);
382    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
383
384    TEST_ASSERT(ret == 0);
385    TEST_ASSERT(cnt_restart >= min_restart);
386    TEST_ASSERT(cnt_restart <= max_restart);
387
388    /* try modifying r */
389
390    TEST_ASSERT(sig->len > 10);
391    sig->x[10]++;
392    do {
393        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
394                                                       hash->x, hash->len, sig->x, sig->len,
395                                                       &rs_ctx);
396    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
397    TEST_ASSERT(ret == MBEDTLS_ERR_ECP_VERIFY_FAILED);
398    sig->x[10]--;
399
400    /* try modifying s */
401    sig->x[sig->len - 1]++;
402    do {
403        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
404                                                       hash->x, hash->len, sig->x, sig->len,
405                                                       &rs_ctx);
406    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
407    TEST_ASSERT(ret == MBEDTLS_ERR_ECP_VERIFY_FAILED);
408    sig->x[sig->len - 1]--;
409
410    /* Do we leak memory when aborting an operation?
411     * This test only makes sense when we actually restart */
412    if (min_restart > 0) {
413        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
414                                                       hash->x, hash->len, sig->x, sig->len,
415                                                       &rs_ctx);
416        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
417    }
418
419exit:
420    mbedtls_ecdsa_free(&ctx);
421    mbedtls_ecdsa_restart_free(&rs_ctx);
422}
423/* END_CASE */
424
425/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
426void ecdsa_write_restart(int id, char *d_str, int md_alg,
427                         data_t *hash, data_t *sig_check,
428                         int max_ops, int min_restart, int max_restart)
429{
430    int ret, cnt_restart;
431    mbedtls_ecdsa_restart_ctx rs_ctx;
432    mbedtls_ecdsa_context ctx;
433    unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
434    size_t slen;
435
436    mbedtls_ecdsa_restart_init(&rs_ctx);
437    mbedtls_ecdsa_init(&ctx);
438    memset(sig, 0, sizeof(sig));
439
440    TEST_ASSERT(mbedtls_ecp_group_load(&ctx.grp, id) == 0);
441    TEST_ASSERT(mbedtls_test_read_mpi(&ctx.d, d_str) == 0);
442
443    mbedtls_ecp_set_max_ops(max_ops);
444
445    slen = sizeof(sig);
446    cnt_restart = 0;
447    do {
448        ret = mbedtls_ecdsa_write_signature_restartable(&ctx,
449                                                        md_alg,
450                                                        hash->x,
451                                                        hash->len,
452                                                        sig,
453                                                        sizeof(sig),
454                                                        &slen,
455                                                        mbedtls_test_rnd_std_rand,
456                                                        NULL,
457                                                        &rs_ctx);
458    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
459
460    TEST_ASSERT(ret == 0);
461    TEST_ASSERT(slen == sig_check->len);
462    TEST_ASSERT(memcmp(sig, sig_check->x, slen) == 0);
463
464    TEST_ASSERT(cnt_restart >= min_restart);
465    TEST_ASSERT(cnt_restart <= max_restart);
466
467    /* Do we leak memory when aborting an operation?
468     * This test only makes sense when we actually restart */
469    if (min_restart > 0) {
470        ret = mbedtls_ecdsa_write_signature_restartable(&ctx,
471                                                        md_alg,
472                                                        hash->x,
473                                                        hash->len,
474                                                        sig,
475                                                        sizeof(sig),
476                                                        &slen,
477                                                        mbedtls_test_rnd_std_rand,
478                                                        NULL,
479                                                        &rs_ctx);
480        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
481    }
482
483exit:
484    mbedtls_ecdsa_restart_free(&rs_ctx);
485    mbedtls_ecdsa_free(&ctx);
486}
487/* END_CASE */
488
489/* BEGIN_CASE */
490void ecdsa_verify(int grp_id, char *x, char *y, char *r, char *s, data_t *content, int expected)
491{
492    mbedtls_ecdsa_context ctx;
493    mbedtls_mpi sig_r, sig_s;
494
495    mbedtls_ecdsa_init(&ctx);
496    mbedtls_mpi_init(&sig_r);
497    mbedtls_mpi_init(&sig_s);
498
499    /* Prepare ECP group context */
500    TEST_EQUAL(mbedtls_ecp_group_load(&ctx.grp, grp_id), 0);
501
502    /* Prepare public key */
503    TEST_EQUAL(mbedtls_test_read_mpi(&ctx.Q.X, x), 0);
504    TEST_EQUAL(mbedtls_test_read_mpi(&ctx.Q.Y, y), 0);
505    TEST_EQUAL(mbedtls_mpi_lset(&ctx.Q.Z, 1), 0);
506
507    /* Prepare signature R & S */
508    TEST_EQUAL(mbedtls_test_read_mpi(&sig_r, r), 0);
509    TEST_EQUAL(mbedtls_test_read_mpi(&sig_s, s), 0);
510
511    /* Test whether public key has expected validity */
512    TEST_EQUAL(mbedtls_ecp_check_pubkey(&ctx.grp, &ctx.Q),
513               expected == MBEDTLS_ERR_ECP_INVALID_KEY ? MBEDTLS_ERR_ECP_INVALID_KEY : 0);
514
515    /* Verification */
516    int result = mbedtls_ecdsa_verify(&ctx.grp, content->x, content->len, &ctx.Q, &sig_r, &sig_s);
517
518    TEST_EQUAL(result, expected);
519exit:
520    mbedtls_ecdsa_free(&ctx);
521    mbedtls_mpi_free(&sig_r);
522    mbedtls_mpi_free(&sig_s);
523}
524/* END_CASE */
525