ed25519.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293
  1. /* ed25519.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 ed25519 Public Domain ref10 work. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. /* in case user set HAVE_ED25519 there */
  26. #include <wolfssl/wolfcrypt/settings.h>
  27. #ifdef HAVE_ED25519
  28. #include <wolfssl/wolfcrypt/ed25519.h>
  29. #include <wolfssl/wolfcrypt/error-crypt.h>
  30. #include <wolfssl/wolfcrypt/hash.h>
  31. #ifdef NO_INLINE
  32. #include <wolfssl/wolfcrypt/misc.h>
  33. #else
  34. #define WOLFSSL_MISC_INCLUDED
  35. #include <wolfcrypt/src/misc.c>
  36. #endif
  37. #ifdef FREESCALE_LTC_ECC
  38. #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
  39. #endif
  40. #ifdef WOLFSSL_SE050
  41. #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
  42. #endif
  43. #ifdef WOLF_CRYPTO_CB
  44. #include <wolfssl/wolfcrypt/cryptocb.h>
  45. #endif
  46. #if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY)
  47. /* Set a static message string for "Sig No Collisions Message SNC".
  48. ** Note this is a static string per spec, see:
  49. ** https://datatracker.ietf.org/doc/rfc8032/
  50. */
  51. #define ED25519CTX_SNC_MESSAGE "SigEd25519 no Ed25519 collisions"
  52. #define ED25519CTX_SIZE 32 /* 32 chars: fixed length of SNC Message. */
  53. /* The 32 bytes of ED25519CTX_SIZE is used elsewhere, but we need one
  54. ** more char for saving the line ending in our ed25519Ctx[] here: */
  55. static const byte ed25519Ctx[ED25519CTX_SIZE + 1] = ED25519CTX_SNC_MESSAGE;
  56. #endif
  57. static int ed25519_hash_init(ed25519_key* key, wc_Sha512 *sha)
  58. {
  59. int ret;
  60. #ifndef WOLFSSL_ED25519_PERSISTENT_SHA
  61. /* when not using persistent SHA, we'll zero the sha param */
  62. XMEMSET(sha, 0, sizeof(wc_Sha512));
  63. #endif
  64. ret = wc_InitSha512_ex(sha, key->heap,
  65. #if defined(WOLF_CRYPTO_CB)
  66. key->devId
  67. #else
  68. INVALID_DEVID
  69. #endif
  70. );
  71. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  72. if (ret == 0)
  73. key->sha_clean_flag = 1;
  74. #endif
  75. return ret;
  76. }
  77. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  78. static int ed25519_hash_reset(ed25519_key* key)
  79. {
  80. int ret;
  81. if (key->sha_clean_flag)
  82. ret = 0;
  83. else {
  84. wc_Sha512Free(&key->sha);
  85. ret = wc_InitSha512_ex(&key->sha, key->heap,
  86. #if defined(WOLF_CRYPTO_CB)
  87. key->devId
  88. #else
  89. INVALID_DEVID
  90. #endif
  91. );
  92. if (ret == 0)
  93. key->sha_clean_flag = 1;
  94. }
  95. return ret;
  96. }
  97. #endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
  98. static int ed25519_hash_update(ed25519_key* key, wc_Sha512 *sha,
  99. const byte* data, word32 len)
  100. {
  101. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  102. if (key->sha_clean_flag)
  103. key->sha_clean_flag = 0;
  104. #else
  105. (void)key;
  106. #endif
  107. return wc_Sha512Update(sha, data, len);
  108. }
  109. static int ed25519_hash_final(ed25519_key* key, wc_Sha512 *sha, byte* hash)
  110. {
  111. int ret = wc_Sha512Final(sha, hash);
  112. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  113. if (ret == 0)
  114. key->sha_clean_flag = 1;
  115. #else
  116. (void)key;
  117. #endif
  118. return ret;
  119. }
  120. static void ed25519_hash_free(ed25519_key* key, wc_Sha512 *sha)
  121. {
  122. wc_Sha512Free(sha);
  123. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  124. key->sha_clean_flag = 0;
  125. #else
  126. (void)key;
  127. #endif
  128. }
  129. static int ed25519_hash(ed25519_key* key, const byte* in, word32 inLen,
  130. byte* hash)
  131. {
  132. int ret;
  133. #ifndef WOLFSSL_ED25519_PERSISTENT_SHA
  134. wc_Sha512 sha[1];
  135. #else
  136. wc_Sha512 *sha;
  137. #endif
  138. if (key == NULL || (in == NULL && inLen > 0) || hash == NULL) {
  139. return BAD_FUNC_ARG;
  140. }
  141. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  142. sha = &key->sha;
  143. ret = ed25519_hash_reset(key);
  144. #else
  145. ret = ed25519_hash_init(key, sha);
  146. #endif
  147. if (ret < 0)
  148. return ret;
  149. ret = ed25519_hash_update(key, sha, in, inLen);
  150. if (ret == 0)
  151. ret = ed25519_hash_final(key, sha, hash);
  152. #ifndef WOLFSSL_ED25519_PERSISTENT_SHA
  153. ed25519_hash_free(key, sha);
  154. #endif
  155. return ret;
  156. }
  157. #ifdef HAVE_ED25519_MAKE_KEY
  158. int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
  159. word32 pubKeySz)
  160. {
  161. int ret = 0;
  162. ALIGN16 byte az[ED25519_PRV_KEY_SIZE];
  163. #if !defined(FREESCALE_LTC_ECC)
  164. ge_p3 A;
  165. #endif
  166. if (key == NULL || pubKey == NULL || pubKeySz != ED25519_PUB_KEY_SIZE)
  167. ret = BAD_FUNC_ARG;
  168. if ((ret == 0) && (!key->privKeySet)) {
  169. ret = ECC_PRIV_KEY_E;
  170. }
  171. if (ret == 0)
  172. ret = ed25519_hash(key, key->k, ED25519_KEY_SIZE, az);
  173. if (ret == 0) {
  174. /* apply clamp */
  175. az[0] &= 248;
  176. az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
  177. az[31] |= 64;
  178. #ifdef FREESCALE_LTC_ECC
  179. ltc_pkha_ecc_point_t publicKey = {0};
  180. publicKey.X = key->pointX;
  181. publicKey.Y = key->pointY;
  182. LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), az,
  183. ED25519_KEY_SIZE, &publicKey, kLTC_Ed25519 /* result on Ed25519 */);
  184. LTC_PKHA_Ed25519_Compress(&publicKey, pubKey);
  185. #else
  186. ge_scalarmult_base(&A, az);
  187. ge_p3_tobytes(pubKey, &A);
  188. #endif
  189. key->pubKeySet = 1;
  190. }
  191. return ret;
  192. }
  193. /* generate an ed25519 key pair.
  194. * returns 0 on success
  195. */
  196. int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
  197. {
  198. int ret;
  199. if (rng == NULL || key == NULL)
  200. return BAD_FUNC_ARG;
  201. /* ed25519 has 32 byte key sizes */
  202. if (keySz != ED25519_KEY_SIZE)
  203. return BAD_FUNC_ARG;
  204. key->privKeySet = 0;
  205. key->pubKeySet = 0;
  206. #ifdef WOLF_CRYPTO_CB
  207. if (key->devId != INVALID_DEVID) {
  208. ret = wc_CryptoCb_Ed25519Gen(rng, keySz, key);
  209. if (ret != CRYPTOCB_UNAVAILABLE)
  210. return ret;
  211. /* fall-through when unavailable */
  212. }
  213. #endif
  214. ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE);
  215. if (ret != 0)
  216. return ret;
  217. key->privKeySet = 1;
  218. ret = wc_ed25519_make_public(key, key->p, ED25519_PUB_KEY_SIZE);
  219. if (ret != 0) {
  220. key->privKeySet = 0;
  221. ForceZero(key->k, ED25519_KEY_SIZE);
  222. return ret;
  223. }
  224. /* put public key after private key, on the same buffer */
  225. XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
  226. return ret;
  227. }
  228. #endif /* HAVE_ED25519_MAKE_KEY */
  229. #ifdef HAVE_ED25519_SIGN
  230. /*
  231. in contains the message to sign
  232. inLen is the length of the message to sign
  233. out is the buffer to write the signature
  234. outLen [in/out] input size of out buf
  235. output gets set as the final length of out
  236. key is the ed25519 key to use when signing
  237. type one of Ed25519, Ed25519ctx or Ed25519ph
  238. context extra signing data
  239. contextLen length of extra signing data
  240. return 0 on success
  241. */
  242. int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
  243. word32 *outLen, ed25519_key* key, byte type,
  244. const byte* context, byte contextLen)
  245. {
  246. int ret;
  247. #ifdef WOLFSSL_SE050
  248. (void)context;
  249. (void)contextLen;
  250. (void)type;
  251. ret = se050_ed25519_sign_msg(in, inLen, out, outLen, key);
  252. #else
  253. #ifdef FREESCALE_LTC_ECC
  254. ALIGN16 byte tempBuf[ED25519_PRV_KEY_SIZE];
  255. ltc_pkha_ecc_point_t ltcPoint = {0};
  256. #else
  257. ge_p3 R;
  258. #endif
  259. ALIGN16 byte nonce[WC_SHA512_DIGEST_SIZE];
  260. ALIGN16 byte hram[WC_SHA512_DIGEST_SIZE];
  261. ALIGN16 byte az[ED25519_PRV_KEY_SIZE];
  262. /* sanity check on arguments */
  263. if (in == NULL || out == NULL || outLen == NULL || key == NULL ||
  264. (context == NULL && contextLen != 0)) {
  265. return BAD_FUNC_ARG;
  266. }
  267. #ifdef WOLF_CRYPTO_CB
  268. if (key->devId != INVALID_DEVID) {
  269. ret = wc_CryptoCb_Ed25519Sign(in, inLen, out, outLen, key, type,
  270. context, contextLen);
  271. if (ret != CRYPTOCB_UNAVAILABLE)
  272. return ret;
  273. /* fall-through when unavailable */
  274. }
  275. #endif
  276. if (!key->pubKeySet)
  277. return BAD_FUNC_ARG;
  278. /* check and set up out length */
  279. if (*outLen < ED25519_SIG_SIZE) {
  280. *outLen = ED25519_SIG_SIZE;
  281. return BUFFER_E;
  282. }
  283. *outLen = ED25519_SIG_SIZE;
  284. /* step 1: create nonce to use where nonce is r in
  285. r = H(h_b, ... ,h_2b-1,M) */
  286. ret = ed25519_hash(key, key->k, ED25519_KEY_SIZE, az);
  287. if (ret != 0)
  288. return ret;
  289. /* apply clamp */
  290. az[0] &= 248;
  291. az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */
  292. az[31] |= 64;
  293. {
  294. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  295. wc_Sha512 *sha = &key->sha;
  296. #else
  297. wc_Sha512 sha[1];
  298. ret = ed25519_hash_init(key, sha);
  299. if (ret < 0) {
  300. return ret;
  301. }
  302. #endif
  303. if (type == Ed25519ctx || type == Ed25519ph) {
  304. ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
  305. if (ret == 0)
  306. ret = ed25519_hash_update(key, sha, &type, sizeof(type));
  307. if (ret == 0)
  308. ret = ed25519_hash_update(key, sha, &contextLen,
  309. sizeof(contextLen));
  310. if (ret == 0 && context != NULL)
  311. ret = ed25519_hash_update(key, sha, context, contextLen);
  312. }
  313. if (ret == 0)
  314. ret = ed25519_hash_update(key, sha, az + ED25519_KEY_SIZE,
  315. ED25519_KEY_SIZE);
  316. if (ret == 0)
  317. ret = ed25519_hash_update(key, sha, in, inLen);
  318. if (ret == 0)
  319. ret = ed25519_hash_final(key, sha, nonce);
  320. #ifndef WOLFSSL_ED25519_PERSISTENT_SHA
  321. ed25519_hash_free(key, sha);
  322. #endif
  323. }
  324. if (ret != 0)
  325. return ret;
  326. #ifdef FREESCALE_LTC_ECC
  327. ltcPoint.X = &tempBuf[0];
  328. ltcPoint.Y = &tempBuf[32];
  329. LTC_PKHA_sc_reduce(nonce);
  330. LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce,
  331. ED25519_KEY_SIZE, &ltcPoint, kLTC_Ed25519 /* result on Ed25519 */);
  332. LTC_PKHA_Ed25519_Compress(&ltcPoint, out);
  333. #else
  334. sc_reduce(nonce);
  335. /* step 2: computing R = rB where rB is the scalar multiplication of
  336. r and B */
  337. ge_scalarmult_base(&R,nonce);
  338. ge_p3_tobytes(out,&R);
  339. #endif
  340. /* step 3: hash R + public key + message getting H(R,A,M) then
  341. creating S = (r + H(R,A,M)a) mod l */
  342. {
  343. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  344. wc_Sha512 *sha = &key->sha;
  345. #else
  346. wc_Sha512 sha[1];
  347. ret = ed25519_hash_init(key, sha);
  348. if (ret < 0)
  349. return ret;
  350. #endif
  351. if (type == Ed25519ctx || type == Ed25519ph) {
  352. ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
  353. if (ret == 0)
  354. ret = ed25519_hash_update(key, sha, &type, sizeof(type));
  355. if (ret == 0)
  356. ret = ed25519_hash_update(key, sha, &contextLen,
  357. sizeof(contextLen));
  358. if (ret == 0 && context != NULL)
  359. ret = ed25519_hash_update(key, sha, context, contextLen);
  360. }
  361. if (ret == 0)
  362. ret = ed25519_hash_update(key, sha, out, ED25519_SIG_SIZE/2);
  363. if (ret == 0)
  364. ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
  365. if (ret == 0)
  366. ret = ed25519_hash_update(key, sha, in, inLen);
  367. if (ret == 0)
  368. ret = ed25519_hash_final(key, sha, hram);
  369. #ifndef WOLFSSL_ED25519_PERSISTENT_SHA
  370. ed25519_hash_free(key, sha);
  371. #endif
  372. }
  373. if (ret != 0)
  374. return ret;
  375. #ifdef FREESCALE_LTC_ECC
  376. LTC_PKHA_sc_reduce(hram);
  377. LTC_PKHA_sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
  378. #else
  379. sc_reduce(hram);
  380. sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
  381. #endif
  382. #endif /* WOLFSSL_SE050 */
  383. return ret;
  384. }
  385. /*
  386. in contains the message to sign
  387. inLen is the length of the message to sign
  388. out is the buffer to write the signature
  389. outLen [in/out] input size of out buf
  390. output gets set as the final length of out
  391. key is the ed25519 key to use when signing
  392. return 0 on success
  393. */
  394. int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
  395. word32 *outLen, ed25519_key* key)
  396. {
  397. return wc_ed25519_sign_msg_ex(in, inLen, out, outLen, key, (byte)Ed25519,
  398. NULL, 0);
  399. }
  400. /*
  401. in contains the message to sign
  402. inLen is the length of the message to sign
  403. out is the buffer to write the signature
  404. outLen [in/out] input size of out buf
  405. output gets set as the final length of out
  406. key is the ed25519 key to use when signing
  407. context extra signing data
  408. contextLen length of extra signing data
  409. return 0 on success
  410. */
  411. int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,
  412. word32 *outLen, ed25519_key* key,
  413. const byte* context, byte contextLen)
  414. {
  415. return wc_ed25519_sign_msg_ex(in, inLen, out, outLen, key, Ed25519ctx,
  416. context, contextLen);
  417. }
  418. /*
  419. hash contains the SHA-512 hash of the message to sign
  420. hashLen is the length of the SHA-512 hash of the message to sign
  421. out is the buffer to write the signature
  422. outLen [in/out] input size of out buf
  423. output gets set as the final length of out
  424. key is the ed25519 key to use when signing
  425. context extra signing data
  426. contextLen length of extra signing data
  427. return 0 on success
  428. */
  429. int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
  430. word32 *outLen, ed25519_key* key,
  431. const byte* context, byte contextLen)
  432. {
  433. return wc_ed25519_sign_msg_ex(hash, hashLen, out, outLen, key, Ed25519ph,
  434. context, contextLen);
  435. }
  436. /*
  437. in contains the message to sign
  438. inLen is the length of the message to sign
  439. out is the buffer to write the signature
  440. outLen [in/out] input size of out buf
  441. output gets set as the final length of out
  442. key is the ed25519 key to use when signing
  443. context extra signing data
  444. contextLen length of extra signing data
  445. return 0 on success
  446. */
  447. int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
  448. word32 *outLen, ed25519_key* key,
  449. const byte* context, byte contextLen)
  450. {
  451. int ret;
  452. byte hash[WC_SHA512_DIGEST_SIZE];
  453. ret = ed25519_hash(key, in, inLen, hash);
  454. if (ret != 0)
  455. return ret;
  456. return wc_ed25519_sign_msg_ex(hash, sizeof(hash), out, outLen, key,
  457. Ed25519ph, context, contextLen);
  458. }
  459. #endif /* HAVE_ED25519_SIGN */
  460. #ifdef HAVE_ED25519_VERIFY
  461. #ifndef WOLFSSL_SE050
  462. /*
  463. sig is array of bytes containing the signature
  464. sigLen is the length of sig byte array
  465. key Ed25519 public key
  466. return 0 on success
  467. type variant to use -- Ed25519, Ed25519ctx, or Ed25519ph
  468. context extra signing data
  469. contextLen length of extra signing data
  470. */
  471. static int ed25519_verify_msg_init_with_sha(const byte* sig, word32 sigLen,
  472. ed25519_key* key, wc_Sha512 *sha,
  473. byte type, const byte* context,
  474. byte contextLen)
  475. {
  476. int ret;
  477. /* sanity check on arguments */
  478. if (sig == NULL || key == NULL ||
  479. (context == NULL && contextLen != 0)) {
  480. return BAD_FUNC_ARG;
  481. }
  482. /* check on basics needed to verify signature */
  483. if (sigLen != ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
  484. return BAD_FUNC_ARG;
  485. /* find H(R,A,M) and store it as h */
  486. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  487. ret = ed25519_hash_reset(key);
  488. if (ret != 0)
  489. return ret;
  490. #else
  491. ret = 0;
  492. #endif
  493. if (type == Ed25519ctx || type == Ed25519ph) {
  494. ret = ed25519_hash_update(key, sha, ed25519Ctx, ED25519CTX_SIZE);
  495. if (ret == 0)
  496. ret = ed25519_hash_update(key, sha, &type, sizeof(type));
  497. if (ret == 0)
  498. ret = ed25519_hash_update(key, sha, &contextLen, sizeof(contextLen));
  499. if (ret == 0 && context != NULL)
  500. ret = ed25519_hash_update(key, sha, context, contextLen);
  501. }
  502. if (ret == 0)
  503. ret = ed25519_hash_update(key, sha, sig, ED25519_SIG_SIZE/2);
  504. if (ret == 0)
  505. ret = ed25519_hash_update(key, sha, key->p, ED25519_PUB_KEY_SIZE);
  506. return ret;
  507. }
  508. /*
  509. msgSegment an array of bytes containing a message segment
  510. msgSegmentLen length of msgSegment
  511. key Ed25519 public key
  512. return 0 on success
  513. */
  514. static int ed25519_verify_msg_update_with_sha(const byte* msgSegment,
  515. word32 msgSegmentLen,
  516. ed25519_key* key,
  517. wc_Sha512 *sha) {
  518. /* sanity check on arguments */
  519. if (msgSegment == NULL || key == NULL)
  520. return BAD_FUNC_ARG;
  521. return ed25519_hash_update(key, sha, msgSegment, msgSegmentLen);
  522. }
  523. /* Low part of order in big endian. */
  524. static const byte ed25519_low_order[] = {
  525. 0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6,
  526. 0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed
  527. };
  528. #define ED25519_SIG_LOW_ORDER_IDX \
  529. ((int)(ED25519_SIG_SIZE/2 + sizeof(ed25519_low_order) - 1))
  530. /*
  531. sig is array of bytes containing the signature
  532. sigLen is the length of sig byte array
  533. res will be 1 on successful verify and 0 on unsuccessful
  534. key Ed25519 public key
  535. return 0 and res of 1 on success
  536. */
  537. static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
  538. int* res, ed25519_key* key,
  539. wc_Sha512 *sha)
  540. {
  541. ALIGN16 byte rcheck[ED25519_KEY_SIZE];
  542. ALIGN16 byte h[WC_SHA512_DIGEST_SIZE];
  543. #ifndef FREESCALE_LTC_ECC
  544. ge_p3 A;
  545. ge_p2 R;
  546. #endif
  547. int ret;
  548. /* sanity check on arguments */
  549. if (sig == NULL || res == NULL || key == NULL)
  550. return BAD_FUNC_ARG;
  551. /* set verification failed by default */
  552. *res = 0;
  553. /* check on basics needed to verify signature */
  554. if (sigLen != ED25519_SIG_SIZE)
  555. return BAD_FUNC_ARG;
  556. /* S is not larger or equal to the order:
  557. * 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed
  558. * = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
  559. */
  560. if (sig[ED25519_SIG_SIZE-1] > 0x10)
  561. return BAD_FUNC_ARG;
  562. if (sig[ED25519_SIG_SIZE-1] == 0x10) {
  563. int i = ED25519_SIG_SIZE-1;
  564. int j;
  565. /* Check high zeros. */
  566. for (--i; i > ED25519_SIG_LOW_ORDER_IDX; i--) {
  567. if (sig[i] > 0x00)
  568. break;
  569. }
  570. /* Did we see all zeros up to lower order index? */
  571. if (i == ED25519_SIG_LOW_ORDER_IDX) {
  572. /* Check lower part. */
  573. for (j = 0; j < (int)sizeof(ed25519_low_order); j++, i--) {
  574. /* Check smaller. */
  575. if (sig[i] < ed25519_low_order[j])
  576. break;
  577. /* Check bigger. */
  578. if (sig[i] > ed25519_low_order[j])
  579. return BAD_FUNC_ARG;
  580. }
  581. /* Check equal - all bytes match. */
  582. if (i == ED25519_SIG_SIZE/2 - 1)
  583. return BAD_FUNC_ARG;
  584. }
  585. }
  586. /* uncompress A (public key), test if valid, and negate it */
  587. #ifndef FREESCALE_LTC_ECC
  588. if (ge_frombytes_negate_vartime(&A, key->p) != 0)
  589. return BAD_FUNC_ARG;
  590. #endif
  591. /* find H(R,A,M) and store it as h */
  592. ret = ed25519_hash_final(key, sha, h);
  593. if (ret != 0)
  594. return ret;
  595. #ifdef FREESCALE_LTC_ECC
  596. ret = LTC_PKHA_sc_reduce(h);
  597. if (ret != kStatus_Success)
  598. return ret;
  599. ret = LTC_PKHA_SignatureForVerify(rcheck, h, sig + (ED25519_SIG_SIZE/2), key);
  600. if (ret != kStatus_Success)
  601. return ret;
  602. #else
  603. sc_reduce(h);
  604. /*
  605. Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
  606. SB - H(R,A,M)A saving decompression of R
  607. */
  608. ret = ge_double_scalarmult_vartime(&R, h, &A, sig + (ED25519_SIG_SIZE/2));
  609. if (ret != 0)
  610. return ret;
  611. ge_tobytes(rcheck, &R);
  612. #endif /* FREESCALE_LTC_ECC */
  613. /* comparison of R created to R in sig */
  614. ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
  615. if (ret != 0) {
  616. ret = SIG_VERIFY_E;
  617. } else {
  618. /* set the verification status */
  619. *res = 1;
  620. }
  621. return ret;
  622. }
  623. #endif /* WOLFSSL_SE050 */
  624. #if defined(WOLFSSL_ED25519_STREAMING_VERIFY) && !defined(WOLFSSL_SE050)
  625. int wc_ed25519_verify_msg_init(const byte* sig, word32 sigLen, ed25519_key* key,
  626. byte type, const byte* context, byte contextLen) {
  627. return ed25519_verify_msg_init_with_sha(sig, sigLen, key, &key->sha,
  628. type, context, contextLen);
  629. }
  630. int wc_ed25519_verify_msg_update(const byte* msgSegment, word32 msgSegmentLen,
  631. ed25519_key* key) {
  632. return ed25519_verify_msg_update_with_sha(msgSegment, msgSegmentLen,
  633. key, &key->sha);
  634. }
  635. int wc_ed25519_verify_msg_final(const byte* sig, word32 sigLen, int* res,
  636. ed25519_key* key) {
  637. return ed25519_verify_msg_final_with_sha(sig, sigLen, res,
  638. key, &key->sha);
  639. }
  640. #endif /* WOLFSSL_ED25519_STREAMING_VERIFY && !WOLFSSL_SE050 */
  641. /*
  642. sig is array of bytes containing the signature
  643. sigLen is the length of sig byte array
  644. msg the array of bytes containing the message
  645. msgLen length of msg array
  646. res will be 1 on successful verify and 0 on unsuccessful
  647. key Ed25519 public key
  648. return 0 and res of 1 on success
  649. */
  650. int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
  651. word32 msgLen, int* res, ed25519_key* key,
  652. byte type, const byte* context, byte contextLen)
  653. {
  654. int ret;
  655. #ifdef WOLFSSL_SE050
  656. (void)type;
  657. (void)context;
  658. (void)contextLen;
  659. (void)ed25519Ctx;
  660. ret = se050_ed25519_verify_msg(sig, sigLen, msg, msgLen, key, res);
  661. #else
  662. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  663. wc_Sha512 *sha;
  664. #else
  665. wc_Sha512 sha[1];
  666. #endif
  667. /* sanity check on arguments */
  668. if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
  669. (context == NULL && contextLen != 0))
  670. return BAD_FUNC_ARG;
  671. #ifdef WOLF_CRYPTO_CB
  672. if (key->devId != INVALID_DEVID) {
  673. ret = wc_CryptoCb_Ed25519Verify(sig, sigLen, msg, msgLen, res, key,
  674. type, context, contextLen);
  675. if (ret != CRYPTOCB_UNAVAILABLE)
  676. return ret;
  677. /* fall-through when unavailable */
  678. }
  679. #endif
  680. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  681. sha = &key->sha;
  682. #else
  683. ret = ed25519_hash_init(key, sha);
  684. if (ret < 0) {
  685. return ret;
  686. }
  687. #endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
  688. ret = ed25519_verify_msg_init_with_sha(sig, sigLen, key, sha, type, context,
  689. contextLen);
  690. if (ret == 0)
  691. ret = ed25519_verify_msg_update_with_sha(msg, msgLen, key, sha);
  692. if (ret == 0)
  693. ret = ed25519_verify_msg_final_with_sha(sig, sigLen, res, key, sha);
  694. #ifndef WOLFSSL_ED25519_PERSISTENT_SHA
  695. ed25519_hash_free(key, sha);
  696. #endif
  697. #endif /* WOLFSSL_SE050 */
  698. return ret;
  699. }
  700. /*
  701. sig is array of bytes containing the signature
  702. sigLen is the length of sig byte array
  703. msg the array of bytes containing the message
  704. msgLen length of msg array
  705. res will be 1 on successful verify and 0 on unsuccessful
  706. key Ed25519 public key
  707. return 0 and res of 1 on success
  708. */
  709. int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
  710. word32 msgLen, int* res, ed25519_key* key)
  711. {
  712. return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key,
  713. (byte)Ed25519, NULL, 0);
  714. }
  715. /*
  716. sig is array of bytes containing the signature
  717. sigLen is the length of sig byte array
  718. msg the array of bytes containing the message
  719. msgLen length of msg array
  720. res will be 1 on successful verify and 0 on unsuccessful
  721. key Ed25519 public key
  722. context extra signing data
  723. contextLen length of extra signing data
  724. return 0 and res of 1 on success
  725. */
  726. int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
  727. word32 msgLen, int* res, ed25519_key* key,
  728. const byte* context, byte contextLen)
  729. {
  730. return wc_ed25519_verify_msg_ex(sig, sigLen, msg, msgLen, res, key,
  731. Ed25519ctx, context, contextLen);
  732. }
  733. /*
  734. sig is array of bytes containing the signature
  735. sigLen is the length of sig byte array
  736. hash the array of bytes containing the SHA-512 hash of the message
  737. hashLen length of hash array
  738. res will be 1 on successful verify and 0 on unsuccessful
  739. key Ed25519 public key
  740. context extra signing data
  741. contextLen length of extra signing data
  742. return 0 and res of 1 on success
  743. */
  744. int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
  745. word32 hashLen, int* res, ed25519_key* key,
  746. const byte* context, byte contextLen)
  747. {
  748. return wc_ed25519_verify_msg_ex(sig, sigLen, hash, hashLen, res, key,
  749. Ed25519ph, context, contextLen);
  750. }
  751. /*
  752. sig is array of bytes containing the signature
  753. sigLen is the length of sig byte array
  754. msg the array of bytes containing the message
  755. msgLen length of msg array
  756. res will be 1 on successful verify and 0 on unsuccessful
  757. key Ed25519 public key
  758. context extra signing data
  759. contextLen length of extra signing data
  760. return 0 and res of 1 on success
  761. */
  762. int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
  763. word32 msgLen, int* res, ed25519_key* key,
  764. const byte* context, byte contextLen)
  765. {
  766. int ret;
  767. byte hash[WC_SHA512_DIGEST_SIZE];
  768. ret = ed25519_hash(key, msg, msgLen, hash);
  769. if (ret != 0)
  770. return ret;
  771. return wc_ed25519_verify_msg_ex(sig, sigLen, hash, sizeof(hash), res, key,
  772. Ed25519ph, context, contextLen);
  773. }
  774. #endif /* HAVE_ED25519_VERIFY */
  775. /* initialize information and memory for key */
  776. int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
  777. {
  778. if (key == NULL)
  779. return BAD_FUNC_ARG;
  780. /* for init, ensure the key is zeroed*/
  781. XMEMSET(key, 0, sizeof(ed25519_key));
  782. #ifdef WOLF_CRYPTO_CB
  783. key->devId = devId;
  784. #else
  785. (void)devId;
  786. #endif
  787. key->heap = heap;
  788. #ifndef FREESCALE_LTC_ECC
  789. fe_init();
  790. #endif
  791. #ifdef WOLFSSL_CHECK_MEM_ZERO
  792. wc_MemZero_Add("wc_ed25519_init_ex key->k", &key->k, sizeof(key->k));
  793. #endif
  794. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  795. return ed25519_hash_init(key, &key->sha);
  796. #else /* !WOLFSSL_ED25519_PERSISTENT_SHA */
  797. return 0;
  798. #endif /* WOLFSSL_ED25519_PERSISTENT_SHA */
  799. }
  800. int wc_ed25519_init(ed25519_key* key)
  801. {
  802. return wc_ed25519_init_ex(key, NULL, INVALID_DEVID);
  803. }
  804. /* clear memory of key */
  805. void wc_ed25519_free(ed25519_key* key)
  806. {
  807. if (key == NULL)
  808. return;
  809. #ifdef WOLFSSL_ED25519_PERSISTENT_SHA
  810. ed25519_hash_free(key, &key->sha);
  811. #endif
  812. #ifdef WOLFSSL_SE050
  813. se050_ed25519_free_key(key);
  814. #endif
  815. ForceZero(key, sizeof(ed25519_key));
  816. #ifdef WOLFSSL_CHECK_MEM_ZERO
  817. wc_MemZero_Check(key, sizeof(ed25519_key));
  818. #endif
  819. }
  820. #ifdef HAVE_ED25519_KEY_EXPORT
  821. /*
  822. outLen should contain the size of out buffer when input. outLen is than set
  823. to the final output length.
  824. returns 0 on success
  825. */
  826. int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
  827. {
  828. /* sanity check on arguments */
  829. if (key == NULL || out == NULL || outLen == NULL)
  830. return BAD_FUNC_ARG;
  831. if (*outLen < ED25519_PUB_KEY_SIZE) {
  832. *outLen = ED25519_PUB_KEY_SIZE;
  833. return BUFFER_E;
  834. }
  835. *outLen = ED25519_PUB_KEY_SIZE;
  836. XMEMCPY(out, key->p, ED25519_PUB_KEY_SIZE);
  837. return 0;
  838. }
  839. #endif /* HAVE_ED25519_KEY_EXPORT */
  840. #ifdef HAVE_ED25519_KEY_IMPORT
  841. /*
  842. Imports a compressed/uncompressed public key.
  843. in the byte array containing the public key
  844. inLen the length of the byte array being passed in
  845. key ed25519 key struct to put the public key in
  846. trusted whether the public key is trusted to match private key if set
  847. */
  848. int wc_ed25519_import_public_ex(const byte* in, word32 inLen, ed25519_key* key,
  849. int trusted)
  850. {
  851. int ret = 0;
  852. /* sanity check on arguments */
  853. if (in == NULL || key == NULL)
  854. return BAD_FUNC_ARG;
  855. if (inLen < ED25519_PUB_KEY_SIZE)
  856. return BAD_FUNC_ARG;
  857. /* compressed prefix according to draft
  858. http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */
  859. if (in[0] == 0x40 && inLen == ED25519_PUB_KEY_SIZE + 1) {
  860. /* key is stored in compressed format so just copy in */
  861. XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE);
  862. #ifdef FREESCALE_LTC_ECC
  863. /* recover X coordinate */
  864. ltc_pkha_ecc_point_t pubKey;
  865. pubKey.X = key->pointX;
  866. pubKey.Y = key->pointY;
  867. LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
  868. #endif
  869. }
  870. /* importing uncompressed public key */
  871. else if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) {
  872. #ifdef FREESCALE_LTC_ECC
  873. /* reverse bytes for little endian byte order */
  874. for (int i = 0; i < ED25519_KEY_SIZE; i++)
  875. {
  876. key->pointX[i] = *(in + ED25519_KEY_SIZE - i);
  877. key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i);
  878. }
  879. XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE);
  880. #else
  881. /* pass in (x,y) and store compressed key */
  882. ret = ge_compress_key(key->p, in+1,
  883. in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE);
  884. #endif /* FREESCALE_LTC_ECC */
  885. }
  886. /* if not specified compressed or uncompressed check key size
  887. if key size is equal to compressed key size copy in key */
  888. else if (inLen == ED25519_PUB_KEY_SIZE) {
  889. XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE);
  890. #ifdef FREESCALE_LTC_ECC
  891. /* recover X coordinate */
  892. ltc_pkha_ecc_point_t pubKey;
  893. pubKey.X = key->pointX;
  894. pubKey.Y = key->pointY;
  895. LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey);
  896. #endif
  897. }
  898. else {
  899. ret = BAD_FUNC_ARG;
  900. }
  901. if (ret == 0) {
  902. key->pubKeySet = 1;
  903. if (key->privKeySet && (!trusted)) {
  904. ret = wc_ed25519_check_key(key);
  905. }
  906. }
  907. if (ret != 0) {
  908. key->pubKeySet = 0;
  909. }
  910. /* bad public key format */
  911. return ret;
  912. }
  913. /*
  914. Imports a compressed/uncompressed public key.
  915. in the byte array containing the public key
  916. inLen the length of the byte array being passed in
  917. key ed25519 key struct to put the public key in
  918. */
  919. int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
  920. {
  921. return wc_ed25519_import_public_ex(in, inLen, key, 0);
  922. }
  923. /*
  924. For importing a private key.
  925. */
  926. int wc_ed25519_import_private_only(const byte* priv, word32 privSz,
  927. ed25519_key* key)
  928. {
  929. int ret = 0;
  930. /* sanity check on arguments */
  931. if (priv == NULL || key == NULL)
  932. return BAD_FUNC_ARG;
  933. /* key size check */
  934. if (privSz != ED25519_KEY_SIZE)
  935. return BAD_FUNC_ARG;
  936. XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
  937. key->privKeySet = 1;
  938. if (key->pubKeySet) {
  939. /* Validate loaded public key */
  940. ret = wc_ed25519_check_key(key);
  941. }
  942. if (ret != 0) {
  943. key->privKeySet = 0;
  944. ForceZero(key->k, ED25519_KEY_SIZE);
  945. }
  946. return ret;
  947. }
  948. /* Import an ed25519 private and public keys from byte array(s).
  949. *
  950. * priv [in] Array holding private key from
  951. * wc_ed25519_export_private_only(), or private+public keys from
  952. * wc_ed25519_export_private().
  953. * privSz [in] Number of bytes of data in private key array.
  954. * pub [in] Array holding public key (or NULL).
  955. * pubSz [in] Number of bytes of data in public key array (or 0).
  956. * key [in] Ed25519 private/public key.
  957. * trusted [in] Indicates whether the public key data is trusted.
  958. * When 0, checks public key matches private key.
  959. * When 1, doesn't check public key matches private key.
  960. * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
  961. * combination of keys/lengths is supplied, 0 otherwise.
  962. */
  963. int wc_ed25519_import_private_key_ex(const byte* priv, word32 privSz,
  964. const byte* pub, word32 pubSz, ed25519_key* key, int trusted)
  965. {
  966. int ret;
  967. /* sanity check on arguments */
  968. if (priv == NULL || key == NULL)
  969. return BAD_FUNC_ARG;
  970. /* key size check */
  971. if (privSz != ED25519_KEY_SIZE && privSz != ED25519_PRV_KEY_SIZE)
  972. return BAD_FUNC_ARG;
  973. if (pub == NULL) {
  974. if (pubSz != 0)
  975. return BAD_FUNC_ARG;
  976. if (privSz != ED25519_PRV_KEY_SIZE)
  977. return BAD_FUNC_ARG;
  978. pub = priv + ED25519_KEY_SIZE;
  979. pubSz = ED25519_PUB_KEY_SIZE;
  980. }
  981. else if (pubSz < ED25519_PUB_KEY_SIZE) {
  982. return BAD_FUNC_ARG;
  983. }
  984. XMEMCPY(key->k, priv, ED25519_KEY_SIZE);
  985. key->privKeySet = 1;
  986. /* import public key */
  987. ret = wc_ed25519_import_public_ex(pub, pubSz, key, trusted);
  988. if (ret != 0) {
  989. key->privKeySet = 0;
  990. ForceZero(key->k, ED25519_KEY_SIZE);
  991. return ret;
  992. }
  993. /* make the private key (priv + pub) */
  994. XMEMCPY(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE);
  995. return ret;
  996. }
  997. /* Import an ed25519 private and public keys from byte array(s).
  998. *
  999. * priv [in] Array holding private key from wc_ed25519_export_private_only(),
  1000. * or private+public keys from wc_ed25519_export_private().
  1001. * privSz [in] Number of bytes of data in private key array.
  1002. * pub [in] Array holding public key (or NULL).
  1003. * pubSz [in] Number of bytes of data in public key array (or 0).
  1004. * key [in] Ed25519 private/public key.
  1005. * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
  1006. * combination of keys/lengths is supplied, 0 otherwise.
  1007. */
  1008. int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
  1009. const byte* pub, word32 pubSz, ed25519_key* key)
  1010. {
  1011. return wc_ed25519_import_private_key_ex(priv, privSz, pub, pubSz, key, 0);
  1012. }
  1013. #endif /* HAVE_ED25519_KEY_IMPORT */
  1014. #ifdef HAVE_ED25519_KEY_EXPORT
  1015. /*
  1016. export private key only (secret part so 32 bytes)
  1017. outLen should contain the size of out buffer when input. outLen is than set
  1018. to the final output length.
  1019. returns 0 on success
  1020. */
  1021. int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen)
  1022. {
  1023. /* sanity checks on arguments */
  1024. if (key == NULL || out == NULL || outLen == NULL)
  1025. return BAD_FUNC_ARG;
  1026. if (*outLen < ED25519_KEY_SIZE) {
  1027. *outLen = ED25519_KEY_SIZE;
  1028. return BUFFER_E;
  1029. }
  1030. *outLen = ED25519_KEY_SIZE;
  1031. XMEMCPY(out, key->k, ED25519_KEY_SIZE);
  1032. return 0;
  1033. }
  1034. /*
  1035. export private key, including public part
  1036. outLen should contain the size of out buffer when input. outLen is than set
  1037. to the final output length.
  1038. returns 0 on success
  1039. */
  1040. int wc_ed25519_export_private(ed25519_key* key, byte* out, word32* outLen)
  1041. {
  1042. /* sanity checks on arguments */
  1043. if (key == NULL || out == NULL || outLen == NULL)
  1044. return BAD_FUNC_ARG;
  1045. if (*outLen < ED25519_PRV_KEY_SIZE) {
  1046. *outLen = ED25519_PRV_KEY_SIZE;
  1047. return BUFFER_E;
  1048. }
  1049. *outLen = ED25519_PRV_KEY_SIZE;
  1050. XMEMCPY(out, key->k, ED25519_PRV_KEY_SIZE);
  1051. return 0;
  1052. }
  1053. /* export full private key and public key
  1054. return 0 on success
  1055. */
  1056. int wc_ed25519_export_key(ed25519_key* key,
  1057. byte* priv, word32 *privSz,
  1058. byte* pub, word32 *pubSz)
  1059. {
  1060. int ret;
  1061. /* export 'full' private part */
  1062. ret = wc_ed25519_export_private(key, priv, privSz);
  1063. if (ret != 0)
  1064. return ret;
  1065. /* export public part */
  1066. ret = wc_ed25519_export_public(key, pub, pubSz);
  1067. return ret;
  1068. }
  1069. #endif /* HAVE_ED25519_KEY_EXPORT */
  1070. /* check the private and public keys match */
  1071. int wc_ed25519_check_key(ed25519_key* key)
  1072. {
  1073. int ret = 0;
  1074. #ifdef HAVE_ED25519_MAKE_KEY
  1075. ALIGN16 unsigned char pubKey[ED25519_PUB_KEY_SIZE];
  1076. if (!key->pubKeySet)
  1077. ret = PUBLIC_KEY_E;
  1078. if (ret == 0)
  1079. ret = wc_ed25519_make_public(key, pubKey, sizeof(pubKey));
  1080. if (ret == 0 && XMEMCMP(pubKey, key->p, ED25519_PUB_KEY_SIZE) != 0)
  1081. ret = PUBLIC_KEY_E;
  1082. #else
  1083. (void)key;
  1084. #endif /* HAVE_ED25519_MAKE_KEY */
  1085. return ret;
  1086. }
  1087. /* returns the private key size (secret only) in bytes */
  1088. int wc_ed25519_size(ed25519_key* key)
  1089. {
  1090. if (key == NULL)
  1091. return BAD_FUNC_ARG;
  1092. return ED25519_KEY_SIZE;
  1093. }
  1094. /* returns the private key size (secret + public) in bytes */
  1095. int wc_ed25519_priv_size(ed25519_key* key)
  1096. {
  1097. if (key == NULL)
  1098. return BAD_FUNC_ARG;
  1099. return ED25519_PRV_KEY_SIZE;
  1100. }
  1101. /* returns the compressed key size in bytes (public key) */
  1102. int wc_ed25519_pub_size(ed25519_key* key)
  1103. {
  1104. if (key == NULL)
  1105. return BAD_FUNC_ARG;
  1106. return ED25519_PUB_KEY_SIZE;
  1107. }
  1108. /* returns the size of signature in bytes */
  1109. int wc_ed25519_sig_size(ed25519_key* key)
  1110. {
  1111. if (key == NULL)
  1112. return BAD_FUNC_ARG;
  1113. return ED25519_SIG_SIZE;
  1114. }
  1115. #endif /* HAVE_ED25519 */