ecdh.c 22 KB

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