blob: 0862f54b78a2f3f7e6e17cb48bb1d3788bcd165f [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/ecdsa.h"
Paul Bakker33b43f12013-08-20 11:48:36 +02003/* END_HEADER */
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +01004
Paul Bakker33b43f12013-08-20 11:48:36 +02005/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006 * depends_on:MBEDTLS_ECDSA_C
Paul Bakker33b43f12013-08-20 11:48:36 +02007 * END_DEPENDENCIES
8 */
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +01009
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050010/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
11void ecdsa_invalid_param( )
12{
13 mbedtls_ecdsa_context ctx;
14 mbedtls_ecp_keypair key;
15 mbedtls_ecp_group grp;
16 mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
17 mbedtls_ecp_point P;
18 mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
19 mbedtls_mpi m;
20 size_t slen;
21 unsigned char buf[42] = { 0 };
22
23 TEST_INVALID_PARAM( mbedtls_ecdsa_init( NULL ) );
24 TEST_VALID_PARAM( mbedtls_ecdsa_free( NULL ) );
25
26#if defined(MBEDTLS_ECP_RESTARTABLE)
27 TEST_INVALID_PARAM( mbedtls_ecdsa_restart_init( NULL ) );
28 TEST_VALID_PARAM( mbedtls_ecdsa_restart_free( NULL ) );
29#endif /* MBEDTLS_ECP_RESTARTABLE */
30
31 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
32 mbedtls_ecdsa_sign( NULL, &m, &m, &m,
33 buf, sizeof( buf ),
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020034 mbedtls_test_rnd_std_rand,
35 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050036 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
37 mbedtls_ecdsa_sign( &grp, NULL, &m, &m,
38 buf, sizeof( buf ),
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020039 mbedtls_test_rnd_std_rand,
40 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050041 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
42 mbedtls_ecdsa_sign( &grp, &m, NULL, &m,
43 buf, sizeof( buf ),
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020044 mbedtls_test_rnd_std_rand,
45 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050046 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
47 mbedtls_ecdsa_sign( &grp, &m, &m, NULL,
48 buf, sizeof( buf ),
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020049 mbedtls_test_rnd_std_rand,
50 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050051 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
52 mbedtls_ecdsa_sign( &grp, &m, &m, &m,
53 NULL, sizeof( buf ),
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020054 mbedtls_test_rnd_std_rand,
55 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050056 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
57 mbedtls_ecdsa_sign( &grp, &m, &m, &m,
58 buf, sizeof( buf ),
59 NULL, NULL ) );
60
61#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
62 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Janos Follath651eac82019-01-04 15:51:24 +000063 mbedtls_ecdsa_sign_det_ext( NULL, &m, &m, &m,
64 buf, sizeof( buf ),
65 valid_md,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020066 mbedtls_test_rnd_std_rand,
67 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050068 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Janos Follath651eac82019-01-04 15:51:24 +000069 mbedtls_ecdsa_sign_det_ext( &grp, NULL, &m, &m,
70 buf, sizeof( buf ),
71 valid_md,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020072 mbedtls_test_rnd_std_rand,
73 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050074 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Janos Follath651eac82019-01-04 15:51:24 +000075 mbedtls_ecdsa_sign_det_ext( &grp, &m, NULL, &m,
76 buf, sizeof( buf ),
77 valid_md,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020078 mbedtls_test_rnd_std_rand,
79 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050080 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Janos Follath651eac82019-01-04 15:51:24 +000081 mbedtls_ecdsa_sign_det_ext( &grp, &m, &m, NULL,
82 buf, sizeof( buf ),
83 valid_md,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020084 mbedtls_test_rnd_std_rand,
85 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050086 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Janos Follath651eac82019-01-04 15:51:24 +000087 mbedtls_ecdsa_sign_det_ext( &grp, &m, &m, &m,
88 NULL, sizeof( buf ),
89 valid_md,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +020090 mbedtls_test_rnd_std_rand,
91 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050092#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
93
94 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
95 mbedtls_ecdsa_verify( NULL,
96 buf, sizeof( buf ),
97 &P, &m, &m ) );
98 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
99 mbedtls_ecdsa_verify( &grp,
100 NULL, sizeof( buf ),
101 &P, &m, &m ) );
102 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
103 mbedtls_ecdsa_verify( &grp,
104 buf, sizeof( buf ),
105 NULL, &m, &m ) );
106 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
107 mbedtls_ecdsa_verify( &grp,
108 buf, sizeof( buf ),
109 &P, NULL, &m ) );
110 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
111 mbedtls_ecdsa_verify( &grp,
112 buf, sizeof( buf ),
113 &P, &m, NULL ) );
114
115 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200116 mbedtls_ecdsa_write_signature( NULL, valid_md, buf, sizeof( buf ),
117 buf, &slen, mbedtls_test_rnd_std_rand,
118 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500119
120 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200121 mbedtls_ecdsa_write_signature( &ctx, valid_md, NULL, sizeof( buf ),
122 buf, &slen, mbedtls_test_rnd_std_rand,
123 NULL ) );
124
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500125 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200126 mbedtls_ecdsa_write_signature( &ctx, valid_md, buf, sizeof( buf ),
127 NULL, &slen, mbedtls_test_rnd_std_rand,
128 NULL ) );
129
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500130 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200131 mbedtls_ecdsa_write_signature( &ctx, valid_md, buf, sizeof( buf ),
132 buf, NULL, mbedtls_test_rnd_std_rand,
133 NULL ) );
134
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500135 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200136 mbedtls_ecdsa_write_signature_restartable( NULL, valid_md, buf,
137 sizeof( buf ), buf, &slen,
138 mbedtls_test_rnd_std_rand,
139 NULL, NULL ) );
140
141 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
142 mbedtls_ecdsa_write_signature_restartable( &ctx, valid_md, NULL,
143 sizeof( buf ), buf, &slen,
144 mbedtls_test_rnd_std_rand,
145 NULL, NULL ) );
146
147 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
148 mbedtls_ecdsa_write_signature_restartable( &ctx, valid_md, buf,
149 sizeof( buf ), NULL, &slen,
150 mbedtls_test_rnd_std_rand,
151 NULL, NULL ) );
152
153 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
154 mbedtls_ecdsa_write_signature_restartable( &ctx, valid_md, buf,
155 sizeof( buf ), buf, NULL,
156 mbedtls_test_rnd_std_rand,
157 NULL, NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500158
159 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
160 mbedtls_ecdsa_read_signature( NULL,
161 buf, sizeof( buf ),
162 buf, sizeof( buf ) ) );
163 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
164 mbedtls_ecdsa_read_signature( &ctx,
165 NULL, sizeof( buf ),
166 buf, sizeof( buf ) ) );
167 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
168 mbedtls_ecdsa_read_signature( &ctx,
169 buf, sizeof( buf ),
170 NULL, sizeof( buf ) ) );
171
172 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
173 mbedtls_ecdsa_read_signature_restartable( NULL,
174 buf, sizeof( buf ),
175 buf, sizeof( buf ),
176 NULL ) );
177 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
178 mbedtls_ecdsa_read_signature_restartable( &ctx,
179 NULL, sizeof( buf ),
180 buf, sizeof( buf ),
181 NULL ) );
182 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
183 mbedtls_ecdsa_read_signature_restartable( &ctx,
184 buf, sizeof( buf ),
185 NULL, sizeof( buf ),
186 NULL ) );
187
188 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
189 mbedtls_ecdsa_genkey( NULL, valid_group,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200190 mbedtls_test_rnd_std_rand,
191 NULL ) );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500192 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
193 mbedtls_ecdsa_genkey( &ctx, valid_group,
194 NULL, NULL ) );
195
196
197 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
198 mbedtls_ecdsa_from_keypair( NULL, &key ) );
199 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
200 mbedtls_ecdsa_from_keypair( &ctx, NULL ) );
201
202exit:
203 return;
204}
205/* END_CASE */
206
Paul Bakker33b43f12013-08-20 11:48:36 +0200207/* BEGIN_CASE */
TRodziewicz40de3c92021-04-07 19:16:18 +0200208void ecdsa_prim_zero( int id )
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100209{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 mbedtls_ecp_group grp;
211 mbedtls_ecp_point Q;
212 mbedtls_mpi d, r, s;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200213 mbedtls_test_rnd_pseudo_info rnd_info;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500214 unsigned char buf[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100215
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 mbedtls_ecp_group_init( &grp );
217 mbedtls_ecp_point_init( &Q );
218 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
Ronald Cron351f0ee2020-06-10 12:12:18 +0200219 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
Manuel Pégourié-Gonnard450a1632013-01-27 09:08:18 +0100220 memset( buf, 0, sizeof( buf ) );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100221
TRodziewicz40de3c92021-04-07 19:16:18 +0200222 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
223 TEST_ASSERT( mbedtls_ecp_gen_keypair( &grp, &d, &Q,
224 &mbedtls_test_rnd_pseudo_rand,
225 &rnd_info ) == 0 );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100226
TRodziewicz40de3c92021-04-07 19:16:18 +0200227 TEST_ASSERT( mbedtls_ecdsa_sign( &grp, &r, &s, &d, buf, sizeof( buf ),
228 &mbedtls_test_rnd_pseudo_rand,
229 &rnd_info ) == 0 );
230 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, buf, sizeof( buf ), &Q, &r, &s ) == 0 );
TRodziewicz5feb6702021-04-06 19:55:17 +0200231
TRodziewicz40de3c92021-04-07 19:16:18 +0200232exit:
233 mbedtls_ecp_group_free( &grp );
234 mbedtls_ecp_point_free( &Q );
235 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
236}
237/* END_CASE */
238
239/* BEGIN_CASE */
240void ecdsa_prim_random( int id )
241{
242 mbedtls_ecp_group grp;
243 mbedtls_ecp_point Q;
244 mbedtls_mpi d, r, s;
245 mbedtls_test_rnd_pseudo_info rnd_info;
246 unsigned char buf[MBEDTLS_MD_MAX_SIZE];
247
248 mbedtls_ecp_group_init( &grp );
249 mbedtls_ecp_point_init( &Q );
250 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
251 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
252 memset( buf, 0, sizeof( buf ) );
253
254 /* prepare material for signature */
255 TEST_ASSERT( mbedtls_test_rnd_pseudo_rand( &rnd_info,
256 buf, sizeof( buf ) ) == 0 );
257 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
258 TEST_ASSERT( mbedtls_ecp_gen_keypair( &grp, &d, &Q,
259 &mbedtls_test_rnd_pseudo_rand,
260 &rnd_info ) == 0 );
261
262 TEST_ASSERT( mbedtls_ecdsa_sign( &grp, &r, &s, &d, buf, sizeof( buf ),
263 &mbedtls_test_rnd_pseudo_rand,
264 &rnd_info ) == 0 );
265 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, buf, sizeof( buf ), &Q, &r, &s ) == 0 );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100266
Paul Bakkerbd51b262014-07-10 15:26:12 +0200267exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 mbedtls_ecp_group_free( &grp );
269 mbedtls_ecp_point_free( &Q );
270 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100271}
Paul Bakker33b43f12013-08-20 11:48:36 +0200272/* END_CASE */
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100273
Paul Bakker33b43f12013-08-20 11:48:36 +0200274/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100275void ecdsa_prim_test_vectors( int id, char * d_str, char * xQ_str,
Azim Khan5fcca462018-06-29 11:05:32 +0100276 char * yQ_str, data_t * rnd_buf,
277 data_t * hash, char * r_str, char * s_str,
Azim Khanf1aaec92017-05-30 14:23:15 +0100278 int result )
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100279{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280 mbedtls_ecp_group grp;
281 mbedtls_ecp_point Q;
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200282 mbedtls_mpi d, r, s, r_check, s_check, zero;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200283 mbedtls_test_rnd_buf_info rnd_info;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100284
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285 mbedtls_ecp_group_init( &grp );
286 mbedtls_ecp_point_init( &Q );
287 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
288 mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200289 mbedtls_mpi_init( &zero );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100290
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200291 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 TEST_ASSERT( mbedtls_ecp_point_read_string( &Q, 16, xQ_str, yQ_str ) == 0 );
Werner Lewis24b60782022-07-07 15:08:17 +0100293 TEST_ASSERT( mbedtls_test_read_mpi( &d, d_str ) == 0 );
294 TEST_ASSERT( mbedtls_test_read_mpi( &r_check, r_str ) == 0 );
295 TEST_ASSERT( mbedtls_test_read_mpi( &s_check, s_str ) == 0 );
Gilles Peskinebef30192021-03-24 00:48:57 +0100296 rnd_info.fallback_f_rng = mbedtls_test_rnd_std_rand;
297 rnd_info.fallback_p_rng = NULL;
Azim Khand30ca132017-06-09 04:32:58 +0100298 rnd_info.buf = rnd_buf->x;
299 rnd_info.length = rnd_buf->len;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100300
Azim Khand30ca132017-06-09 04:32:58 +0100301 /* Fix rnd_buf->x by shifting it left if necessary */
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100302 if( grp.nbits % 8 != 0 )
303 {
304 unsigned char shift = 8 - ( grp.nbits % 8 );
305 size_t i;
306
307 for( i = 0; i < rnd_info.length - 1; i++ )
Azim Khand30ca132017-06-09 04:32:58 +0100308 rnd_buf->x[i] = rnd_buf->x[i] << shift | rnd_buf->x[i+1] >> ( 8 - shift );
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100309
Azim Khand30ca132017-06-09 04:32:58 +0100310 rnd_buf->x[rnd_info.length-1] <<= shift;
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100311 }
312
Azim Khand30ca132017-06-09 04:32:58 +0100313 TEST_ASSERT( mbedtls_ecdsa_sign( &grp, &r, &s, &d, hash->x, hash->len,
Ronald Cron351f0ee2020-06-10 12:12:18 +0200314 mbedtls_test_rnd_buffer_rand, &rnd_info ) == result );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100315
Darryl Greenf5bcbed2017-11-17 17:09:31 +0000316 if ( result == 0)
317 {
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200318 /* Check we generated the expected values */
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200319 TEST_EQUAL( mbedtls_mpi_cmp_mpi( &r, &r_check ), 0 );
320 TEST_EQUAL( mbedtls_mpi_cmp_mpi( &s, &s_check ), 0 );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100321
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200322 /* Valid signature */
323 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
324 &Q, &r_check, &s_check ), 0 );
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200325
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200326 /* Invalid signature: wrong public key (G instead of Q) */
327 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
328 &grp.G, &r_check, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200329
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200330 /* Invalid signatures: r or s or both one off */
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200331 TEST_EQUAL( mbedtls_mpi_sub_int( &r, &r_check, 1 ), 0 );
332 TEST_EQUAL( mbedtls_mpi_add_int( &s, &s_check, 1 ), 0 );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200333
334 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
335 &r, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
336 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
337 &r_check, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
338 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
339 &r, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
340
341 /* Invalid signatures: r, s or both (CVE-2022-21449) are zero */
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200342 TEST_EQUAL( mbedtls_mpi_lset( &zero, 0 ), 0 );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200343
344 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200345 &zero, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200346 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200347 &r_check, &zero ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200348 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200349 &zero, &zero ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200350
351 /* Invalid signatures: r, s or both are == N */
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200352 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
353 &grp.N, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
354 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
355 &r_check, &grp.N ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
356 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
357 &grp.N, &grp.N ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
358
359 /* Invalid signatures: r, s or both are negative */
360 TEST_EQUAL( mbedtls_mpi_sub_mpi( &r, &r_check, &grp.N ), 0 );
361 TEST_EQUAL( mbedtls_mpi_sub_mpi( &s, &s_check, &grp.N ), 0 );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200362
363 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
364 &r, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
365 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
366 &r_check, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
367 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
368 &r, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
369
370 /* Invalid signatures: r or s or both are > N */
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200371 TEST_EQUAL( mbedtls_mpi_add_mpi( &r, &r_check, &grp.N ), 0 );
372 TEST_EQUAL( mbedtls_mpi_add_mpi( &s, &s_check, &grp.N ), 0 );
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200373
374 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
375 &r, &s_check ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
376 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
377 &r_check, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
378 TEST_EQUAL( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q,
379 &r, &s ), MBEDTLS_ERR_ECP_VERIFY_FAILED );
Darryl Greenf5bcbed2017-11-17 17:09:31 +0000380 }
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100381
Paul Bakkerbd51b262014-07-10 15:26:12 +0200382exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_ecp_group_free( &grp );
384 mbedtls_ecp_point_free( &Q );
385 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
386 mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200387 mbedtls_mpi_free( &zero );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100388}
Paul Bakker33b43f12013-08-20 11:48:36 +0200389/* END_CASE */
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
Azim Khanf1aaec92017-05-30 14:23:15 +0100392void ecdsa_det_test_vectors( int id, char * d_str, int md_alg, char * msg,
393 char * r_str, char * s_str )
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100394{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 mbedtls_ecp_group grp;
396 mbedtls_mpi d, r, s, r_check, s_check;
397 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100398 size_t hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 mbedtls_ecp_group_init( &grp );
402 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
403 mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100404 memset( hash, 0, sizeof( hash ) );
405
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200406 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Werner Lewis24b60782022-07-07 15:08:17 +0100407 TEST_ASSERT( mbedtls_test_read_mpi( &d, d_str ) == 0 );
408 TEST_ASSERT( mbedtls_test_read_mpi( &r_check, r_str ) == 0 );
409 TEST_ASSERT( mbedtls_test_read_mpi( &s_check, s_str ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakker94b916c2014-04-17 16:07:20 +0200412 TEST_ASSERT( md_info != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 hlen = mbedtls_md_get_size( md_info );
Hanno Becker198611d2018-10-17 13:58:19 +0100414 TEST_ASSERT( mbedtls_md( md_info, (const unsigned char *) msg,
415 strlen( msg ), hash ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100416
Janos Follath651eac82019-01-04 15:51:24 +0000417 TEST_ASSERT(
418 mbedtls_ecdsa_sign_det_ext( &grp, &r, &s, &d, hash, hlen,
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200419 md_alg, mbedtls_test_rnd_std_rand,
420 NULL )
Janos Follath651eac82019-01-04 15:51:24 +0000421 == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
424 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100425
Paul Bakkerbd51b262014-07-10 15:26:12 +0200426exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_ecp_group_free( &grp );
428 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
429 mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100430}
431/* END_CASE */
432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
TRodziewicz40de3c92021-04-07 19:16:18 +0200434void ecdsa_write_read_zero( int id )
435{
436 mbedtls_ecdsa_context ctx;
437 mbedtls_test_rnd_pseudo_info rnd_info;
438 unsigned char hash[32];
439 unsigned char sig[200];
440 size_t sig_len, i;
441
442 mbedtls_ecdsa_init( &ctx );
443 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
444 memset( hash, 0, sizeof( hash ) );
445 memset( sig, 0x2a, sizeof( sig ) );
TRodziewicz40de3c92021-04-07 19:16:18 +0200446
447 /* generate signing key */
448 TEST_ASSERT( mbedtls_ecdsa_genkey( &ctx, id,
449 &mbedtls_test_rnd_pseudo_rand,
450 &rnd_info ) == 0 );
451
452 /* generate and write signature, then read and verify it */
453 TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
454 hash, sizeof( hash ),
455 sig, &sig_len, &mbedtls_test_rnd_pseudo_rand,
456 &rnd_info ) == 0 );
457 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
458 sig, sig_len ) == 0 );
459
460 /* check we didn't write past the announced length */
461 for( i = sig_len; i < sizeof( sig ); i++ )
462 TEST_ASSERT( sig[i] == 0x2a );
463
464 /* try verification with invalid length */
465 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
466 sig, sig_len - 1 ) != 0 );
467 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
468 sig, sig_len + 1 ) != 0 );
469
470 /* try invalid sequence tag */
471 sig[0]++;
472 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
473 sig, sig_len ) != 0 );
474 sig[0]--;
475
476 /* try modifying r */
477 sig[10]++;
478 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
479 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
480 sig[10]--;
481
482 /* try modifying s */
483 sig[sig_len - 1]++;
484 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
485 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
486 sig[sig_len - 1]--;
487
488exit:
489 mbedtls_ecdsa_free( &ctx );
490}
491/* END_CASE */
492
493/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200494void ecdsa_write_read_random( int id )
495{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 mbedtls_ecdsa_context ctx;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200497 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200498 unsigned char hash[32];
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200499 unsigned char sig[200];
500 size_t sig_len, i;
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 mbedtls_ecdsa_init( &ctx );
Ronald Cron351f0ee2020-06-10 12:12:18 +0200503 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200504 memset( hash, 0, sizeof( hash ) );
TRodziewicz40de3c92021-04-07 19:16:18 +0200505 memset( sig, 0x2a, sizeof( sig ) );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200506
TRodziewicz40de3c92021-04-07 19:16:18 +0200507 /* prepare material for signature */
508 TEST_ASSERT( mbedtls_test_rnd_pseudo_rand( &rnd_info,
509 hash, sizeof( hash ) ) == 0 );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200510
TRodziewicz40de3c92021-04-07 19:16:18 +0200511 /* generate signing key */
512 TEST_ASSERT( mbedtls_ecdsa_genkey( &ctx, id,
513 &mbedtls_test_rnd_pseudo_rand,
514 &rnd_info ) == 0 );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200515
TRodziewicz40de3c92021-04-07 19:16:18 +0200516 /* generate and write signature, then read and verify it */
517 TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
518 hash, sizeof( hash ),
519 sig, &sig_len, &mbedtls_test_rnd_pseudo_rand,
520 &rnd_info ) == 0 );
521 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
522 sig, sig_len ) == 0 );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200523
TRodziewicz40de3c92021-04-07 19:16:18 +0200524 /* check we didn't write past the announced length */
525 for( i = sig_len; i < sizeof( sig ); i++ )
526 TEST_ASSERT( sig[i] == 0x2a );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200527
TRodziewicz40de3c92021-04-07 19:16:18 +0200528 /* try verification with invalid length */
529 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
530 sig, sig_len - 1 ) != 0 );
531 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
532 sig, sig_len + 1 ) != 0 );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200533
TRodziewicz40de3c92021-04-07 19:16:18 +0200534 /* try invalid sequence tag */
535 sig[0]++;
536 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
537 sig, sig_len ) != 0 );
538 sig[0]--;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200539
TRodziewicz40de3c92021-04-07 19:16:18 +0200540 /* try modifying r */
541 sig[10]++;
542 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
543 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
544 sig[10]--;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200545
TRodziewicz40de3c92021-04-07 19:16:18 +0200546 /* try modifying s */
547 sig[sig_len - 1]++;
548 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
549 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
550 sig[sig_len - 1]--;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200551
Paul Bakkerbd51b262014-07-10 15:26:12 +0200552exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 mbedtls_ecdsa_free( &ctx );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200554}
555/* END_CASE */
Manuel Pégourié-Gonnard937340b2014-01-06 10:27:16 +0100556
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200557/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Ronald Cron9ed40732020-06-25 09:03:34 +0200558void ecdsa_read_restart( int id, data_t *pk, data_t *hash, data_t *sig,
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200559 int max_ops, int min_restart, int max_restart )
560{
561 mbedtls_ecdsa_context ctx;
562 mbedtls_ecdsa_restart_ctx rs_ctx;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200563 int ret, cnt_restart;
564
565 mbedtls_ecdsa_init( &ctx );
566 mbedtls_ecdsa_restart_init( &rs_ctx );
567
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200568 TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
Ronald Cron9ed40732020-06-25 09:03:34 +0200569 TEST_ASSERT( mbedtls_ecp_point_read_binary( &ctx.grp, &ctx.Q,
570 pk->x, pk->len ) == 0 );
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200571
572 mbedtls_ecp_set_max_ops( max_ops );
573
574 cnt_restart = 0;
575 do {
576 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
Ronald Cron9ed40732020-06-25 09:03:34 +0200577 hash->x, hash->len, sig->x, sig->len, &rs_ctx );
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200578 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
579
580 TEST_ASSERT( ret == 0 );
581 TEST_ASSERT( cnt_restart >= min_restart );
582 TEST_ASSERT( cnt_restart <= max_restart );
583
584 /* try modifying r */
Ronald Cron9ed40732020-06-25 09:03:34 +0200585
586 TEST_ASSERT( sig->len > 10 );
587 sig->x[10]++;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200588 do {
589 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
Ronald Cron9ed40732020-06-25 09:03:34 +0200590 hash->x, hash->len, sig->x, sig->len, &rs_ctx );
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200591 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
592 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Ronald Cron9ed40732020-06-25 09:03:34 +0200593 sig->x[10]--;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200594
595 /* try modifying s */
Ronald Cron9ed40732020-06-25 09:03:34 +0200596 sig->x[sig->len - 1]++;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200597 do {
598 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
Ronald Cron9ed40732020-06-25 09:03:34 +0200599 hash->x, hash->len, sig->x, sig->len, &rs_ctx );
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200600 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
601 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Ronald Cron9ed40732020-06-25 09:03:34 +0200602 sig->x[sig->len - 1]--;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200603
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200604 /* Do we leak memory when aborting an operation?
605 * This test only makes sense when we actually restart */
606 if( min_restart > 0 )
607 {
608 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
Ronald Cron9ed40732020-06-25 09:03:34 +0200609 hash->x, hash->len, sig->x, sig->len, &rs_ctx );
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200610 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
611 }
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200612
613exit:
614 mbedtls_ecdsa_free( &ctx );
615 mbedtls_ecdsa_restart_free( &rs_ctx );
616}
617/* END_CASE */
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200618
619/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
620void ecdsa_write_restart( int id, char *d_str, int md_alg,
Ronald Cron9ed40732020-06-25 09:03:34 +0200621 char *msg, data_t *sig_check,
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200622 int max_ops, int min_restart, int max_restart )
623{
624 int ret, cnt_restart;
625 mbedtls_ecdsa_restart_ctx rs_ctx;
626 mbedtls_ecdsa_context ctx;
627 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
628 unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
Ronald Cron9ed40732020-06-25 09:03:34 +0200629 size_t hlen, slen;
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200630 const mbedtls_md_info_t *md_info;
631
632 mbedtls_ecdsa_restart_init( &rs_ctx );
633 mbedtls_ecdsa_init( &ctx );
634 memset( hash, 0, sizeof( hash ) );
635 memset( sig, 0, sizeof( sig ) );
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200636
637 TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
Werner Lewis24b60782022-07-07 15:08:17 +0100638 TEST_ASSERT( mbedtls_test_read_mpi( &ctx.d, d_str ) == 0 );
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200639
640 md_info = mbedtls_md_info_from_type( md_alg );
641 TEST_ASSERT( md_info != NULL );
642
643 hlen = mbedtls_md_get_size( md_info );
Gilles Peskine84984ae2020-01-21 16:52:08 +0100644 TEST_ASSERT( mbedtls_md( md_info,
645 (const unsigned char *) msg, strlen( msg ),
646 hash ) == 0 );
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200647
648 mbedtls_ecp_set_max_ops( max_ops );
649
650 slen = sizeof( sig );
651 cnt_restart = 0;
652 do {
653 ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
654 md_alg, hash, hlen, sig, &slen, NULL, NULL, &rs_ctx );
655 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
656
657 TEST_ASSERT( ret == 0 );
Ronald Cron9ed40732020-06-25 09:03:34 +0200658 TEST_ASSERT( slen == sig_check->len );
659 TEST_ASSERT( memcmp( sig, sig_check->x, slen ) == 0 );
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200660
661 TEST_ASSERT( cnt_restart >= min_restart );
662 TEST_ASSERT( cnt_restart <= max_restart );
663
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200664 /* Do we leak memory when aborting an operation?
665 * This test only makes sense when we actually restart */
666 if( min_restart > 0 )
667 {
668 ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
669 md_alg, hash, hlen, sig, &slen, NULL, NULL, &rs_ctx );
670 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
671 }
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200672
673exit:
674 mbedtls_ecdsa_restart_free( &rs_ctx );
675 mbedtls_ecdsa_free( &ctx );
676}
677/* END_CASE */
Dave Rodgman535dcce2022-08-10 11:32:07 +0100678
679/* BEGIN_CASE */
680void ecdsa_verify( int grp_id, char * x, char * y, char * r, char * s, int len, int key_is_valid, int expected )
681{
682 uint8_t FUZZ_DATA[] = {
683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 136, 251, 46, 240, 45, 45, 27, 62, 60, 0, 0, 0, 32, 32, 32, 32, 124, 102, 235, 242, 220, 21, 68, 255, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 121, 1, 0, 0, 0, 91, 1, 0, 0, 0, 151, 1, 0, 0, 0, 32, 32, 255, 32, 32, 150, 14, 240, 249, 163, 174, 190, 100, 0, 0, 0, 0, 32, 32, 32, 32, 51, 48, 79, 125, 229, 21, 223, 118, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
685 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
686 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
687 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
688 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
689 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
690 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
691 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
692 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
693 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
694 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
695 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
696 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
697 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
698 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
699 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
700 };
701
702 mbedtls_ecdsa_context ctx;
703 mbedtls_mpi sig_r, sig_s;
704 const mbedtls_ecp_curve_info *curve_info;
705
706 mbedtls_ecdsa_init( &ctx );
707 mbedtls_mpi_init( &sig_r );
708 mbedtls_mpi_init( &sig_s );
709
710 /* Prepare ECP group context */
711 curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
712 TEST_ASSERT( curve_info != NULL );
713 TEST_EQUAL( mbedtls_ecp_group_load( &ctx.grp, curve_info->grp_id ), 0 );
714
715 /* Prepare public key */
716 TEST_EQUAL( mbedtls_mpi_read_string( &ctx.Q.X, 16, x ), 0 );
717 TEST_EQUAL( mbedtls_mpi_read_string( &ctx.Q.Y, 16, y ), 0 );
718 TEST_EQUAL( mbedtls_mpi_lset( &ctx.Q.Z, 1 ), 0 );
719
720 /* Prepare signature R & S */
721 TEST_EQUAL( mbedtls_mpi_read_string( &sig_r, 16, r ), 0 );
722 TEST_EQUAL( mbedtls_mpi_read_string( &sig_s, 16, s ), 0 );
723
724 /* Test whether public key has expected validity */
725 TEST_EQUAL( mbedtls_ecp_check_pubkey( &ctx.grp, &ctx.Q ), key_is_valid ? 0 : MBEDTLS_ERR_ECP_INVALID_KEY );
726
727 /* Verification */
728 int result = mbedtls_ecdsa_verify( &ctx.grp, FUZZ_DATA, ( size_t ) len, &ctx.Q, &sig_r, &sig_s );
729
730 TEST_EQUAL( result, expected );
731
732 if ( !key_is_valid ) {
733 /* Invalid public key must always fail */
734 TEST_ASSERT( result != 0 );
735 }
736
737exit:
738 mbedtls_ecdsa_free( &ctx );
739 mbedtls_mpi_free( &sig_r );
740 mbedtls_mpi_free( &sig_s );
741}
742/* END_CASE */