blob: d6bed7f4c3722b50847856d78cf757949a59e5a8 [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/ecdh.h"
Gilles Peskine552563b2018-11-07 22:07:58 +01003
4static int load_public_key( int grp_id, data_t *point,
5 mbedtls_ecp_keypair *ecp )
6{
7 int ok = 0;
8 TEST_ASSERT( mbedtls_ecp_group_load( &ecp->grp, grp_id ) == 0 );
9 TEST_ASSERT( mbedtls_ecp_point_read_binary( &ecp->grp,
10 &ecp->Q,
11 point->x,
12 point->len ) == 0 );
13 TEST_ASSERT( mbedtls_ecp_check_pubkey( &ecp->grp,
14 &ecp->Q ) == 0 );
15 ok = 1;
16exit:
17 return( ok );
18}
19
20static int load_private_key( int grp_id, data_t *private_key,
21 mbedtls_ecp_keypair *ecp,
22 rnd_pseudo_info *rnd_info )
23{
24 int ok = 0;
Janos Follath171a7ef2019-02-15 16:17:45 +000025 TEST_ASSERT( mbedtls_ecp_read_key( grp_id, ecp,
26 private_key->x,
27 private_key->len ) == 0 );
Gilles Peskine552563b2018-11-07 22:07:58 +010028 TEST_ASSERT( mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) == 0 );
29 /* Calculate the public key from the private key. */
30 TEST_ASSERT( mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d,
31 &ecp->grp.G,
32 &rnd_pseudo_rand, rnd_info ) == 0 );
33 ok = 1;
34exit:
35 return( ok );
36}
37
Paul Bakker33b43f12013-08-20 11:48:36 +020038/* END_HEADER */
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +010039
Paul Bakker33b43f12013-08-20 11:48:36 +020040/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041 * depends_on:MBEDTLS_ECDH_C
Paul Bakker33b43f12013-08-20 11:48:36 +020042 * END_DEPENDENCIES
43 */
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +010044
Paul Bakker33b43f12013-08-20 11:48:36 +020045/* BEGIN_CASE */
Hanno Becker4c818482018-12-17 18:32:22 +000046void ecdh_valid_param( )
47{
48 TEST_VALID_PARAM( mbedtls_ecdh_free( NULL ) );
49}
50/* END_CASE */
51
52/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
53void ecdh_invalid_param( )
54{
55 mbedtls_ecp_group grp;
56 mbedtls_ecdh_context ctx;
57 mbedtls_mpi m;
58 mbedtls_ecp_point P;
59 mbedtls_ecp_keypair kp;
60 size_t olen;
61 unsigned char buf[42] = { 0 };
62 const unsigned char *buf_null = NULL;
63 size_t const buflen = sizeof( buf );
64 int invalid_side = 42;
65 mbedtls_ecp_group_id valid_grp = MBEDTLS_ECP_DP_SECP192R1;
66
67 TEST_INVALID_PARAM( mbedtls_ecdh_init( NULL ) );
68
69#if defined(MBEDTLS_ECP_RESTARTABLE)
70 TEST_INVALID_PARAM( mbedtls_ecdh_enable_restart( NULL ) );
71#endif /* MBEDTLS_ECP_RESTARTABLE */
72
73 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
74 mbedtls_ecdh_gen_public( NULL, &m, &P,
75 rnd_std_rand, NULL ) );
76 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
77 mbedtls_ecdh_gen_public( &grp, NULL, &P,
78 rnd_std_rand, NULL ) );
79 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
80 mbedtls_ecdh_gen_public( &grp, &m, NULL,
81 rnd_std_rand, NULL ) );
82 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
83 mbedtls_ecdh_gen_public( &grp, &m, &P,
84 NULL, NULL ) );
85
86 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
87 mbedtls_ecdh_compute_shared( NULL, &m, &P, &m,
88 rnd_std_rand, NULL ) );
89 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
90 mbedtls_ecdh_compute_shared( &grp, NULL, &P, &m,
91 rnd_std_rand, NULL ) );
92 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
93 mbedtls_ecdh_compute_shared( &grp, &m, NULL, &m,
94 rnd_std_rand, NULL ) );
95 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
96 mbedtls_ecdh_compute_shared( &grp, &m, &P, NULL,
97 rnd_std_rand, NULL ) );
98
99 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
100 mbedtls_ecdh_setup( NULL, valid_grp ) );
101
102 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
103 mbedtls_ecdh_make_params( NULL, &olen,
104 buf, buflen,
105 rnd_std_rand, NULL ) );
106 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
107 mbedtls_ecdh_make_params( &ctx, NULL,
108 buf, buflen,
109 rnd_std_rand, NULL ) );
110 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
111 mbedtls_ecdh_make_params( &ctx, &olen,
112 NULL, buflen,
113 rnd_std_rand, NULL ) );
114 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
115 mbedtls_ecdh_make_params( &ctx, &olen,
116 buf, buflen,
117 NULL, NULL ) );
118
119 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
120 mbedtls_ecdh_read_params( NULL,
121 (const unsigned char**) &buf,
122 buf ) );
123 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
124 mbedtls_ecdh_read_params( &ctx, &buf_null,
125 buf ) );
126 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
127 mbedtls_ecdh_read_params( &ctx, NULL, buf ) );
128 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
129 mbedtls_ecdh_read_params( &ctx,
130 (const unsigned char**) &buf,
131 NULL ) );
132
133 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
134 mbedtls_ecdh_get_params( NULL, &kp,
135 MBEDTLS_ECDH_OURS ) );
136 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
137 mbedtls_ecdh_get_params( &ctx, NULL,
138 MBEDTLS_ECDH_OURS ) );
139 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
140 mbedtls_ecdh_get_params( &ctx, &kp,
141 invalid_side ) );
142
143 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
144 mbedtls_ecdh_make_public( NULL, &olen,
145 buf, buflen,
146 rnd_std_rand,
147 NULL ) );
148 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
149 mbedtls_ecdh_make_public( &ctx, NULL,
150 buf, buflen,
151 rnd_std_rand,
152 NULL ) );
153 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
154 mbedtls_ecdh_make_public( &ctx, &olen,
155 NULL, buflen,
156 rnd_std_rand,
157 NULL ) );
158 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
159 mbedtls_ecdh_make_public( &ctx, &olen,
160 buf, buflen,
161 NULL,
162 NULL ) );
163
164 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
165 mbedtls_ecdh_read_public( NULL, buf, buflen ) );
166 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
167 mbedtls_ecdh_read_public( &ctx, NULL, buflen ) );
168
169 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
170 mbedtls_ecdh_calc_secret( NULL, &olen, buf, buflen,
171 rnd_std_rand,
172 NULL ) );
173 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
174 mbedtls_ecdh_calc_secret( &ctx, NULL, buf, buflen,
175 rnd_std_rand,
176 NULL ) );
177 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
178 mbedtls_ecdh_calc_secret( &ctx, &olen, NULL, buflen,
179 rnd_std_rand,
180 NULL ) );
181
182exit:
183 return;
184}
185/* END_CASE */
186
187/* BEGIN_CASE */
Paul Bakker33b43f12013-08-20 11:48:36 +0200188void ecdh_primitive_random( int id )
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100189{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190 mbedtls_ecp_group grp;
191 mbedtls_ecp_point qA, qB;
192 mbedtls_mpi dA, dB, zA, zB;
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100193 rnd_pseudo_info rnd_info;
194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 mbedtls_ecp_group_init( &grp );
196 mbedtls_ecp_point_init( &qA ); mbedtls_ecp_point_init( &qB );
197 mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &dB );
198 mbedtls_mpi_init( &zA ); mbedtls_mpi_init( &zB );
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100199 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
200
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200201 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dA, &qA, &rnd_pseudo_rand, &rnd_info )
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100204 == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dB, &qB, &rnd_pseudo_rand, &rnd_info )
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100206 == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA,
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +0200208 &rnd_pseudo_rand, &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB,
Manuel Pégourié-Gonnarde09d2f82013-09-02 14:29:09 +0200210 NULL, NULL ) == 0 );
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &zB ) == 0 );
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100213
Paul Bakkerbd51b262014-07-10 15:26:12 +0200214exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 mbedtls_ecp_group_free( &grp );
216 mbedtls_ecp_point_free( &qA ); mbedtls_ecp_point_free( &qB );
217 mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &dB );
218 mbedtls_mpi_free( &zA ); mbedtls_mpi_free( &zB );
Manuel Pégourié-Gonnard61ce13b2013-01-26 16:20:32 +0100219}
Paul Bakker33b43f12013-08-20 11:48:36 +0200220/* END_CASE */
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100221
Paul Bakker33b43f12013-08-20 11:48:36 +0200222/* BEGIN_CASE */
Azim Khan5fcca462018-06-29 11:05:32 +0100223void ecdh_primitive_testvec( int id, data_t * rnd_buf_A, char * xA_str,
224 char * yA_str, data_t * rnd_buf_B,
Azim Khand30ca132017-06-09 04:32:58 +0100225 char * xB_str, char * yB_str, char * z_str )
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100226{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 mbedtls_ecp_group grp;
228 mbedtls_ecp_point qA, qB;
229 mbedtls_mpi dA, dB, zA, zB, check;
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100230 rnd_buf_info rnd_info_A, rnd_info_B;
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232 mbedtls_ecp_group_init( &grp );
233 mbedtls_ecp_point_init( &qA ); mbedtls_ecp_point_init( &qB );
234 mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &dB );
235 mbedtls_mpi_init( &zA ); mbedtls_mpi_init( &zB ); mbedtls_mpi_init( &check );
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100236
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200237 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100238
Azim Khand30ca132017-06-09 04:32:58 +0100239 rnd_info_A.buf = rnd_buf_A->x;
240 rnd_info_A.length = rnd_buf_A->len;
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100241
Azim Khand30ca132017-06-09 04:32:58 +0100242 /* Fix rnd_buf_A->x by shifting it left if necessary */
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100243 if( grp.nbits % 8 != 0 )
244 {
245 unsigned char shift = 8 - ( grp.nbits % 8 );
246 size_t i;
247
248 for( i = 0; i < rnd_info_A.length - 1; i++ )
Azim Khand30ca132017-06-09 04:32:58 +0100249 rnd_buf_A->x[i] = rnd_buf_A->x[i] << shift
250 | rnd_buf_A->x[i+1] >> ( 8 - shift );
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100251
Azim Khand30ca132017-06-09 04:32:58 +0100252 rnd_buf_A->x[rnd_info_A.length-1] <<= shift;
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100253 }
254
Azim Khand30ca132017-06-09 04:32:58 +0100255 rnd_info_B.buf = rnd_buf_B->x;
256 rnd_info_B.length = rnd_buf_B->len;
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100257
Azim Khand30ca132017-06-09 04:32:58 +0100258 /* Fix rnd_buf_B->x by shifting it left if necessary */
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100259 if( grp.nbits % 8 != 0 )
260 {
261 unsigned char shift = 8 - ( grp.nbits % 8 );
262 size_t i;
263
264 for( i = 0; i < rnd_info_B.length - 1; i++ )
Azim Khand30ca132017-06-09 04:32:58 +0100265 rnd_buf_B->x[i] = rnd_buf_B->x[i] << shift
266 | rnd_buf_B->x[i+1] >> ( 8 - shift );
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100267
Azim Khand30ca132017-06-09 04:32:58 +0100268 rnd_buf_B->x[rnd_info_B.length-1] <<= shift;
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100269 }
270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dA, &qA,
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100272 rnd_buffer_rand, &rnd_info_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273 TEST_ASSERT( ! mbedtls_ecp_is_zero( &qA ) );
274 TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, xA_str ) == 0 );
275 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.X, &check ) == 0 );
276 TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, yA_str ) == 0 );
277 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.Y, &check ) == 0 );
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100278
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200279 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dB, &qB,
Manuel Pégourié-Gonnard544416a2014-01-23 16:55:18 +0100280 rnd_buffer_rand, &rnd_info_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281 TEST_ASSERT( ! mbedtls_ecp_is_zero( &qB ) );
282 TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, xB_str ) == 0 );
283 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.X, &check ) == 0 );
284 TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, yB_str ) == 0 );
285 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.Y, &check ) == 0 );
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 TEST_ASSERT( mbedtls_mpi_read_string( &check, 16, z_str ) == 0 );
288 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA, NULL, NULL ) == 0 );
289 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &check ) == 0 );
290 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB, NULL, NULL ) == 0 );
291 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zB, &check ) == 0 );
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100292
Paul Bakkerbd51b262014-07-10 15:26:12 +0200293exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 mbedtls_ecp_group_free( &grp );
295 mbedtls_ecp_point_free( &qA ); mbedtls_ecp_point_free( &qB );
296 mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &dB );
297 mbedtls_mpi_free( &zA ); mbedtls_mpi_free( &zB ); mbedtls_mpi_free( &check );
Manuel Pégourié-Gonnard007b7172013-01-27 08:56:21 +0100298}
Paul Bakker33b43f12013-08-20 11:48:36 +0200299/* END_CASE */
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100300
Paul Bakker33b43f12013-08-20 11:48:36 +0200301/* BEGIN_CASE */
302void ecdh_exchange( int id )
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100303{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304 mbedtls_ecdh_context srv, cli;
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100305 unsigned char buf[1000];
306 const unsigned char *vbuf;
307 size_t len;
308 rnd_pseudo_info rnd_info;
Janos Follath36c5f7f2018-10-30 14:08:52 +0000309 unsigned char res_buf[1000];
310 size_t res_len;
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312 mbedtls_ecdh_init( &srv );
313 mbedtls_ecdh_init( &cli );
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100314 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
315
Janos Follathfc03e8d2018-10-04 17:17:54 +0100316 TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 );
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100317
318 memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000,
Janos Follathfc03e8d2018-10-04 17:17:54 +0100320 &rnd_pseudo_rand, &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100322
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100323 memset( buf, 0x00, sizeof( buf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000,
Janos Follathfc03e8d2018-10-04 17:17:54 +0100325 &rnd_pseudo_rand, &rnd_info ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard5cceb412013-02-11 21:51:45 +0100327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000,
Janos Follath36c5f7f2018-10-30 14:08:52 +0000329 &rnd_pseudo_rand, &rnd_info ) == 0 );
330 TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &res_len, res_buf, 1000,
331 NULL, NULL ) == 0 );
332 TEST_ASSERT( len == res_len );
333 TEST_ASSERT( memcmp( buf, res_buf, len ) == 0 );
Manuel Pégourié-Gonnard424fda52013-02-11 22:05:42 +0100334
Paul Bakkerbd51b262014-07-10 15:26:12 +0200335exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 mbedtls_ecdh_free( &srv );
337 mbedtls_ecdh_free( &cli );
Manuel Pégourié-Gonnard854fbd72013-02-11 20:28:55 +0100338}
Paul Bakker33b43f12013-08-20 11:48:36 +0200339/* END_CASE */
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200340
341/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
342void ecdh_restart( int id, char *dA_str, char *dB_str, char *z_str,
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200343 int enable, int max_ops, int min_restart, int max_restart )
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200344{
345 int ret;
346 mbedtls_ecdh_context srv, cli;
347 unsigned char buf[1000];
348 const unsigned char *vbuf;
349 size_t len;
350 unsigned char z[MBEDTLS_ECP_MAX_BYTES];
351 size_t z_len;
352 unsigned char rnd_buf_A[MBEDTLS_ECP_MAX_BYTES];
353 unsigned char rnd_buf_B[MBEDTLS_ECP_MAX_BYTES];
354 rnd_buf_info rnd_info_A, rnd_info_B;
355 int cnt_restart;
Janos Follath36c5f7f2018-10-30 14:08:52 +0000356 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200357
Janos Follath36c5f7f2018-10-30 14:08:52 +0000358 mbedtls_ecp_group_init( &grp );
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200359 mbedtls_ecdh_init( &srv );
360 mbedtls_ecdh_init( &cli );
361
362 z_len = unhexify( z, z_str );
363
364 rnd_info_A.buf = rnd_buf_A;
365 rnd_info_A.length = unhexify( rnd_buf_A, dA_str );
366
367 rnd_info_B.buf = rnd_buf_B;
368 rnd_info_B.length = unhexify( rnd_buf_B, dB_str );
369
Janos Follath36c5f7f2018-10-30 14:08:52 +0000370 /* The ECDH context is not guaranteed ot have an mbedtls_ecp_group structure
371 * in every configuration, therefore we load it separately. */
372 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200373
Janos Follath36c5f7f2018-10-30 14:08:52 +0000374 /* Otherwise we would have to fix the random buffer,
375 * as in ecdh_primitive_testvec. */
376 TEST_ASSERT( grp.nbits % 8 == 0 );
377
378 TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 );
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200379
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200380 /* set up restart parameters */
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200381 mbedtls_ecp_set_max_ops( max_ops );
382
Janos Follath36c5f7f2018-10-30 14:08:52 +0000383 if( enable )
Manuel Pégourié-Gonnard23e41622017-05-18 12:35:37 +0200384 {
385 mbedtls_ecdh_enable_restart( &srv );
386 mbedtls_ecdh_enable_restart( &cli );
387 }
388
Antonin Décimo36e89b52019-01-23 15:24:37 +0100389 /* server writes its parameters */
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200390 memset( buf, 0x00, sizeof( buf ) );
391 len = 0;
392
393 cnt_restart = 0;
394 do {
395 ret = mbedtls_ecdh_make_params( &srv, &len, buf, sizeof( buf ),
396 rnd_buffer_rand, &rnd_info_A );
397 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
398
399 TEST_ASSERT( ret == 0 );
400 TEST_ASSERT( cnt_restart >= min_restart );
401 TEST_ASSERT( cnt_restart <= max_restart );
402
403 /* client read server params */
404 vbuf = buf;
405 TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
406
407 /* client writes its key share */
408 memset( buf, 0x00, sizeof( buf ) );
409 len = 0;
410
411 cnt_restart = 0;
412 do {
413 ret = mbedtls_ecdh_make_public( &cli, &len, buf, sizeof( buf ),
414 rnd_buffer_rand, &rnd_info_B );
415 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
416
417 TEST_ASSERT( ret == 0 );
418 TEST_ASSERT( cnt_restart >= min_restart );
419 TEST_ASSERT( cnt_restart <= max_restart );
420
421 /* server reads client key share */
422 TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
423
424 /* server computes shared secret */
425 memset( buf, 0, sizeof( buf ) );
426 len = 0;
427
428 cnt_restart = 0;
429 do {
430 ret = mbedtls_ecdh_calc_secret( &srv, &len, buf, sizeof( buf ),
431 NULL, NULL );
432 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
433
434 TEST_ASSERT( ret == 0 );
435 TEST_ASSERT( cnt_restart >= min_restart );
436 TEST_ASSERT( cnt_restart <= max_restart );
437
438 TEST_ASSERT( len == z_len );
439 TEST_ASSERT( memcmp( buf, z, len ) == 0 );
440
441 /* client computes shared secret */
442 memset( buf, 0, sizeof( buf ) );
443 len = 0;
444
445 cnt_restart = 0;
446 do {
447 ret = mbedtls_ecdh_calc_secret( &cli, &len, buf, sizeof( buf ),
448 NULL, NULL );
449 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
450
451 TEST_ASSERT( ret == 0 );
452 TEST_ASSERT( cnt_restart >= min_restart );
453 TEST_ASSERT( cnt_restart <= max_restart );
454
455 TEST_ASSERT( len == z_len );
456 TEST_ASSERT( memcmp( buf, z, len ) == 0 );
457
458exit:
Janos Follath36c5f7f2018-10-30 14:08:52 +0000459 mbedtls_ecp_group_free( &grp );
Manuel Pégourié-Gonnard71b2c532017-04-27 10:38:52 +0200460 mbedtls_ecdh_free( &srv );
461 mbedtls_ecdh_free( &cli );
462}
463/* END_CASE */
Janos Follathfc03e8d2018-10-04 17:17:54 +0100464
Janos Follath36c5f7f2018-10-30 14:08:52 +0000465/* BEGIN_CASE depends_on:MBEDTLS_ECDH_LEGACY_CONTEXT */
Janos Follathfc03e8d2018-10-04 17:17:54 +0100466void ecdh_exchange_legacy( int id )
467{
468 mbedtls_ecdh_context srv, cli;
469 unsigned char buf[1000];
470 const unsigned char *vbuf;
471 size_t len;
472
473 rnd_pseudo_info rnd_info;
474
475 mbedtls_ecdh_init( &srv );
476 mbedtls_ecdh_init( &cli );
477 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
478
479 TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
480
481 memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
482 TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000,
483 &rnd_pseudo_rand, &rnd_info ) == 0 );
484 TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
485
486 memset( buf, 0x00, sizeof( buf ) );
487 TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000,
488 &rnd_pseudo_rand, &rnd_info ) == 0 );
489 TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
490
491 TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000,
492 &rnd_pseudo_rand, &rnd_info ) == 0 );
493 TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &len, buf, 1000, NULL,
494 NULL ) == 0 );
495 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
496
497exit:
498 mbedtls_ecdh_free( &srv );
499 mbedtls_ecdh_free( &cli );
500}
501/* END_CASE */
Gilles Peskine552563b2018-11-07 22:07:58 +0100502
503/* BEGIN_CASE */
504void ecdh_exchange_calc_secret( int grp_id,
505 data_t *our_private_key,
506 data_t *their_point,
507 int ours_first,
508 data_t *expected )
509{
510 rnd_pseudo_info rnd_info;
511 mbedtls_ecp_keypair our_key;
512 mbedtls_ecp_keypair their_key;
513 mbedtls_ecdh_context ecdh;
514 unsigned char shared_secret[MBEDTLS_ECP_MAX_BYTES];
515 size_t shared_secret_length = 0;
516
517 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
518 mbedtls_ecdh_init( &ecdh );
519 mbedtls_ecp_keypair_init( &our_key );
520 mbedtls_ecp_keypair_init( &their_key );
521
522 if( ! load_private_key( grp_id, our_private_key, &our_key, &rnd_info ) )
523 goto exit;
524 if( ! load_public_key( grp_id, their_point, &their_key ) )
525 goto exit;
526
527 /* Import the keys to the ECDH calculation. */
528 if( ours_first )
529 {
530 TEST_ASSERT( mbedtls_ecdh_get_params(
531 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 );
532 TEST_ASSERT( mbedtls_ecdh_get_params(
533 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 );
534 }
535 else
536 {
537 TEST_ASSERT( mbedtls_ecdh_get_params(
538 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 );
539 TEST_ASSERT( mbedtls_ecdh_get_params(
540 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 );
541 }
542
543 /* Perform the ECDH calculation. */
544 TEST_ASSERT( mbedtls_ecdh_calc_secret(
545 &ecdh,
546 &shared_secret_length,
547 shared_secret, sizeof( shared_secret ),
548 &rnd_pseudo_rand, &rnd_info ) == 0 );
549 TEST_ASSERT( shared_secret_length == expected->len );
550 TEST_ASSERT( memcmp( expected->x, shared_secret,
551 shared_secret_length ) == 0 );
552
553exit:
554 mbedtls_ecdh_free( &ecdh );
555 mbedtls_ecp_keypair_free( &our_key );
556 mbedtls_ecp_keypair_free( &their_key );
557}
558/* END_CASE */
Gilles Peskinec4dff062018-11-07 22:09:29 +0100559
560/* BEGIN_CASE */
561void ecdh_exchange_get_params_fail( int our_grp_id,
562 data_t *our_private_key,
563 int their_grp_id,
564 data_t *their_point,
565 int ours_first,
566 int expected_ret )
567{
568 rnd_pseudo_info rnd_info;
569 mbedtls_ecp_keypair our_key;
570 mbedtls_ecp_keypair their_key;
571 mbedtls_ecdh_context ecdh;
572
573 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
574 mbedtls_ecdh_init( &ecdh );
575 mbedtls_ecp_keypair_init( &our_key );
576 mbedtls_ecp_keypair_init( &their_key );
577
578 if( ! load_private_key( our_grp_id, our_private_key, &our_key, &rnd_info ) )
579 goto exit;
580 if( ! load_public_key( their_grp_id, their_point, &their_key ) )
581 goto exit;
582
583 if( ours_first )
584 {
585 TEST_ASSERT( mbedtls_ecdh_get_params(
586 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 );
587 TEST_ASSERT( mbedtls_ecdh_get_params(
588 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) ==
589 expected_ret );
590 }
591 else
592 {
593 TEST_ASSERT( mbedtls_ecdh_get_params(
594 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 );
595 TEST_ASSERT( mbedtls_ecdh_get_params(
596 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) ==
597 expected_ret );
598 }
599
600exit:
601 mbedtls_ecdh_free( &ecdh );
602 mbedtls_ecp_keypair_free( &our_key );
603 mbedtls_ecp_keypair_free( &their_key );
604}
605/* END_CASE */