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