blob: d091a354dbad8ca77aa9c4576a82273c278a4bb2 [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
Hanno Beckeraf05a902018-12-14 16:43:38 +000010/* 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 ),
34 rnd_std_rand, NULL ) );
35 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
36 mbedtls_ecdsa_sign( &grp, NULL, &m, &m,
37 buf, sizeof( buf ),
38 rnd_std_rand, NULL ) );
39 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
40 mbedtls_ecdsa_sign( &grp, &m, NULL, &m,
41 buf, sizeof( buf ),
42 rnd_std_rand, NULL ) );
43 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
44 mbedtls_ecdsa_sign( &grp, &m, &m, NULL,
45 buf, sizeof( buf ),
46 rnd_std_rand, NULL ) );
47 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
48 mbedtls_ecdsa_sign( &grp, &m, &m, &m,
49 NULL, sizeof( buf ),
50 rnd_std_rand, NULL ) );
51 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
52 mbedtls_ecdsa_sign( &grp, &m, &m, &m,
53 buf, sizeof( buf ),
54 NULL, NULL ) );
55
56#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
57 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
58 mbedtls_ecdsa_sign_det( NULL, &m, &m, &m,
59 buf, sizeof( buf ),
60 valid_md ) );
61 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
62 mbedtls_ecdsa_sign_det( &grp, NULL, &m, &m,
63 buf, sizeof( buf ),
64 valid_md ) );
65 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
66 mbedtls_ecdsa_sign_det( &grp, &m, NULL, &m,
67 buf, sizeof( buf ),
68 valid_md ) );
69 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
70 mbedtls_ecdsa_sign_det( &grp, &m, &m, NULL,
71 buf, sizeof( buf ),
72 valid_md ) );
73 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
74 mbedtls_ecdsa_sign_det( &grp, &m, &m, &m,
75 NULL, sizeof( buf ),
76 valid_md ) );
77#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
78
79 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
80 mbedtls_ecdsa_verify( NULL,
81 buf, sizeof( buf ),
82 &P, &m, &m ) );
83 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
84 mbedtls_ecdsa_verify( &grp,
85 NULL, sizeof( buf ),
86 &P, &m, &m ) );
87 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
88 mbedtls_ecdsa_verify( &grp,
89 buf, sizeof( buf ),
90 NULL, &m, &m ) );
91 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
92 mbedtls_ecdsa_verify( &grp,
93 buf, sizeof( buf ),
94 &P, NULL, &m ) );
95 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
96 mbedtls_ecdsa_verify( &grp,
97 buf, sizeof( buf ),
98 &P, &m, NULL ) );
99
100 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
101 mbedtls_ecdsa_write_signature( NULL,
102 valid_md,
103 buf, sizeof( buf ),
104 buf, &slen,
105 rnd_std_rand,
106 NULL ) );
107 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
108 mbedtls_ecdsa_write_signature( &ctx,
109 valid_md,
110 NULL, sizeof( buf ),
111 buf, &slen,
112 rnd_std_rand,
113 NULL ) );
114 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
115 mbedtls_ecdsa_write_signature( &ctx,
116 valid_md,
117 buf, sizeof( buf ),
118 NULL, &slen,
119 rnd_std_rand,
120 NULL ) );
121 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
122 mbedtls_ecdsa_write_signature( &ctx,
123 valid_md,
124 buf, sizeof( buf ),
125 buf, NULL,
126 rnd_std_rand,
127 NULL ) );
128
129 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
130 mbedtls_ecdsa_write_signature_restartable( NULL,
131 valid_md,
132 buf, sizeof( buf ),
133 buf, &slen,
134 rnd_std_rand,
135 NULL, NULL ) );
136 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
137 mbedtls_ecdsa_write_signature_restartable( &ctx,
138 valid_md,
139 NULL, sizeof( buf ),
140 buf, &slen,
141 rnd_std_rand,
142 NULL, NULL ) );
143 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
144 mbedtls_ecdsa_write_signature_restartable( &ctx,
145 valid_md,
146 buf, sizeof( buf ),
147 NULL, &slen,
148 rnd_std_rand,
149 NULL, NULL ) );
150 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
151 mbedtls_ecdsa_write_signature_restartable( &ctx,
152 valid_md,
153 buf, sizeof( buf ),
154 buf, NULL,
155 rnd_std_rand,
156 NULL, NULL ) );
157
158#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_DEPRECATED_REMOVED)
159 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
160 mbedtls_ecdsa_write_signature_det( NULL,
161 buf,
162 sizeof( buf ),
163 buf, &slen,
164 valid_md ) );
165 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
166 mbedtls_ecdsa_write_signature_det( &ctx,
167 NULL,
168 sizeof( buf ),
169 buf, &slen,
170 valid_md ) );
171 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
172 mbedtls_ecdsa_write_signature_det( &ctx,
173 buf,
174 sizeof( buf ),
175 NULL, &slen,
176 valid_md ) );
177 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
178 mbedtls_ecdsa_write_signature_det( &ctx,
179 buf,
180 sizeof( buf ),
181 buf, NULL,
182 valid_md ) );
183#endif /* MBEDTLS_ECDSA_DETERMINISTIC && !MBEDTLS_DEPRECATED_REMOVED */
184
185 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
186 mbedtls_ecdsa_read_signature( NULL,
187 buf, sizeof( buf ),
188 buf, sizeof( buf ) ) );
189 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
190 mbedtls_ecdsa_read_signature( &ctx,
191 NULL, sizeof( buf ),
192 buf, sizeof( buf ) ) );
193 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
194 mbedtls_ecdsa_read_signature( &ctx,
195 buf, sizeof( buf ),
196 NULL, sizeof( buf ) ) );
197
198 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
199 mbedtls_ecdsa_read_signature_restartable( NULL,
200 buf, sizeof( buf ),
201 buf, sizeof( buf ),
202 NULL ) );
203 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
204 mbedtls_ecdsa_read_signature_restartable( &ctx,
205 NULL, sizeof( buf ),
206 buf, sizeof( buf ),
207 NULL ) );
208 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
209 mbedtls_ecdsa_read_signature_restartable( &ctx,
210 buf, sizeof( buf ),
211 NULL, sizeof( buf ),
212 NULL ) );
213
214 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
215 mbedtls_ecdsa_genkey( NULL, valid_group,
216 rnd_std_rand, NULL ) );
217 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
218 mbedtls_ecdsa_genkey( &ctx, valid_group,
219 NULL, NULL ) );
220
221
222 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
223 mbedtls_ecdsa_from_keypair( NULL, &key ) );
224 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
225 mbedtls_ecdsa_from_keypair( &ctx, NULL ) );
226
227exit:
228 return;
229}
230/* END_CASE */
231
Paul Bakker33b43f12013-08-20 11:48:36 +0200232/* BEGIN_CASE */
233void ecdsa_prim_random( int id )
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100234{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235 mbedtls_ecp_group grp;
236 mbedtls_ecp_point Q;
237 mbedtls_mpi d, r, s;
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100238 rnd_pseudo_info rnd_info;
Ron Eldor7a977882018-11-19 13:45:22 +0200239 unsigned char buf[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100240
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 mbedtls_ecp_group_init( &grp );
242 mbedtls_ecp_point_init( &Q );
243 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100244 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
Manuel Pégourié-Gonnard450a1632013-01-27 09:08:18 +0100245 memset( buf, 0, sizeof( buf ) );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100246
247 /* prepare material for signature */
248 TEST_ASSERT( rnd_pseudo_rand( &rnd_info, buf, sizeof( buf ) ) == 0 );
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200249 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 TEST_ASSERT( mbedtls_ecp_gen_keypair( &grp, &d, &Q, &rnd_pseudo_rand, &rnd_info )
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100251 == 0 );
252
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 TEST_ASSERT( mbedtls_ecdsa_sign( &grp, &r, &s, &d, buf, sizeof( buf ),
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100254 &rnd_pseudo_rand, &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, buf, sizeof( buf ), &Q, &r, &s ) == 0 );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100256
Paul Bakkerbd51b262014-07-10 15:26:12 +0200257exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 mbedtls_ecp_group_free( &grp );
259 mbedtls_ecp_point_free( &Q );
260 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100261}
Paul Bakker33b43f12013-08-20 11:48:36 +0200262/* END_CASE */
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100263
Paul Bakker33b43f12013-08-20 11:48:36 +0200264/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100265void ecdsa_prim_test_vectors( int id, char * d_str, char * xQ_str,
Azim Khan5fcca462018-06-29 11:05:32 +0100266 char * yQ_str, data_t * rnd_buf,
267 data_t * hash, char * r_str, char * s_str,
Azim Khanf1aaec92017-05-30 14:23:15 +0100268 int result )
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100269{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 mbedtls_ecp_group grp;
271 mbedtls_ecp_point Q;
272 mbedtls_mpi d, r, s, r_check, s_check;
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100273 rnd_buf_info rnd_info;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 mbedtls_ecp_group_init( &grp );
276 mbedtls_ecp_point_init( &Q );
277 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
278 mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100279
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200280 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281 TEST_ASSERT( mbedtls_ecp_point_read_string( &Q, 16, xQ_str, yQ_str ) == 0 );
282 TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
283 TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
284 TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
Azim Khand30ca132017-06-09 04:32:58 +0100285 rnd_info.buf = rnd_buf->x;
286 rnd_info.length = rnd_buf->len;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100287
Azim Khand30ca132017-06-09 04:32:58 +0100288 /* Fix rnd_buf->x by shifting it left if necessary */
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100289 if( grp.nbits % 8 != 0 )
290 {
291 unsigned char shift = 8 - ( grp.nbits % 8 );
292 size_t i;
293
294 for( i = 0; i < rnd_info.length - 1; i++ )
Azim Khand30ca132017-06-09 04:32:58 +0100295 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 +0100296
Azim Khand30ca132017-06-09 04:32:58 +0100297 rnd_buf->x[rnd_info.length-1] <<= shift;
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100298 }
299
Azim Khand30ca132017-06-09 04:32:58 +0100300 TEST_ASSERT( mbedtls_ecdsa_sign( &grp, &r, &s, &d, hash->x, hash->len,
Darryl Greenf5bcbed2017-11-17 17:09:31 +0000301 rnd_buffer_rand, &rnd_info ) == result );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100302
Darryl Greenf5bcbed2017-11-17 17:09:31 +0000303 if ( result == 0)
304 {
305 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
306 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100307
Azim Khand30ca132017-06-09 04:32:58 +0100308 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q, &r_check, &s_check ) == 0 );
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200309
310 TEST_ASSERT( mbedtls_mpi_sub_int( &r, &r, 1 ) == 0 );
311 TEST_ASSERT( mbedtls_mpi_add_int( &s, &s, 1 ) == 0 );
312
Manuel Pégourié-Gonnard125af942018-09-11 11:08:12 +0200313 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200314 &Q, &r, &s_check ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnard125af942018-09-11 11:08:12 +0200315 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200316 &Q, &r_check, &s ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnard125af942018-09-11 11:08:12 +0200317 TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200318 &grp.G, &r_check, &s_check ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Darryl Greenf5bcbed2017-11-17 17:09:31 +0000319 }
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100320
Paul Bakkerbd51b262014-07-10 15:26:12 +0200321exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 mbedtls_ecp_group_free( &grp );
323 mbedtls_ecp_point_free( &Q );
324 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
325 mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100326}
Paul Bakker33b43f12013-08-20 11:48:36 +0200327/* END_CASE */
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
Azim Khanf1aaec92017-05-30 14:23:15 +0100330void ecdsa_det_test_vectors( int id, char * d_str, int md_alg, char * msg,
331 char * r_str, char * s_str )
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100332{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_ecp_group grp;
334 mbedtls_mpi d, r, s, r_check, s_check;
335 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100336 size_t hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 mbedtls_ecp_group_init( &grp );
340 mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
341 mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100342 memset( hash, 0, sizeof( hash ) );
343
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200344 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345 TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
346 TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
347 TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakker94b916c2014-04-17 16:07:20 +0200350 TEST_ASSERT( md_info != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 hlen = mbedtls_md_get_size( md_info );
Hanno Becker198611d2018-10-17 13:58:19 +0100352 TEST_ASSERT( mbedtls_md( md_info, (const unsigned char *) msg,
353 strlen( msg ), hash ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100354
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 TEST_ASSERT( mbedtls_ecdsa_sign_det( &grp, &r, &s, &d, hash, hlen, md_alg ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100356
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
358 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100359
Paul Bakkerbd51b262014-07-10 15:26:12 +0200360exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 mbedtls_ecp_group_free( &grp );
362 mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
363 mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100364}
365/* END_CASE */
366
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200368void ecdsa_write_read_random( int id )
369{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 mbedtls_ecdsa_context ctx;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200371 rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200372 unsigned char hash[32];
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200373 unsigned char sig[200];
374 size_t sig_len, i;
375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 mbedtls_ecdsa_init( &ctx );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200377 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
378 memset( hash, 0, sizeof( hash ) );
379 memset( sig, 0x2a, sizeof( sig ) );
380
381 /* prepare material for signature */
382 TEST_ASSERT( rnd_pseudo_rand( &rnd_info, hash, sizeof( hash ) ) == 0 );
383
384 /* generate signing key */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 TEST_ASSERT( mbedtls_ecdsa_genkey( &ctx, id, &rnd_pseudo_rand, &rnd_info ) == 0 );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200386
387 /* generate and write signature, then read and verify it */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200389 hash, sizeof( hash ),
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200390 sig, &sig_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200392 sig, sig_len ) == 0 );
393
394 /* check we didn't write past the announced length */
395 for( i = sig_len; i < sizeof( sig ); i++ )
396 TEST_ASSERT( sig[i] == 0x2a );
397
398 /* try verification with invalid length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200400 sig, sig_len - 1 ) != 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200402 sig, sig_len + 1 ) != 0 );
403
404 /* try invalid sequence tag */
405 sig[0]++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200407 sig, sig_len ) != 0 );
408 sig[0]--;
409
410 /* try modifying r */
411 sig[10]++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
Manuel Pégourié-Gonnard1ed25052017-04-21 10:04:02 +0200413 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200414 sig[10]--;
415
416 /* try modifying s */
417 sig[sig_len - 1]++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
Manuel Pégourié-Gonnard1ed25052017-04-21 10:04:02 +0200419 sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200420 sig[sig_len - 1]--;
421
Paul Bakkerbd51b262014-07-10 15:26:12 +0200422exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_ecdsa_free( &ctx );
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200424}
425/* END_CASE */
Manuel Pégourié-Gonnard937340b2014-01-06 10:27:16 +0100426
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200427/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
428void ecdsa_read_restart( int id, char *k_str, char *h_str, char *s_str,
429 int max_ops, int min_restart, int max_restart )
430{
431 mbedtls_ecdsa_context ctx;
432 mbedtls_ecdsa_restart_ctx rs_ctx;
433 unsigned char hash[64];
434 unsigned char sig[200];
435 unsigned char pk[65];
436 size_t sig_len, hash_len, pk_len;
437 int ret, cnt_restart;
438
439 mbedtls_ecdsa_init( &ctx );
440 mbedtls_ecdsa_restart_init( &rs_ctx );
441
442 hash_len = unhexify(hash, h_str);
443 sig_len = unhexify(sig, s_str);
444 pk_len = unhexify(pk, k_str);
445
446 TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
447 TEST_ASSERT( mbedtls_ecp_point_read_binary( &ctx.grp, &ctx.Q, pk, pk_len ) == 0 );
448
449 mbedtls_ecp_set_max_ops( max_ops );
450
451 cnt_restart = 0;
452 do {
453 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
454 hash, hash_len, sig, sig_len, &rs_ctx );
455 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
456
457 TEST_ASSERT( ret == 0 );
458 TEST_ASSERT( cnt_restart >= min_restart );
459 TEST_ASSERT( cnt_restart <= max_restart );
460
461 /* try modifying r */
462 sig[10]++;
463 do {
464 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
465 hash, hash_len, sig, sig_len, &rs_ctx );
466 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
467 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
468 sig[10]--;
469
470 /* try modifying s */
471 sig[sig_len - 1]++;
472 do {
473 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
474 hash, hash_len, sig, sig_len, &rs_ctx );
475 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
476 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
477 sig[sig_len - 1]--;
478
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200479 /* Do we leak memory when aborting an operation?
480 * This test only makes sense when we actually restart */
481 if( min_restart > 0 )
482 {
483 ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
484 hash, hash_len, sig, sig_len, &rs_ctx );
485 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
486 }
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200487
488exit:
489 mbedtls_ecdsa_free( &ctx );
490 mbedtls_ecdsa_restart_free( &rs_ctx );
491}
492/* END_CASE */
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200493
494/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
495void ecdsa_write_restart( int id, char *d_str, int md_alg,
496 char *msg, char *sig_str,
497 int max_ops, int min_restart, int max_restart )
498{
499 int ret, cnt_restart;
500 mbedtls_ecdsa_restart_ctx rs_ctx;
501 mbedtls_ecdsa_context ctx;
502 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
503 unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
504 unsigned char sig_check[MBEDTLS_ECDSA_MAX_LEN];
505 size_t hlen, slen, slen_check;
506 const mbedtls_md_info_t *md_info;
507
508 mbedtls_ecdsa_restart_init( &rs_ctx );
509 mbedtls_ecdsa_init( &ctx );
510 memset( hash, 0, sizeof( hash ) );
511 memset( sig, 0, sizeof( sig ) );
512 memset( sig_check, 0, sizeof( sig_check ) );
513
514 TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
515 TEST_ASSERT( mbedtls_mpi_read_string( &ctx.d, 16, d_str ) == 0 );
516 slen_check = unhexify( sig_check, sig_str );
517
518 md_info = mbedtls_md_info_from_type( md_alg );
519 TEST_ASSERT( md_info != NULL );
520
521 hlen = mbedtls_md_get_size( md_info );
522 mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
523
524 mbedtls_ecp_set_max_ops( max_ops );
525
526 slen = sizeof( sig );
527 cnt_restart = 0;
528 do {
529 ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
530 md_alg, hash, hlen, sig, &slen, NULL, NULL, &rs_ctx );
531 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
532
533 TEST_ASSERT( ret == 0 );
534 TEST_ASSERT( slen == slen_check );
535 TEST_ASSERT( memcmp( sig, sig_check, slen ) == 0 );
536
537 TEST_ASSERT( cnt_restart >= min_restart );
538 TEST_ASSERT( cnt_restart <= max_restart );
539
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200540 /* Do we leak memory when aborting an operation?
541 * This test only makes sense when we actually restart */
542 if( min_restart > 0 )
543 {
544 ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
545 md_alg, hash, hlen, sig, &slen, NULL, NULL, &rs_ctx );
546 TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
547 }
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200548
549exit:
550 mbedtls_ecdsa_restart_free( &rs_ctx );
551 mbedtls_ecdsa_free( &ctx );
552}
553/* END_CASE */