curve25519.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /* curve25519.c
  2. *
  3. * Copyright (C) 2006-2022 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include <wolfssl/wolfcrypt/settings.h>
  26. #ifdef HAVE_CURVE25519
  27. #include <wolfssl/wolfcrypt/curve25519.h>
  28. #include <wolfssl/wolfcrypt/error-crypt.h>
  29. #ifdef NO_INLINE
  30. #include <wolfssl/wolfcrypt/misc.h>
  31. #else
  32. #define WOLFSSL_MISC_INCLUDED
  33. #include <wolfcrypt/src/misc.c>
  34. #endif
  35. #if defined(FREESCALE_LTC_ECC)
  36. #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
  37. #endif
  38. #ifdef WOLFSSL_SE050
  39. #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
  40. #endif
  41. #ifdef WOLF_CRYPTO_CB
  42. #include <wolfssl/wolfcrypt/cryptocb.h>
  43. #endif
  44. const curve25519_set_type curve25519_sets[] = {
  45. {
  46. CURVE25519_KEYSIZE,
  47. "CURVE25519",
  48. }
  49. };
  50. static const unsigned char kCurve25519BasePoint[CURVE25519_KEYSIZE] = {9};
  51. /* Curve25519 private key must be less than order */
  52. /* These functions clamp private k and check it */
  53. static WC_INLINE int curve25519_priv_clamp(byte* priv)
  54. {
  55. priv[0] &= 248;
  56. priv[CURVE25519_KEYSIZE-1] &= 127;
  57. priv[CURVE25519_KEYSIZE-1] |= 64;
  58. return 0;
  59. }
  60. static WC_INLINE int curve25519_priv_clamp_check(const byte* priv)
  61. {
  62. /* check that private part of key has been clamped */
  63. int ret = 0;
  64. if ((priv[0] & ~248) ||
  65. (priv[CURVE25519_KEYSIZE-1] & 128)) {
  66. ret = ECC_BAD_ARG_E;
  67. }
  68. return ret;
  69. }
  70. static WC_INLINE void curve25519_copy_point(byte* out, const byte* point,
  71. int endian)
  72. {
  73. int i;
  74. if (endian == EC25519_BIG_ENDIAN) {
  75. /* put shared secret key in Big Endian format */
  76. for (i = 0; i < CURVE25519_KEYSIZE; i++) {
  77. out[i] = point[CURVE25519_KEYSIZE - i -1];
  78. }
  79. }
  80. else { /* put shared secret key in Little Endian format */
  81. XMEMCPY(out, point, CURVE25519_KEYSIZE);
  82. }
  83. }
  84. /* compute the public key from an existing private key, using bare vectors.
  85. *
  86. * return value is propagated from curve25519() (0 on success), or
  87. * ECC_BAD_ARG_E, and the byte vectors are little endian.
  88. */
  89. int wc_curve25519_make_pub(int public_size, byte* pub, int private_size,
  90. const byte* priv)
  91. {
  92. int ret;
  93. #ifdef FREESCALE_LTC_ECC
  94. const ECPoint* basepoint = nxp_ltc_curve25519_GetBasePoint();
  95. ECPoint wc_pub;
  96. #endif
  97. if ( (public_size != CURVE25519_KEYSIZE) ||
  98. (private_size != CURVE25519_KEYSIZE)) {
  99. return ECC_BAD_ARG_E;
  100. }
  101. if ((pub == NULL) || (priv == NULL)) {
  102. return ECC_BAD_ARG_E;
  103. }
  104. /* check clamping */
  105. ret = curve25519_priv_clamp_check(priv);
  106. if (ret != 0)
  107. return ret;
  108. #ifdef FREESCALE_LTC_ECC
  109. /* input basepoint on Weierstrass curve */
  110. ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
  111. if (ret == 0) {
  112. XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE);
  113. }
  114. #else
  115. fe_init();
  116. SAVE_VECTOR_REGISTERS(return _svr_ret;);
  117. ret = curve25519(pub, priv, kCurve25519BasePoint);
  118. RESTORE_VECTOR_REGISTERS();
  119. #endif
  120. return ret;
  121. }
  122. /* compute the public key from an existing private key, with supplied basepoint,
  123. * using bare vectors.
  124. *
  125. * return value is propagated from curve25519() (0 on success),
  126. * and the byte vectors are little endian.
  127. */
  128. int wc_curve25519_generic(int public_size, byte* pub,
  129. int private_size, const byte* priv,
  130. int basepoint_size, const byte* basepoint)
  131. {
  132. #ifdef FREESCALE_LTC_ECC
  133. /* unsupported with NXP LTC, only supports single basepoint with
  134. * nxp_ltc_curve25519_GetBasePoint() */
  135. return WC_HW_E;
  136. #else
  137. int ret;
  138. if ((public_size != CURVE25519_KEYSIZE) ||
  139. (private_size != CURVE25519_KEYSIZE) ||
  140. (basepoint_size != CURVE25519_KEYSIZE)) {
  141. return ECC_BAD_ARG_E;
  142. }
  143. if ((pub == NULL) || (priv == NULL) || (basepoint == NULL))
  144. return ECC_BAD_ARG_E;
  145. /* check clamping */
  146. ret = curve25519_priv_clamp_check(priv);
  147. if (ret != 0)
  148. return ret;
  149. fe_init();
  150. SAVE_VECTOR_REGISTERS(return _svr_ret;);
  151. ret = curve25519(pub, priv, basepoint);
  152. RESTORE_VECTOR_REGISTERS();
  153. return ret;
  154. #endif /* FREESCALE_LTC_ECC */
  155. }
  156. /* generate a new private key, as a bare vector.
  157. *
  158. * return value is propagated from wc_RNG_GenerateBlock(() (0 on success),
  159. * or BAD_FUNC_ARG/ECC_BAD_ARG_E, and the byte vector is little endian.
  160. */
  161. int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* key)
  162. {
  163. int ret;
  164. if (key == NULL || rng == NULL)
  165. return BAD_FUNC_ARG;
  166. /* currently only a key size of 32 bytes is used */
  167. if (keysize != CURVE25519_KEYSIZE)
  168. return ECC_BAD_ARG_E;
  169. /* random number for private key */
  170. ret = wc_RNG_GenerateBlock(rng, key, keysize);
  171. if (ret == 0) {
  172. /* Clamp the private key */
  173. ret = curve25519_priv_clamp(key);
  174. }
  175. return ret;
  176. }
  177. /* generate a new keypair.
  178. *
  179. * return value is propagated from wc_curve25519_make_private() or
  180. * wc_curve25519_make_pub() (0 on success).
  181. */
  182. int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
  183. {
  184. int ret;
  185. if (key == NULL || rng == NULL)
  186. return BAD_FUNC_ARG;
  187. #ifdef WOLF_CRYPTO_CB
  188. if (key->devId != INVALID_DEVID) {
  189. ret = wc_CryptoCb_Curve25519Gen(rng, keysize, key);
  190. if (ret != CRYPTOCB_UNAVAILABLE)
  191. return ret;
  192. /* fall-through when unavailable */
  193. }
  194. #endif
  195. #ifdef WOLFSSL_SE050
  196. ret = se050_curve25519_create_key(key, keysize);
  197. #else
  198. ret = wc_curve25519_make_priv(rng, keysize, key->k);
  199. if (ret == 0) {
  200. key->privSet = 1;
  201. ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
  202. (int)sizeof(key->k), key->k);
  203. key->pubSet = (ret == 0);
  204. }
  205. #endif
  206. return ret;
  207. }
  208. #ifdef HAVE_CURVE25519_SHARED_SECRET
  209. int wc_curve25519_shared_secret(curve25519_key* private_key,
  210. curve25519_key* public_key,
  211. byte* out, word32* outlen)
  212. {
  213. return wc_curve25519_shared_secret_ex(private_key, public_key,
  214. out, outlen, EC25519_BIG_ENDIAN);
  215. }
  216. int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
  217. curve25519_key* public_key,
  218. byte* out, word32* outlen, int endian)
  219. {
  220. int ret;
  221. ECPoint o;
  222. /* sanity check */
  223. if (private_key == NULL || public_key == NULL ||
  224. out == NULL || outlen == NULL || *outlen < CURVE25519_KEYSIZE) {
  225. return BAD_FUNC_ARG;
  226. }
  227. /* make sure we have a populated private and public key */
  228. if (!public_key->pubSet
  229. #ifndef WOLFSSL_SE050
  230. || !private_key->privSet
  231. #endif
  232. ) {
  233. return ECC_BAD_ARG_E;
  234. }
  235. /* avoid implementation fingerprinting - make sure signed bit is not set */
  236. if (public_key->p.point[CURVE25519_KEYSIZE-1] & 0x80) {
  237. return ECC_BAD_ARG_E;
  238. }
  239. #ifdef WOLF_CRYPTO_CB
  240. if (private_key->devId != INVALID_DEVID) {
  241. ret = wc_CryptoCb_Curve25519(private_key, public_key, out, outlen,
  242. endian);
  243. if (ret != CRYPTOCB_UNAVAILABLE)
  244. return ret;
  245. /* fall-through when unavailable */
  246. }
  247. #endif
  248. XMEMSET(&o, 0, sizeof(o));
  249. #ifdef FREESCALE_LTC_ECC
  250. /* input point P on Curve25519 */
  251. ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
  252. kLTC_Curve25519);
  253. #else
  254. #ifdef WOLFSSL_SE050
  255. if (!private_key->privSet) {
  256. /* use NXP SE050: "privSet" is not set */
  257. ret = se050_curve25519_shared_secret(private_key, public_key, &o);
  258. }
  259. else
  260. #endif
  261. {
  262. SAVE_VECTOR_REGISTERS(return _svr_ret;);
  263. ret = curve25519(o.point, private_key->k, public_key->p.point);
  264. RESTORE_VECTOR_REGISTERS();
  265. }
  266. #endif
  267. #ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
  268. if (ret == 0) {
  269. int i;
  270. byte t = 0;
  271. for (i = 0; i < CURVE25519_KEYSIZE; i++) {
  272. t |= o.point[i];
  273. }
  274. if (t == 0) {
  275. ret = ECC_OUT_OF_RANGE_E;
  276. }
  277. }
  278. #endif
  279. if (ret != 0) {
  280. ForceZero(&o, sizeof(o));
  281. return ret;
  282. }
  283. curve25519_copy_point(out, o.point, endian);
  284. *outlen = CURVE25519_KEYSIZE;
  285. ForceZero(&o, sizeof(o));
  286. return ret;
  287. }
  288. #endif /* HAVE_CURVE25519_SHARED_SECRET */
  289. #ifdef HAVE_CURVE25519_KEY_EXPORT
  290. /* export curve25519 public key (Big endian)
  291. * return 0 on success */
  292. int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen)
  293. {
  294. return wc_curve25519_export_public_ex(key, out, outLen, EC25519_BIG_ENDIAN);
  295. }
  296. /* export curve25519 public key (Big or Little endian)
  297. * return 0 on success */
  298. int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
  299. word32* outLen, int endian)
  300. {
  301. int ret = 0;
  302. if (key == NULL || out == NULL || outLen == NULL) {
  303. return BAD_FUNC_ARG;
  304. }
  305. /* check and set outgoing key size */
  306. if (*outLen < CURVE25519_KEYSIZE) {
  307. *outLen = CURVE25519_KEYSIZE;
  308. return ECC_BAD_ARG_E;
  309. }
  310. /* calculate public if missing */
  311. if (!key->pubSet) {
  312. ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
  313. (int)sizeof(key->k), key->k);
  314. key->pubSet = (ret == 0);
  315. }
  316. /* export public point with endianess */
  317. curve25519_copy_point(out, key->p.point, endian);
  318. *outLen = CURVE25519_KEYSIZE;
  319. return ret;
  320. }
  321. #endif /* HAVE_CURVE25519_KEY_EXPORT */
  322. #ifdef HAVE_CURVE25519_KEY_IMPORT
  323. /* import curve25519 public key (Big endian)
  324. * return 0 on success */
  325. int wc_curve25519_import_public(const byte* in, word32 inLen,
  326. curve25519_key* key)
  327. {
  328. return wc_curve25519_import_public_ex(in, inLen, key, EC25519_BIG_ENDIAN);
  329. }
  330. /* import curve25519 public key (Big or Little endian)
  331. * return 0 on success */
  332. int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
  333. curve25519_key* key, int endian)
  334. {
  335. #ifdef FREESCALE_LTC_ECC
  336. ltc_pkha_ecc_point_t ltcPoint;
  337. #endif
  338. /* sanity check */
  339. if (key == NULL || in == NULL) {
  340. return BAD_FUNC_ARG;
  341. }
  342. /* check size of incoming keys */
  343. if (inLen != CURVE25519_KEYSIZE) {
  344. return ECC_BAD_ARG_E;
  345. }
  346. /* import public point with endianess */
  347. curve25519_copy_point(key->p.point, in, endian);
  348. key->pubSet = 1;
  349. key->dp = &curve25519_sets[0];
  350. /* LTC needs also Y coordinate - let's compute it */
  351. #ifdef FREESCALE_LTC_ECC
  352. ltcPoint.X = &key->p.point[0];
  353. ltcPoint.Y = &key->p.pointY[0];
  354. LTC_PKHA_Curve25519ComputeY(&ltcPoint);
  355. #endif
  356. return 0;
  357. }
  358. /* Check the public key value (big or little endian)
  359. *
  360. * pub Public key bytes.
  361. * pubSz Size of public key in bytes.
  362. * endian Public key bytes passed in as big-endian or little-endian.
  363. * returns BAD_FUNC_ARGS when pub is NULL,
  364. * BUFFER_E when size of public key is zero;
  365. * ECC_OUT_OF_RANGE_E if the high bit is set;
  366. * ECC_BAD_ARG_E if key length is not 32 bytes, public key value is
  367. * zero or one; and
  368. * 0 otherwise.
  369. */
  370. int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian)
  371. {
  372. word32 i;
  373. if (pub == NULL)
  374. return BAD_FUNC_ARG;
  375. /* Check for empty key data */
  376. if (pubSz == 0)
  377. return BUFFER_E;
  378. /* Check key length */
  379. if (pubSz != CURVE25519_KEYSIZE)
  380. return ECC_BAD_ARG_E;
  381. if (endian == EC25519_LITTLE_ENDIAN) {
  382. /* Check for value of zero or one */
  383. for (i = CURVE25519_KEYSIZE - 1; i > 0; i--) {
  384. if (pub[i] != 0)
  385. break;
  386. }
  387. if (i == 0 && (pub[0] == 0 || pub[0] == 1))
  388. return ECC_BAD_ARG_E;
  389. /* Check high bit set */
  390. if (pub[CURVE25519_KEYSIZE - 1] & 0x80)
  391. return ECC_OUT_OF_RANGE_E;
  392. /* Check for order-1 or higher. */
  393. if (pub[CURVE25519_KEYSIZE - 1] == 0x7f) {
  394. for (i = CURVE25519_KEYSIZE - 2; i > 0; i--) {
  395. if (pub[i] != 0xff)
  396. break;
  397. }
  398. if (i == 0 && (pub[0] >= 0xec))
  399. return ECC_BAD_ARG_E;
  400. }
  401. }
  402. else {
  403. /* Check for value of zero or one */
  404. for (i = 0; i < CURVE25519_KEYSIZE - 1; i++) {
  405. if (pub[i] != 0)
  406. break;
  407. }
  408. if (i == CURVE25519_KEYSIZE - 1 && (pub[i] == 0 || pub[i] == 1))
  409. return ECC_BAD_ARG_E;
  410. /* Check high bit set */
  411. if (pub[0] & 0x80)
  412. return ECC_OUT_OF_RANGE_E;
  413. /* Check for order-1 or higher. */
  414. if (pub[0] == 0x7f) {
  415. for (i = 1; i < CURVE25519_KEYSIZE - 1; i++) {
  416. if (pub[i] != 0)
  417. break;
  418. }
  419. if (i == CURVE25519_KEYSIZE - 1 && (pub[i] >= 0xec))
  420. return ECC_BAD_ARG_E;
  421. }
  422. }
  423. return 0;
  424. }
  425. #endif /* HAVE_CURVE25519_KEY_IMPORT */
  426. #ifdef HAVE_CURVE25519_KEY_EXPORT
  427. /* export curve25519 private key only raw (Big endian)
  428. * outLen is in/out size
  429. * return 0 on success */
  430. int wc_curve25519_export_private_raw(curve25519_key* key, byte* out,
  431. word32* outLen)
  432. {
  433. return wc_curve25519_export_private_raw_ex(key, out, outLen,
  434. EC25519_BIG_ENDIAN);
  435. }
  436. /* export curve25519 private key only raw (Big or Little endian)
  437. * outLen is in/out size
  438. * return 0 on success */
  439. int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
  440. word32* outLen, int endian)
  441. {
  442. /* sanity check */
  443. if (key == NULL || out == NULL || outLen == NULL)
  444. return BAD_FUNC_ARG;
  445. /* check size of outgoing buffer */
  446. if (*outLen < CURVE25519_KEYSIZE) {
  447. *outLen = CURVE25519_KEYSIZE;
  448. return ECC_BAD_ARG_E;
  449. }
  450. /* export private scalar with endianess */
  451. curve25519_copy_point(out, key->k, endian);
  452. *outLen = CURVE25519_KEYSIZE;
  453. return 0;
  454. }
  455. /* curve25519 key pair export (Big or Little endian)
  456. * return 0 on success */
  457. int wc_curve25519_export_key_raw(curve25519_key* key,
  458. byte* priv, word32 *privSz,
  459. byte* pub, word32 *pubSz)
  460. {
  461. return wc_curve25519_export_key_raw_ex(key, priv, privSz,
  462. pub, pubSz, EC25519_BIG_ENDIAN);
  463. }
  464. /* curve25519 key pair export (Big or Little endian)
  465. * return 0 on success */
  466. int wc_curve25519_export_key_raw_ex(curve25519_key* key,
  467. byte* priv, word32 *privSz,
  468. byte* pub, word32 *pubSz,
  469. int endian)
  470. {
  471. int ret;
  472. /* export private part */
  473. ret = wc_curve25519_export_private_raw_ex(key, priv, privSz, endian);
  474. if (ret != 0)
  475. return ret;
  476. /* export public part */
  477. return wc_curve25519_export_public_ex(key, pub, pubSz, endian);
  478. }
  479. #endif /* HAVE_CURVE25519_KEY_EXPORT */
  480. #ifdef HAVE_CURVE25519_KEY_IMPORT
  481. /* curve25519 private key import (Big endian)
  482. * Public key to match private key needs to be imported too
  483. * return 0 on success */
  484. int wc_curve25519_import_private_raw(const byte* priv, word32 privSz,
  485. const byte* pub, word32 pubSz,
  486. curve25519_key* key)
  487. {
  488. return wc_curve25519_import_private_raw_ex(priv, privSz, pub, pubSz,
  489. key, EC25519_BIG_ENDIAN);
  490. }
  491. /* curve25519 private key import (Big or Little endian)
  492. * Public key to match private key needs to be imported too
  493. * return 0 on success */
  494. int wc_curve25519_import_private_raw_ex(const byte* priv, word32 privSz,
  495. const byte* pub, word32 pubSz,
  496. curve25519_key* key, int endian)
  497. {
  498. int ret;
  499. /* import private part */
  500. ret = wc_curve25519_import_private_ex(priv, privSz, key, endian);
  501. if (ret != 0)
  502. return ret;
  503. /* import public part */
  504. return wc_curve25519_import_public_ex(pub, pubSz, key, endian);
  505. }
  506. /* curve25519 private key import only. (Big endian)
  507. * return 0 on success */
  508. int wc_curve25519_import_private(const byte* priv, word32 privSz,
  509. curve25519_key* key)
  510. {
  511. return wc_curve25519_import_private_ex(priv, privSz,
  512. key, EC25519_BIG_ENDIAN);
  513. }
  514. /* curve25519 private key import only. (Big or Little endian)
  515. * return 0 on success */
  516. int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
  517. curve25519_key* key, int endian)
  518. {
  519. /* sanity check */
  520. if (key == NULL || priv == NULL) {
  521. return BAD_FUNC_ARG;
  522. }
  523. /* check size of incoming keys */
  524. if ((int)privSz != CURVE25519_KEYSIZE) {
  525. return ECC_BAD_ARG_E;
  526. }
  527. #ifdef WOLFSSL_SE050
  528. /* release NXP resources if set */
  529. se050_curve25519_free_key(key);
  530. #endif
  531. /* import private scalar with endianess */
  532. curve25519_copy_point(key->k, priv, endian);
  533. key->privSet = 1;
  534. key->dp = &curve25519_sets[0];
  535. /* Clamp the key */
  536. return curve25519_priv_clamp(key->k);
  537. }
  538. #endif /* HAVE_CURVE25519_KEY_IMPORT */
  539. int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId)
  540. {
  541. if (key == NULL)
  542. return BAD_FUNC_ARG;
  543. XMEMSET(key, 0, sizeof(*key));
  544. /* currently the format for curve25519 */
  545. key->dp = &curve25519_sets[0];
  546. #ifdef WOLF_CRYPTO_CB
  547. key->devId = devId;
  548. #else
  549. (void)devId;
  550. #endif
  551. (void)heap; /* if needed for XMALLOC/XFREE in future */
  552. #ifndef FREESCALE_LTC_ECC
  553. fe_init();
  554. #endif
  555. #ifdef WOLFSSL_CHECK_MEM_ZERO
  556. wc_MemZero_Add("wc_curve25519_init_ex key->k", key->k, CURVE25519_KEYSIZE);
  557. #endif
  558. return 0;
  559. }
  560. int wc_curve25519_init(curve25519_key* key)
  561. {
  562. return wc_curve25519_init_ex(key, NULL, INVALID_DEVID);
  563. }
  564. /* Clean the memory of a key */
  565. void wc_curve25519_free(curve25519_key* key)
  566. {
  567. if (key == NULL)
  568. return;
  569. #ifdef WOLFSSL_SE050
  570. se050_curve25519_free_key(key);
  571. #endif
  572. key->dp = NULL;
  573. ForceZero(key->k, sizeof(key->k));
  574. XMEMSET(&key->p, 0, sizeof(key->p));
  575. key->pubSet = 0;
  576. key->privSet = 0;
  577. #ifdef WOLFSSL_CHECK_MEM_ZERO
  578. wc_MemZero_Check(key, sizeof(curve25519_key));
  579. #endif
  580. }
  581. /* get key size */
  582. int wc_curve25519_size(curve25519_key* key)
  583. {
  584. if (key == NULL)
  585. return 0;
  586. return key->dp->size;
  587. }
  588. #endif /*HAVE_CURVE25519*/