test_suite_ecdh.function 16 KB

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