1/* BEGIN_HEADER */ 2#include "mbedtls/dhm.h" 3 4/* Sanity checks on a Diffie-Hellman parameter: check the length-value 5 * syntax and check that the value is the expected one (taken from the 6 * DHM context by the caller). */ 7static int check_dhm_param_output( const mbedtls_mpi *expected, 8 const unsigned char *buffer, 9 size_t size, 10 size_t *offset ) 11{ 12 size_t n; 13 mbedtls_mpi actual; 14 int ok = 0; 15 mbedtls_mpi_init( &actual ); 16 17 TEST_ASSERT( size >= *offset + 2 ); 18 n = ( buffer[*offset] << 8 ) | buffer[*offset + 1]; 19 *offset += 2; 20 /* The DHM param output from Mbed TLS has leading zeros stripped, as 21 * permitted but not required by RFC 5246 \S4.4. */ 22 TEST_EQUAL( n, mbedtls_mpi_size( expected ) ); 23 TEST_ASSERT( size >= *offset + n ); 24 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &actual, buffer + *offset, n ) ); 25 TEST_EQUAL( 0, mbedtls_mpi_cmp_mpi( expected, &actual ) ); 26 *offset += n; 27 28 ok = 1; 29exit: 30 mbedtls_mpi_free( &actual ); 31 return( ok ); 32} 33 34/* Sanity checks on Diffie-Hellman parameters: syntax, range, and comparison 35 * against the context. */ 36static int check_dhm_params( const mbedtls_dhm_context *ctx, 37 size_t x_size, 38 const unsigned char *ske, size_t ske_len ) 39{ 40 size_t offset = 0; 41 42 /* Check that ctx->X and ctx->GX are within range. */ 43 TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->X, 1 ) > 0 ); 44 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) < 0 ); 45 TEST_ASSERT( mbedtls_mpi_size( &ctx->X ) <= x_size ); 46 TEST_ASSERT( mbedtls_mpi_cmp_int( &ctx->GX, 1 ) > 0 ); 47 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx->GX, &ctx->P ) < 0 ); 48 49 /* Check ske: it must contain P, G and G^X, each prefixed with a 50 * 2-byte size. */ 51 if( !check_dhm_param_output( &ctx->P, ske, ske_len, &offset ) ) 52 goto exit; 53 if( !check_dhm_param_output( &ctx->G, ske, ske_len, &offset ) ) 54 goto exit; 55 if( !check_dhm_param_output( &ctx->GX, ske, ske_len, &offset ) ) 56 goto exit; 57 TEST_EQUAL( offset, ske_len ); 58 59 return( 1 ); 60exit: 61 return( 0 ); 62} 63 64/* END_HEADER */ 65 66/* BEGIN_DEPENDENCIES 67 * depends_on:MBEDTLS_DHM_C:MBEDTLS_BIGNUM_C 68 * END_DEPENDENCIES 69 */ 70 71/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */ 72void dhm_invalid_params( ) 73{ 74 mbedtls_dhm_context ctx; 75 unsigned char buf[42] = { 0 }; 76 unsigned char *buf_null = NULL; 77 mbedtls_mpi X; 78 size_t const buflen = sizeof( buf ); 79 size_t len; 80 81 TEST_INVALID_PARAM( mbedtls_dhm_init( NULL ) ); 82 TEST_VALID_PARAM( mbedtls_dhm_free( NULL ) ); 83 84 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 85 mbedtls_dhm_read_params( NULL, 86 (unsigned char**) &buf, 87 buf ) ); 88 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 89 mbedtls_dhm_read_params( &ctx, &buf_null, buf ) ); 90 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 91 mbedtls_dhm_read_params( &ctx, NULL, buf ) ); 92 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 93 mbedtls_dhm_read_params( &ctx, 94 (unsigned char**) &buf, 95 NULL ) ); 96 97 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 98 mbedtls_dhm_make_params( NULL, buflen, 99 buf, &len, 100 rnd_std_rand, 101 NULL ) ); 102 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 103 mbedtls_dhm_make_params( &ctx, buflen, 104 NULL, &len, 105 rnd_std_rand, 106 NULL ) ); 107 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 108 mbedtls_dhm_make_params( &ctx, buflen, 109 buf, NULL, 110 rnd_std_rand, 111 NULL ) ); 112 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 113 mbedtls_dhm_make_params( &ctx, buflen, 114 buf, &len, 115 NULL, 116 NULL ) ); 117 118 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 119 mbedtls_dhm_set_group( NULL, &X, &X ) ); 120 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 121 mbedtls_dhm_set_group( &ctx, NULL, &X ) ); 122 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 123 mbedtls_dhm_set_group( &ctx, &X, NULL ) ); 124 125 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 126 mbedtls_dhm_read_public( NULL, buf, buflen ) ); 127 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 128 mbedtls_dhm_read_public( &ctx, NULL, buflen ) ); 129 130 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 131 mbedtls_dhm_make_public( NULL, buflen, 132 buf, buflen, 133 rnd_std_rand, 134 NULL ) ); 135 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 136 mbedtls_dhm_make_public( &ctx, buflen, 137 NULL, buflen, 138 rnd_std_rand, 139 NULL ) ); 140 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 141 mbedtls_dhm_make_public( &ctx, buflen, 142 buf, buflen, 143 NULL, 144 NULL ) ); 145 146 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 147 mbedtls_dhm_calc_secret( NULL, buf, buflen, 148 &len, rnd_std_rand, 149 NULL ) ); 150 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 151 mbedtls_dhm_calc_secret( &ctx, NULL, buflen, 152 &len, rnd_std_rand, 153 NULL ) ); 154 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 155 mbedtls_dhm_calc_secret( &ctx, buf, buflen, 156 NULL, rnd_std_rand, 157 NULL ) ); 158 159#if defined(MBEDTLS_ASN1_PARSE_C) 160 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 161 mbedtls_dhm_parse_dhm( NULL, buf, buflen ) ); 162 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 163 mbedtls_dhm_parse_dhm( &ctx, NULL, buflen ) ); 164 165#if defined(MBEDTLS_FS_IO) 166 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 167 mbedtls_dhm_parse_dhmfile( NULL, "" ) ); 168 TEST_INVALID_PARAM_RET( MBEDTLS_ERR_DHM_BAD_INPUT_DATA, 169 mbedtls_dhm_parse_dhmfile( &ctx, NULL ) ); 170#endif /* MBEDTLS_FS_IO */ 171#endif /* MBEDTLS_ASN1_PARSE_C */ 172 173exit: 174 return; 175} 176/* END_CASE */ 177 178/* BEGIN_CASE */ 179void dhm_do_dhm( int radix_P, char *input_P, int x_size, 180 int radix_G, char *input_G, int result ) 181{ 182 mbedtls_dhm_context ctx_srv; 183 mbedtls_dhm_context ctx_cli; 184 unsigned char ske[1000]; 185 unsigned char *p = ske; 186 unsigned char pub_cli[1000]; 187 unsigned char sec_srv[1000]; 188 unsigned char sec_cli[1000]; 189 size_t ske_len = 0; 190 size_t pub_cli_len = 0; 191 size_t sec_srv_len; 192 size_t sec_cli_len; 193 int i; 194 rnd_pseudo_info rnd_info; 195 196 mbedtls_dhm_init( &ctx_srv ); 197 mbedtls_dhm_init( &ctx_cli ); 198 memset( ske, 0x00, 1000 ); 199 memset( pub_cli, 0x00, 1000 ); 200 memset( sec_srv, 0x00, 1000 ); 201 memset( sec_cli, 0x00, 1000 ); 202 memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) ); 203 204 /* 205 * Set params 206 */ 207 TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.P, radix_P, input_P ) == 0 ); 208 TEST_ASSERT( mbedtls_test_read_mpi( &ctx_srv.G, radix_G, input_G ) == 0 ); 209 pub_cli_len = mbedtls_mpi_size( &ctx_srv.P ); 210 211 /* 212 * First key exchange 213 */ 214 TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len, 215 &rnd_pseudo_rand, 216 &rnd_info ) == result ); 217 if ( result != 0 ) 218 goto exit; 219 if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) ) 220 goto exit; 221 222 ske[ske_len++] = 0; 223 ske[ske_len++] = 0; 224 TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 ); 225 226 TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len, &rnd_pseudo_rand, &rnd_info ) == 0 ); 227 TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 ); 228 229 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ), &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 ); 230 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 ); 231 232 TEST_ASSERT( sec_srv_len == sec_cli_len ); 233 TEST_ASSERT( sec_srv_len != 0 ); 234 TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 ); 235 236 /* Re-do calc_secret on server a few times to test update of blinding values */ 237 for( i = 0; i < 3; i++ ) 238 { 239 sec_srv_len = 1000; 240 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ), &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 ); 241 242 TEST_ASSERT( sec_srv_len == sec_cli_len ); 243 TEST_ASSERT( sec_srv_len != 0 ); 244 TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 ); 245 } 246 247 /* 248 * Second key exchange to test change of blinding values on server 249 */ 250 p = ske; 251 252 TEST_ASSERT( mbedtls_dhm_make_params( &ctx_srv, x_size, ske, &ske_len, 253 &rnd_pseudo_rand, 254 &rnd_info ) == 0 ); 255 if( !check_dhm_params( &ctx_srv, x_size, ske, ske_len ) ) 256 goto exit; 257 ske[ske_len++] = 0; 258 ske[ske_len++] = 0; 259 TEST_ASSERT( mbedtls_dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 ); 260 261 TEST_ASSERT( mbedtls_dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len, &rnd_pseudo_rand, &rnd_info ) == 0 ); 262 TEST_ASSERT( mbedtls_dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 ); 263 264 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_srv, sec_srv, sizeof( sec_srv ), &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 ); 265 TEST_ASSERT( mbedtls_dhm_calc_secret( &ctx_cli, sec_cli, sizeof( sec_cli ), &sec_cli_len, NULL, NULL ) == 0 ); 266 267 TEST_ASSERT( sec_srv_len == sec_cli_len ); 268 TEST_ASSERT( sec_srv_len != 0 ); 269 TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 ); 270 271exit: 272 mbedtls_dhm_free( &ctx_srv ); 273 mbedtls_dhm_free( &ctx_cli ); 274} 275/* END_CASE */ 276 277/* BEGIN_CASE */ 278void dhm_make_public( int P_bytes, int radix_G, char *input_G, int result ) 279{ 280 mbedtls_mpi P, G; 281 mbedtls_dhm_context ctx; 282 unsigned char output[MBEDTLS_MPI_MAX_SIZE]; 283 284 mbedtls_mpi_init( &P ); 285 mbedtls_mpi_init( &G ); 286 mbedtls_dhm_init( &ctx ); 287 288 TEST_ASSERT( mbedtls_mpi_lset( &P, 1 ) == 0 ); 289 TEST_ASSERT( mbedtls_mpi_shift_l( &P, ( P_bytes * 8 ) - 1 ) == 0 ); 290 TEST_ASSERT( mbedtls_mpi_set_bit( &P, 0, 1 ) == 0 ); 291 292 TEST_ASSERT( mbedtls_test_read_mpi( &G, radix_G, input_G ) == 0 ); 293 294 TEST_ASSERT( mbedtls_dhm_set_group( &ctx, &P, &G ) == 0 ); 295 TEST_ASSERT( mbedtls_dhm_make_public( &ctx, (int) mbedtls_mpi_size( &P ), 296 output, sizeof(output), 297 &rnd_pseudo_rand, 298 NULL ) == result ); 299 300exit: 301 mbedtls_mpi_free( &P ); 302 mbedtls_mpi_free( &G ); 303 mbedtls_dhm_free( &ctx ); 304} 305/* END_CASE */ 306 307/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ 308void dhm_file( char * filename, char * p, char * g, int len ) 309{ 310 mbedtls_dhm_context ctx; 311 mbedtls_mpi P, G; 312 313 mbedtls_dhm_init( &ctx ); 314 mbedtls_mpi_init( &P ); mbedtls_mpi_init( &G ); 315 316 TEST_ASSERT( mbedtls_test_read_mpi( &P, 16, p ) == 0 ); 317 TEST_ASSERT( mbedtls_test_read_mpi( &G, 16, g ) == 0 ); 318 319 TEST_ASSERT( mbedtls_dhm_parse_dhmfile( &ctx, filename ) == 0 ); 320 321 TEST_ASSERT( ctx.len == (size_t) len ); 322 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.P, &P ) == 0 ); 323 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &ctx.G, &G ) == 0 ); 324 325exit: 326 mbedtls_mpi_free( &P ); mbedtls_mpi_free( &G ); 327 mbedtls_dhm_free( &ctx ); 328} 329/* END_CASE */ 330 331/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ 332void dhm_selftest( ) 333{ 334 TEST_ASSERT( mbedtls_dhm_self_test( 1 ) == 0 ); 335} 336/* END_CASE */ 337