test_suite_dhm.function 10.0 KB

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