1/* BEGIN_HEADER */ 2#include "mbedtls/ecdh.h" 3 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 mbedtls_test_rnd_pseudo_info *rnd_info ) 23{ 24 int ok = 0; 25 TEST_ASSERT( mbedtls_ecp_read_key( grp_id, ecp, 26 private_key->x, 27 private_key->len ) == 0 ); 28 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 &mbedtls_test_rnd_pseudo_rand, 33 rnd_info ) == 0 ); 34 ok = 1; 35exit: 36 return( ok ); 37} 38 39/* END_HEADER */ 40 41/* BEGIN_DEPENDENCIES 42 * depends_on:MBEDTLS_ECDH_C 43 * END_DEPENDENCIES 44 */ 45 46/* BEGIN_CASE depends_on:NOT_DEFINED */ 47void ecdh_invalid_param( ) 48{ 49 mbedtls_ecdh_context ctx; 50 mbedtls_ecp_keypair kp; 51 int invalid_side = 42; 52 53 TEST_EQUAL( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, 54 mbedtls_ecdh_get_params( &ctx, &kp, 55 invalid_side ) ); 56 57exit: 58 return; 59} 60/* END_CASE */ 61 62/* BEGIN_CASE */ 63void ecdh_primitive_random( int id ) 64{ 65 mbedtls_ecp_group grp; 66 mbedtls_ecp_point qA, qB; 67 mbedtls_mpi dA, dB, zA, zB; 68 mbedtls_test_rnd_pseudo_info rnd_info; 69 70 mbedtls_ecp_group_init( &grp ); 71 mbedtls_ecp_point_init( &qA ); mbedtls_ecp_point_init( &qB ); 72 mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &dB ); 73 mbedtls_mpi_init( &zA ); mbedtls_mpi_init( &zB ); 74 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) ); 75 76 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 ); 77 78 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dA, &qA, 79 &mbedtls_test_rnd_pseudo_rand, 80 &rnd_info ) == 0 ); 81 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dB, &qB, 82 &mbedtls_test_rnd_pseudo_rand, 83 &rnd_info ) == 0 ); 84 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA, 85 &mbedtls_test_rnd_pseudo_rand, 86 &rnd_info ) == 0 ); 87 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB, 88 &mbedtls_test_rnd_pseudo_rand, 89 &rnd_info ) == 0 ); 90 91 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &zB ) == 0 ); 92 93exit: 94 mbedtls_ecp_group_free( &grp ); 95 mbedtls_ecp_point_free( &qA ); mbedtls_ecp_point_free( &qB ); 96 mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &dB ); 97 mbedtls_mpi_free( &zA ); mbedtls_mpi_free( &zB ); 98} 99/* END_CASE */ 100 101/* BEGIN_CASE */ 102void ecdh_primitive_testvec( int id, data_t * rnd_buf_A, char * xA_str, 103 char * yA_str, data_t * rnd_buf_B, 104 char * xB_str, char * yB_str, char * z_str ) 105{ 106 mbedtls_ecp_group grp; 107 mbedtls_ecp_point qA, qB; 108 mbedtls_mpi dA, dB, zA, zB, check; 109 mbedtls_test_rnd_buf_info rnd_info_A, rnd_info_B; 110 mbedtls_test_rnd_pseudo_info rnd_info; 111 112 mbedtls_ecp_group_init( &grp ); 113 mbedtls_ecp_point_init( &qA ); mbedtls_ecp_point_init( &qB ); 114 mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &dB ); 115 mbedtls_mpi_init( &zA ); mbedtls_mpi_init( &zB ); mbedtls_mpi_init( &check ); 116 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) ); 117 118 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 ); 119 120 rnd_info_A.buf = rnd_buf_A->x; 121 rnd_info_A.length = rnd_buf_A->len; 122 rnd_info_A.fallback_f_rng = mbedtls_test_rnd_std_rand; 123 rnd_info_A.fallback_p_rng = NULL; 124 125 /* Fix rnd_buf_A->x by shifting it left if necessary */ 126 if( grp.nbits % 8 != 0 ) 127 { 128 unsigned char shift = 8 - ( grp.nbits % 8 ); 129 size_t i; 130 131 for( i = 0; i < rnd_info_A.length - 1; i++ ) 132 rnd_buf_A->x[i] = rnd_buf_A->x[i] << shift 133 | rnd_buf_A->x[i+1] >> ( 8 - shift ); 134 135 rnd_buf_A->x[rnd_info_A.length-1] <<= shift; 136 } 137 138 rnd_info_B.buf = rnd_buf_B->x; 139 rnd_info_B.length = rnd_buf_B->len; 140 rnd_info_B.fallback_f_rng = mbedtls_test_rnd_std_rand; 141 rnd_info_B.fallback_p_rng = NULL; 142 143 /* Fix rnd_buf_B->x by shifting it left if necessary */ 144 if( grp.nbits % 8 != 0 ) 145 { 146 unsigned char shift = 8 - ( grp.nbits % 8 ); 147 size_t i; 148 149 for( i = 0; i < rnd_info_B.length - 1; i++ ) 150 rnd_buf_B->x[i] = rnd_buf_B->x[i] << shift 151 | rnd_buf_B->x[i+1] >> ( 8 - shift ); 152 153 rnd_buf_B->x[rnd_info_B.length-1] <<= shift; 154 } 155 156 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dA, &qA, 157 mbedtls_test_rnd_buffer_rand, 158 &rnd_info_A ) == 0 ); 159 TEST_ASSERT( ! mbedtls_ecp_is_zero( &qA ) ); 160 TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, xA_str ) == 0 ); 161 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.X, &check ) == 0 ); 162 TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, yA_str ) == 0 ); 163 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qA.Y, &check ) == 0 ); 164 165 TEST_ASSERT( mbedtls_ecdh_gen_public( &grp, &dB, &qB, 166 mbedtls_test_rnd_buffer_rand, 167 &rnd_info_B ) == 0 ); 168 TEST_ASSERT( ! mbedtls_ecp_is_zero( &qB ) ); 169 TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, xB_str ) == 0 ); 170 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.X, &check ) == 0 ); 171 TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, yB_str ) == 0 ); 172 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &qB.Y, &check ) == 0 ); 173 174 TEST_ASSERT( mbedtls_test_read_mpi( &check, 16, z_str ) == 0 ); 175 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zA, &qB, &dA, 176 &mbedtls_test_rnd_pseudo_rand, 177 &rnd_info ) == 0 ); 178 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zA, &check ) == 0 ); 179 TEST_ASSERT( mbedtls_ecdh_compute_shared( &grp, &zB, &qA, &dB, 180 &mbedtls_test_rnd_pseudo_rand, 181 &rnd_info ) == 0 ); 182 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &zB, &check ) == 0 ); 183 184exit: 185 mbedtls_ecp_group_free( &grp ); 186 mbedtls_ecp_point_free( &qA ); mbedtls_ecp_point_free( &qB ); 187 mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &dB ); 188 mbedtls_mpi_free( &zA ); mbedtls_mpi_free( &zB ); mbedtls_mpi_free( &check ); 189} 190/* END_CASE */ 191 192/* BEGIN_CASE */ 193void ecdh_exchange( int id ) 194{ 195 mbedtls_ecdh_context srv, cli; 196 unsigned char buf[1000]; 197 const unsigned char *vbuf; 198 size_t len; 199 mbedtls_test_rnd_pseudo_info rnd_info; 200 unsigned char res_buf[1000]; 201 size_t res_len; 202 203 mbedtls_ecdh_init( &srv ); 204 mbedtls_ecdh_init( &cli ); 205 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) ); 206 207 TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 ); 208 209 memset( buf, 0x00, sizeof( buf ) ); vbuf = buf; 210 TEST_ASSERT( mbedtls_ecdh_make_params( &srv, &len, buf, 1000, 211 &mbedtls_test_rnd_pseudo_rand, 212 &rnd_info ) == 0 ); 213 TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 ); 214 215 memset( buf, 0x00, sizeof( buf ) ); 216 TEST_ASSERT( mbedtls_ecdh_make_public( &cli, &len, buf, 1000, 217 &mbedtls_test_rnd_pseudo_rand, 218 &rnd_info ) == 0 ); 219 TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 ); 220 221 TEST_ASSERT( mbedtls_ecdh_calc_secret( &srv, &len, buf, 1000, 222 &mbedtls_test_rnd_pseudo_rand, 223 &rnd_info ) == 0 ); 224 TEST_ASSERT( mbedtls_ecdh_calc_secret( &cli, &res_len, res_buf, 1000, 225 &mbedtls_test_rnd_pseudo_rand, 226 &rnd_info ) == 0 ); 227 TEST_ASSERT( len == res_len ); 228 TEST_ASSERT( memcmp( buf, res_buf, len ) == 0 ); 229 230exit: 231 mbedtls_ecdh_free( &srv ); 232 mbedtls_ecdh_free( &cli ); 233} 234/* END_CASE */ 235 236/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ 237void ecdh_restart( int id, data_t *dA, data_t *dB, data_t *z, 238 int enable, int max_ops, int min_restart, int max_restart ) 239{ 240 int ret; 241 mbedtls_ecdh_context srv, cli; 242 unsigned char buf[1000]; 243 const unsigned char *vbuf; 244 size_t len; 245 mbedtls_test_rnd_buf_info rnd_info_A, rnd_info_B; 246 mbedtls_test_rnd_pseudo_info rnd_info; 247 int cnt_restart; 248 mbedtls_ecp_group grp; 249 250 mbedtls_ecp_group_init( &grp ); 251 mbedtls_ecdh_init( &srv ); 252 mbedtls_ecdh_init( &cli ); 253 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) ); 254 255 rnd_info_A.fallback_f_rng = mbedtls_test_rnd_std_rand; 256 rnd_info_A.fallback_p_rng = NULL; 257 rnd_info_A.buf = dA->x; 258 rnd_info_A.length = dA->len; 259 260 rnd_info_B.fallback_f_rng = mbedtls_test_rnd_std_rand; 261 rnd_info_B.fallback_p_rng = NULL; 262 rnd_info_B.buf = dB->x; 263 rnd_info_B.length = dB->len; 264 265 /* The ECDH context is not guaranteed ot have an mbedtls_ecp_group structure 266 * in every configuration, therefore we load it separately. */ 267 TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 ); 268 269 /* Otherwise we would have to fix the random buffer, 270 * as in ecdh_primitive_testvec. */ 271 TEST_ASSERT( grp.nbits % 8 == 0 ); 272 273 TEST_ASSERT( mbedtls_ecdh_setup( &srv, id ) == 0 ); 274 275 /* set up restart parameters */ 276 mbedtls_ecp_set_max_ops( max_ops ); 277 278 if( enable ) 279 { 280 mbedtls_ecdh_enable_restart( &srv ); 281 mbedtls_ecdh_enable_restart( &cli ); 282 } 283 284 /* server writes its parameters */ 285 memset( buf, 0x00, sizeof( buf ) ); 286 len = 0; 287 288 cnt_restart = 0; 289 do { 290 ret = mbedtls_ecdh_make_params( &srv, &len, buf, sizeof( buf ), 291 mbedtls_test_rnd_buffer_rand, 292 &rnd_info_A ); 293 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart ); 294 295 TEST_ASSERT( ret == 0 ); 296 TEST_ASSERT( cnt_restart >= min_restart ); 297 TEST_ASSERT( cnt_restart <= max_restart ); 298 299 /* client read server params */ 300 vbuf = buf; 301 TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 ); 302 303 /* client writes its key share */ 304 memset( buf, 0x00, sizeof( buf ) ); 305 len = 0; 306 307 cnt_restart = 0; 308 do { 309 ret = mbedtls_ecdh_make_public( &cli, &len, buf, sizeof( buf ), 310 mbedtls_test_rnd_buffer_rand, 311 &rnd_info_B ); 312 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart ); 313 314 TEST_ASSERT( ret == 0 ); 315 TEST_ASSERT( cnt_restart >= min_restart ); 316 TEST_ASSERT( cnt_restart <= max_restart ); 317 318 /* server reads client key share */ 319 TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 ); 320 321 /* server computes shared secret */ 322 memset( buf, 0, sizeof( buf ) ); 323 len = 0; 324 325 cnt_restart = 0; 326 do { 327 ret = mbedtls_ecdh_calc_secret( &srv, &len, buf, sizeof( buf ), 328 &mbedtls_test_rnd_pseudo_rand, 329 &rnd_info ); 330 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart ); 331 332 TEST_ASSERT( ret == 0 ); 333 TEST_ASSERT( cnt_restart >= min_restart ); 334 TEST_ASSERT( cnt_restart <= max_restart ); 335 336 TEST_ASSERT( len == z->len ); 337 TEST_ASSERT( memcmp( buf, z->x, len ) == 0 ); 338 339 /* client computes shared secret */ 340 memset( buf, 0, sizeof( buf ) ); 341 len = 0; 342 343 cnt_restart = 0; 344 do { 345 ret = mbedtls_ecdh_calc_secret( &cli, &len, buf, sizeof( buf ), 346 &mbedtls_test_rnd_pseudo_rand, 347 &rnd_info ); 348 } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart ); 349 350 TEST_ASSERT( ret == 0 ); 351 TEST_ASSERT( cnt_restart >= min_restart ); 352 TEST_ASSERT( cnt_restart <= max_restart ); 353 354 TEST_ASSERT( len == z->len ); 355 TEST_ASSERT( memcmp( buf, z->x, len ) == 0 ); 356 357exit: 358 mbedtls_ecp_group_free( &grp ); 359 mbedtls_ecdh_free( &srv ); 360 mbedtls_ecdh_free( &cli ); 361} 362/* END_CASE */ 363 364/* BEGIN_CASE */ 365void ecdh_exchange_calc_secret( int grp_id, 366 data_t *our_private_key, 367 data_t *their_point, 368 int ours_first, 369 data_t *expected ) 370{ 371 mbedtls_test_rnd_pseudo_info rnd_info; 372 mbedtls_ecp_keypair our_key; 373 mbedtls_ecp_keypair their_key; 374 mbedtls_ecdh_context ecdh; 375 unsigned char shared_secret[MBEDTLS_ECP_MAX_BYTES]; 376 size_t shared_secret_length = 0; 377 378 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) ); 379 mbedtls_ecdh_init( &ecdh ); 380 mbedtls_ecp_keypair_init( &our_key ); 381 mbedtls_ecp_keypair_init( &their_key ); 382 383 if( ! load_private_key( grp_id, our_private_key, &our_key, &rnd_info ) ) 384 goto exit; 385 if( ! load_public_key( grp_id, their_point, &their_key ) ) 386 goto exit; 387 388 /* Import the keys to the ECDH calculation. */ 389 if( ours_first ) 390 { 391 TEST_ASSERT( mbedtls_ecdh_get_params( 392 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 ); 393 TEST_ASSERT( mbedtls_ecdh_get_params( 394 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 ); 395 } 396 else 397 { 398 TEST_ASSERT( mbedtls_ecdh_get_params( 399 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 ); 400 TEST_ASSERT( mbedtls_ecdh_get_params( 401 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 ); 402 } 403 404 /* Perform the ECDH calculation. */ 405 TEST_ASSERT( mbedtls_ecdh_calc_secret( 406 &ecdh, 407 &shared_secret_length, 408 shared_secret, sizeof( shared_secret ), 409 &mbedtls_test_rnd_pseudo_rand, &rnd_info ) == 0 ); 410 TEST_ASSERT( shared_secret_length == expected->len ); 411 TEST_ASSERT( memcmp( expected->x, shared_secret, 412 shared_secret_length ) == 0 ); 413 414exit: 415 mbedtls_ecdh_free( &ecdh ); 416 mbedtls_ecp_keypair_free( &our_key ); 417 mbedtls_ecp_keypair_free( &their_key ); 418} 419/* END_CASE */ 420 421/* BEGIN_CASE */ 422void ecdh_exchange_get_params_fail( int our_grp_id, 423 data_t *our_private_key, 424 int their_grp_id, 425 data_t *their_point, 426 int ours_first, 427 int expected_ret ) 428{ 429 mbedtls_test_rnd_pseudo_info rnd_info; 430 mbedtls_ecp_keypair our_key; 431 mbedtls_ecp_keypair their_key; 432 mbedtls_ecdh_context ecdh; 433 434 memset( &rnd_info, 0x00, sizeof( mbedtls_test_rnd_pseudo_info ) ); 435 mbedtls_ecdh_init( &ecdh ); 436 mbedtls_ecp_keypair_init( &our_key ); 437 mbedtls_ecp_keypair_init( &their_key ); 438 439 if( ! load_private_key( our_grp_id, our_private_key, &our_key, &rnd_info ) ) 440 goto exit; 441 if( ! load_public_key( their_grp_id, their_point, &their_key ) ) 442 goto exit; 443 444 if( ours_first ) 445 { 446 TEST_ASSERT( mbedtls_ecdh_get_params( 447 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 0 ); 448 TEST_ASSERT( mbedtls_ecdh_get_params( 449 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 450 expected_ret ); 451 } 452 else 453 { 454 TEST_ASSERT( mbedtls_ecdh_get_params( 455 &ecdh, &their_key, MBEDTLS_ECDH_THEIRS ) == 0 ); 456 TEST_ASSERT( mbedtls_ecdh_get_params( 457 &ecdh, &our_key, MBEDTLS_ECDH_OURS ) == 458 expected_ret ); 459 } 460 461exit: 462 mbedtls_ecdh_free( &ecdh ); 463 mbedtls_ecp_keypair_free( &our_key ); 464 mbedtls_ecp_keypair_free( &their_key ); 465} 466/* END_CASE */ 467