ecdh.c 23 KB

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