ecdh.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /*
  2. * Elliptic curve Diffie-Hellman
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  6. */
  7. /*
  8. * References:
  9. *
  10. * SEC1 https://www.secg.org/sec1-v2.pdf
  11. * RFC 4492
  12. */
  13. #include "common.h"
  14. #if defined(MBEDTLS_ECDH_C)
  15. #include "mbedtls/ecdh.h"
  16. #include "mbedtls/platform_util.h"
  17. #include "mbedtls/error.h"
  18. #include <string.h>
  19. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  20. typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
  21. #endif
  22. static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
  23. const mbedtls_ecdh_context *ctx)
  24. {
  25. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  26. return ctx->grp.id;
  27. #else
  28. return ctx->grp_id;
  29. #endif
  30. }
  31. int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid)
  32. {
  33. /* At this time, all groups support ECDH. */
  34. (void) gid;
  35. return 1;
  36. }
  37. #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
  38. /*
  39. * Generate public key (restartable version)
  40. *
  41. * Note: this internal function relies on its caller preserving the value of
  42. * the output parameter 'd' across continuation calls. This would not be
  43. * acceptable for a public function but is OK here as we control call sites.
  44. */
  45. static int ecdh_gen_public_restartable(mbedtls_ecp_group *grp,
  46. mbedtls_mpi *d, mbedtls_ecp_point *Q,
  47. int (*f_rng)(void *, unsigned char *, size_t),
  48. void *p_rng,
  49. mbedtls_ecp_restart_ctx *rs_ctx)
  50. {
  51. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  52. int restarting = 0;
  53. #if defined(MBEDTLS_ECP_RESTARTABLE)
  54. restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL);
  55. #endif
  56. /* If multiplication is in progress, we already generated a privkey */
  57. if (!restarting) {
  58. MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng));
  59. }
  60. MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G,
  61. f_rng, p_rng, rs_ctx));
  62. cleanup:
  63. return ret;
  64. }
  65. /*
  66. * Generate public key
  67. */
  68. int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
  69. int (*f_rng)(void *, unsigned char *, size_t),
  70. void *p_rng)
  71. {
  72. return ecdh_gen_public_restartable(grp, d, Q, f_rng, p_rng, NULL);
  73. }
  74. #endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
  75. #if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
  76. /*
  77. * Compute shared secret (SEC1 3.3.1)
  78. */
  79. static int ecdh_compute_shared_restartable(mbedtls_ecp_group *grp,
  80. mbedtls_mpi *z,
  81. const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
  82. int (*f_rng)(void *, unsigned char *, size_t),
  83. void *p_rng,
  84. mbedtls_ecp_restart_ctx *rs_ctx)
  85. {
  86. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  87. mbedtls_ecp_point P;
  88. mbedtls_ecp_point_init(&P);
  89. MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q,
  90. f_rng, p_rng, rs_ctx));
  91. if (mbedtls_ecp_is_zero(&P)) {
  92. ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  93. goto cleanup;
  94. }
  95. MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X));
  96. cleanup:
  97. mbedtls_ecp_point_free(&P);
  98. return ret;
  99. }
  100. /*
  101. * Compute shared secret (SEC1 3.3.1)
  102. */
  103. int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
  104. const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
  105. int (*f_rng)(void *, unsigned char *, size_t),
  106. void *p_rng)
  107. {
  108. return ecdh_compute_shared_restartable(grp, z, Q, d,
  109. f_rng, p_rng, NULL);
  110. }
  111. #endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
  112. static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx)
  113. {
  114. mbedtls_ecp_group_init(&ctx->grp);
  115. mbedtls_mpi_init(&ctx->d);
  116. mbedtls_ecp_point_init(&ctx->Q);
  117. mbedtls_ecp_point_init(&ctx->Qp);
  118. mbedtls_mpi_init(&ctx->z);
  119. #if defined(MBEDTLS_ECP_RESTARTABLE)
  120. mbedtls_ecp_restart_init(&ctx->rs);
  121. #endif
  122. }
  123. mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx)
  124. {
  125. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  126. return ctx->MBEDTLS_PRIVATE(grp).id;
  127. #else
  128. return ctx->MBEDTLS_PRIVATE(grp_id);
  129. #endif
  130. }
  131. /*
  132. * Initialize context
  133. */
  134. void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx)
  135. {
  136. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  137. ecdh_init_internal(ctx);
  138. mbedtls_ecp_point_init(&ctx->Vi);
  139. mbedtls_ecp_point_init(&ctx->Vf);
  140. mbedtls_mpi_init(&ctx->_d);
  141. #else
  142. memset(ctx, 0, sizeof(mbedtls_ecdh_context));
  143. ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
  144. #endif
  145. ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
  146. #if defined(MBEDTLS_ECP_RESTARTABLE)
  147. ctx->restart_enabled = 0;
  148. #endif
  149. }
  150. static int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx,
  151. mbedtls_ecp_group_id grp_id)
  152. {
  153. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  154. ret = mbedtls_ecp_group_load(&ctx->grp, grp_id);
  155. if (ret != 0) {
  156. return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
  157. }
  158. return 0;
  159. }
  160. /*
  161. * Setup context
  162. */
  163. int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id)
  164. {
  165. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  166. return ecdh_setup_internal(ctx, grp_id);
  167. #else
  168. switch (grp_id) {
  169. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  170. case MBEDTLS_ECP_DP_CURVE25519:
  171. ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
  172. ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
  173. ctx->grp_id = grp_id;
  174. return mbedtls_everest_setup(&ctx->ctx.everest_ecdh, grp_id);
  175. #endif
  176. default:
  177. ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
  178. ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
  179. ctx->grp_id = grp_id;
  180. ecdh_init_internal(&ctx->ctx.mbed_ecdh);
  181. return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id);
  182. }
  183. #endif
  184. }
  185. static void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx)
  186. {
  187. mbedtls_ecp_group_free(&ctx->grp);
  188. mbedtls_mpi_free(&ctx->d);
  189. mbedtls_ecp_point_free(&ctx->Q);
  190. mbedtls_ecp_point_free(&ctx->Qp);
  191. mbedtls_mpi_free(&ctx->z);
  192. #if defined(MBEDTLS_ECP_RESTARTABLE)
  193. mbedtls_ecp_restart_free(&ctx->rs);
  194. #endif
  195. }
  196. #if defined(MBEDTLS_ECP_RESTARTABLE)
  197. /*
  198. * Enable restartable operations for context
  199. */
  200. void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx)
  201. {
  202. ctx->restart_enabled = 1;
  203. }
  204. #endif
  205. /*
  206. * Free context
  207. */
  208. void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx)
  209. {
  210. if (ctx == NULL) {
  211. return;
  212. }
  213. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  214. mbedtls_ecp_point_free(&ctx->Vi);
  215. mbedtls_ecp_point_free(&ctx->Vf);
  216. mbedtls_mpi_free(&ctx->_d);
  217. ecdh_free_internal(ctx);
  218. #else
  219. switch (ctx->var) {
  220. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  221. case MBEDTLS_ECDH_VARIANT_EVEREST:
  222. mbedtls_everest_free(&ctx->ctx.everest_ecdh);
  223. break;
  224. #endif
  225. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  226. ecdh_free_internal(&ctx->ctx.mbed_ecdh);
  227. break;
  228. default:
  229. break;
  230. }
  231. ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
  232. ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
  233. ctx->grp_id = MBEDTLS_ECP_DP_NONE;
  234. #endif
  235. }
  236. static int ecdh_make_params_internal(mbedtls_ecdh_context_mbed *ctx,
  237. size_t *olen, int point_format,
  238. unsigned char *buf, size_t blen,
  239. int (*f_rng)(void *,
  240. unsigned char *,
  241. size_t),
  242. void *p_rng,
  243. int restart_enabled)
  244. {
  245. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  246. size_t grp_len, pt_len;
  247. #if defined(MBEDTLS_ECP_RESTARTABLE)
  248. mbedtls_ecp_restart_ctx *rs_ctx = NULL;
  249. #endif
  250. if (ctx->grp.pbits == 0) {
  251. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  252. }
  253. #if defined(MBEDTLS_ECP_RESTARTABLE)
  254. if (restart_enabled) {
  255. rs_ctx = &ctx->rs;
  256. }
  257. #else
  258. (void) restart_enabled;
  259. #endif
  260. #if defined(MBEDTLS_ECP_RESTARTABLE)
  261. if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q,
  262. f_rng, p_rng, rs_ctx)) != 0) {
  263. return ret;
  264. }
  265. #else
  266. if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q,
  267. f_rng, p_rng)) != 0) {
  268. return ret;
  269. }
  270. #endif /* MBEDTLS_ECP_RESTARTABLE */
  271. if ((ret = mbedtls_ecp_tls_write_group(&ctx->grp, &grp_len, buf,
  272. blen)) != 0) {
  273. return ret;
  274. }
  275. buf += grp_len;
  276. blen -= grp_len;
  277. if ((ret = mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format,
  278. &pt_len, buf, blen)) != 0) {
  279. return ret;
  280. }
  281. *olen = grp_len + pt_len;
  282. return 0;
  283. }
  284. /*
  285. * Setup and write the ServerKeyExchange parameters (RFC 4492)
  286. * struct {
  287. * ECParameters curve_params;
  288. * ECPoint public;
  289. * } ServerECDHParams;
  290. */
  291. int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen,
  292. unsigned char *buf, size_t blen,
  293. int (*f_rng)(void *, unsigned char *, size_t),
  294. void *p_rng)
  295. {
  296. int restart_enabled = 0;
  297. #if defined(MBEDTLS_ECP_RESTARTABLE)
  298. restart_enabled = ctx->restart_enabled;
  299. #else
  300. (void) restart_enabled;
  301. #endif
  302. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  303. return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen,
  304. f_rng, p_rng, restart_enabled);
  305. #else
  306. switch (ctx->var) {
  307. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  308. case MBEDTLS_ECDH_VARIANT_EVEREST:
  309. return mbedtls_everest_make_params(&ctx->ctx.everest_ecdh, olen,
  310. buf, blen, f_rng, p_rng);
  311. #endif
  312. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  313. return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen,
  314. ctx->point_format, buf, blen,
  315. f_rng, p_rng,
  316. restart_enabled);
  317. default:
  318. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  319. }
  320. #endif
  321. }
  322. static int ecdh_read_params_internal(mbedtls_ecdh_context_mbed *ctx,
  323. const unsigned char **buf,
  324. const unsigned char *end)
  325. {
  326. return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf,
  327. (size_t) (end - *buf));
  328. }
  329. /*
  330. * Read the ServerKeyExchange parameters (RFC 4492)
  331. * struct {
  332. * ECParameters curve_params;
  333. * ECPoint public;
  334. * } ServerECDHParams;
  335. */
  336. int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx,
  337. const unsigned char **buf,
  338. const unsigned char *end)
  339. {
  340. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  341. mbedtls_ecp_group_id grp_id;
  342. if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, (size_t) (end - *buf)))
  343. != 0) {
  344. return ret;
  345. }
  346. if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) {
  347. return ret;
  348. }
  349. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  350. return ecdh_read_params_internal(ctx, buf, end);
  351. #else
  352. switch (ctx->var) {
  353. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  354. case MBEDTLS_ECDH_VARIANT_EVEREST:
  355. return mbedtls_everest_read_params(&ctx->ctx.everest_ecdh,
  356. buf, end);
  357. #endif
  358. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  359. return ecdh_read_params_internal(&ctx->ctx.mbed_ecdh,
  360. buf, end);
  361. default:
  362. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  363. }
  364. #endif
  365. }
  366. static int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx,
  367. const mbedtls_ecp_keypair *key,
  368. mbedtls_ecdh_side side)
  369. {
  370. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  371. /* If it's not our key, just import the public part as Qp */
  372. if (side == MBEDTLS_ECDH_THEIRS) {
  373. return mbedtls_ecp_copy(&ctx->Qp, &key->Q);
  374. }
  375. /* Our key: import public (as Q) and private parts */
  376. if (side != MBEDTLS_ECDH_OURS) {
  377. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  378. }
  379. if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 ||
  380. (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) {
  381. return ret;
  382. }
  383. return 0;
  384. }
  385. /*
  386. * Get parameters from a keypair
  387. */
  388. int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx,
  389. const mbedtls_ecp_keypair *key,
  390. mbedtls_ecdh_side side)
  391. {
  392. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  393. if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) {
  394. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  395. }
  396. if (mbedtls_ecdh_grp_id(ctx) == MBEDTLS_ECP_DP_NONE) {
  397. /* This is the first call to get_params(). Set up the context
  398. * for use with the group. */
  399. if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) {
  400. return ret;
  401. }
  402. } else {
  403. /* This is not the first call to get_params(). Check that the
  404. * current key's group is the same as the context's, which was set
  405. * from the first key's group. */
  406. if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) {
  407. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  408. }
  409. }
  410. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  411. return ecdh_get_params_internal(ctx, key, side);
  412. #else
  413. switch (ctx->var) {
  414. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  415. case MBEDTLS_ECDH_VARIANT_EVEREST:
  416. {
  417. mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
  418. MBEDTLS_EVEREST_ECDH_OURS :
  419. MBEDTLS_EVEREST_ECDH_THEIRS;
  420. return mbedtls_everest_get_params(&ctx->ctx.everest_ecdh,
  421. key, s);
  422. }
  423. #endif
  424. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  425. return ecdh_get_params_internal(&ctx->ctx.mbed_ecdh,
  426. key, side);
  427. default:
  428. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  429. }
  430. #endif
  431. }
  432. static int ecdh_make_public_internal(mbedtls_ecdh_context_mbed *ctx,
  433. size_t *olen, int point_format,
  434. unsigned char *buf, size_t blen,
  435. int (*f_rng)(void *,
  436. unsigned char *,
  437. size_t),
  438. void *p_rng,
  439. int restart_enabled)
  440. {
  441. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  442. #if defined(MBEDTLS_ECP_RESTARTABLE)
  443. mbedtls_ecp_restart_ctx *rs_ctx = NULL;
  444. #endif
  445. if (ctx->grp.pbits == 0) {
  446. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  447. }
  448. #if defined(MBEDTLS_ECP_RESTARTABLE)
  449. if (restart_enabled) {
  450. rs_ctx = &ctx->rs;
  451. }
  452. #else
  453. (void) restart_enabled;
  454. #endif
  455. #if defined(MBEDTLS_ECP_RESTARTABLE)
  456. if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q,
  457. f_rng, p_rng, rs_ctx)) != 0) {
  458. return ret;
  459. }
  460. #else
  461. if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q,
  462. f_rng, p_rng)) != 0) {
  463. return ret;
  464. }
  465. #endif /* MBEDTLS_ECP_RESTARTABLE */
  466. return mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, olen,
  467. buf, blen);
  468. }
  469. /*
  470. * Setup and export the client public value
  471. */
  472. int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen,
  473. unsigned char *buf, size_t blen,
  474. int (*f_rng)(void *, unsigned char *, size_t),
  475. void *p_rng)
  476. {
  477. int restart_enabled = 0;
  478. #if defined(MBEDTLS_ECP_RESTARTABLE)
  479. restart_enabled = ctx->restart_enabled;
  480. #endif
  481. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  482. return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen,
  483. f_rng, p_rng, restart_enabled);
  484. #else
  485. switch (ctx->var) {
  486. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  487. case MBEDTLS_ECDH_VARIANT_EVEREST:
  488. return mbedtls_everest_make_public(&ctx->ctx.everest_ecdh, olen,
  489. buf, blen, f_rng, p_rng);
  490. #endif
  491. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  492. return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen,
  493. ctx->point_format, buf, blen,
  494. f_rng, p_rng,
  495. restart_enabled);
  496. default:
  497. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  498. }
  499. #endif
  500. }
  501. static int ecdh_read_public_internal(mbedtls_ecdh_context_mbed *ctx,
  502. const unsigned char *buf, size_t blen)
  503. {
  504. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  505. const unsigned char *p = buf;
  506. if ((ret = mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, &p,
  507. blen)) != 0) {
  508. return ret;
  509. }
  510. if ((size_t) (p - buf) != blen) {
  511. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  512. }
  513. return 0;
  514. }
  515. /*
  516. * Parse and import the client's public value
  517. */
  518. int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx,
  519. const unsigned char *buf, size_t blen)
  520. {
  521. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  522. return ecdh_read_public_internal(ctx, buf, blen);
  523. #else
  524. switch (ctx->var) {
  525. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  526. case MBEDTLS_ECDH_VARIANT_EVEREST:
  527. return mbedtls_everest_read_public(&ctx->ctx.everest_ecdh,
  528. buf, blen);
  529. #endif
  530. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  531. return ecdh_read_public_internal(&ctx->ctx.mbed_ecdh,
  532. buf, blen);
  533. default:
  534. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  535. }
  536. #endif
  537. }
  538. static int ecdh_calc_secret_internal(mbedtls_ecdh_context_mbed *ctx,
  539. size_t *olen, unsigned char *buf,
  540. size_t blen,
  541. int (*f_rng)(void *,
  542. unsigned char *,
  543. size_t),
  544. void *p_rng,
  545. int restart_enabled)
  546. {
  547. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  548. #if defined(MBEDTLS_ECP_RESTARTABLE)
  549. mbedtls_ecp_restart_ctx *rs_ctx = NULL;
  550. #endif
  551. if (ctx == NULL || ctx->grp.pbits == 0) {
  552. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  553. }
  554. #if defined(MBEDTLS_ECP_RESTARTABLE)
  555. if (restart_enabled) {
  556. rs_ctx = &ctx->rs;
  557. }
  558. #else
  559. (void) restart_enabled;
  560. #endif
  561. #if defined(MBEDTLS_ECP_RESTARTABLE)
  562. if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp,
  563. &ctx->d, f_rng, p_rng,
  564. rs_ctx)) != 0) {
  565. return ret;
  566. }
  567. #else
  568. if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp,
  569. &ctx->d, f_rng, p_rng)) != 0) {
  570. return ret;
  571. }
  572. #endif /* MBEDTLS_ECP_RESTARTABLE */
  573. if (mbedtls_mpi_size(&ctx->z) > blen) {
  574. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  575. }
  576. *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0);
  577. if (mbedtls_ecp_get_type(&ctx->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
  578. return mbedtls_mpi_write_binary_le(&ctx->z, buf, *olen);
  579. }
  580. return mbedtls_mpi_write_binary(&ctx->z, buf, *olen);
  581. }
  582. /*
  583. * Derive and export the shared secret
  584. */
  585. int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen,
  586. unsigned char *buf, size_t blen,
  587. int (*f_rng)(void *, unsigned char *, size_t),
  588. void *p_rng)
  589. {
  590. int restart_enabled = 0;
  591. #if defined(MBEDTLS_ECP_RESTARTABLE)
  592. restart_enabled = ctx->restart_enabled;
  593. #endif
  594. #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
  595. return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng,
  596. restart_enabled);
  597. #else
  598. switch (ctx->var) {
  599. #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
  600. case MBEDTLS_ECDH_VARIANT_EVEREST:
  601. return mbedtls_everest_calc_secret(&ctx->ctx.everest_ecdh, olen,
  602. buf, blen, f_rng, p_rng);
  603. #endif
  604. case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
  605. return ecdh_calc_secret_internal(&ctx->ctx.mbed_ecdh, olen, buf,
  606. blen, f_rng, p_rng,
  607. restart_enabled);
  608. default:
  609. return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  610. }
  611. #endif
  612. }
  613. #endif /* MBEDTLS_ECDH_C */