• 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    {
113        unsigned char shift = 8 - ( grp.nbits % 8 );
114        size_t i;
115
116        for( i = 0; i < rnd_info.length - 1; i++ )
117            rnd_buf->x[i] = rnd_buf->x[i] << shift | rnd_buf->x[i+1] >> ( 8 - shift );
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    {
127        /* Check we generated the expected values */
128        TEST_EQUAL( mbedtls_mpi_cmp_mpi( &r, &r_check ), 0 );
129        TEST_EQUAL( mbedtls_mpi_cmp_mpi( &s, &s_check ), 0 );
130
131        /* Valid signature */
132        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
133                                          &Q, &r_check, &s_check ), 0 );
134
135        /* Invalid signature: wrong public key (G instead of Q) */
136        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
137                    &grp.G, &r_check, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
138
139        /* Invalid signatures: r or s or both one off */
140        TEST_EQUAL( mbedtls_mpi_sub_int( &r, &r_check, 1 ), 0 );
141        TEST_EQUAL( mbedtls_mpi_add_int( &s, &s_check, 1 ), 0 );
142
143        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
144                    &r, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
145        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
146                    &r_check, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
147        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
148                    &r, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
149
150        /* Invalid signatures: r, s or both (CVE-2022-21449) are zero */
151        TEST_EQUAL( mbedtls_mpi_lset( &zero, 0 ), 0 );
152
153        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
154                    &zero, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
155        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
156                    &r_check, &zero ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
157        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
158                    &zero, &zero ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
159
160        /* Invalid signatures: r, s or both are == N */
161        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
162                    &grp.N, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
163        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
164                    &r_check, &grp.N ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
165        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
166                    &grp.N, &grp.N ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
167
168        /* Invalid signatures: r, s or both are negative */
169        TEST_EQUAL( mbedtls_mpi_sub_mpi( &r, &r_check, &grp.N ), 0 );
170        TEST_EQUAL( mbedtls_mpi_sub_mpi( &s, &s_check, &grp.N ), 0 );
171
172        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
173                    &r, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
174        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
175                    &r_check, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
176        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
177                    &r, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
178
179        /* Invalid signatures: r or s or both are > N */
180        TEST_EQUAL( mbedtls_mpi_add_mpi( &r, &r_check, &grp.N ), 0 );
181        TEST_EQUAL( mbedtls_mpi_add_mpi( &s, &s_check, &grp.N ), 0 );
182
183        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
184                    &r, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
185        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
186                    &r_check, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
187        TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
188                    &r, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
189    }
190
191exit:
192    mbedtls_ecp_group_free( &grp );
193    mbedtls_ecp_point_free( &Q );
194    mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
195    mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
196    mbedtls_mpi_free( &zero );
197}
198/* END_CASE */
199
200/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
201void ecdsa_det_test_vectors( int id, char * d_str, int md_alg, data_t * hash,
202                             char * r_str, char * s_str )
203{
204    mbedtls_ecp_group grp;
205    mbedtls_mpi d, r, s, r_check, s_check;
206
207    mbedtls_ecp_group_init( &grp );
208    mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
209    mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
210
211    TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
212    TEST_ASSERT( mbedtls_test_read_mpi( &d, d_str ) == 0 );
213    TEST_ASSERT( mbedtls_test_read_mpi( &r_check, r_str ) == 0 );
214    TEST_ASSERT( mbedtls_test_read_mpi( &s_check, s_str ) == 0 );
215
216    TEST_ASSERT(
217                mbedtls_ecdsa_sign_det_ext( &grp, &r, &s, &d,
218                                            hash->x, hash->len, md_alg,
219                                            mbedtls_test_rnd_std_rand,
220                                            NULL )
221                == 0 );
222
223    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
224    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
225
226exit:
227    mbedtls_ecp_group_free( &grp );
228    mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
229    mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
230}
231/* END_CASE */
232
233/* BEGIN_CASE depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_IF_DETERMINISTIC */
234void ecdsa_write_read_zero( int id )
235{
236    mbedtls_ecdsa_context ctx;
237    mbedtls_test_rnd_pseudo_info rnd_info;
238    unsigned char hash[32];
239    unsigned char sig[200];
240    size_t sig_len, i;
241
242    mbedtls_ecdsa_init( &ctx );
243    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
244    memset( hash, 0, sizeof( hash ) );
245    memset( sig, 0x2a, sizeof( sig ) );
246
247    /* generate signing key */
248    TEST_ASSERT( mbedtls_ecdsa_genkey( &ctx, id,
249                                       &mbedtls_test_rnd_pseudo_rand,
250                                       &rnd_info ) == 0 );
251
252    /* generate and write signature, then read and verify it */
253    TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
254                 hash, sizeof( hash ),
255                 sig, sizeof( sig ), &sig_len, &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    /* 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}
291/* END_CASE */
292
293/* BEGIN_CASE depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_IF_DETERMINISTIC */
294void ecdsa_write_read_random( int id )
295{
296    mbedtls_ecdsa_context ctx;
297    mbedtls_test_rnd_pseudo_info rnd_info;
298    unsigned char hash[32];
299    unsigned char sig[200];
300    size_t sig_len, i;
301
302    mbedtls_ecdsa_init( &ctx );
303    memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
304    memset( hash, 0, sizeof( hash ) );
305    memset( sig, 0x2a, sizeof( sig ) );
306
307    /* prepare material for signature */
308    TEST_ASSERT( mbedtls_test_rnd_pseudo_rand( &rnd_info,
309                                               hash, sizeof( hash ) ) == 0 );
310
311    /* generate signing key */
312    TEST_ASSERT( mbedtls_ecdsa_genkey( &ctx, id,
313                                       &mbedtls_test_rnd_pseudo_rand,
314                                       &rnd_info ) == 0 );
315
316    /* generate and write signature, then read and verify it */
317    TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
318                 hash, sizeof( hash ),
319                 sig, sizeof( sig ), &sig_len, &mbedtls_test_rnd_pseudo_rand,
320                 &rnd_info ) == 0 );
321    TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
322                 sig, sig_len ) == 0 );
323
324    /* check we didn't write past the announced length */
325    for( i = sig_len; i < sizeof( sig ); i++ )
326        TEST_ASSERT( sig[i] == 0x2a );
327
328    /* try verification with invalid length */
329    TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
330                 sig, sig_len - 1 ) != 0 );
331    TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
332                 sig, sig_len + 1 ) != 0 );
333
334    /* try invalid sequence tag */
335    sig[0]++;
336    TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
337                 sig, sig_len ) != 0 );
338    sig[0]--;
339
340    /* try modifying r */
341    sig[10]++;
342    TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
343                 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
344    sig[10]--;
345
346    /* try modifying s */
347    sig[sig_len - 1]++;
348    TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
349                 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
350    sig[sig_len - 1]--;
351
352exit:
353    mbedtls_ecdsa_free( &ctx );
354}
355/* END_CASE */
356
357/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
358void ecdsa_read_restart( int id, data_t *pk, data_t *hash, data_t *sig,
359                         int max_ops, int min_restart, int max_restart )
360{
361    mbedtls_ecdsa_context ctx;
362    mbedtls_ecdsa_restart_ctx rs_ctx;
363    int ret, cnt_restart;
364
365    mbedtls_ecdsa_init( &ctx );
366    mbedtls_ecdsa_restart_init( &rs_ctx );
367
368    TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
369    TEST_ASSERT( mbedtls_ecp_point_read_binary( &ctx.grp, &ctx.Q,
370                                                pk->x, pk->len ) == 0 );
371
372    mbedtls_ecp_set_max_ops( max_ops );
373
374    cnt_restart = 0;
375    do {
376        ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
377                            hash->x, hash->len, sig->x, sig->len, &rs_ctx );
378    } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
379
380    TEST_ASSERT( ret == 0 );
381    TEST_ASSERT( cnt_restart >= min_restart );
382    TEST_ASSERT( cnt_restart <= max_restart );
383
384    /* try modifying r */
385
386    TEST_ASSERT( sig->len > 10 );
387    sig->x[10]++;
388    do {
389        ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
390                            hash->x, hash->len, sig->x, sig->len, &rs_ctx );
391    } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
392    TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
393    sig->x[10]--;
394
395    /* try modifying s */
396    sig->x[sig->len - 1]++;
397    do {
398        ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
399                            hash->x, hash->len, sig->x, sig->len, &rs_ctx );
400    } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
401    TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
402    sig->x[sig->len - 1]--;
403
404    /* Do we leak memory when aborting an operation?
405     * This test only makes sense when we actually restart */
406    if( min_restart > 0 )
407    {
408        ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
409                            hash->x, hash->len, sig->x, sig->len, &rs_ctx );
410        TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
411    }
412
413exit:
414    mbedtls_ecdsa_free( &ctx );
415    mbedtls_ecdsa_restart_free( &rs_ctx );
416}
417/* END_CASE */
418
419/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
420void ecdsa_write_restart( int id, char *d_str, int md_alg,
421                          data_t *hash, data_t *sig_check,
422                          int max_ops, int min_restart, int max_restart )
423{
424    int ret, cnt_restart;
425    mbedtls_ecdsa_restart_ctx rs_ctx;
426    mbedtls_ecdsa_context ctx;
427    unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
428    size_t slen;
429
430    mbedtls_ecdsa_restart_init( &rs_ctx );
431    mbedtls_ecdsa_init( &ctx );
432    memset( sig, 0, sizeof( sig ) );
433
434    TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
435    TEST_ASSERT( mbedtls_test_read_mpi( &ctx.d, d_str ) == 0 );
436
437    mbedtls_ecp_set_max_ops( max_ops );
438
439    slen = sizeof( sig );
440    cnt_restart = 0;
441    do {
442        ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
443                md_alg, hash->x, hash->len, sig, sizeof( sig ), &slen,
444                mbedtls_test_rnd_std_rand, NULL, &rs_ctx );
445    } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
446
447    TEST_ASSERT( ret == 0 );
448    TEST_ASSERT( slen == sig_check->len );
449    TEST_ASSERT( memcmp( sig, sig_check->x, slen ) == 0 );
450
451    TEST_ASSERT( cnt_restart >= min_restart );
452    TEST_ASSERT( cnt_restart <= max_restart );
453
454    /* Do we leak memory when aborting an operation?
455     * This test only makes sense when we actually restart */
456    if( min_restart > 0 )
457    {
458        ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
459                md_alg, hash->x, hash->len, sig, sizeof( sig ), &slen,
460                mbedtls_test_rnd_std_rand, NULL, &rs_ctx );
461        TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
462    }
463
464exit:
465    mbedtls_ecdsa_restart_free( &rs_ctx );
466    mbedtls_ecdsa_free( &ctx );
467}
468/* END_CASE */
469
470/* BEGIN_CASE */
471void ecdsa_verify( int grp_id, char * x, char * y, char * r, char * s, data_t * content, int expected )
472{
473    mbedtls_ecdsa_context ctx;
474    mbedtls_mpi sig_r, sig_s;
475
476    mbedtls_ecdsa_init( &ctx );
477    mbedtls_mpi_init( &sig_r );
478    mbedtls_mpi_init( &sig_s );
479
480    /* Prepare ECP group context */
481    TEST_EQUAL( mbedtls_ecp_group_load( &ctx.grp, grp_id ), 0 );
482
483    /* Prepare public key */
484    TEST_EQUAL( mbedtls_test_read_mpi( &ctx.Q.X, x ), 0 );
485    TEST_EQUAL( mbedtls_test_read_mpi( &ctx.Q.Y, y ), 0 );
486    TEST_EQUAL( mbedtls_mpi_lset( &ctx.Q.Z, 1 ), 0 );
487
488    /* Prepare signature R & S */
489    TEST_EQUAL( mbedtls_test_read_mpi( &sig_r, r ), 0 );
490    TEST_EQUAL( mbedtls_test_read_mpi( &sig_s, s ), 0 );
491
492    /* Test whether public key has expected validity */
493    TEST_EQUAL( mbedtls_ecp_check_pubkey( &ctx.grp, &ctx.Q ),
494        expected == MBEDTLS_ERR_ECP_INVALID_KEY ? MBEDTLS_ERR_ECP_INVALID_KEY : 0 );
495
496    /* Verification */
497    int result = mbedtls_ecdsa_verify( &ctx.grp, content->x, content->len, &ctx.Q, &sig_r, &sig_s );
498
499    TEST_EQUAL( result, expected );
500exit:
501    mbedtls_ecdsa_free( &ctx );
502    mbedtls_mpi_free( &sig_r );
503    mbedtls_mpi_free( &sig_s );
504}
505/* END_CASE */
506