curve25519.c 19 KB

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