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