eccsi.c 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297
  1. /* eccsi.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. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #ifdef NO_INLINE
  26. #include <wolfssl/wolfcrypt/misc.h>
  27. #else
  28. #define WOLFSSL_MISC_INCLUDED
  29. #include <wolfcrypt/src/misc.c>
  30. #endif
  31. #ifdef WOLFCRYPT_HAVE_ECCSI
  32. #include <wolfssl/wolfcrypt/error-crypt.h>
  33. #include <wolfssl/wolfcrypt/eccsi.h>
  34. #include <wolfssl/wolfcrypt/asn_public.h>
  35. #ifdef WOLFSSL_HAVE_SP_ECC
  36. #include <wolfssl/wolfcrypt/sp.h>
  37. #endif
  38. #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
  39. /* FIPS build has replaced ecc.h. */
  40. #define wc_ecc_key_get_priv(key) (&((key)->k))
  41. #define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
  42. #endif
  43. /**
  44. * Initialize the components of the ECCSI key and use the specified curve.
  45. *
  46. * Must be called before performing any operations.
  47. * Free the ECCSI key with wc_FreeEccsiKey() when no longer needed.
  48. *
  49. * @param [in] key ECCSI key to initialize.
  50. * @param [in] heap Heap hint.
  51. * @param [in] devId Device identifier.
  52. * Use INVALID_DEVID when no device used.
  53. * @return 0 on success.
  54. * @return BAD_FUNC_ARG when key is NULL.
  55. * @return MEMORY_E when dynamic memory allocation fails.
  56. */
  57. int wc_InitEccsiKey_ex(EccsiKey* key, int keySz, int curveId, void* heap,
  58. int devId)
  59. {
  60. int err = 0;
  61. ecc_key* ecc = NULL;
  62. ecc_key* pubkey = NULL;
  63. EccsiKeyParams* params = NULL;
  64. if (key == NULL) {
  65. err = BAD_FUNC_ARG;
  66. }
  67. if (err == 0) {
  68. XMEMSET(key, 0, sizeof(*key));
  69. key->heap = heap;
  70. params = &key->params;
  71. err = wc_ecc_init_ex(&key->ecc, heap, devId);
  72. }
  73. if (err == 0) {
  74. ecc = &key->ecc;
  75. err = wc_ecc_init_ex(&key->pubkey, heap, devId);
  76. }
  77. if (err == 0) {
  78. key->pvt = wc_ecc_new_point_h(heap);
  79. if (key->pvt == NULL) {
  80. err = MEMORY_E;
  81. }
  82. }
  83. if (err == 0) {
  84. pubkey = &key->pubkey;
  85. err = mp_init_multi(&params->order,
  86. #ifdef WOLFCRYPT_ECCSI_CLIENT
  87. &params->a, &params->b, &params->prime, &key->tmp, &key->ssk
  88. #else
  89. NULL, NULL, NULL, NULL, NULL
  90. #endif
  91. );
  92. }
  93. if (err == 0) {
  94. err = wc_ecc_set_curve(&key->ecc, keySz, curveId);
  95. }
  96. if (err == 0) {
  97. err = wc_ecc_set_curve(&key->pubkey, keySz, curveId);
  98. }
  99. if (err != 0) {
  100. wc_ecc_free(pubkey);
  101. wc_ecc_free(ecc);
  102. }
  103. return err;
  104. }
  105. /**
  106. * Initialize the components of the ECCSI key.
  107. * Default curve used: NIST_P256 (ECC_SECP256R1)
  108. *
  109. * Must be called before performing any operations.
  110. * Free the ECCSI key with wc_FreeEccsiKey() when no longer needed.
  111. *
  112. * @param [in] key ECCSI key to initialize.
  113. * @param [in] heap Heap hint.
  114. * @param [in] devId Device identifier.
  115. * Use INVALID_DEVID when no device used.
  116. * @return 0 on success.
  117. * @return BAD_FUNC_ARG when key is NULL.
  118. * @return MEMORY_E when dynamic memory allocation fails.
  119. */
  120. int wc_InitEccsiKey(EccsiKey* key, void* heap, int devId)
  121. {
  122. return wc_InitEccsiKey_ex(key, 32, ECC_SECP256R1, heap, devId);
  123. }
  124. /**
  125. * Frees memory associated with components of the ECCIS key.
  126. *
  127. * Must be called when finished with the ECCIS key.
  128. *
  129. * @param [in] key ECCIS key.
  130. */
  131. void wc_FreeEccsiKey(EccsiKey* key)
  132. {
  133. if (key != NULL) {
  134. EccsiKeyParams* params = &key->params;
  135. wc_ecc_del_point_h(params->base, key->heap);
  136. #ifdef WOLFCRYPT_ECCSI_CLIENT
  137. mp_free(&key->ssk);
  138. mp_free(&key->tmp);
  139. mp_free(&params->prime);
  140. mp_free(&params->b);
  141. mp_free(&params->a);
  142. #endif
  143. mp_free(&params->order);
  144. wc_ecc_del_point_h(key->pvt, key->heap);
  145. wc_ecc_free(&key->pubkey);
  146. wc_ecc_free(&key->ecc);
  147. XMEMSET(key, 0, sizeof(*key));
  148. }
  149. }
  150. /*
  151. * Order, as a hex string in the ECC object, loaded into mp_int in key.
  152. * Flags that the order is available so it isn't loaded multiple times.
  153. *
  154. * @param [in] key ECCSI key.
  155. * @return 0 on success.
  156. * @return MEMORY_E when dynamic memory allocation fails.
  157. */
  158. static int eccsi_load_order(EccsiKey* key)
  159. {
  160. int err = 0;
  161. if (!key->params.haveOrder) {
  162. err = mp_read_radix(&key->params.order, key->ecc.dp->order,
  163. MP_RADIX_HEX);
  164. if (err == 0) {
  165. key->params.haveOrder = 1;
  166. }
  167. }
  168. return err;
  169. }
  170. #ifdef WOLFCRYPT_ECCSI_CLIENT
  171. /*
  172. * Parameters, as a hex strings in the ECC object, loaded into mp_ints in key.
  173. *
  174. * Parameters loaded: order, A, B, prime.
  175. * Flags that each parameter is available so they aren't loaded multiple times.
  176. *
  177. * @param [in] key ECCSI key.
  178. * @return 0 on success.
  179. * @return MEMORY_E when dynamic memory allocation fails.
  180. */
  181. static int eccsi_load_ecc_params(EccsiKey* key)
  182. {
  183. int err = 0;
  184. EccsiKeyParams* params = &key->params;
  185. err = eccsi_load_order(key);
  186. if ((err == 0) && (!params->haveA)) {
  187. err = mp_read_radix(&params->a, key->ecc.dp->Af, MP_RADIX_HEX);
  188. if (err == 0) {
  189. params->haveA = 1;
  190. }
  191. }
  192. if ((err == 0) && (!params->haveB)) {
  193. err = mp_read_radix(&params->b, key->ecc.dp->Bf, MP_RADIX_HEX);
  194. if (err == 0) {
  195. params->haveB = 1;
  196. }
  197. }
  198. if ((err == 0) && (!params->havePrime)) {
  199. err = mp_read_radix(&params->prime, key->ecc.dp->prime, MP_RADIX_HEX);
  200. if (err == 0) {
  201. params->havePrime = 1;
  202. }
  203. }
  204. return err;
  205. }
  206. #endif /* WOLFCRYPT_ECCSI_CLIENT */
  207. /*
  208. * Get the base point, hex encoded in the ECC object, as an ecc_point.
  209. *
  210. * Flags that base is available so it isn't loaded multiple times.
  211. * @param [in] key ECCSI key.
  212. * @param [out] base Base point of curve.
  213. * @return 0 on success.
  214. * @return MEMORY_E when dynamic memory allocation fails.
  215. */
  216. static int eccsi_load_base(EccsiKey* key)
  217. {
  218. int err = 0;
  219. EccsiKeyParams* params = &key->params;
  220. if (!params->haveBase) {
  221. if (params->base == NULL) {
  222. params->base = wc_ecc_new_point_h(key->heap);
  223. if (params->base == NULL) {
  224. err = MEMORY_E;
  225. }
  226. }
  227. if (err == 0) {
  228. err = mp_read_radix(params->base->x, key->ecc.dp->Gx, MP_RADIX_HEX);
  229. }
  230. if (err == 0) {
  231. err = mp_read_radix(params->base->y, key->ecc.dp->Gy, MP_RADIX_HEX);
  232. }
  233. if (err == 0) {
  234. err = mp_set(params->base->z, 1);
  235. }
  236. if (err == 0) {
  237. params->haveBase = 1;
  238. }
  239. }
  240. return err;
  241. }
  242. /*
  243. * Encode the base point of the curve.
  244. *
  245. * Base point is hex encoded in the ECC object or cached as an ECC point from
  246. * previous load calls.
  247. *
  248. * @param [in] key ECCSI key.
  249. * @param [out] data Buffer to encode base point into.
  250. * @param [out] dataSz Length of base point in bytes.
  251. * @return 0 on success.
  252. * @return MEMORY_E when dynamic memory allocation fails.
  253. * @return Other -ve value when an internal operation fails.
  254. */
  255. static int eccsi_encode_base(EccsiKey* key, byte* data, word32* dataSz)
  256. {
  257. int err;
  258. int idx = wc_ecc_get_curve_idx(key->ecc.dp->id);
  259. err = eccsi_load_base(key);
  260. if (err == 0) {
  261. err = wc_ecc_export_point_der(idx, key->params.base, data, dataSz);
  262. }
  263. return err;
  264. }
  265. #ifndef WOLFSSL_HAVE_SP_ECC
  266. /*
  267. * Convert the KPAK to montgomery form.
  268. *
  269. * The KPAK is needed in Montgomery form for verification.
  270. *
  271. * @param [in] key ECCSI key.
  272. * @return 0 on success.
  273. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  274. * @return Other -ve value when an internal operation fails.
  275. */
  276. static int eccsi_kpak_to_mont(EccsiKey* key)
  277. {
  278. int err = 0;
  279. ecc_point* kpak = &key->ecc.pubkey;
  280. mp_int* mu = &key->tmp;
  281. mp_int* prime = &key->params.prime;
  282. if (!key->kpakMont) {
  283. err = mp_montgomery_calc_normalization(mu, prime);
  284. if (err == 0) {
  285. err = mp_mulmod(kpak->x, mu, prime, kpak->x);
  286. }
  287. if (err == 0) {
  288. err = mp_mulmod(kpak->y, mu, prime, kpak->y);
  289. }
  290. if (err == 0) {
  291. err = mp_mulmod(kpak->z, mu, prime, kpak->z);
  292. }
  293. if (err == 0) {
  294. key->kpakMont = 1;
  295. }
  296. }
  297. return err;
  298. }
  299. #endif
  300. /*
  301. * Convert the KPAK from montgomery form.
  302. *
  303. * The KPAK is needed in Montgomery form for verification.
  304. *
  305. * @param [in] key ECCSI key.
  306. * @return 0 on success.
  307. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  308. * @return Other -ve value when an internal operation fails.
  309. */
  310. static int eccsi_kpak_from_mont(EccsiKey* key)
  311. {
  312. int err = 0;
  313. ecc_point* kpak = &key->ecc.pubkey;
  314. mp_digit mp;
  315. mp_int* prime = &key->params.prime;
  316. if (key->kpakMont) {
  317. err = mp_montgomery_setup(prime, &mp);
  318. if (err == 0) {
  319. err = mp_montgomery_reduce(kpak->x, prime, mp);
  320. }
  321. if (err == 0) {
  322. err = mp_montgomery_reduce(kpak->y, prime, mp);
  323. }
  324. if (err == 0) {
  325. err = mp_montgomery_reduce(kpak->z, prime, mp);
  326. }
  327. if (err == 0) {
  328. key->kpakMont = 0;
  329. }
  330. }
  331. return err;
  332. }
  333. /*
  334. * Compute HS = hash( G | KPAK | ID | PVT )
  335. *
  336. * Use when making a (SSK,PVT) pair, signing and verifying.
  337. *
  338. * @param [in] key ECCSI key.
  339. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  340. * @param [in] id Identity to create hash from.
  341. * @param [in] idSz Length of identity in bytes.
  342. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  343. * @param [out] hash Buffer to hold hash data.
  344. * @param [out] hashSz Length of hash data in bytes.
  345. * @return 0 on success.
  346. * @return MEMORY_E when dynamic memory allocation fails.
  347. * @return Other -ve value when an internal operation fails.
  348. */
  349. static int eccsi_compute_hs(EccsiKey* key, enum wc_HashType hashType,
  350. const byte* id, word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz)
  351. {
  352. int err;
  353. word32 dataSz = 0;
  354. int idx = wc_ecc_get_curve_idx(key->ecc.dp->id);
  355. ecc_point* kpak = &key->ecc.pubkey;
  356. int hash_inited = 0;
  357. /* HS = hash( G | KPAK | ID | PVT ) */
  358. err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID);
  359. if (err == 0) {
  360. hash_inited = 1;
  361. /* Base Point - G */
  362. dataSz = sizeof(key->data);
  363. err = eccsi_encode_base(key, key->data, &dataSz);
  364. }
  365. if (err == 0) {
  366. err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
  367. }
  368. if (err == 0) {
  369. err = eccsi_kpak_from_mont(key);
  370. }
  371. if (err == 0) {
  372. dataSz = sizeof(key->data);
  373. /* KPAK - public key */
  374. err = wc_ecc_export_point_der(idx, kpak, key->data, &dataSz);
  375. }
  376. if (err == 0) {
  377. err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
  378. }
  379. if (err == 0) {
  380. /* Id - Signer's ID */
  381. err = wc_HashUpdate(&key->hash, hashType, id, idSz);
  382. }
  383. if (err == 0) {
  384. dataSz = sizeof(key->data);
  385. /* PVT - Public Validation Token */
  386. err = wc_ecc_export_point_der(idx, pvt, key->data, &dataSz);
  387. }
  388. if (err == 0) {
  389. /* PVT - Public Validation Token */
  390. err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
  391. }
  392. if (err == 0) {
  393. err = wc_HashFinal(&key->hash, hashType, hash);
  394. }
  395. if (err == 0) {
  396. *hashSz = (byte)wc_HashGetDigestSize(hashType);
  397. }
  398. if (hash_inited) {
  399. (void)wc_HashFree(&key->hash, hashType);
  400. }
  401. return err;
  402. }
  403. #ifdef WOLFCRYPT_ECCSI_KMS
  404. /**
  405. * Generate KMS Secret Auth Key (KSAK) and KMS Public Auth Key (KPAK).
  406. *
  407. * RFC 6507, Section 4.2
  408. *
  409. * Called when establishing a new KMS.\n
  410. * KSAK must be kept secret while KPAK is required by clients for signing
  411. * and verifying.\n
  412. * Export key using wc_ExportEccsiKey(), once generated, to reuse the key.\n
  413. * Export KPAK using wc_ExportEccsiPublicKey(), once generate to send to
  414. * clients.
  415. *
  416. * Creates a random private key and multiplies it by the base point to calculate
  417. * the public key.
  418. *
  419. * @param [in] key ECCSI key.
  420. * @param [in] rng Random number generator.
  421. * @return 0 on success.
  422. * @return BAD_FUNC_ARG when key or rng is NULL.
  423. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  424. * @return Other -ve value when an internal operation fails.
  425. */
  426. int wc_MakeEccsiKey(EccsiKey* key, WC_RNG* rng)
  427. {
  428. int err = 0;
  429. if ((key == NULL) || (rng == NULL)) {
  430. err = BAD_FUNC_ARG;
  431. }
  432. if (err == 0) {
  433. err = wc_ecc_make_key_ex(rng, key->ecc.dp->size, &key->ecc,
  434. key->ecc.dp->id);
  435. }
  436. return err;
  437. }
  438. /*
  439. * Encode a point into a buffer.
  440. *
  441. * X and y ordinate of point concatenated. Each number is zero padded tosize.
  442. * Descriptor byte (0x04) is prepended when not raw.
  443. *
  444. * @param [in] point ECC point to encode.
  445. * @param [in] size Size of prime in bytes - maximum ordinate length.
  446. * @param [out] data Buffer to hold encoded data.
  447. * NULL when needing length of encoded data.
  448. * @param [in,out] sz In, the size of the buffer in bytes.
  449. * Out, the size of the encoded data in bytes.
  450. * @param [in] raw On 0, prepend descriptor byte.
  451. * On 1, only include ordinates.
  452. * @return 0 on success.
  453. * @return BAD_FUNC_ARG when key or sz is NULL.
  454. * @return LENGTH_ONLY_E when data is NULL - sz will hold the size in bytes of
  455. * the encoded data.
  456. * @return BUFFER_E when size of buffer is too small.
  457. */
  458. static int eccsi_encode_point(ecc_point* point, word32 size, byte* data,
  459. word32* sz, int raw)
  460. {
  461. int err = 0;
  462. if (data == NULL) {
  463. *sz = size * 2 + !raw;
  464. err = LENGTH_ONLY_E;
  465. }
  466. if ((err == 0) && (*sz < size * 2 + !raw)) {
  467. err = BUFFER_E;
  468. }
  469. if (err == 0) {
  470. if (!raw) {
  471. data[0] = 0x04;
  472. data++;
  473. }
  474. /* Write out the point's x ordinate into key size bytes. */
  475. err = mp_to_unsigned_bin_len(point->x, data, (int)size);
  476. }
  477. if (err == 0) {
  478. data += size;
  479. /* Write out the point's y ordinate into key size bytes. */
  480. err = mp_to_unsigned_bin_len(point->y, data, (int)size);
  481. }
  482. if (err == 0) {
  483. *sz = size * 2 + !raw;
  484. }
  485. return err;
  486. }
  487. /*
  488. * Decode the data into an ECC point.
  489. *
  490. * X and y ordinate of point concatenated. Each number is zero padded to
  491. * key size. Supports prepended descriptor byte (0x04).
  492. *
  493. * @param [out] point ECC point to encode.
  494. * @param [in] size Size of prime in bytes - maximum ordinate length.
  495. * @param [in] data Encoded public key.
  496. * @param [in] sz Size of the encoded public key in bytes.
  497. * @return 0 on success.
  498. * @return BAD_FUNC_ARG when key or z is NULL.
  499. * @return BUFFER_E when size of data is not equal to the expected size.
  500. * @return ASN_PARSE_E when format byte is invalid.
  501. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  502. */
  503. static int eccsi_decode_point(ecc_point* point, word32 size, const byte* data,
  504. word32 sz)
  505. {
  506. int err = 0;
  507. if ((sz != size * 2) && (sz != size * 2 + 1)) {
  508. err = BUFFER_E;
  509. }
  510. if ((err == 0) && (sz & 1)) {
  511. if (data[0] != 0x04) {
  512. err = ASN_PARSE_E;
  513. }
  514. data++;
  515. }
  516. if (err == 0) {
  517. /* Read the public key point's x value from key size bytes. */
  518. err = mp_read_unsigned_bin(point->x, data, size);
  519. }
  520. if (err == 0) {
  521. data += size;
  522. /* Read the public key point's y value from key size bytes. */
  523. err = mp_read_unsigned_bin(point->y, data, size);
  524. }
  525. if (err == 0) {
  526. err = mp_set(point->z, 1);
  527. }
  528. return err;
  529. }
  530. /*
  531. * Encode the ECCSI key.
  532. *
  533. * Encodes the private key as big-endian bytes of fixed length.
  534. * Encodes the public key x and y ordinates as big-endian bytes of fixed length.
  535. *
  536. * @param [in] key ECCSI key.
  537. * @param [out] data Buffer to hold encoded ECCSI key.
  538. * @return 0 on success.
  539. * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
  540. */
  541. static int eccsi_encode_key(EccsiKey* key, byte* data)
  542. {
  543. int err;
  544. word32 sz = (word32)key->ecc.dp->size * 2;
  545. /* Write out the secret value into key size bytes. */
  546. err = mp_to_unsigned_bin_len(wc_ecc_key_get_priv(&key->ecc), data,
  547. key->ecc.dp->size);
  548. if (err == 0) {
  549. data += key->ecc.dp->size;
  550. /* Write the public key. */
  551. err = eccsi_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
  552. data, &sz, 1);
  553. }
  554. return err;
  555. }
  556. /**
  557. * Export the ECCSI key as encoded public/private ECC key.
  558. *
  559. * Use when saving the KMS key pair.
  560. *
  561. * Private key, x ordinate of public key and y ordinate of public key
  562. * concatenated. Each number is zero padded to key size.
  563. *
  564. * @param [in] key ECCSI key.
  565. * @param [out] data Buffer to hold encoded ECCSI key.
  566. * NULL when requesting required length.
  567. * @param [in,out] sz On in, size of buffer in bytes.
  568. * On out, size of encoded ECCSI key in bytes.
  569. * @return 0 on success.
  570. * @return BAD_FUNC_ARG when key or sz is NULL
  571. * @return BAD_STATE_E when no key to export.
  572. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  573. * @return BUFFER_E when the buffer passed in is too small.
  574. * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
  575. */
  576. int wc_ExportEccsiKey(EccsiKey* key, byte* data, word32* sz)
  577. {
  578. int err = 0;
  579. if ((key == NULL) || (sz == NULL)) {
  580. err = BAD_FUNC_ARG;
  581. }
  582. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
  583. err = BAD_STATE_E;
  584. }
  585. if (err == 0) {
  586. if (data == NULL) {
  587. *sz = (word32)(key->ecc.dp->size * 3);
  588. err = LENGTH_ONLY_E;
  589. }
  590. else if (*sz < (word32)key->ecc.dp->size * 3) {
  591. err = BUFFER_E;
  592. }
  593. else {
  594. *sz = (word32)(key->ecc.dp->size * 3);
  595. }
  596. }
  597. if (err == 0) {
  598. err = eccsi_kpak_from_mont(key);
  599. }
  600. if (err == 0) {
  601. /* Encode key */
  602. err = eccsi_encode_key(key, data);
  603. }
  604. return err;
  605. }
  606. /*
  607. * Import the ECCSI key as encoded public/private ECC key.
  608. *
  609. * Decodes the private key as big-endian bytes of fixed length.
  610. * Decodes the public key x and y ordinates as big-endian bytes of fixed length.
  611. *
  612. * @param [in] key ECCSI key.
  613. * @param [in] data Buffer holding encoded ECCSI key.
  614. * @return 0 on success.
  615. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  616. */
  617. static int eccsi_decode_key(EccsiKey* key, const byte* data)
  618. {
  619. int err;
  620. /* Read the secret value from key size bytes. */
  621. err = mp_read_unsigned_bin(wc_ecc_key_get_priv(&key->ecc), data,
  622. (word32)key->ecc.dp->size);
  623. if (err == 0) {
  624. data += key->ecc.dp->size;
  625. /* Read public key. */
  626. err = eccsi_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
  627. data, (word32)(key->ecc.dp->size * 2));
  628. }
  629. return err;
  630. }
  631. /**
  632. * Import the ECCSI key as encoded public/private ECC key.
  633. *
  634. * Use when restoring the KMS key pair.
  635. *
  636. * Private key, x ordinate of public key and y ordinate of public key
  637. * concatenated. Each number is zero padded to key size.
  638. *
  639. * @param [in] key ECCSI key.
  640. * @param [in] data Buffer holding encoded ECCSI key.
  641. * @param [in] sz Size of encoded ECCSI key in bytes.
  642. * @return 0 on success.
  643. * @return BAD_FUNC_ARG when key or data is NULL.
  644. * @return BUFFER_E when size of data is not equal to the expected size.
  645. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  646. */
  647. int wc_ImportEccsiKey(EccsiKey* key, const byte* data, word32 sz)
  648. {
  649. int err = 0;
  650. if ((key == NULL) || (data == NULL)) {
  651. err = BAD_FUNC_ARG;
  652. }
  653. if ((err == 0) && (sz != (word32)key->ecc.dp->size * 3)) {
  654. err = BUFFER_E;
  655. }
  656. if (err == 0) {
  657. key->kpakMont = 0;
  658. /* Decode key */
  659. err = eccsi_decode_key(key, data);
  660. }
  661. if (err == 0) {
  662. key->ecc.type = ECC_PRIVATEKEY;
  663. }
  664. return err;
  665. }
  666. /**
  667. * Export the ECCSI private key.
  668. *
  669. * Use when saving the KMS key.
  670. *
  671. * Private key is zero padded to key size.
  672. *
  673. * @param [in] key ECCSI key.
  674. * @param [out] data Buffer to hold encoded ECCSI private key.
  675. * NULL when requesting required length.
  676. * @param [in,out] sz On in, size of buffer in bytes.
  677. * On out, size of encoded ECCSI private key in bytes.
  678. * @return 0 on success.
  679. * @return BAD_FUNC_ARG when key or sz is NULL
  680. * @return BAD_STATE_E when no key to export.
  681. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  682. * @return BUFFER_E when the buffer passed in is too small.
  683. * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
  684. */
  685. int wc_ExportEccsiPrivateKey(EccsiKey* key, byte* data, word32* sz)
  686. {
  687. int err = 0;
  688. if ((key == NULL) || (sz == NULL)) {
  689. err = BAD_FUNC_ARG;
  690. }
  691. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
  692. err = BAD_STATE_E;
  693. }
  694. if (err == 0) {
  695. if (data == NULL) {
  696. *sz = (word32)key->ecc.dp->size;
  697. err = LENGTH_ONLY_E;
  698. }
  699. else if (*sz < (word32)key->ecc.dp->size) {
  700. err = BUFFER_E;
  701. }
  702. else {
  703. *sz = (word32)key->ecc.dp->size;
  704. }
  705. }
  706. if (err == 0) {
  707. err = mp_to_unsigned_bin_len(wc_ecc_key_get_priv(&key->ecc), data,
  708. key->ecc.dp->size);
  709. }
  710. return err;
  711. }
  712. /**
  713. * Import the ECCSI private key.
  714. *
  715. * Use when restoring the KMS key pair.
  716. *
  717. * Private key is zero padded to key size.
  718. *
  719. * @param [in] key ECCSI key.
  720. * @param [in] data Buffer holding encoded ECCSI private key.
  721. * @param [in] sz Size of encoded ECCSI private key in bytes.
  722. * @return 0 on success.
  723. * @return BAD_FUNC_ARG when key or data is NULL.
  724. * @return BUFFER_E when size of data is not equal to the expected size.
  725. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  726. */
  727. int wc_ImportEccsiPrivateKey(EccsiKey* key, const byte* data, word32 sz)
  728. {
  729. int err = 0;
  730. if ((key == NULL) || (data == NULL)) {
  731. err = BAD_FUNC_ARG;
  732. }
  733. if ((err == 0) && (sz != (word32)key->ecc.dp->size)) {
  734. err = BUFFER_E;
  735. }
  736. if (err == 0) {
  737. err = mp_read_unsigned_bin(wc_ecc_key_get_priv(&key->ecc), data,
  738. (word32)key->ecc.dp->size);
  739. }
  740. return err;
  741. }
  742. /**
  743. * Export the KMS Public Auth Key (KPAK) from the ECCSI object.
  744. *
  745. * KPAK is required by all clients in order to perform cryptographic operations.
  746. *
  747. * X and y ordinate of public key concatenated. Each number is zero padded to
  748. * key size.
  749. * Descriptor byte (0x04) is prepended when not raw.
  750. *
  751. * @param [in] key ECCSI key.
  752. * @param [out] data Buffer to hold the encoded public key.
  753. * @param [in,out] sz On in, size of buffer in bytes.
  754. * On out, length of encoded public key in bytes.
  755. * @param [in] raw On 0, prepend descriptor byte.
  756. * On 1, only include ordinates.
  757. * @return 0 on success.
  758. * @return BAD_FUNC_ARG when key or sz is NULL.
  759. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  760. * @return BUFFER_E when the buffer passed in is too small.
  761. */
  762. int wc_ExportEccsiPublicKey(EccsiKey* key, byte* data, word32* sz, int raw)
  763. {
  764. int err = 0;
  765. if ((key == NULL) || (sz == NULL)) {
  766. err = BAD_FUNC_ARG;
  767. }
  768. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
  769. (key->ecc.type != ECC_PUBLICKEY)) {
  770. err = BAD_STATE_E;
  771. }
  772. if ((err == 0) && (data != NULL)) {
  773. err = eccsi_kpak_from_mont(key);
  774. }
  775. if (err == 0) {
  776. /* Write out public key. */
  777. err = eccsi_encode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
  778. data, sz, raw);
  779. }
  780. return err;
  781. }
  782. /*
  783. * Generates an (SSK, PVT) Pair - signing key pair.
  784. *
  785. * RFC 6507, Section 5.1.1
  786. *
  787. * @param [in] key ECCSI key.
  788. * @param [in] rng Random number generator.
  789. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  790. * @param [in] id Identity to create hash from.
  791. * @param [in] idSz Length of identity in bytes.
  792. * @param [out] ssk Secret Signing Key as an MP integer.
  793. * @param [out] pvt Public Validation Token (PVT) as an ECC point.
  794. * @return 0 on success.
  795. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  796. * @return Other -ve value when an internal operation fails.
  797. */
  798. static int eccsi_make_pair(EccsiKey* key, WC_RNG* rng,
  799. enum wc_HashType hashType, const byte* id, word32 idSz, mp_int* ssk,
  800. ecc_point* pvt)
  801. {
  802. int err = 0;
  803. byte hashSz = 0;
  804. int genTryCnt = 0;
  805. do {
  806. /* Don't infinitely make pairs when random number generator fails. */
  807. if ((++genTryCnt) > ECCSI_MAX_GEN_COUNT) {
  808. err = RNG_FAILURE_E;
  809. }
  810. if (err == 0) {
  811. wc_ecc_free(&key->pubkey);
  812. /* Step 1 and 2: Generate ephemeral key - v, PVT = [v]G */
  813. err = wc_ecc_make_key_ex(rng, key->ecc.dp->size, &key->pubkey,
  814. key->ecc.dp->id);
  815. }
  816. if (err == 0) {
  817. err = wc_ecc_copy_point(&key->pubkey.pubkey, pvt);
  818. }
  819. /* Step 3: Compute HS */
  820. if (err == 0) {
  821. hashSz = (byte)sizeof(key->data);
  822. err = eccsi_compute_hs(key, hashType, id, idSz, pvt, key->data,
  823. &hashSz);
  824. }
  825. /* Step 4: Compute SSK = ( KSAK + HS * v ) modulo q */
  826. if (err == 0) {
  827. err = mp_read_unsigned_bin(ssk, key->data, hashSz);
  828. }
  829. if (err == 0) {
  830. err = mp_mulmod(ssk, wc_ecc_key_get_priv(&key->pubkey),
  831. &key->params.order, ssk);
  832. }
  833. if (err == 0) {
  834. err = mp_addmod(ssk, wc_ecc_key_get_priv(&key->ecc),
  835. &key->params.order, ssk);
  836. }
  837. }
  838. while ((err == 0) && (mp_iszero(ssk) ||
  839. (mp_cmp(ssk, wc_ecc_key_get_priv(&key->ecc)) == MP_EQ)));
  840. /* Step 5: ensure SSK and HS are non-zero (code lines above) */
  841. /* Step 6: Copy out SSK (done during calc) and PVT. Erase v */
  842. mp_forcezero(wc_ecc_key_get_priv(&key->pubkey));
  843. return err;
  844. }
  845. /**
  846. * Generates an (SSK, PVT) Pair - signing key pair.
  847. *
  848. * RFC 6507, Section 5.1.1
  849. *
  850. * ID should include information to indicate a revocation date.\n
  851. * SSK must be zeroized after sending to client.\n
  852. * SSK is sent to signing client only.\n
  853. * PVT is sent to all client types.
  854. *
  855. * @param [in] key ECCSI key.
  856. * @param [in] rng Random number generator.
  857. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  858. * @param [in] id Identity to create hash from.
  859. * @param [in] idSz Length of identity in bytes.
  860. * @param [out] ssk Secret Signing Key as an MP integer.
  861. * @param [out] pvt Public Validation Token (PVT) as an ECC point.
  862. * @return 0 on success.
  863. * @return BAD_FUNC_ARG when key, rng, id, ssk or pvt is NULL.
  864. * @return BAD_STATE_E when curve not set (key not set).
  865. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  866. * @return Other -ve value when an internal operation fails.
  867. */
  868. int wc_MakeEccsiPair(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType,
  869. const byte* id, word32 idSz, mp_int* ssk, ecc_point* pvt)
  870. {
  871. int err = 0;
  872. if ((key == NULL) || (rng == NULL) || (id == NULL) || (ssk == NULL) ||
  873. (pvt == NULL)) {
  874. err = BAD_FUNC_ARG;
  875. }
  876. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
  877. err = BAD_STATE_E;
  878. }
  879. if (err == 0) {
  880. err = eccsi_load_order(key);
  881. }
  882. if (err == 0) {
  883. err = eccsi_make_pair(key, rng, hashType, id, idSz, ssk, pvt);
  884. }
  885. return err;
  886. }
  887. /**
  888. * Encode the SSK and PVT into a buffer.
  889. *
  890. * SSK and PVT required by client signing messages.
  891. *
  892. * @param [in] key ECCSI key.
  893. * @param [in] ssk Secret Signing Key as an MP integer.
  894. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  895. * @param [out] data Buffer to encode key pair into.
  896. * @param [in,out] sz In, size of buffer in bytes.
  897. * Out, size of encoded pair data in bytes.
  898. * @return 0 on success.
  899. * @return BAD_FUNC_ARG when key, ssk, pvt or sz is NULL.
  900. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  901. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  902. */
  903. int wc_EncodeEccsiPair(const EccsiKey* key, mp_int* ssk, ecc_point* pvt,
  904. byte* data, word32* sz)
  905. {
  906. int err = 0;
  907. if ((key == NULL) || (ssk == NULL) || (pvt == NULL) || (sz == NULL)) {
  908. err = BAD_FUNC_ARG;
  909. }
  910. if ((err == 0) && (data == NULL)) {
  911. *sz = (word32)(key->ecc.dp->size * 3);
  912. err = LENGTH_ONLY_E;
  913. }
  914. if ((err == 0) && (*sz < (word32)(key->ecc.dp->size * 3))) {
  915. err = BUFFER_E;
  916. }
  917. if (err == 0) {
  918. err = mp_to_unsigned_bin_len(ssk, data, key->ecc.dp->size);
  919. }
  920. if (err == 0) {
  921. data += key->ecc.dp->size;
  922. /* Write out the PVT's x ordinate into key size bytes. */
  923. err = mp_to_unsigned_bin_len(pvt->x, data, key->ecc.dp->size);
  924. }
  925. if (err == 0) {
  926. data += key->ecc.dp->size;
  927. /* Write out the PVT's y ordinate into key size bytes. */
  928. err = mp_to_unsigned_bin_len(pvt->y, data, key->ecc.dp->size);
  929. }
  930. if (err == 0) {
  931. *sz = (word32)(key->ecc.dp->size * 3);
  932. }
  933. return err;
  934. }
  935. /**
  936. * Encode the Secret Signing Key (SSK).
  937. *
  938. * Use when saving the key pair.
  939. *
  940. * SSK is zero padded to key size.
  941. *
  942. * @param [in] key ECCSI key.
  943. * @param [in] ssk Secret Signing Key as an MP integer.
  944. * @param [out] data Buffer to hold encoded SSK.
  945. * NULL when requesting required length.
  946. * @param [in,out] sz On in, size of buffer in bytes.
  947. * On out, size of encoded ECCSI key in bytes.
  948. * @return 0 on success.
  949. * @return BAD_FUNC_ARG when key, ssk or sz is NULL
  950. * @return BAD_STATE_E when no key to export.
  951. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  952. * @return BUFFER_E when the buffer passed in is too small.
  953. * @return MEMORY_E when dynamic memory allocation fails (WOLFSSL_SMALL_STACK).
  954. */
  955. int wc_EncodeEccsiSsk(const EccsiKey* key, mp_int* ssk, byte* data, word32* sz)
  956. {
  957. int err = 0;
  958. if ((key == NULL) || (ssk == NULL) || (sz == NULL)) {
  959. err = BAD_FUNC_ARG;
  960. }
  961. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY)) {
  962. err = BAD_STATE_E;
  963. }
  964. if (err == 0) {
  965. if (data == NULL) {
  966. *sz = (word32)key->ecc.dp->size;
  967. err = LENGTH_ONLY_E;
  968. }
  969. else if (*sz < (word32)key->ecc.dp->size) {
  970. err = BUFFER_E;
  971. }
  972. else {
  973. *sz = (word32)key->ecc.dp->size;
  974. }
  975. }
  976. if (err == 0) {
  977. err = mp_to_unsigned_bin_len(ssk, data, key->ecc.dp->size);
  978. }
  979. return err;
  980. }
  981. /**
  982. * Decode the Secret Signing Key (SSK).
  983. *
  984. * Use when restoring the key pair.
  985. *
  986. * SSK is zero padded to key size.
  987. *
  988. * @param [in] key ECCSI key.
  989. * @param [in] data Buffer holding encoded ECCSI key.
  990. * @param [in] sz Size of encoded ECCSI key in bytes.
  991. * @param [out] ssk Secret Signing Key as an MP integer.
  992. * @return 0 on success.
  993. * @return BAD_FUNC_ARG when key, data or ssk is NULL.
  994. * @return BUFFER_E when size of data is not equal to the expected size.
  995. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  996. */
  997. int wc_DecodeEccsiSsk(const EccsiKey* key, const byte* data, word32 sz,
  998. mp_int* ssk)
  999. {
  1000. int err = 0;
  1001. if ((key == NULL) || (data == NULL) || (ssk == NULL)) {
  1002. err = BAD_FUNC_ARG;
  1003. }
  1004. if ((err == 0) && (sz != (word32)key->ecc.dp->size)) {
  1005. err = BUFFER_E;
  1006. }
  1007. if (err == 0) {
  1008. err = mp_read_unsigned_bin(ssk, data, (word32)key->ecc.dp->size);
  1009. }
  1010. return err;
  1011. }
  1012. /**
  1013. * Encode the PVT into a buffer.
  1014. *
  1015. * PVT required by client verifying messages.
  1016. *
  1017. * X and y ordinate of public key concatenated. Each number is zero padded to
  1018. * key size.
  1019. * Descriptor byte (0x04) is prepended when not raw.
  1020. *
  1021. * @param [in] key ECCSI key.
  1022. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  1023. * @param [out] data Buffer to encode key pair into.
  1024. * @param [in,out] sz In, size of buffer in bytes.
  1025. * Out, size of encoded pair data in bytes.
  1026. * @param [in] raw On 0, prepend descriptor byte.
  1027. * On 1, only include ordinates.
  1028. * @return 0 on success.
  1029. * @return BAD_FUNC_ARG when key, pvt or sz is NULL.
  1030. * @return BAD_STATE_E when PVT has not been set.
  1031. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1032. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  1033. */
  1034. int wc_EncodeEccsiPvt(const EccsiKey* key, ecc_point* pvt, byte* data,
  1035. word32* sz, int raw)
  1036. {
  1037. int err = 0;
  1038. if ((key == NULL) || (pvt == NULL) || (sz == NULL)) {
  1039. err = BAD_FUNC_ARG;
  1040. }
  1041. if (err == 0) {
  1042. err = eccsi_encode_point(pvt, (word32)key->ecc.dp->size, data, sz, raw);
  1043. }
  1044. return err;
  1045. }
  1046. #endif /* WOLFCRYPT_ECCSI_KMS */
  1047. #ifdef WOLFCRYPT_ECCSI_CLIENT
  1048. /**
  1049. * Decode the SSK and PVT data into separate variables.
  1050. *
  1051. * A signing client decodes the data so that it can validate the pair and sign.
  1052. *
  1053. * @param [in] key ECCSI key.
  1054. * @param [in] data Buffer holding key pair data.
  1055. * @param [in] sz Size of data in bytes.
  1056. * @param [out] ssk Secret Signing Key as an MP integer.
  1057. * @param [out] pvt Public Validation Token (PVT) as an ECC point.
  1058. * @return 0 on success.
  1059. * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL.
  1060. * @return LENGTH_ONLY_E when data is NULL - sz is set.
  1061. * @return BUFFER_E when size of data is not equal to the expected size.
  1062. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1063. */
  1064. int wc_DecodeEccsiPair(const EccsiKey* key, const byte* data, word32 sz,
  1065. mp_int* ssk, ecc_point* pvt)
  1066. {
  1067. int err = 0;
  1068. if ((key == NULL) || (data == NULL) || (ssk == NULL) || (pvt == NULL)) {
  1069. err = BAD_FUNC_ARG;
  1070. }
  1071. if ((err == 0) && (sz != (word32)(key->ecc.dp->size * 3))) {
  1072. err = BUFFER_E;
  1073. }
  1074. if (err == 0) {
  1075. /* Read the SSK value from key size bytes. */
  1076. err = mp_read_unsigned_bin(ssk, data, (word32)key->ecc.dp->size);
  1077. }
  1078. if (err == 0) {
  1079. data += key->ecc.dp->size;
  1080. /* Read the PVT's x value from key size bytes. */
  1081. err = mp_read_unsigned_bin(pvt->x, data, (word32)key->ecc.dp->size);
  1082. }
  1083. if (err == 0) {
  1084. data += key->ecc.dp->size;
  1085. /* Read the PVT's y value from key size bytes. */
  1086. err = mp_read_unsigned_bin(pvt->y, data, (word32)key->ecc.dp->size);
  1087. }
  1088. if (err == 0) {
  1089. err = mp_set(pvt->z, 1);
  1090. }
  1091. return err;
  1092. }
  1093. /**
  1094. * Decode the PVT data into an ECC point.
  1095. *
  1096. * A verifying client decodes the data so that it can verify a message.
  1097. *
  1098. * X and y ordinate of public key concatenated. Each number is zero padded to
  1099. * key size.
  1100. * Descriptor byte (0x04) is prepended when not raw.
  1101. *
  1102. * @param [in] key ECCSI key.
  1103. * @param [in] data Buffer holding PVT data.
  1104. * @param [in] sz Size of data in bytes.
  1105. * @param [out] pvt Public Validation Token (PVT) as an ECC point.
  1106. * @return 0 on success.
  1107. * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL.
  1108. * @return BUFFER_E when size of data is not equal to the expected size.
  1109. * @return ASN_PARSE_E when format byte is invalid.
  1110. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1111. */
  1112. int wc_DecodeEccsiPvt(const EccsiKey* key, const byte* data, word32 sz,
  1113. ecc_point* pvt)
  1114. {
  1115. int err = 0;
  1116. if ((key == NULL) || (data == NULL) || (pvt == NULL)) {
  1117. err = BAD_FUNC_ARG;
  1118. }
  1119. if (err == 0) {
  1120. err = eccsi_decode_point(pvt, (word32)key->ecc.dp->size, data, sz);
  1121. }
  1122. return err;
  1123. }
  1124. /**
  1125. * Decode the PVT data, from a signature, into an ECC point.
  1126. *
  1127. * A verifying client decodes the data so that it can calculate the identity
  1128. * hash.
  1129. *
  1130. * X and y ordinate of public key concatenated. Each number is zero padded to
  1131. * key size.
  1132. * Descriptor byte (0x04) is prepended when not raw.
  1133. *
  1134. * @param [in] key ECCSI key.
  1135. * @param [in] sig Buffer holding signature data.
  1136. * @param [in] sz Size of data in bytes.
  1137. * @param [out] pvt Public Validation Token (PVT) as an ECC point.
  1138. * @return 0 on success.
  1139. * @return BAD_FUNC_ARG when key, data, ssk or pvt is NULL.
  1140. * @return BUFFER_E when size of data is not equal to the expected size.
  1141. * @return ASN_PARSE_E when format byte is invalid.
  1142. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1143. */
  1144. int wc_DecodeEccsiPvtFromSig(const EccsiKey* key, const byte* sig, word32 sz,
  1145. ecc_point* pvt)
  1146. {
  1147. int err = 0;
  1148. if ((key == NULL) || (sig == NULL) || (pvt == NULL)) {
  1149. err = BAD_FUNC_ARG;
  1150. }
  1151. if (err == 0) {
  1152. word32 rSz = (word32)(key->ecc.dp->size * 2);
  1153. err = eccsi_decode_point(pvt, (word32)key->ecc.dp->size, sig + rSz,
  1154. sz - rSz);
  1155. }
  1156. return err;
  1157. }
  1158. /**
  1159. * Import the KMS Public Auth Key (KPAK) into the ECCSI object.
  1160. *
  1161. * Clients import the KPAK to perform cryptographic operations.
  1162. *
  1163. * X and y ordinate of public key concatenated. Each number is zero padded to
  1164. * key size.
  1165. * Descriptor byte (0x04) is prepended when not raw.
  1166. *
  1167. * @param [in] key ECCSI key.
  1168. * @param [in] data Encoded public key as an array of bytes.
  1169. * @param [in] sz Length of encoded KPAK in bytes.
  1170. * @param [in] trusted 1 when public key is trusted.
  1171. * 0 when validation is required to be performed.
  1172. * @return 0 on success.
  1173. * @return BAD_FUNC_ARG when key or data is NULL.
  1174. * @return BUFFER_E when size of data is not equal to the expected size.
  1175. * @return ASN_PARSE_E when format byte is invalid.
  1176. * @return ECC_OUT_OF_RANGE_E when point is invalid.
  1177. * @return ECC_INF_E when point is at infinity and invalid.
  1178. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1179. */
  1180. int wc_ImportEccsiPublicKey(EccsiKey* key, const byte* data, word32 sz,
  1181. int trusted)
  1182. {
  1183. int err = 0;
  1184. if ((key == NULL) || (data == NULL)) {
  1185. err = BAD_FUNC_ARG;
  1186. }
  1187. if (err == 0) {
  1188. key->kpakMont = 0;
  1189. /* Read the public key. */
  1190. err = eccsi_decode_point(&key->ecc.pubkey, (word32)key->ecc.dp->size,
  1191. data, sz);
  1192. }
  1193. if (err == 0) {
  1194. key->ecc.type = ECC_PUBLICKEY;
  1195. }
  1196. if ((err == 0) && (!trusted)) {
  1197. err = wc_ecc_check_key(&key->ecc);
  1198. }
  1199. return err;
  1200. }
  1201. /*
  1202. * Scalar multiply the base point of the curve and add a point.
  1203. *
  1204. * @param [in] key ECCSI key.
  1205. * @param [in] n MP integer representing scalar to multiply by.
  1206. * @param [in] a ECC point to add.
  1207. * @param [out] res ECC point representation of the resulting point.
  1208. * @param [in] mp Montgomery reduction multiplier.
  1209. * @param [in] map 0 indicates to leave in projective representation.
  1210. * 1 indicates map projective point to affine.
  1211. * @return 0 on success.
  1212. * @return MEMORY_E when dynamic memory allocation fails.
  1213. * @return Other -ve value when an internal operation fails.
  1214. */
  1215. static int eccsi_mulmod_base_add(EccsiKey* key, const mp_int* n,
  1216. ecc_point* a, ecc_point* res, mp_digit mp, int map)
  1217. {
  1218. int err = 0;
  1219. #if defined(WOLFSSL_HAVE_SP_ECC) && !defined(WOLFSSL_SP_NO_256)
  1220. if ((key->ecc.idx != ECC_CUSTOM_IDX) &&
  1221. (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) {
  1222. err = sp_ecc_mulmod_base_add_256(n, a, 1, res, map, key->heap);
  1223. }
  1224. else
  1225. #endif
  1226. #ifndef WOLFSSL_SP_MATH
  1227. {
  1228. EccsiKeyParams* params = &key->params;
  1229. err = wc_ecc_mulmod(n, params->base, params->base, &params->a,
  1230. &params->prime, 0);
  1231. key->params.haveBase = 0;
  1232. if (err == 0) {
  1233. err = ecc_projective_add_point(params->base, a, res, &params->a,
  1234. &params->prime, mp);
  1235. }
  1236. if ((err == 0) && map) {
  1237. err = ecc_map(res, &params->prime, mp);
  1238. }
  1239. }
  1240. #else
  1241. {
  1242. err = NOT_COMPILED_IN;
  1243. }
  1244. (void)key;
  1245. (void)n;
  1246. (void)a;
  1247. (void)res;
  1248. (void)mp;
  1249. (void)map;
  1250. #endif
  1251. return err;
  1252. }
  1253. /*
  1254. * Scalar multiply a point on the curve.
  1255. *
  1256. * @param [in] key ECCSI key.
  1257. * @param [in] n MP integer representing scalar to multiply by.
  1258. * @param [in] point ECC point representation of a point on the curve.
  1259. * @param [out] res ECC point representation of the resulting point.
  1260. * @param [in] map 0 indicates to leave in projective representation.
  1261. * 1 indicates map projective point to affine.
  1262. * @return 0 on success.
  1263. * @return MEMORY_E when dynamic memory allocation fails.
  1264. * @return Other -ve value when an internal operation fails.
  1265. */
  1266. static int eccsi_mulmod_point(EccsiKey* key, const mp_int* n, ecc_point* point,
  1267. ecc_point* res, int map)
  1268. {
  1269. int err;
  1270. #if defined(WOLFSSL_HAVE_SP_ECC) && !defined(WOLFSSL_SP_NO_256)
  1271. if ((key->ecc.idx != ECC_CUSTOM_IDX) &&
  1272. (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) {
  1273. err = sp_ecc_mulmod_256(n, point, res, map, key->heap);
  1274. }
  1275. else
  1276. #endif
  1277. {
  1278. EccsiKeyParams* params = &key->params;
  1279. err = wc_ecc_mulmod(n, point, res, &params->a, &params->prime, map);
  1280. }
  1281. return err;
  1282. }
  1283. /*
  1284. * Scalar multiply a point on the curve and add a.
  1285. *
  1286. * @param [in] key ECCSI key.
  1287. * @param [in] n MP integer representing scalar to multiply by.
  1288. * @param [in] point ECC point representation of a point on the curve.
  1289. * @param [in] a ECC point to add.
  1290. * @param [out] res ECC point representation of the resulting point.
  1291. * @param [in] mp Montgomery reduction multiplier.
  1292. * @param [in] map 0 indicates to leave in projective representation.
  1293. * 1 indicates map projective point to affine.
  1294. * @return 0 on success.
  1295. * @return MEMORY_E when dynamic memory allocation fails.
  1296. * @return Other -ve value when an internal operation fails.
  1297. */
  1298. static int eccsi_mulmod_point_add(EccsiKey* key, const mp_int* n,
  1299. ecc_point* point, ecc_point* a, ecc_point* res, mp_digit mp, int map)
  1300. {
  1301. #if defined(WOLFSSL_HAVE_SP_ECC) && !defined(WOLFSSL_SP_NO_256)
  1302. int err = NOT_COMPILED_IN;
  1303. if ((key->ecc.idx != ECC_CUSTOM_IDX) &&
  1304. (ecc_sets[key->ecc.idx].id == ECC_SECP256R1)) {
  1305. err = sp_ecc_mulmod_add_256(n, point, a, 0, res, map, key->heap);
  1306. }
  1307. (void)mp;
  1308. return err;
  1309. #else
  1310. int err;
  1311. EccsiKeyParams* params = &key->params;
  1312. err = wc_ecc_mulmod(n, point, res, &params->a, &params->prime, 0);
  1313. if (err == 0) {
  1314. err = ecc_projective_add_point(res, a, res, &key->params.a,
  1315. &params->prime, mp);
  1316. }
  1317. if ((err == 0) && map) {
  1318. err = ecc_map(res, &params->prime, mp);
  1319. }
  1320. return err;
  1321. #endif
  1322. }
  1323. /**
  1324. * Validate an (SSV, PVT) Pair.
  1325. *
  1326. * RFC 6507, Section 5.1.2
  1327. *
  1328. * A signing client should validate the key pair before first use.
  1329. *
  1330. * @param [in] key ECCSI key.
  1331. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  1332. * @param [in] id Identity to create hash from.
  1333. * @param [in] idSz Length of identity in bytes.
  1334. * @param [in] ssk Secret Signing Key as an MP integer.
  1335. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  1336. * @param [out] valid 1 when pair is valid and 0 otherwise.
  1337. * @return 0 on success.
  1338. * @return BAD_FUNC_ARG when key, id, ssk, pvt or valid is NULL.
  1339. * @return BAD_STATE_E when curve not set (key not set).
  1340. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1341. * @return IS_POINT_E when point is not on the curve.
  1342. * @return Other -ve value when an internal operation fails.
  1343. */
  1344. int wc_ValidateEccsiPair(EccsiKey* key, enum wc_HashType hashType,
  1345. const byte* id, word32 idSz, const mp_int* ssk, ecc_point* pvt,
  1346. int* valid)
  1347. {
  1348. int err = 0;
  1349. ecc_point* res = NULL;
  1350. mp_int* hs = NULL;
  1351. mp_digit mp = 0;
  1352. byte hashSz = 0;
  1353. EccsiKeyParams* params = NULL;
  1354. if ((key == NULL) || (id == NULL) || (ssk == NULL) || (pvt == NULL) ||
  1355. (valid == NULL)) {
  1356. err = BAD_FUNC_ARG;
  1357. }
  1358. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
  1359. (key->ecc.type != ECC_PUBLICKEY)) {
  1360. err = BAD_STATE_E;
  1361. }
  1362. if (err != 0)
  1363. return err;
  1364. SAVE_VECTOR_REGISTERS(return _svr_ret;);
  1365. params = &key->params;
  1366. hs = &key->tmp;
  1367. res = &key->pubkey.pubkey;
  1368. err = eccsi_load_base(key);
  1369. if (err == 0) {
  1370. err = eccsi_load_ecc_params(key);
  1371. }
  1372. if (err == 0) {
  1373. err = mp_montgomery_setup(&params->prime, &mp);
  1374. }
  1375. /* Step 1: Validate PVT is on curve */
  1376. if (err == 0) {
  1377. err = wc_ecc_is_point(pvt, &params->a, &params->b, &params->prime);
  1378. if (err == -1) {
  1379. err = IS_POINT_E;
  1380. }
  1381. }
  1382. /* Step 2: Compute HS = hash( G | KPAK | ID | PVT ) */
  1383. if (err == 0) {
  1384. hashSz = (byte)sizeof(key->data);
  1385. /* Converts KPAK from mont. */
  1386. err = eccsi_compute_hs(key, hashType, id, idSz, pvt, key->data,
  1387. &hashSz);
  1388. }
  1389. /* Step 3: Validate that KPAK = [SSK]G - [HS]PVT */
  1390. if (err == 0) {
  1391. err = mp_read_unsigned_bin(hs, key->data, hashSz);
  1392. }
  1393. /* [HS]PVT */
  1394. if (err == 0) {
  1395. err = eccsi_mulmod_point(key, hs, pvt, res, 0);
  1396. }
  1397. /* -[HS]PVT */
  1398. if (err == 0) {
  1399. err = mp_sub(&params->prime, res->y, res->y);
  1400. }
  1401. /* [SSK]G + -[HS]PVT */
  1402. if (err == 0) {
  1403. err = eccsi_mulmod_base_add(key, ssk, res, res, mp, 1);
  1404. }
  1405. if (valid != NULL) {
  1406. *valid = (err == 0);
  1407. if (err == 0) {
  1408. ecc_point* kpak = &key->ecc.pubkey;
  1409. /* Compare KPAK and [SSK]G + -[HS]PVT */
  1410. *valid = (wc_ecc_cmp_point(res, kpak) == MP_EQ);
  1411. }
  1412. }
  1413. RESTORE_VECTOR_REGISTERS();
  1414. return err;
  1415. }
  1416. /**
  1417. * Validate Public Validation Token (PVT) is on the curve.
  1418. *
  1419. * RFC 6507, Section 5.1.2, Step 1
  1420. *
  1421. * A verifying client should validate the PVT before first use.
  1422. *
  1423. * @param [in] key ECCSI key.
  1424. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  1425. * @param [out] valid 1 when PVT is valid and 0 otherwise.
  1426. * @return 0 on success.
  1427. * @return BAD_FUNC_ARG when key, pvt or valid is NULL.
  1428. * @return BAD_STATE_E when curve not set (key not set).
  1429. * @return MP_MEM or MEMORY_E when dynamic memory allocation fails.
  1430. * @return Other -ve value when an internal operation fails.
  1431. */
  1432. int wc_ValidateEccsiPvt(EccsiKey* key, const ecc_point* pvt, int* valid)
  1433. {
  1434. int err = 0;
  1435. if ((key == NULL)| (pvt == NULL) || (valid == NULL)) {
  1436. err = BAD_FUNC_ARG;
  1437. }
  1438. if (err == 0) {
  1439. err = wc_ecc_set_curve(&key->pubkey, key->ecc.dp->size,
  1440. key->ecc.dp->id);
  1441. }
  1442. if (err == 0) {
  1443. err = wc_ecc_copy_point(pvt, &key->pubkey.pubkey);
  1444. }
  1445. if (err == 0) {
  1446. *valid = (wc_ecc_check_key(&key->pubkey) == 0);
  1447. }
  1448. return err;
  1449. }
  1450. /**
  1451. * Creates the Hash of the ID and PVT with the ECCSI key.
  1452. *
  1453. * The hash ID is required as input to the sign and verify operations.\n
  1454. * Signing clients may cache this value.
  1455. *
  1456. * RFC 6507, Section 5.2.1, Step 3
  1457. *
  1458. * Set the calculated hash internally for use.
  1459. *
  1460. * @param [in] key ECCSI key.
  1461. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  1462. * @param [in] id Identity to create hash from.
  1463. * @param [in] idSz Length of identity in bytes.
  1464. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  1465. * @param [out] hash Buffer to hold hash result.
  1466. * @param [out] hashSz Length of hash data in bytes.
  1467. * @return 0 on success.
  1468. * @return BAD_FUNC_ARG when key, id, pvt, hash or hashSz is NULL.
  1469. * @return BAD_FUNC_ARG when hash size doesn't match curve size.
  1470. * @return BAD_STATE_E when public key not set.
  1471. * @return MEMORY_E when dynamic memory allocation fails.
  1472. * @return Other -ve value when an internal operation fails.
  1473. */
  1474. int wc_HashEccsiId(EccsiKey* key, enum wc_HashType hashType, const byte* id,
  1475. word32 idSz, ecc_point* pvt, byte* hash, byte* hashSz)
  1476. {
  1477. int err = 0;
  1478. int dgstSz = -1;
  1479. int curveSz = -1;
  1480. if ((key == NULL) || (id == NULL) || (pvt == NULL) || (hash == NULL) ||
  1481. (hashSz == NULL)) {
  1482. err = BAD_FUNC_ARG;
  1483. }
  1484. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
  1485. (key->ecc.type != ECC_PUBLICKEY)) {
  1486. err = BAD_STATE_E;
  1487. }
  1488. /* Ensure digest output size matches curve size (RFC 6507 4.1). */
  1489. if (err == 0) {
  1490. dgstSz = wc_HashGetDigestSize(hashType);
  1491. if (dgstSz < 0) {
  1492. err = dgstSz;
  1493. }
  1494. }
  1495. if (err == 0) {
  1496. curveSz = wc_ecc_get_curve_size_from_id(key->ecc.dp->id);
  1497. if (curveSz < 0) {
  1498. err = curveSz;
  1499. }
  1500. }
  1501. if ((err == 0) && (dgstSz != curveSz)) {
  1502. err = BAD_FUNC_ARG;
  1503. }
  1504. /* Load the curve parameters for operations */
  1505. if (err == 0) {
  1506. err = eccsi_load_ecc_params(key);
  1507. }
  1508. if (err == 0) {
  1509. err = eccsi_compute_hs(key, hashType, id, idSz, pvt, hash, hashSz);
  1510. }
  1511. if (err == 0) {
  1512. XMEMCPY(key->idHash, hash, *hashSz);
  1513. key->idHashSz = *hashSz;
  1514. }
  1515. return err;
  1516. }
  1517. /**
  1518. * Set the identity hash for use with signing/verification.
  1519. *
  1520. * @param [in] key ECCSI key.
  1521. * @param [in] hash Buffer with hash of identity.
  1522. * @param [in] hashSz Length of hash data in bytes.
  1523. * @return 0 on success.
  1524. * @return BAD_FUNC_ARG when key or hash is NULL, or hashSz is greater than
  1525. * WC_MAX_DIGEST_SIZE.
  1526. */
  1527. int wc_SetEccsiHash(EccsiKey* key, const byte* hash, byte hashSz)
  1528. {
  1529. int err = 0;
  1530. if ((key == NULL) || (hash == NULL) || (hashSz > WC_MAX_DIGEST_SIZE)) {
  1531. err = BAD_FUNC_ARG;
  1532. }
  1533. if (err == 0) {
  1534. XMEMCPY(key->idHash, hash, hashSz);
  1535. key->idHashSz = hashSz;
  1536. }
  1537. return err;
  1538. }
  1539. /**
  1540. * Set an (SSV, PVT) Pair for signing.
  1541. *
  1542. * @param [in] key ECCSI key.
  1543. * @param [in] ssk Secret Signing Key as an MP integer.
  1544. * @param [in] pvt Public Validation Token (PVT) as an ECC point.
  1545. * @return 0 on success.
  1546. * @return BAD_FUNC_ARG when key, ssk or pvt is NULL.
  1547. * @return MP math errors when copy fails
  1548. */
  1549. int wc_SetEccsiPair(EccsiKey* key, const mp_int* ssk, const ecc_point* pvt)
  1550. {
  1551. int err = 0;
  1552. if ((key == NULL) || (ssk == NULL) || (pvt == NULL)) {
  1553. err = BAD_FUNC_ARG;
  1554. }
  1555. if (err == 0) {
  1556. err = mp_copy(ssk, &key->ssk);
  1557. }
  1558. if (err == 0) {
  1559. err = wc_ecc_copy_point(pvt, key->pvt);
  1560. }
  1561. return err;
  1562. }
  1563. #ifdef ECCSI_ORDER_MORE_BITS_THAN_PRIME
  1564. /*
  1565. * Fit the number to the maximum number of bytes.
  1566. *
  1567. * If the number is too big then subtract from order.
  1568. * RFC 6507, Section 5.2.1, Note at end.
  1569. * This should only happen when order is larger than prime in bits.
  1570. *
  1571. * @param [in] a MP integer to fix.
  1572. * @param [in] order MP integer representing order of curve.
  1573. * @param [in] m Maximum number of bytes to encode into.
  1574. * @param [out] r MP integer that is the result after fixing.
  1575. * @return 0 on success.
  1576. * @return MEMORY_E when dynamic memory allocation fails.
  1577. */
  1578. static int eccsi_fit_to_octets(const mp_int* a, mp_int* order, int m,
  1579. mp_int* r)
  1580. {
  1581. int err;
  1582. if (mp_count_bits(a) > m * 8) {
  1583. err = mp_sub(order, (mp_int*)a, r);
  1584. }
  1585. else
  1586. {
  1587. err = mp_copy(a, r);
  1588. }
  1589. return err;
  1590. }
  1591. #else
  1592. /*
  1593. * Fit the number to the maximum number of bytes.
  1594. *
  1595. * If the number is too big then subtract from order.
  1596. * RFC 6507, Section 5.2.1, Note at end.
  1597. * This should only happen when order is larger than prime in bits.
  1598. *
  1599. * @param [in] a MP integer to fix.
  1600. * @param [in] order MP integer representing order of curve.
  1601. * @param [in] m Maximum number of bytes to encode into.
  1602. * @param [out] r MP integer that is the result after fixing.
  1603. * @return 0 on success.
  1604. * @return MEMORY_E when dynamic memory allocation fails.
  1605. */
  1606. static int eccsi_fit_to_octets(const mp_int* a, const mp_int* order, int m,
  1607. mp_int* r)
  1608. {
  1609. (void)order;
  1610. (void)m;
  1611. /* Duplicate line to stop static analyzer complaining. */
  1612. return mp_copy(a, r);
  1613. }
  1614. #endif
  1615. /*
  1616. * Compute the HE = hash( HS | r | M ), hash value of signature.
  1617. *
  1618. * Partial result required for signing and verification.
  1619. *
  1620. * @param [in] key ECCSI key.
  1621. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  1622. * @param [in] r MP integer that is the first signature element.
  1623. * @param [in] msg Message of signature.
  1624. * @param [in] msgSz Length of message in bytes.
  1625. * @param [out] he Signature hash.
  1626. * @param [out] heSz Length of signature hash in bytes
  1627. * @return 0 on success.
  1628. * @return MEMORY_E when dynamic memory allocation fails.
  1629. * @return Other -ve value when an internal operation fails.
  1630. */
  1631. static int eccsi_compute_he(EccsiKey* key, enum wc_HashType hashType,
  1632. mp_int* r, const byte* msg, word32 msgSz, byte* he, word32* heSz)
  1633. {
  1634. int err = 0;
  1635. word32 dataSz = (word32)key->ecc.dp->size;
  1636. int hash_inited = 0;
  1637. /* HE = hash( HS | r | M ) */
  1638. err = wc_HashInit_ex(&key->hash, hashType, key->heap, INVALID_DEVID);
  1639. if (err == 0) {
  1640. hash_inited = 1;
  1641. /* HS */
  1642. err = wc_HashUpdate(&key->hash, hashType, key->idHash, key->idHashSz);
  1643. }
  1644. if (err == 0) {
  1645. err = mp_to_unsigned_bin_len(r, key->data, (int)dataSz);
  1646. }
  1647. if (err == 0) {
  1648. /* r */
  1649. err = wc_HashUpdate(&key->hash, hashType, key->data, dataSz);
  1650. }
  1651. if (err == 0) {
  1652. /* M */
  1653. err = wc_HashUpdate(&key->hash, hashType, msg, msgSz);
  1654. }
  1655. if (err == 0) {
  1656. err = wc_HashFinal(&key->hash, hashType, he);
  1657. }
  1658. if (err == 0) {
  1659. *heSz = (word32)wc_HashGetDigestSize(hashType);
  1660. }
  1661. if (hash_inited) {
  1662. (void)wc_HashFree(&key->hash, hashType);
  1663. }
  1664. return err;
  1665. }
  1666. /*
  1667. * Encode the signature = ( r | s | PVT )
  1668. *
  1669. * @param [in] key ECCSI key.
  1670. * @param [in] r MP integer that is the first signature element.
  1671. * @param [in] s MP integer that is the second signature element.
  1672. * @param [in] pvt ECC point representing Public Validation Token.
  1673. * @param [out] sig Signature of message.
  1674. * @param [out] sigSz Length of signature in bytes.
  1675. */
  1676. static int eccsi_encode_sig(const EccsiKey* key, mp_int* r, mp_int* s,
  1677. byte* sig, word32* sigSz)
  1678. {
  1679. int err;
  1680. word32 sz = (word32)key->ecc.dp->size;
  1681. err = mp_to_unsigned_bin_len(r, sig, (int)sz);
  1682. if (err == 0) {
  1683. err = mp_to_unsigned_bin_len(s, sig + sz, (int)sz);
  1684. }
  1685. if (err == 0) {
  1686. *sigSz = (word32)(key->ecc.dp->size * 2 + 1);
  1687. err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(key->ecc.dp->id),
  1688. key->pvt, sig + sz * 2, sigSz);
  1689. }
  1690. if (err == 0) {
  1691. *sigSz = sz * 4 + 1;
  1692. }
  1693. return err;
  1694. }
  1695. /*
  1696. * Sign the ECCSI hash (of ID with the key) to two mp_int objects: r and s.
  1697. *
  1698. * RFC 6507, Section 5.2.1, Steps 1 to 4
  1699. *
  1700. * @param [in] key ECCSI key.
  1701. * @param [in] rng Random number generator.
  1702. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  1703. * @param [in] msg Message to sign.
  1704. * @param [in] msgSz Length of message in bytes.
  1705. * @param [out] r First big number integer part of signature.
  1706. * @param [out] s Second big number integer part of signature.
  1707. * @return 0 on success.
  1708. * @return MEMORY_E when dynamic memory allocation fails.
  1709. * @return Other -ve value when an internal operation fails.
  1710. */
  1711. static int eccsi_gen_sig(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType,
  1712. const byte* msg, word32 msgSz, mp_int* r, mp_int* s)
  1713. {
  1714. int err = 0;
  1715. int sz = key->ecc.dp->size;
  1716. word32 heSz = 0;
  1717. const mp_int* jx = NULL;
  1718. mp_int* he = &key->tmp;
  1719. int genTryCnt = 0;
  1720. do {
  1721. /* Don't infinitely gen sigs when random number generator fails. */
  1722. if ((++genTryCnt) > ECCSI_MAX_GEN_COUNT) {
  1723. err = RNG_FAILURE_E;
  1724. }
  1725. if (err == 0) {
  1726. wc_ecc_free(&key->pubkey);
  1727. /* Step 1 and 2: Generate ephemeral key - j, J = [j]G, r = Jx */
  1728. err = wc_ecc_make_key_ex(rng, sz, &key->pubkey, key->ecc.dp->id);
  1729. }
  1730. if (err == 0) {
  1731. jx = key->pubkey.pubkey.x;
  1732. err = eccsi_fit_to_octets(jx, &key->params.order, sz, r);
  1733. }
  1734. /* Step 3: Compute HE = hash( HS | r | M ) */
  1735. if (err == 0) {
  1736. err = eccsi_compute_he(key, hashType, r, msg, msgSz, key->data,
  1737. &heSz);
  1738. }
  1739. /* Step 4: Verify that HE + r * SSK is non-zero modulo q */
  1740. if (err == 0) {
  1741. err = mp_read_unsigned_bin(he, key->data, heSz);
  1742. }
  1743. /* s' = r * SSK */
  1744. if (err == 0) {
  1745. err = mp_mulmod(r, &key->ssk, &key->params.order, s);
  1746. }
  1747. /* s' = HE + r * SSK */
  1748. if (err == 0) {
  1749. err = mp_addmod(he, s, &key->params.order, s);
  1750. }
  1751. }
  1752. while ((err == 0) && (mp_iszero(s) || (mp_cmp(s, he) == MP_EQ)));
  1753. return err;
  1754. }
  1755. /**
  1756. * Sign the ECCSI hash (of ID with the key).
  1757. *
  1758. * RFC 6507, Section 5.2.1
  1759. *
  1760. * Must have imported KPAK using wc_ImportEccsiPublicKey() before calling.\n
  1761. * Use wc_HashEccsiId() to calculate the hash and wc_SetEccsiHash() to set
  1762. * the identity hash to use.
  1763. *
  1764. * @param [in] key ECCSI key.
  1765. * @param [in] rng Random number generator.
  1766. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  1767. * @param [in] msg Message to sign.
  1768. * @param [in] msgSz Length of message in bytes.
  1769. * @param [out] sig Signature of message.
  1770. * @param [out] sigSz Length of signature in bytes.
  1771. * @return 0 on success.
  1772. * @return BAD_FUNC_ARG when key, rng, msg or sigSz is NULL.
  1773. * @return BAD_STATE_E when the curve or id hash has not been set (no key set).
  1774. * @return LENGTH_ONLY_E when sig is NULL - sigSz is set.
  1775. * @return MEMORY_E when dynamic memory allocation fails.
  1776. * @return Other -ve value when an internal operation fails.
  1777. */
  1778. int wc_SignEccsiHash(EccsiKey* key, WC_RNG* rng, enum wc_HashType hashType,
  1779. const byte* msg, word32 msgSz, byte* sig, word32* sigSz)
  1780. {
  1781. int err = 0;
  1782. mp_int* r = NULL;
  1783. mp_int* s = NULL;
  1784. mp_int* j = NULL;
  1785. word32 sz = 0;
  1786. if ((key == NULL) || (rng == NULL) || (msg == NULL) || (sigSz == NULL)) {
  1787. err = BAD_FUNC_ARG;
  1788. }
  1789. if ((err == 0) && (key->ecc.type != ECC_PUBLICKEY) &&
  1790. (key->ecc.type != ECC_PRIVATEKEY)) {
  1791. err = BAD_STATE_E;
  1792. }
  1793. if ((err == 0) && (sig != NULL) && (key->idHashSz == 0)) {
  1794. err = BAD_STATE_E;
  1795. }
  1796. if (err == 0) {
  1797. sz = (word32)key->ecc.dp->size;
  1798. if (sig == NULL) {
  1799. *sigSz = sz * 4 + 1;
  1800. err = LENGTH_ONLY_E;
  1801. }
  1802. }
  1803. if ((err == 0) && (*sigSz < sz * 4 + 1)) {
  1804. err = BAD_FUNC_ARG;
  1805. }
  1806. if (err == 0) {
  1807. r = key->pubkey.pubkey.y;
  1808. s = key->pubkey.pubkey.z;
  1809. err = eccsi_load_order(key);
  1810. }
  1811. if (err == 0) {
  1812. /* Steps 1 to 4. */
  1813. err = eccsi_gen_sig(key, rng, hashType, msg, msgSz, r, s);
  1814. }
  1815. /* Step 5: s' = ( (( HE + r * SSK )^-1) * j ) modulo q, erase j */
  1816. if (err == 0) {
  1817. err = mp_invmod(s, &key->params.order, s);
  1818. }
  1819. if (err == 0) {
  1820. j = wc_ecc_key_get_priv(&key->pubkey);
  1821. err = mp_mulmod(s, j, &key->params.order, s);
  1822. }
  1823. if (err == 0) {
  1824. mp_forcezero(j);
  1825. /* Step 6: s = s' fitted */
  1826. err = eccsi_fit_to_octets(s, &key->params.order, (int)sz, s);
  1827. }
  1828. /* Step 7: Output Signature = ( r | s | PVT ) */
  1829. if (err == 0) {
  1830. err = eccsi_encode_sig(key, r, s, sig, sigSz);
  1831. }
  1832. return err;
  1833. }
  1834. /*
  1835. * Decode the s part of the signature = ( r | s | PVT )
  1836. *
  1837. * @param [in] key ECCSI key.
  1838. * @param [in] sig Signature of message.
  1839. * @param [in] sigSz Length of signature in bytes.
  1840. * @param [out] s MP integer that is the second signature element.
  1841. * @return 0 on success.
  1842. * @return MEMORY_E when dynamic memory allocation fails.
  1843. * @return Other -ve value when an internal operation fails.
  1844. */
  1845. static int eccsi_decode_sig_s(const EccsiKey* key, const byte* sig,
  1846. word32 sigSz, mp_int* s)
  1847. {
  1848. int err = 0;
  1849. word32 sz = (word32)key->ecc.dp->size;
  1850. if (sigSz != sz * 4 + 1) {
  1851. err = BAD_FUNC_ARG;
  1852. }
  1853. if (err == 0) {
  1854. err = mp_read_unsigned_bin(s, sig + sz, sz);
  1855. }
  1856. return err;
  1857. }
  1858. /*
  1859. * Decode the r and pvt part of the signature = ( r | s | PVT )
  1860. *
  1861. * @param [in] key ECCSI key.
  1862. * @param [in] sig Signature of message.
  1863. * @param [in] sigSz Length of signature in bytes.
  1864. * @param [out] r MP integer that is the first signature element.
  1865. * @param [out] pvt ECC point representing Public Validation Token.
  1866. * @return 0 on success.
  1867. * @return MEMORY_E when dynamic memory allocation fails.
  1868. * @return Other -ve value when an internal operation fails.
  1869. */
  1870. static int eccsi_decode_sig_r_pvt(const EccsiKey* key, const byte* sig,
  1871. word32 sigSz, mp_int* r, ecc_point* pvt)
  1872. {
  1873. int err = 0;
  1874. word32 sz = (word32)key->ecc.dp->size;
  1875. if (sigSz != sz * 4 + 1) {
  1876. err = BAD_FUNC_ARG;
  1877. }
  1878. if (err == 0) {
  1879. err = mp_read_unsigned_bin(r, sig, sz);
  1880. }
  1881. if (err == 0) {
  1882. /* must free previous public point otherwise wc_ecc_import_point_der
  1883. * could leak memory */
  1884. mp_clear(pvt->x);
  1885. mp_clear(pvt->y);
  1886. mp_clear(pvt->z);
  1887. err = wc_ecc_import_point_der(sig + sz * 2, sz * 2 + 1,
  1888. wc_ecc_get_curve_idx(key->ecc.dp->id), pvt);
  1889. }
  1890. return err;
  1891. }
  1892. /*
  1893. * Calculate Y point as part of verification process.
  1894. *
  1895. * Y = [HS]PVT + KPAK
  1896. *
  1897. * @param [in] key ECCSI key.
  1898. * @param [in] pvt ECC point representing Public Validation Token.
  1899. * @param [in] mp Montgomery reduction multiplier.
  1900. * @param [out] y ECC point representing calculated value Y.
  1901. * @return 0 on success.
  1902. * @return MEMORY_E when dynamic memory allocation fails.
  1903. * @return Other value when an an internal operation fails.
  1904. */
  1905. static int eccsi_calc_y(EccsiKey* key, ecc_point* pvt, mp_digit mp,
  1906. ecc_point* y)
  1907. {
  1908. int err;
  1909. mp_int* hs = &key->ssk;
  1910. err = mp_read_unsigned_bin(hs, key->idHash, key->idHashSz);
  1911. #ifndef WOLFSSL_HAVE_SP_ECC
  1912. /* Need KPAK in montgomery form. */
  1913. if (err == 0) {
  1914. err = eccsi_kpak_to_mont(key);
  1915. }
  1916. #endif
  1917. /* [HS]PVT + KPAK */
  1918. if (err == 0) {
  1919. ecc_point* kpak = &key->ecc.pubkey;
  1920. err = eccsi_mulmod_point_add(key, hs, pvt, kpak, y, mp, 1);
  1921. }
  1922. return err;
  1923. }
  1924. /*
  1925. * Calculate J point as part of verification process.
  1926. *
  1927. * J = [s]( [HE]G + [r]Y )
  1928. *
  1929. * @param [in] key ECCSI key.
  1930. * @param [in] hem MP int representation of HE = Hash (hs, r and message).
  1931. * @param [in] sig Signature of message.
  1932. * @param [in] sigSz Length of signature in bytes.
  1933. * @param [in] y ECC point representing [r]Y.
  1934. * @param [in] mp Montgomery reduction multiplier.
  1935. * @param [out] j ECC point representing calculated value J.
  1936. * @return 0 on success.
  1937. * @return MEMORY_E when dynamic memory allocation fails.
  1938. * @return Other value when an an internal operation fails.
  1939. */
  1940. static int eccsi_calc_j(EccsiKey* key, const mp_int* hem, const byte* sig,
  1941. word32 sigSz, ecc_point* y, mp_digit mp, ecc_point* j)
  1942. {
  1943. int err;
  1944. mp_int* s = &key->tmp;
  1945. /* [HE]G + [r]Y */
  1946. err = eccsi_mulmod_base_add(key, hem, y, j, mp, 1);
  1947. if (err == 0) {
  1948. err = eccsi_decode_sig_s(key, sig, sigSz, s);
  1949. }
  1950. /* [s]( [HE]G + [r]Y ) */
  1951. if (err == 0) {
  1952. err = eccsi_mulmod_point(key, s, j, j, 1);
  1953. }
  1954. return err;
  1955. }
  1956. /**
  1957. * Verify the ECCSI hash (of ID with the key).
  1958. *
  1959. * RFC 6507, Section 5.2.2
  1960. *
  1961. * Must have imported KPAK using wc_ImportEccsiPublicKey() before calling.\n
  1962. * Use wc_HashEccsiId() to calculate the hash and wc_SetEccsiHash() to set
  1963. * the identity hash to use.
  1964. *
  1965. * @param [in] key ECCSI key.
  1966. * @param [in] hashType Type of hash algorithm. e.g. WC_SHA256
  1967. * @param [in] msg Message to verify.
  1968. * @param [in] msgSz Length of message in bytes.
  1969. * @param [in] sig Signature of message.
  1970. * @param [in] sigSz Length of signature in bytes.
  1971. * @param [out] verified 1 when the signature was verified and 0 otherwise.
  1972. * @return 0 on success.
  1973. * @return BAD_FUNC_ARG when key, hash, msg, sig or ret is NULL.
  1974. * @return BAD_STATE_E when the curve or id hash has not been set (no key set).
  1975. * @return MEMORY_E when dynamic memory allocation fails.
  1976. * @return Other value when an an internal operation fails.
  1977. */
  1978. int wc_VerifyEccsiHash(EccsiKey* key, enum wc_HashType hashType,
  1979. const byte* msg, word32 msgSz, const byte* sig, word32 sigSz,
  1980. int* verified)
  1981. {
  1982. int err = 0;
  1983. byte* he = NULL;
  1984. word32 heSz = 0;
  1985. mp_int* r = NULL;
  1986. mp_int* jx = NULL;
  1987. mp_int* hem = NULL;
  1988. ecc_point* pvt = NULL;
  1989. ecc_point* y = NULL;
  1990. ecc_point* j = NULL;
  1991. mp_digit mp = 0;
  1992. EccsiKeyParams* params = NULL;
  1993. if ((key == NULL) || (msg == NULL) || (sig == NULL) || (verified == NULL)) {
  1994. err = BAD_FUNC_ARG;
  1995. }
  1996. if ((err == 0) && (key->ecc.type != ECC_PRIVATEKEY) &&
  1997. (key->ecc.type != ECC_PUBLICKEY)) {
  1998. err = BAD_STATE_E;
  1999. }
  2000. if ((err == 0) && (key->idHashSz == 0)) {
  2001. err = BAD_STATE_E;
  2002. }
  2003. if (err != 0)
  2004. return err;
  2005. SAVE_VECTOR_REGISTERS(return _svr_ret;);
  2006. /* Decode the signature into components. */
  2007. r = wc_ecc_key_get_priv(&key->pubkey);
  2008. pvt = &key->pubkey.pubkey;
  2009. err = eccsi_decode_sig_r_pvt(key, sig, sigSz, r, pvt);
  2010. /* Load the curve parameters for operations */
  2011. if (err == 0) {
  2012. err = eccsi_load_base(key);
  2013. }
  2014. if (err == 0) {
  2015. err = eccsi_load_ecc_params(key);
  2016. }
  2017. if (err == 0) {
  2018. params = &key->params;
  2019. err = mp_montgomery_setup(&params->prime, &mp);
  2020. }
  2021. /* Step 1: Validate PVT is on curve */
  2022. if (err == 0) {
  2023. err = wc_ecc_is_point(pvt, &params->a, &params->b, &params->prime);
  2024. }
  2025. /* Step 2: Compute HS = hash( G | KPAK | ID | PVT )
  2026. * HS is key->idHash, key->idHashSz */
  2027. /* Step 3: Compute HE = hash( HS | r | M ) */
  2028. if (err == 0) {
  2029. he = key->data;
  2030. err = eccsi_compute_he(key, hashType, r, msg, msgSz, he, &heSz);
  2031. }
  2032. /* Step 4: Y = [HS]PVT + KPAK */
  2033. if (err == 0) {
  2034. y = pvt;
  2035. err = eccsi_calc_y(key, pvt, mp, y);
  2036. }
  2037. /* Step 5: Compute J = [s]( [HE]G + [r]Y ) */
  2038. /* [r]Y */
  2039. if (err == 0) {
  2040. hem = &key->tmp;
  2041. err = mp_read_unsigned_bin(hem, he, heSz);
  2042. }
  2043. if (err == 0) {
  2044. err = eccsi_mulmod_point(key, r, y, y, 0);
  2045. }
  2046. if (err == 0) {
  2047. j = params->base;
  2048. err = eccsi_calc_j(key, hem, sig, sigSz, y, mp, j);
  2049. key->params.haveBase = 0;
  2050. }
  2051. /* Step 6: Jx fitting, compare with r */
  2052. if (err == 0) {
  2053. jx = &key->tmp;
  2054. err = eccsi_fit_to_octets(j->x, &params->order, key->ecc.dp->size, jx);
  2055. }
  2056. if (verified != NULL) {
  2057. *verified = ((err == 0) && (mp_cmp(jx, r) == MP_EQ));
  2058. }
  2059. RESTORE_VECTOR_REGISTERS();
  2060. return err;
  2061. }
  2062. #endif /* WOLFCRYPT_ECCSI_CLIENT */
  2063. #endif /* WOLFCRYPT_HAVE_ECCSI */