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