nu_crypto.c 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673
  1. /**************************************************************************//**
  2. * @file crypto.c
  3. * @version V1.10
  4. * @brief Cryptographic Accelerator driver source file
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. * @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  8. *****************************************************************************/
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "nuc980.h"
  12. #include "nu_crypto.h"
  13. /** @cond HIDDEN_SYMBOLS */
  14. #define ENABLE_DEBUG 0
  15. #if ENABLE_DEBUG
  16. #define CRPT_DBGMSG printf
  17. #else
  18. #define CRPT_DBGMSG(...) do { } while (0) /* disable debug */
  19. #endif
  20. /** @endcond HIDDEN_SYMBOLS */
  21. /** @addtogroup Standard_Driver Standard Driver
  22. @{
  23. */
  24. /** @addtogroup CRYPTO_Driver CRYPTO Driver
  25. @{
  26. */
  27. /** @addtogroup CRYPTO_EXPORTED_FUNCTIONS CRYPTO Exported Functions
  28. @{
  29. */
  30. /** @cond HIDDEN_SYMBOLS */
  31. static uint32_t g_AES_CTL;
  32. static char hex_char_tbl[] = "0123456789abcdef";
  33. static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count);
  34. static char get_Nth_nibble_char(uint32_t val32, uint32_t idx);
  35. static void Hex2Reg(char input[], uint32_t volatile reg[]);
  36. static void Reg2Hex(int32_t count, uint32_t volatile reg[], char output[]);
  37. static void Hex2RegEx(char input[], uint32_t volatile reg[], int shift);
  38. static char ch2hex(char ch);
  39. static int get_nibble_value(char c);
  40. /** @endcond HIDDEN_SYMBOLS */
  41. /**
  42. * @brief Open PRNG function
  43. * @param[in] crpt Reference to Crypto module.
  44. * @param[in] u32KeySize is PRNG key size, including:
  45. * - \ref PRNG_KEY_SIZE_64
  46. * - \ref PRNG_KEY_SIZE_128
  47. * - \ref PRNG_KEY_SIZE_192
  48. * - \ref PRNG_KEY_SIZE_256
  49. * @param[in] u32SeedReload is PRNG seed reload or not, including:
  50. * - \ref PRNG_SEED_CONT
  51. * - \ref PRNG_SEED_RELOAD
  52. * @param[in] u32Seed The new seed. Only valid when u32SeedReload is PRNG_SEED_RELOAD.
  53. * @return None
  54. */
  55. void PRNG_Open(CRPT_T *crpt, uint32_t u32KeySize, uint32_t u32SeedReload, uint32_t u32Seed)
  56. {
  57. if (u32SeedReload)
  58. {
  59. crpt->PRNG_SEED = u32Seed;
  60. }
  61. crpt->PRNG_CTL = (u32KeySize << CRPT_PRNG_CTL_KEYSZ_Pos) |
  62. (u32SeedReload << CRPT_PRNG_CTL_SEEDRLD_Pos);
  63. }
  64. /**
  65. * @brief Start to generate one PRNG key.
  66. * @param[in] crpt Reference to Crypto module.
  67. * @return None
  68. */
  69. void PRNG_Start(CRPT_T *crpt)
  70. {
  71. crpt->PRNG_CTL |= CRPT_PRNG_CTL_START_Msk;
  72. }
  73. /**
  74. * @brief Read the PRNG key.
  75. * @param[in] crpt Reference to Crypto module.
  76. * @param[out] u32RandKey The key buffer to store newly generated PRNG key.
  77. * @return None
  78. */
  79. void PRNG_Read(CRPT_T *crpt, uint32_t u32RandKey[])
  80. {
  81. uint32_t i, wcnt;
  82. wcnt = (((crpt->PRNG_CTL & CRPT_PRNG_CTL_KEYSZ_Msk) >> CRPT_PRNG_CTL_KEYSZ_Pos) + 1U) * 2U;
  83. for (i = 0U; i < wcnt; i++)
  84. {
  85. u32RandKey[i] = crpt->PRNG_KEY[i];
  86. }
  87. crpt->PRNG_CTL &= ~CRPT_PRNG_CTL_SEEDRLD_Msk;
  88. }
  89. /**
  90. * @brief Open AES encrypt/decrypt function.
  91. * @param[in] crpt Reference to Crypto module.
  92. * @param[in] u32EncDec 1: AES encode; 0: AES decode
  93. * @param[in] u32OpMode AES operation mode, including:
  94. * - \ref AES_MODE_ECB
  95. * - \ref AES_MODE_CBC
  96. * - \ref AES_MODE_CFB
  97. * - \ref AES_MODE_OFB
  98. * - \ref AES_MODE_CTR
  99. * - \ref AES_MODE_CBC_CS1
  100. * - \ref AES_MODE_CBC_CS2
  101. * - \ref AES_MODE_CBC_CS3
  102. * @param[in] u32KeySize is AES key size, including:
  103. * - \ref AES_KEY_SIZE_128
  104. * - \ref AES_KEY_SIZE_192
  105. * - \ref AES_KEY_SIZE_256
  106. * @param[in] u32SwapType is AES input/output data swap control, including:
  107. * - \ref AES_NO_SWAP
  108. * - \ref AES_OUT_SWAP
  109. * - \ref AES_IN_SWAP
  110. * - \ref AES_IN_OUT_SWAP
  111. * @return None
  112. */
  113. void AES_Open(CRPT_T *crpt, uint32_t u32EncDec,
  114. uint32_t u32OpMode, uint32_t u32KeySize, uint32_t u32SwapType)
  115. {
  116. crpt->AES_CTL = (u32EncDec << CRPT_AES_CTL_ENCRPT_Pos) |
  117. (u32OpMode << CRPT_AES_CTL_OPMODE_Pos) |
  118. (u32KeySize << CRPT_AES_CTL_KEYSZ_Pos) |
  119. (u32SwapType << CRPT_AES_CTL_OUTSWAP_Pos);
  120. g_AES_CTL = crpt->AES_CTL;
  121. }
  122. /**
  123. * @brief Start AES encrypt/decrypt
  124. * @param[in] crpt Reference to Crypto module.
  125. * @param[in] u32DMAMode AES DMA control, including:
  126. * - \ref CRYPTO_DMA_ONE_SHOT One shop AES encrypt/decrypt.
  127. * - \ref CRYPTO_DMA_CONTINUE Continuous AES encrypt/decrypt.
  128. * - \ref CRYPTO_DMA_LAST Last AES encrypt/decrypt of a series of AES_Start.
  129. * @return None
  130. */
  131. void AES_Start(CRPT_T *crpt, uint32_t u32DMAMode)
  132. {
  133. crpt->AES_CTL = g_AES_CTL;
  134. crpt->AES_CTL |= CRPT_AES_CTL_START_Msk | (u32DMAMode << CRPT_AES_CTL_DMALAST_Pos);
  135. }
  136. /**
  137. * @brief Set AES keys
  138. * @param[in] crpt Reference to Crypto module.
  139. * @param[in] au32Keys An word array contains AES keys.
  140. * @param[in] u32KeySize is AES key size, including:
  141. * - \ref AES_KEY_SIZE_128
  142. * - \ref AES_KEY_SIZE_192
  143. * - \ref AES_KEY_SIZE_256
  144. * @return None
  145. */
  146. void AES_SetKey(CRPT_T *crpt, uint32_t au32Keys[], uint32_t u32KeySize)
  147. {
  148. uint32_t i, wcnt, key_reg_addr;
  149. key_reg_addr = (uint32_t)&crpt->AES0_KEY[0];
  150. wcnt = 4UL + u32KeySize * 2UL;
  151. for (i = 0U; i < wcnt; i++)
  152. {
  153. outpw(key_reg_addr, au32Keys[i]);
  154. key_reg_addr += 4UL;
  155. }
  156. }
  157. /**
  158. * @brief Set AES initial vectors
  159. * @param[in] crpt Reference to Crypto module.
  160. * @param[in] au32IV A four entry word array contains AES initial vectors.
  161. * @return None
  162. */
  163. void AES_SetInitVect(CRPT_T *crpt, uint32_t au32IV[])
  164. {
  165. uint32_t i, key_reg_addr;
  166. key_reg_addr = (uint32_t)&crpt->AES0_IV[0];
  167. for (i = 0U; i < 4U; i++)
  168. {
  169. outpw(key_reg_addr, au32IV[i]);
  170. key_reg_addr += 4UL;
  171. }
  172. }
  173. /**
  174. * @brief Set AES DMA transfer configuration.
  175. * @param[in] crpt Reference to Crypto module.
  176. * @param[in] u32SrcAddr AES DMA source address
  177. * @param[in] u32DstAddr AES DMA destination address
  178. * @param[in] u32TransCnt AES DMA transfer byte count
  179. * @return None
  180. */
  181. void AES_SetDMATransfer(CRPT_T *crpt, uint32_t u32SrcAddr,
  182. uint32_t u32DstAddr, uint32_t u32TransCnt)
  183. {
  184. uint32_t reg_addr;
  185. reg_addr = (uint32_t)&crpt->AES0_SADDR;
  186. outpw(reg_addr, u32SrcAddr);
  187. reg_addr = (uint32_t)&crpt->AES0_DADDR;
  188. outpw(reg_addr, u32DstAddr);
  189. reg_addr = (uint32_t)&crpt->AES0_CNT;
  190. outpw(reg_addr, u32TransCnt);
  191. }
  192. /**
  193. * @brief Open SHA encrypt function.
  194. * @param[in] crpt Reference to Crypto module.
  195. * @param[in] u32OpMode SHA operation mode, including:
  196. * - \ref SHA_MODE_SHA1
  197. * - \ref SHA_MODE_SHA224
  198. * - \ref SHA_MODE_SHA256
  199. * - \ref SHA_MODE_SHA384
  200. * - \ref SHA_MODE_SHA512
  201. * @param[in] u32SwapType is SHA input/output data swap control, including:
  202. * - \ref SHA_NO_SWAP
  203. * - \ref SHA_OUT_SWAP
  204. * - \ref SHA_IN_SWAP
  205. * - \ref SHA_IN_OUT_SWAP
  206. * @param[in] hmac_key_len HMAC key byte count
  207. * @return None
  208. */
  209. void SHA_Open(CRPT_T *crpt, uint32_t u32OpMode, uint32_t u32SwapType, uint32_t hmac_key_len)
  210. {
  211. crpt->HMAC_CTL = (u32OpMode << CRPT_HMAC_CTL_OPMODE_Pos) |
  212. (u32SwapType << CRPT_HMAC_CTL_OUTSWAP_Pos);
  213. if (hmac_key_len != 0UL)
  214. {
  215. crpt->HMAC_KEYCNT = hmac_key_len;
  216. crpt->HMAC_CTL |= CRPT_HMAC_CTL_HMACEN_Msk;
  217. }
  218. }
  219. /**
  220. * @brief Start SHA encrypt
  221. * @param[in] crpt Reference to Crypto module.
  222. * @param[in] u32DMAMode TDES DMA control, including:
  223. * - \ref CRYPTO_DMA_ONE_SHOT One shop SHA encrypt.
  224. * - \ref CRYPTO_DMA_CONTINUE Continuous SHA encrypt.
  225. * - \ref CRYPTO_DMA_LAST Last SHA encrypt of a series of SHA_Start.
  226. * @return None
  227. */
  228. void SHA_Start(CRPT_T *crpt, uint32_t u32DMAMode)
  229. {
  230. crpt->HMAC_CTL &= ~(0x7UL << CRPT_HMAC_CTL_DMALAST_Pos);
  231. crpt->HMAC_CTL |= CRPT_HMAC_CTL_START_Msk | (u32DMAMode << CRPT_HMAC_CTL_DMALAST_Pos);
  232. }
  233. /**
  234. * @brief Set SHA DMA transfer
  235. * @param[in] crpt Reference to Crypto module.
  236. * @param[in] u32SrcAddr SHA DMA source address
  237. * @param[in] u32TransCnt SHA DMA transfer byte count
  238. * @return None
  239. */
  240. void SHA_SetDMATransfer(CRPT_T *crpt, uint32_t u32SrcAddr, uint32_t u32TransCnt)
  241. {
  242. crpt->HMAC_SADDR = u32SrcAddr;
  243. crpt->HMAC_DMACNT = u32TransCnt;
  244. }
  245. /**
  246. * @brief Read the SHA digest.
  247. * @param[in] crpt Reference to Crypto module.
  248. * @param[out] u32Digest The SHA encrypt output digest.
  249. * @return None
  250. */
  251. void SHA_Read(CRPT_T *crpt, uint32_t u32Digest[])
  252. {
  253. uint32_t i, wcnt, reg_addr;
  254. i = (crpt->HMAC_CTL & CRPT_HMAC_CTL_OPMODE_Msk) >> CRPT_HMAC_CTL_OPMODE_Pos;
  255. if (i == SHA_MODE_SHA1)
  256. {
  257. wcnt = 5UL;
  258. }
  259. else if (i == SHA_MODE_SHA224)
  260. {
  261. wcnt = 7UL;
  262. }
  263. else if (i == SHA_MODE_SHA256)
  264. {
  265. wcnt = 8UL;
  266. }
  267. else if (i == SHA_MODE_SHA384)
  268. {
  269. wcnt = 12UL;
  270. }
  271. else
  272. {
  273. /* SHA_MODE_SHA512 */
  274. wcnt = 16UL;
  275. }
  276. reg_addr = (uint32_t) & (crpt->HMAC_DGST[0]);
  277. for (i = 0UL; i < wcnt; i++)
  278. {
  279. u32Digest[i] = inpw(reg_addr);
  280. reg_addr += 4UL;
  281. }
  282. }
  283. /** @cond HIDDEN_SYMBOLS */
  284. /*-----------------------------------------------------------------------------------------------*/
  285. /* */
  286. /* ECC */
  287. /* */
  288. /*-----------------------------------------------------------------------------------------------*/
  289. #define ECCOP_POINT_MUL (0x0UL << CRPT_ECC_CTL_ECCOP_Pos)
  290. #define ECCOP_MODULE (0x1UL << CRPT_ECC_CTL_ECCOP_Pos)
  291. #define ECCOP_POINT_ADD (0x2UL << CRPT_ECC_CTL_ECCOP_Pos)
  292. #define ECCOP_POINT_DOUBLE (0x0UL << CRPT_ECC_CTL_ECCOP_Pos)
  293. #define MODOP_DIV (0x0UL << CRPT_ECC_CTL_MODOP_Pos)
  294. #define MODOP_MUL (0x1UL << CRPT_ECC_CTL_MODOP_Pos)
  295. #define MODOP_ADD (0x2UL << CRPT_ECC_CTL_MODOP_Pos)
  296. #define MODOP_SUB (0x3UL << CRPT_ECC_CTL_MODOP_Pos)
  297. enum
  298. {
  299. CURVE_GF_P,
  300. CURVE_GF_2M,
  301. };
  302. /*-----------------------------------------------------*/
  303. /* Define elliptic curve (EC): */
  304. /*-----------------------------------------------------*/
  305. typedef struct e_curve_t
  306. {
  307. E_ECC_CURVE curve_id;
  308. int32_t Echar;
  309. char Ea[144];
  310. char Eb[144];
  311. char Px[144];
  312. char Py[144];
  313. int32_t Epl;
  314. char Pp[176];
  315. int32_t Eol;
  316. char Eorder[176];
  317. int32_t key_len;
  318. int32_t irreducible_k1;
  319. int32_t irreducible_k2;
  320. int32_t irreducible_k3;
  321. int32_t GF;
  322. } ECC_CURVE;
  323. const ECC_CURVE _Curve[] =
  324. {
  325. {
  326. /* NIST: Curve P-192 : y^2=x^3-ax+b (mod p) */
  327. CURVE_P_192,
  328. 48, /* Echar */
  329. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* "000000000000000000000000000000000000000000000003" */
  330. "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
  331. "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
  332. "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
  333. 58, /* Epl */
  334. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* "6277101735386680763835789423207666416083908700390324961279" */
  335. 58, /* Eol */
  336. "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* "6277101735386680763835789423176059013767194773182842284081" */
  337. 192, /* key_len */
  338. 7,
  339. 2,
  340. 1,
  341. CURVE_GF_P
  342. },
  343. {
  344. /* NIST: Curve P-224 : y^2=x^3-ax+b (mod p) */
  345. CURVE_P_224,
  346. 56, /* Echar */
  347. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* "00000000000000000000000000000000000000000000000000000003" */
  348. "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
  349. "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
  350. "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
  351. 70, /* Epl */
  352. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "0026959946667150639794667015087019630673557916260026308143510066298881" */
  353. 70, /* Eol */
  354. "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* "0026959946667150639794667015087019625940457807714424391721682722368061" */
  355. 224, /* key_len */
  356. 9,
  357. 8,
  358. 3,
  359. CURVE_GF_P
  360. },
  361. {
  362. /* NIST: Curve P-256 : y^2=x^3-ax+b (mod p) */
  363. CURVE_P_256,
  364. 64, /* Echar */
  365. "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* "0000000000000000000000000000000000000000000000000000000000000003" */
  366. "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
  367. "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
  368. "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
  369. 78, /* Epl */
  370. "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* "115792089210356248762697446949407573530086143415290314195533631308867097853951" */
  371. 78, /* Eol */
  372. "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* "115792089210356248762697446949407573529996955224135760342422259061068512044369" */
  373. 256, /* key_len */
  374. 10,
  375. 5,
  376. 2,
  377. CURVE_GF_P
  378. },
  379. {
  380. /* NIST: Curve P-384 : y^2=x^3-ax+b (mod p) */
  381. CURVE_P_384,
  382. 96, /* Echar */
  383. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" */
  384. "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
  385. "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
  386. "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
  387. 116, /* Epl */
  388. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319" */
  389. 116, /* Eol */
  390. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643" */
  391. 384, /* key_len */
  392. 12,
  393. 3,
  394. 2,
  395. CURVE_GF_P
  396. },
  397. {
  398. /* NIST: Curve P-521 : y^2=x^3-ax+b (mod p)*/
  399. CURVE_P_521,
  400. 131, /* Echar */
  401. "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003" */
  402. "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
  403. "0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
  404. "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
  405. 157, /* Epl */
  406. "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151" */
  407. 157, /* Eol */
  408. "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* "6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449" */
  409. 521, /* key_len */
  410. 32,
  411. 32,
  412. 32,
  413. CURVE_GF_P
  414. },
  415. {
  416. /* NIST: Curve B-163 : y^2+xy=x^3+ax^2+b */
  417. CURVE_B_163,
  418. 41, /* Echar */
  419. "00000000000000000000000000000000000000001",
  420. "20a601907b8c953ca1481eb10512f78744a3205fd",
  421. "3f0eba16286a2d57ea0991168d4994637e8343e36",
  422. "0d51fbc6c71a0094fa2cdd545b11c5c0c797324f1",
  423. 68, /* Epl */
  424. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  425. 49, /* Eol */
  426. "40000000000000000000292FE77E70C12A4234C33", /* "5846006549323611672814742442876390689256843201587" */
  427. 163, /* key_len */
  428. 7,
  429. 6,
  430. 3,
  431. CURVE_GF_2M
  432. },
  433. {
  434. /* NIST: Curve B-233 : y^2+xy=x^3+ax^2+b */
  435. CURVE_B_233,
  436. 59, /* Echar 59 */
  437. "00000000000000000000000000000000000000000000000000000000001",
  438. "066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad",
  439. "0fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b",
  440. "1006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052",
  441. 68, /* Epl */
  442. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  443. 70, /* Eol */
  444. "1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", /* "6901746346790563787434755862277025555839812737345013555379383634485463" */
  445. 233, /* key_len */
  446. 74,
  447. 74,
  448. 74,
  449. CURVE_GF_2M
  450. },
  451. {
  452. /* NIST: Curve B-283 : y^2+xy=x^3+ax^2+b */
  453. CURVE_B_283,
  454. 71, /* Echar */
  455. "00000000000000000000000000000000000000000000000000000000000000000000001",
  456. "27b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5",
  457. "5f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053",
  458. "3676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4",
  459. 68, /* Epl */
  460. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  461. 85, /* Eol */
  462. "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", /* "7770675568902916283677847627294075626569625924376904889109196526770044277787378692871" */
  463. 283, /* key_len */
  464. 12,
  465. 7,
  466. 5,
  467. CURVE_GF_2M
  468. },
  469. {
  470. /* NIST: Curve B-409 : y^2+xy=x^3+ax^2+b */
  471. CURVE_B_409,
  472. 103, /* Echar */
  473. "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  474. "021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f",
  475. "15d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7",
  476. "061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706",
  477. 68, /* Epl */
  478. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  479. 123, /* Eol */
  480. "10000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", /* "661055968790248598951915308032771039828404682964281219284648798304157774827374805208143723762179110965979867288366567526771" */
  481. 409, /* key_len */
  482. 87,
  483. 87,
  484. 87,
  485. CURVE_GF_2M
  486. },
  487. {
  488. /* NIST: Curve B-571 : y^2+xy=x^3+ax^2+b */
  489. CURVE_B_571,
  490. 143, /* Echar */
  491. "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  492. "2f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a",
  493. "303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19",
  494. "37bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b",
  495. 68, /* Epl */
  496. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  497. 172, /* Eol */
  498. "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", /* "3864537523017258344695351890931987344298927329706434998657235251451519142289560424536143999389415773083133881121926944486246872462816813070234528288303332411393191105285703" */
  499. 571, /* key_len */
  500. 10,
  501. 5,
  502. 2,
  503. CURVE_GF_2M
  504. },
  505. {
  506. /* NIST: Curve K-163 : y^2+xy=x^3+ax^2+b */
  507. CURVE_K_163,
  508. 41, /* Echar */
  509. "00000000000000000000000000000000000000001",
  510. "00000000000000000000000000000000000000001",
  511. "2fe13c0537bbc11acaa07d793de4e6d5e5c94eee8",
  512. "289070fb05d38ff58321f2e800536d538ccdaa3d9",
  513. 68, /* Epl */
  514. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  515. 49, /* Eol */
  516. "4000000000000000000020108A2E0CC0D99F8A5EF", /* "5846006549323611672814741753598448348329118574063" */
  517. 163, /* key_len */
  518. 7,
  519. 6,
  520. 3,
  521. CURVE_GF_2M
  522. },
  523. {
  524. /* NIST: Curve K-233 : y^2+xy=x^3+ax^2+b */
  525. CURVE_K_233,
  526. 59, /* Echar 59 */
  527. "00000000000000000000000000000000000000000000000000000000000",
  528. "00000000000000000000000000000000000000000000000000000000001",
  529. "17232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126",
  530. "1db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3",
  531. 68, /* Epl */
  532. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  533. 70, /* Eol */
  534. "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", /* "3450873173395281893717377931138512760570940988862252126328087024741343" */
  535. 233, /* key_len */
  536. 74,
  537. 74,
  538. 74,
  539. CURVE_GF_2M
  540. },
  541. {
  542. /* NIST: Curve K-283 : y^2+xy=x^3+ax^2+b */
  543. CURVE_K_283,
  544. 71, /* Echar */
  545. "00000000000000000000000000000000000000000000000000000000000000000000000",
  546. "00000000000000000000000000000000000000000000000000000000000000000000001",
  547. "503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836",
  548. "1ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259",
  549. 68, /* Epl */
  550. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  551. 85, /* Eol */
  552. "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", /* "3885337784451458141838923813647037813284811733793061324295874997529815829704422603873" */
  553. 283, /* key_len */
  554. 12,
  555. 7,
  556. 5,
  557. CURVE_GF_2M
  558. },
  559. {
  560. /* NIST: Curve K-409 : y^2+xy=x^3+ax^2+b */
  561. CURVE_K_409,
  562. 103, /* Echar */
  563. "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  564. "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  565. "060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746",
  566. "1e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b",
  567. 68, /* Epl */
  568. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  569. 123, /* Eol */
  570. "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", /* "330527984395124299475957654016385519914202341482140609642324395022880711289249191050673258457777458014096366590617731358671" */
  571. 409, /* key_len */
  572. 87,
  573. 87,
  574. 87,
  575. CURVE_GF_2M
  576. },
  577. {
  578. /* NIST: Curve K-571 : y^2+xy=x^3+ax^2+b */
  579. CURVE_K_571,
  580. 143, /* Echar */
  581. "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  582. "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
  583. "26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972",
  584. "349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3",
  585. 68, /* Epl */
  586. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* "26959946667150639794667015087019630673557916260026308143510066298881" */
  587. 172, /* Eol */
  588. "20000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", /* "1932268761508629172347675945465993672149463664853217499328617625725759571144780212268133978522706711834706712800825351461273674974066617311929682421617092503555733685276673" */
  589. 571, /* key_len */
  590. 10,
  591. 5,
  592. 2,
  593. CURVE_GF_2M
  594. },
  595. {
  596. /* Koblitz: Curve secp192k1 : y2 = x3+ax+b over Fp */
  597. CURVE_KO_192,
  598. 48, /* Echar */
  599. "00000000000000000000000000000000000000000",
  600. "00000000000000000000000000000000000000003",
  601. "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
  602. "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
  603. 58, /* Epl */
  604. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* p */
  605. 58, /* Eol */
  606. "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* n */
  607. 192, /* key_len */
  608. 7,
  609. 2,
  610. 1,
  611. CURVE_GF_P
  612. },
  613. {
  614. /* Koblitz: Curve secp224k1 : y2 = x3+ax+b over Fp */
  615. CURVE_KO_224,
  616. 56, /* Echar */
  617. "00000000000000000000000000000000000000000000000000000000",
  618. "00000000000000000000000000000000000000000000000000000005",
  619. "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
  620. "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
  621. 70, /* Epl */
  622. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* p */
  623. 70, /* Eol */
  624. "0000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", /* n */
  625. 224, /* key_len */
  626. 7,
  627. 2,
  628. 1,
  629. CURVE_GF_P
  630. },
  631. {
  632. /* Koblitz: Curve secp256k1 : y2 = x3+ax+b over Fp */
  633. CURVE_KO_256,
  634. 64, /* Echar */
  635. "0000000000000000000000000000000000000000000000000000000000000000",
  636. "0000000000000000000000000000000000000000000000000000000000000007",
  637. "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
  638. "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
  639. 78, /* Epl */
  640. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* p */
  641. 78, /* Eol */
  642. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* n */
  643. 256, /* key_len */
  644. 7,
  645. 2,
  646. 1,
  647. CURVE_GF_P
  648. },
  649. {
  650. /* Brainpool: Curve brainpoolP256r1 */
  651. CURVE_BP_256,
  652. 64, /* Echar */
  653. "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A */
  654. "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B */
  655. "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* x */
  656. "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* y */
  657. 78, /* Epl */
  658. "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* p */
  659. 78, /* Eol */
  660. "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* q */
  661. 256, /* key_len */
  662. 7,
  663. 2,
  664. 1,
  665. CURVE_GF_P
  666. },
  667. {
  668. /* Brainpool: Curve brainpoolP384r1 */
  669. CURVE_BP_384,
  670. 96, /* Echar */
  671. "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A */
  672. "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B */
  673. "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* x */
  674. "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* y */
  675. 116, /* Epl */
  676. "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* p */
  677. 116, /* Eol */
  678. "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* q */
  679. 384, /* key_len */
  680. 7,
  681. 2,
  682. 1,
  683. CURVE_GF_P
  684. },
  685. {
  686. /* Brainpool: Curve brainpoolP512r1 */
  687. CURVE_BP_512,
  688. 128, /* Echar */
  689. "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A */
  690. "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B */
  691. "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* x */
  692. "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* y */
  693. 156, /* Epl */
  694. "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* p */
  695. 156, /* Eol */
  696. "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* q */
  697. 512, /* key_len */
  698. 7,
  699. 2,
  700. 1,
  701. CURVE_GF_P
  702. },
  703. };
  704. static ECC_CURVE *pCurve;
  705. static ECC_CURVE Curve_Copy;
  706. static ECC_CURVE *get_curve(E_ECC_CURVE ecc_curve);
  707. static int32_t ecc_init_curve(CRPT_T *crpt, E_ECC_CURVE ecc_curve);
  708. static void run_ecc_codec(CRPT_T *crpt, uint32_t mode);
  709. static char temp_hex_str[160];
  710. #if ENABLE_DEBUG
  711. static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count)
  712. {
  713. int32_t i;
  714. printf("%s => ", str);
  715. for (i = 0; i < count; i++)
  716. {
  717. printf("0x%08x ", regs[i]);
  718. }
  719. printf("\n");
  720. }
  721. #else
  722. static void dump_ecc_reg(char *str, uint32_t volatile regs[], int32_t count)
  723. {
  724. }
  725. #endif
  726. static char ch2hex(char ch)
  727. {
  728. if (ch <= '9')
  729. {
  730. ch = ch - '0';
  731. }
  732. else if ((ch <= 'z') && (ch >= 'a'))
  733. {
  734. ch = ch - 'a' + 10U;
  735. }
  736. else
  737. {
  738. ch = ch - 'A' + 10U;
  739. }
  740. return ch;
  741. }
  742. static void Hex2Reg(char input[], uint32_t volatile reg[])
  743. {
  744. char hex;
  745. int si, ri;
  746. uint32_t i, val32;
  747. si = (int)strlen(input) - 1;
  748. ri = 0;
  749. while (si >= 0)
  750. {
  751. val32 = 0UL;
  752. for (i = 0UL; (i < 8UL) && (si >= 0); i++)
  753. {
  754. hex = ch2hex(input[si]);
  755. val32 |= (uint32_t)hex << (i * 4UL);
  756. si--;
  757. }
  758. reg[ri++] = val32;
  759. }
  760. }
  761. static void Hex2RegEx(char input[], uint32_t volatile reg[], int shift)
  762. {
  763. uint32_t hex, carry;
  764. int si, ri;
  765. uint32_t i, val32;
  766. si = (int)strlen(input) - 1;
  767. ri = 0L;
  768. carry = 0UL;
  769. while (si >= 0)
  770. {
  771. val32 = 0UL;
  772. for (i = 0UL; (i < 8UL) && (si >= 0L); i++)
  773. {
  774. hex = (uint32_t)ch2hex(input[si]);
  775. hex <<= shift;
  776. val32 |= (uint32_t)((hex & 0xFUL) | carry) << (i * 4UL);
  777. carry = (hex >> 4UL) & 0xFUL;
  778. si--;
  779. }
  780. reg[ri++] = val32;
  781. }
  782. if (carry != 0UL)
  783. {
  784. reg[ri] = carry;
  785. }
  786. }
  787. /**
  788. * @brief Extract specified nibble from an unsigned word in character format.
  789. * For example:
  790. * Suppose val32 is 0x786543210, get_Nth_nibble_char(val32, 3) will return a '3'.
  791. * @param[in] val32 The input unsigned word
  792. * @param[in] idx The Nth nibble to be extracted.
  793. * @return The nibble in character format.
  794. */
  795. static char get_Nth_nibble_char(uint32_t val32, uint32_t idx)
  796. {
  797. return hex_char_tbl[(val32 >> (idx * 4U)) & 0xfU ];
  798. }
  799. static void Reg2Hex(int32_t count, uint32_t volatile reg[], char output[])
  800. {
  801. int32_t idx, ri;
  802. uint32_t i;
  803. output[count] = 0U;
  804. idx = count - 1;
  805. for (ri = 0; idx >= 0; ri++)
  806. {
  807. for (i = 0UL; (i < 8UL) && (idx >= 0); i++)
  808. {
  809. output[idx] = get_Nth_nibble_char(reg[ri], i);
  810. idx--;
  811. }
  812. }
  813. }
  814. static ECC_CURVE *get_curve(E_ECC_CURVE ecc_curve)
  815. {
  816. uint32_t i;
  817. ECC_CURVE *ret = NULL;
  818. for (i = 0UL; i < sizeof(_Curve) / sizeof(ECC_CURVE); i++)
  819. {
  820. if (ecc_curve == _Curve[i].curve_id)
  821. {
  822. memcpy((char *)&Curve_Copy, &_Curve[i], sizeof(ECC_CURVE));
  823. ret = &Curve_Copy; /* (ECC_CURVE *)&_Curve[i]; */
  824. }
  825. if (ret != NULL)
  826. {
  827. break;
  828. }
  829. }
  830. return ret;
  831. }
  832. static int32_t ecc_init_curve(CRPT_T *crpt, E_ECC_CURVE ecc_curve)
  833. {
  834. int32_t i, ret = 0;
  835. pCurve = get_curve(ecc_curve);
  836. if (pCurve == NULL)
  837. {
  838. CRPT_DBGMSG("Cannot find curve %d!!\n", ecc_curve);
  839. ret = -1;
  840. }
  841. if (ret == 0)
  842. {
  843. for (i = 0; i < 18; i++)
  844. {
  845. crpt->ECC_A[i] = 0UL;
  846. crpt->ECC_B[i] = 0UL;
  847. crpt->ECC_X1[i] = 0UL;
  848. crpt->ECC_Y1[i] = 0UL;
  849. crpt->ECC_N[i] = 0UL;
  850. }
  851. Hex2Reg(pCurve->Ea, crpt->ECC_A);
  852. Hex2Reg(pCurve->Eb, crpt->ECC_B);
  853. Hex2Reg(pCurve->Px, crpt->ECC_X1);
  854. Hex2Reg(pCurve->Py, crpt->ECC_Y1);
  855. CRPT_DBGMSG("Key length = %d\n", pCurve->key_len);
  856. dump_ecc_reg("CRPT_ECC_CURVE_A", crpt->ECC_A, 10);
  857. dump_ecc_reg("CRPT_ECC_CURVE_B", crpt->ECC_B, 10);
  858. dump_ecc_reg("CRPT_ECC_POINT_X1", crpt->ECC_X1, 10);
  859. dump_ecc_reg("CRPT_ECC_POINT_Y1", crpt->ECC_Y1, 10);
  860. if (pCurve->GF == (int)CURVE_GF_2M)
  861. {
  862. crpt->ECC_N[0] = 0x1UL;
  863. crpt->ECC_N[(pCurve->key_len) / 32] |= (1UL << ((pCurve->key_len) % 32));
  864. crpt->ECC_N[(pCurve->irreducible_k1) / 32] |= (1UL << ((pCurve->irreducible_k1) % 32));
  865. crpt->ECC_N[(pCurve->irreducible_k2) / 32] |= (1UL << ((pCurve->irreducible_k2) % 32));
  866. crpt->ECC_N[(pCurve->irreducible_k3) / 32] |= (1UL << ((pCurve->irreducible_k3) % 32));
  867. }
  868. else
  869. {
  870. Hex2Reg(pCurve->Pp, crpt->ECC_N);
  871. }
  872. }
  873. dump_ecc_reg("CRPT_ECC_CURVE_N", crpt->ECC_N, 10);
  874. return ret;
  875. }
  876. static int get_nibble_value(char c)
  877. {
  878. if ((c >= '0') && (c <= '9'))
  879. {
  880. c = c - '0';
  881. }
  882. if ((c >= 'a') && (c <= 'f'))
  883. {
  884. c = c - 'a' + (char)10;
  885. }
  886. if ((c >= 'A') && (c <= 'F'))
  887. {
  888. c = c - 'A' + (char)10;
  889. }
  890. return (int)c;
  891. }
  892. static int ecc_strcmp(char *s1, char *s2)
  893. {
  894. char c1, c2;
  895. while (*s1 == '0') s1++;
  896. while (*s2 == '0') s2++;
  897. for (; *s1 || *s2; s1++, s2++)
  898. {
  899. if ((*s1 >= 'A') && (*s1 <= 'Z'))
  900. c1 = *s1 + 32;
  901. else
  902. c1 = *s1;
  903. if ((*s2 >= 'A') && (*s2 <= 'Z'))
  904. c2 = *s2 + 32;
  905. else
  906. c2 = *s2;
  907. if (c1 != c2)
  908. return 1;
  909. }
  910. return 0;
  911. }
  912. volatile uint32_t g_ECC_done, g_ECCERR_done;
  913. /** @endcond HIDDEN_SYMBOLS */
  914. /**
  915. * @brief ECC interrupt service routine. User application must invoke this function in
  916. * his CRYPTO_IRQHandler() to let Crypto driver know ECC processing was done.
  917. * @param[in] crpt Reference to Crypto module.
  918. * @return none
  919. */
  920. void ECC_Complete(CRPT_T *crpt)
  921. {
  922. if (crpt->INTSTS & CRPT_INTSTS_ECCIF_Msk)
  923. {
  924. g_ECC_done = 1UL;
  925. crpt->INTSTS = CRPT_INTSTS_ECCIF_Msk;
  926. /* printf("ECC done IRQ.\n"); */
  927. }
  928. if (crpt->INTSTS & CRPT_INTSTS_ECCEIF_Msk)
  929. {
  930. g_ECCERR_done = 1UL;
  931. crpt->INTSTS = CRPT_INTSTS_ECCEIF_Msk;
  932. /* printf("ECCERRIF is set!!\n"); */
  933. }
  934. }
  935. /**
  936. * @brief Check if the private key is located in valid range of curve.
  937. * @param[in] crpt Reference to Crypto module.
  938. * @param[in] ecc_curve The pre-defined ECC curve.
  939. * @param[in] private_k The input private key.
  940. * @return 1 Is valid.
  941. * @return 0 Is not valid.
  942. * @return -1 Invalid curve.
  943. */
  944. int ECC_IsPrivateKeyValid(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char private_k[])
  945. {
  946. uint32_t i;
  947. int ret = -1;
  948. pCurve = get_curve(ecc_curve);
  949. if (pCurve == NULL)
  950. {
  951. ret = -1;
  952. }
  953. if (strlen(private_k) < strlen(pCurve->Eorder))
  954. {
  955. ret = 1;
  956. }
  957. if (strlen(private_k) > strlen(pCurve->Eorder))
  958. {
  959. ret = 0;
  960. }
  961. for (i = 0UL; i < strlen(private_k); i++)
  962. {
  963. if (get_nibble_value(private_k[i]) < get_nibble_value(pCurve->Eorder[i]))
  964. {
  965. ret = 1;
  966. break;
  967. }
  968. if (get_nibble_value(private_k[i]) > get_nibble_value(pCurve->Eorder[i]))
  969. {
  970. ret = 0;
  971. break;
  972. }
  973. }
  974. return ret;
  975. }
  976. /**
  977. * @brief Given a private key and curve to generate the public key pair.
  978. * @param[in] crpt Reference to Crypto module.
  979. * @param[in] private_k The input private key.
  980. * @param[in] ecc_curve The pre-defined ECC curve.
  981. * @param[out] public_k1 The output public key 1.
  982. * @param[out] public_k2 The output public key 2.
  983. * @return 0 Success.
  984. * @return -1 "ecc_curve" value is invalid.
  985. */
  986. int32_t ECC_GeneratePublicKey(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *private_k, char public_k1[], char public_k2[])
  987. {
  988. int32_t i, ret = 0;
  989. if (ecc_init_curve(crpt, ecc_curve) != 0)
  990. {
  991. ret = -1;
  992. }
  993. if (ret == 0)
  994. {
  995. for (i = 0; i < 18; i++)
  996. {
  997. crpt->ECC_K[i] = 0UL;
  998. }
  999. Hex2Reg(private_k, crpt->ECC_K);
  1000. /* set FSEL (Field selection) */
  1001. if (pCurve->GF == (int)CURVE_GF_2M)
  1002. {
  1003. crpt->ECC_CTL = 0UL;
  1004. }
  1005. else
  1006. {
  1007. /* CURVE_GF_P */
  1008. crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
  1009. }
  1010. g_ECC_done = g_ECCERR_done = 0UL;
  1011. crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
  1012. ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
  1013. while ((g_ECC_done | g_ECCERR_done) == 0UL)
  1014. {
  1015. }
  1016. Reg2Hex(pCurve->Echar, crpt->ECC_X1, public_k1);
  1017. Reg2Hex(pCurve->Echar, crpt->ECC_Y1, public_k2);
  1018. }
  1019. return ret;
  1020. }
  1021. /**
  1022. * @brief Given a private key and curve to generate the public key pair.
  1023. * @param[in] crpt Reference to Crypto module.
  1024. * @param[out] x1 The x-coordinate of input point.
  1025. * @param[out] y1 The y-coordinate of input point.
  1026. * @param[in] k The private key
  1027. * @param[in] ecc_curve The pre-defined ECC curve.
  1028. * @param[out] x2 The x-coordinate of output point.
  1029. * @param[out] y2 The y-coordinate of output point.
  1030. * @return 0 Success.
  1031. * @return -1 "ecc_curve" value is invalid.
  1032. */
  1033. int32_t ECC_Mutiply(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char x1[], char y1[], char *k, char x2[], char y2[])
  1034. {
  1035. int32_t i, ret = 0;
  1036. if (ecc_init_curve(crpt, ecc_curve) != 0)
  1037. {
  1038. ret = -1;
  1039. }
  1040. if (ret == 0)
  1041. {
  1042. for (i = 0; i < 18; i++)
  1043. {
  1044. crpt->ECC_X1[i] = 0UL;
  1045. crpt->ECC_Y1[i] = 0UL;
  1046. crpt->ECC_K[i] = 0UL;
  1047. }
  1048. Hex2Reg(x1, crpt->ECC_X1);
  1049. Hex2Reg(y1, crpt->ECC_Y1);
  1050. Hex2Reg(k, crpt->ECC_K);
  1051. /* set FSEL (Field selection) */
  1052. if (pCurve->GF == (int)CURVE_GF_2M)
  1053. {
  1054. crpt->ECC_CTL = 0UL;
  1055. }
  1056. else
  1057. {
  1058. /* CURVE_GF_P */
  1059. crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
  1060. }
  1061. g_ECC_done = g_ECCERR_done = 0UL;
  1062. crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
  1063. ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
  1064. while ((g_ECC_done | g_ECCERR_done) == 0UL)
  1065. {
  1066. }
  1067. Reg2Hex(pCurve->Echar, crpt->ECC_X1, x2);
  1068. Reg2Hex(pCurve->Echar, crpt->ECC_Y1, y2);
  1069. }
  1070. return ret;
  1071. }
  1072. /**
  1073. * @brief Given a curve parameter, the other party's public key, and one's own private key to generate the secret Z.
  1074. * @param[in] crpt Reference to Crypto module.
  1075. * @param[in] ecc_curve The pre-defined ECC curve.
  1076. * @param[in] private_k One's own private key.
  1077. * @param[in] public_k1 The other party's publick key 1.
  1078. * @param[in] public_k2 The other party's publick key 2.
  1079. * @param[out] secret_z The ECC CDH secret Z.
  1080. * @return 0 Success.
  1081. * @return -1 "ecc_curve" value is invalid.
  1082. */
  1083. int32_t ECC_GenerateSecretZ(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *private_k, char public_k1[], char public_k2[], char secret_z[])
  1084. {
  1085. int32_t i, ret = 0;
  1086. if (ecc_init_curve(crpt, ecc_curve) != 0)
  1087. {
  1088. ret = -1;
  1089. }
  1090. if (ret == 0)
  1091. {
  1092. for (i = 0; i < 18; i++)
  1093. {
  1094. crpt->ECC_K[i] = 0UL;
  1095. crpt->ECC_X1[i] = 0UL;
  1096. crpt->ECC_Y1[i] = 0UL;
  1097. }
  1098. if ((ecc_curve == CURVE_B_163) || (ecc_curve == CURVE_B_233) || (ecc_curve == CURVE_B_283) ||
  1099. (ecc_curve == CURVE_B_409) || (ecc_curve == CURVE_B_571) || (ecc_curve == CURVE_K_163))
  1100. {
  1101. Hex2RegEx(private_k, crpt->ECC_K, 1);
  1102. }
  1103. else if ((ecc_curve == CURVE_K_233) || (ecc_curve == CURVE_K_283) ||
  1104. (ecc_curve == CURVE_K_409) || (ecc_curve == CURVE_K_571))
  1105. {
  1106. Hex2RegEx(private_k, crpt->ECC_K, 2);
  1107. }
  1108. else
  1109. {
  1110. Hex2Reg(private_k, crpt->ECC_K);
  1111. }
  1112. Hex2Reg(public_k1, crpt->ECC_X1);
  1113. Hex2Reg(public_k2, crpt->ECC_Y1);
  1114. /* set FSEL (Field selection) */
  1115. if (pCurve->GF == (int)CURVE_GF_2M)
  1116. {
  1117. crpt->ECC_CTL = 0UL;
  1118. }
  1119. else
  1120. {
  1121. /* CURVE_GF_P */
  1122. crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
  1123. }
  1124. g_ECC_done = g_ECCERR_done = 0UL;
  1125. crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) |
  1126. ECCOP_POINT_MUL | CRPT_ECC_CTL_START_Msk;
  1127. while ((g_ECC_done | g_ECCERR_done) == 0UL)
  1128. {
  1129. }
  1130. Reg2Hex(pCurve->Echar, crpt->ECC_X1, secret_z);
  1131. }
  1132. return ret;
  1133. }
  1134. /** @cond HIDDEN_SYMBOLS */
  1135. static void run_ecc_codec(CRPT_T *crpt, uint32_t mode)
  1136. {
  1137. if ((mode & CRPT_ECC_CTL_ECCOP_Msk) == ECCOP_MODULE)
  1138. {
  1139. crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
  1140. }
  1141. else
  1142. {
  1143. if (pCurve->GF == (int)CURVE_GF_2M)
  1144. {
  1145. /* point */
  1146. crpt->ECC_CTL = 0UL;
  1147. }
  1148. else
  1149. {
  1150. /* CURVE_GF_P */
  1151. crpt->ECC_CTL = CRPT_ECC_CTL_FSEL_Msk;
  1152. }
  1153. }
  1154. g_ECC_done = g_ECCERR_done = 0UL;
  1155. crpt->ECC_CTL |= ((uint32_t)pCurve->key_len << CRPT_ECC_CTL_CURVEM_Pos) | mode | CRPT_ECC_CTL_START_Msk;
  1156. while ((g_ECC_done | g_ECCERR_done) == 0UL)
  1157. {
  1158. }
  1159. while (crpt->ECC_STS & CRPT_ECC_STS_BUSY_Msk)
  1160. {
  1161. }
  1162. }
  1163. /** @endcond HIDDEN_SYMBOLS */
  1164. /**
  1165. * @brief ECDSA digital signature generation.
  1166. * @param[in] crpt Reference to Crypto module.
  1167. * @param[in] ecc_curve The pre-defined ECC curve.
  1168. * @param[in] message The hash value of source context.
  1169. * @param[in] d The private key.
  1170. * @param[in] k The selected random integer.
  1171. * @param[out] R R of the (R,S) pair digital signature
  1172. * @param[out] S S of the (R,S) pair digital signature
  1173. * @return 0 Success.
  1174. * @return -1 "ecc_curve" value is invalid.
  1175. */
  1176. int32_t ECC_GenerateSignature(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message,
  1177. char *d, char *k, char *R, char *S)
  1178. {
  1179. uint32_t volatile temp_result1[18], temp_result2[18];
  1180. int32_t i, ret = 0;
  1181. if (ecc_init_curve(crpt, ecc_curve) != 0)
  1182. {
  1183. ret = -1;
  1184. }
  1185. if (ret == 0)
  1186. {
  1187. /*
  1188. * 1. Calculate e = HASH(m), where HASH is a cryptographic hashing algorithm, (i.e. SHA-1)
  1189. * (1) Use SHA to calculate e
  1190. */
  1191. /* 2. Select a random integer k form [1, n-1]
  1192. * (1) Notice that n is order, not prime modulus or irreducible polynomial function
  1193. */
  1194. /*
  1195. * 3. Compute r = x1 (mod n), where (x1, y1) = k * G. If r = 0, go to step 2
  1196. * (1) Write the curve parameter A, B, and curve length M to corresponding registers
  1197. * (2) Write the prime modulus or irreducible polynomial function to N registers according
  1198. * (3) Write the point G(x, y) to X1, Y1 registers
  1199. * (4) Write the random integer k to K register
  1200. * (5) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
  1201. * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
  1202. * (7) Set START(CRPT_ECC_CTL[0]) to 1
  1203. * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1204. * (9) Write the curve order and curve length to N ,M registers according
  1205. * (10) Write 0x0 to Y1 registers
  1206. * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1207. * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
  1208. * (13) Set START(CRPT_ECC_CTL[0]) to 1 *
  1209. * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1210. * (15) Read X1 registers to get r
  1211. */
  1212. /* 3-(4) Write the random integer k to K register */
  1213. for (i = 0; i < 18; i++)
  1214. {
  1215. crpt->ECC_K[i] = 0UL;
  1216. }
  1217. Hex2Reg(k, crpt->ECC_K);
  1218. run_ecc_codec(crpt, ECCOP_POINT_MUL);
  1219. /* 3-(9) Write the curve order to N registers */
  1220. for (i = 0; i < 18; i++)
  1221. {
  1222. crpt->ECC_N[i] = 0UL;
  1223. }
  1224. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1225. /* 3-(10) Write 0x0 to Y1 registers */
  1226. for (i = 0; i < 18; i++)
  1227. {
  1228. crpt->ECC_Y1[i] = 0UL;
  1229. }
  1230. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
  1231. /* 3-(15) Read X1 registers to get r */
  1232. for (i = 0; i < 18; i++)
  1233. {
  1234. temp_result1[i] = crpt->ECC_X1[i];
  1235. }
  1236. Reg2Hex(pCurve->Echar, temp_result1, R);
  1237. /*
  1238. * 4. Compute s = k ? 1 * (e + d * r)(mod n). If s = 0, go to step 2
  1239. * (1) Write the curve order to N registers according
  1240. * (2) Write 0x1 to Y1 registers
  1241. * (3) Write the random integer k to X1 registers according
  1242. * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1243. * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
  1244. * (6) Set START(CRPT_ECC_CTL[0]) to 1
  1245. * (7) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1246. * (8) Read X1 registers to get k^-1
  1247. * (9) Write the curve order and curve length to N ,M registers
  1248. * (10) Write r, d to X1, Y1 registers
  1249. * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1250. * (12) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
  1251. * (13) Set START(CRPT_ECC_CTL[0]) to 1
  1252. * (14) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1253. * (15) Write the curve order to N registers
  1254. * (16) Write e to Y1 registers
  1255. * (17) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1256. * (18) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
  1257. * (19) Set START(CRPT_ECC_CTL[0]) to 1
  1258. * (20) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1259. * (21) Write the curve order and curve length to N ,M registers
  1260. * (22) Write k^-1 to Y1 registers
  1261. * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1262. * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
  1263. * (25) Set START(CRPT_ECC_CTL[0]) to 1
  1264. * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1265. * (27) Read X1 registers to get s
  1266. */
  1267. /* S/W: GFp_add_mod_order(pCurve->key_len+2, 0, x1, a, R); */
  1268. /* 4-(1) Write the curve order to N registers */
  1269. for (i = 0; i < 18; i++)
  1270. {
  1271. crpt->ECC_N[i] = 0UL;
  1272. }
  1273. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1274. /* 4-(2) Write 0x1 to Y1 registers */
  1275. for (i = 0; i < 18; i++)
  1276. {
  1277. crpt->ECC_Y1[i] = 0UL;
  1278. }
  1279. crpt->ECC_Y1[0] = 0x1UL;
  1280. /* 4-(3) Write the random integer k to X1 registers */
  1281. for (i = 0; i < 18; i++)
  1282. {
  1283. crpt->ECC_X1[i] = 0UL;
  1284. }
  1285. Hex2Reg(k, crpt->ECC_X1);
  1286. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
  1287. #if ENABLE_DEBUG
  1288. Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
  1289. CRPT_DBGMSG("(7) output = %s\n", temp_hex_str);
  1290. #endif
  1291. /* 4-(8) Read X1 registers to get k^-1 */
  1292. for (i = 0; i < 18; i++)
  1293. {
  1294. temp_result2[i] = crpt->ECC_X1[i];
  1295. }
  1296. #if ENABLE_DEBUG
  1297. Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
  1298. CRPT_DBGMSG("k^-1 = %s\n", temp_hex_str);
  1299. #endif
  1300. /* 4-(9) Write the curve order and curve length to N ,M registers */
  1301. for (i = 0; i < 18; i++)
  1302. {
  1303. crpt->ECC_N[i] = 0UL;
  1304. }
  1305. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1306. /* 4-(10) Write r, d to X1, Y1 registers */
  1307. for (i = 0; i < 18; i++)
  1308. {
  1309. crpt->ECC_X1[i] = temp_result1[i];
  1310. }
  1311. for (i = 0; i < 18; i++)
  1312. {
  1313. crpt->ECC_Y1[i] = 0UL;
  1314. }
  1315. Hex2Reg(d, crpt->ECC_Y1);
  1316. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
  1317. #if ENABLE_DEBUG
  1318. Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
  1319. CRPT_DBGMSG("(14) output = %s\n", temp_hex_str);
  1320. #endif
  1321. /* 4-(15) Write the curve order to N registers */
  1322. for (i = 0; i < 18; i++)
  1323. {
  1324. crpt->ECC_N[i] = 0UL;
  1325. }
  1326. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1327. /* 4-(16) Write e to Y1 registers */
  1328. for (i = 0; i < 18; i++)
  1329. {
  1330. crpt->ECC_Y1[i] = 0UL;
  1331. }
  1332. Hex2Reg(message, crpt->ECC_Y1);
  1333. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
  1334. #if ENABLE_DEBUG
  1335. Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
  1336. CRPT_DBGMSG("(20) output = %s\n", temp_hex_str);
  1337. #endif
  1338. /* 4-(21) Write the curve order and curve length to N ,M registers */
  1339. for (i = 0; i < 18; i++)
  1340. {
  1341. crpt->ECC_N[i] = 0UL;
  1342. }
  1343. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1344. /* 4-(22) Write k^-1 to Y1 registers */
  1345. for (i = 0; i < 18; i++)
  1346. {
  1347. crpt->ECC_Y1[i] = temp_result2[i];
  1348. }
  1349. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
  1350. /* 4-(27) Read X1 registers to get s */
  1351. for (i = 0; i < 18; i++)
  1352. {
  1353. temp_result2[i] = crpt->ECC_X1[i];
  1354. }
  1355. Reg2Hex(pCurve->Echar, temp_result2, S);
  1356. } /* ret == 0 */
  1357. return ret;
  1358. }
  1359. /**
  1360. * @brief ECDSA dogotal signature verification.
  1361. * @param[in] crpt Reference to Crypto module.
  1362. * @param[in] ecc_curve The pre-defined ECC curve.
  1363. * @param[in] message The hash value of source context.
  1364. * @param[in] public_k1 The public key 1.
  1365. * @param[in] public_k2 The public key 2.
  1366. * @param[in] R R of the (R,S) pair digital signature
  1367. * @param[in] S S of the (R,S) pair digital signature
  1368. * @return 0 Success.
  1369. * @return -1 "ecc_curve" value is invalid.
  1370. * @return -2 Verification failed.
  1371. */
  1372. int32_t ECC_VerifySignature(CRPT_T *crpt, E_ECC_CURVE ecc_curve, char *message,
  1373. char *public_k1, char *public_k2, char *R, char *S)
  1374. {
  1375. uint32_t temp_result1[18], temp_result2[18];
  1376. uint32_t temp_x[18], temp_y[18];
  1377. int32_t i, ret = 0;
  1378. /*
  1379. * 1. Verify that r and s are integers in the interval [1, n-1]. If not, the signature is invalid
  1380. * 2. Compute e = HASH (m), where HASH is the hashing algorithm in signature generation
  1381. * (1) Use SHA to calculate e
  1382. */
  1383. /*
  1384. * 3. Compute w = s^-1 (mod n)
  1385. * (1) Write the curve order to N registers
  1386. * (2) Write 0x1 to Y1 registers
  1387. * (3) Write s to X1 registers
  1388. * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1389. * (5) Set MOPOP(CRPT_ECC_CTL[12:11]) to 00
  1390. * (6) Set FSEL(CRPT_ECC_CTL[8]) according to used curve of prime field or binary field
  1391. * (7) Set START(CRPT_ECC_CTL[0]) to 1
  1392. * (8) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1393. * (9) Read X1 registers to get w
  1394. */
  1395. if (ecc_init_curve(crpt, ecc_curve) != 0)
  1396. {
  1397. ret = -1;
  1398. }
  1399. if (ret == 0)
  1400. {
  1401. /* 3-(1) Write the curve order to N registers */
  1402. for (i = 0; i < 18; i++)
  1403. {
  1404. crpt->ECC_N[i] = 0UL;
  1405. }
  1406. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1407. /* 3-(2) Write 0x1 to Y1 registers */
  1408. for (i = 0; i < 18; i++)
  1409. {
  1410. crpt->ECC_Y1[i] = 0UL;
  1411. }
  1412. crpt->ECC_Y1[0] = 0x1UL;
  1413. /* 3-(3) Write s to X1 registers */
  1414. for (i = 0; i < 18; i++)
  1415. {
  1416. crpt->ECC_X1[i] = 0UL;
  1417. }
  1418. Hex2Reg(S, crpt->ECC_X1);
  1419. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_DIV);
  1420. /* 3-(9) Read X1 registers to get w */
  1421. for (i = 0; i < 18; i++)
  1422. {
  1423. temp_result2[i] = crpt->ECC_X1[i];
  1424. }
  1425. #if ENABLE_DEBUG
  1426. CRPT_DBGMSG("e = %s\n", message);
  1427. Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
  1428. CRPT_DBGMSG("w = %s\n", temp_hex_str);
  1429. CRPT_DBGMSG("o = %s (order)\n", pCurve->Eorder);
  1430. #endif
  1431. /*
  1432. * 4. Compute u1 = e * w (mod n) and u2 = r * w (mod n)
  1433. * (1) Write the curve order and curve length to N ,M registers
  1434. * (2) Write e, w to X1, Y1 registers
  1435. * (3) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1436. * (4) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
  1437. * (5) Set START(CRPT_ECC_CTL[0]) to 1
  1438. * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1439. * (7) Read X1 registers to get u1
  1440. * (8) Write the curve order and curve length to N ,M registers
  1441. * (9) Write r, w to X1, Y1 registers
  1442. * (10) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1443. * (11) Set MOPOP(CRPT_ECC_CTL[12:11]) to 01
  1444. * (12) Set START(CRPT_ECC_CTL[0]) to 1
  1445. * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1446. * (14) Read X1 registers to get u2
  1447. */
  1448. /* 4-(1) Write the curve order and curve length to N ,M registers */
  1449. for (i = 0; i < 18; i++)
  1450. {
  1451. crpt->ECC_N[i] = 0UL;
  1452. }
  1453. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1454. /* 4-(2) Write e, w to X1, Y1 registers */
  1455. for (i = 0; i < 18; i++)
  1456. {
  1457. crpt->ECC_X1[i] = 0UL;
  1458. }
  1459. Hex2Reg(message, crpt->ECC_X1);
  1460. for (i = 0; i < 18; i++)
  1461. {
  1462. crpt->ECC_Y1[i] = temp_result2[i];
  1463. }
  1464. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
  1465. /* 4-(7) Read X1 registers to get u1 */
  1466. for (i = 0; i < 18; i++)
  1467. {
  1468. temp_result1[i] = crpt->ECC_X1[i];
  1469. }
  1470. #if ENABLE_DEBUG
  1471. Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
  1472. CRPT_DBGMSG("u1 = %s\n", temp_hex_str);
  1473. #endif
  1474. /* 4-(8) Write the curve order and curve length to N ,M registers */
  1475. for (i = 0; i < 18; i++)
  1476. {
  1477. crpt->ECC_N[i] = 0UL;
  1478. }
  1479. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1480. /* 4-(9) Write r, w to X1, Y1 registers */
  1481. for (i = 0; i < 18; i++)
  1482. {
  1483. crpt->ECC_X1[i] = 0UL;
  1484. }
  1485. Hex2Reg(R, crpt->ECC_X1);
  1486. for (i = 0; i < 18; i++)
  1487. {
  1488. crpt->ECC_Y1[i] = temp_result2[i];
  1489. }
  1490. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_MUL);
  1491. /* 4-(14) Read X1 registers to get u2 */
  1492. for (i = 0; i < 18; i++)
  1493. {
  1494. temp_result2[i] = crpt->ECC_X1[i];
  1495. }
  1496. #if ENABLE_DEBUG
  1497. Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
  1498. CRPT_DBGMSG("u2 = %s\n", temp_hex_str);
  1499. #endif
  1500. /*
  1501. * 5. Compute X' (x1' y1') = u1 * G + u2 * Q
  1502. * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
  1503. * (2) Write the point G(x, y) to X1, Y1 registers
  1504. * (3) Write u1 to K registers
  1505. * (4) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
  1506. * (5) Set START(CRPT_ECC_CTL[0]) to 1
  1507. * (6) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1508. * (7) Read X1, Y1 registers to get u1*G
  1509. * (8) Write the curve parameter A, B, N, and curve length M to corresponding registers
  1510. * (9) Write the public key Q(x,y) to X1, Y1 registers
  1511. * (10) Write u2 to K registers
  1512. * (11) Set ECCOP(CRPT_ECC_CTL[10:9]) to 00
  1513. * (12) Set START(CRPT_ECC_CTL[0]) to 1
  1514. * (13) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1515. * (14) Write the curve parameter A, B, N, and curve length M to corresponding registers
  1516. * (15) Write the result data u1*G to X2, Y2 registers
  1517. * (16) Set ECCOP(CRPT_ECC_CTL[10:9]) to 10
  1518. * (17) Set START(CRPT_ECC_CTL[0]) to 1
  1519. * (18) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1520. * (19) Read X1, Y1 registers to get X('x1', y1')
  1521. * (20) Write the curve order and curve length to N ,M registers
  1522. * (21) Write x1' to X1 registers
  1523. * (22) Write 0x0 to Y1 registers
  1524. * (23) Set ECCOP(CRPT_ECC_CTL[10:9]) to 01
  1525. * (24) Set MOPOP(CRPT_ECC_CTL[12:11]) to 10
  1526. * (25) Set START(CRPT_ECC_CTL[0]) to 1
  1527. * (26) Wait for BUSY(CRPT_ECC_STS[0]) be cleared
  1528. * (27) Read X1 registers to get x1' (mod n)
  1529. *
  1530. * 6. The signature is valid if x1' = r, otherwise it is invalid
  1531. */
  1532. /*
  1533. * (1) Write the curve parameter A, B, N, and curve length M to corresponding registers
  1534. * (2) Write the point G(x, y) to X1, Y1 registers
  1535. */
  1536. ecc_init_curve(crpt, ecc_curve);
  1537. /* (3) Write u1 to K registers */
  1538. for (i = 0; i < 18; i++)
  1539. {
  1540. crpt->ECC_K[i] = temp_result1[i];
  1541. }
  1542. run_ecc_codec(crpt, ECCOP_POINT_MUL);
  1543. /* (7) Read X1, Y1 registers to get u1*G */
  1544. for (i = 0; i < 18; i++)
  1545. {
  1546. temp_x[i] = crpt->ECC_X1[i];
  1547. temp_y[i] = crpt->ECC_Y1[i];
  1548. }
  1549. #if ENABLE_DEBUG
  1550. Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
  1551. CRPT_DBGMSG("5-(7) u1*G, x = %s\n", temp_hex_str);
  1552. Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
  1553. CRPT_DBGMSG("5-(7) u1*G, y = %s\n", temp_hex_str);
  1554. #endif
  1555. /* (8) Write the curve parameter A, B, N, and curve length M to corresponding registers */
  1556. ecc_init_curve(crpt, ecc_curve);
  1557. /* (9) Write the public key Q(x,y) to X1, Y1 registers */
  1558. for (i = 0; i < 18; i++)
  1559. {
  1560. crpt->ECC_X1[i] = 0UL;
  1561. crpt->ECC_Y1[i] = 0UL;
  1562. }
  1563. Hex2Reg(public_k1, crpt->ECC_X1);
  1564. Hex2Reg(public_k2, crpt->ECC_Y1);
  1565. /* (10) Write u2 to K registers */
  1566. for (i = 0; i < 18; i++)
  1567. {
  1568. crpt->ECC_K[i] = temp_result2[i];
  1569. }
  1570. run_ecc_codec(crpt, ECCOP_POINT_MUL);
  1571. for (i = 0; i < 18; i++)
  1572. {
  1573. temp_result1[i] = crpt->ECC_X1[i];
  1574. temp_result2[i] = crpt->ECC_Y1[i];
  1575. }
  1576. #if ENABLE_DEBUG
  1577. Reg2Hex(pCurve->Echar, temp_result1, temp_hex_str);
  1578. CRPT_DBGMSG("5-(13) u2*Q, x = %s\n", temp_hex_str);
  1579. Reg2Hex(pCurve->Echar, temp_result2, temp_hex_str);
  1580. CRPT_DBGMSG("5-(13) u2*Q, y = %s\n", temp_hex_str);
  1581. #endif
  1582. /* (14) Write the curve parameter A, B, N, and curve length M to corresponding registers */
  1583. ecc_init_curve(crpt, ecc_curve);
  1584. /* Write the result data u2*Q to X1, Y1 registers */
  1585. for (i = 0; i < 18; i++)
  1586. {
  1587. crpt->ECC_X1[i] = temp_result1[i];
  1588. crpt->ECC_Y1[i] = temp_result2[i];
  1589. }
  1590. /* (15) Write the result data u1*G to X2, Y2 registers */
  1591. for (i = 0; i < 18; i++)
  1592. {
  1593. crpt->ECC_X2[i] = temp_x[i];
  1594. crpt->ECC_Y2[i] = temp_y[i];
  1595. }
  1596. run_ecc_codec(crpt, ECCOP_POINT_ADD);
  1597. /* (19) Read X1, Y1 registers to get X'(x1' y1') */
  1598. for (i = 0; i < 18; i++)
  1599. {
  1600. temp_x[i] = crpt->ECC_X1[i];
  1601. temp_y[i] = crpt->ECC_Y1[i];
  1602. }
  1603. #if ENABLE_DEBUG
  1604. Reg2Hex(pCurve->Echar, temp_x, temp_hex_str);
  1605. CRPT_DBGMSG("5-(19) x' = %s\n", temp_hex_str);
  1606. Reg2Hex(pCurve->Echar, temp_y, temp_hex_str);
  1607. CRPT_DBGMSG("5-(19) y' = %s\n", temp_hex_str);
  1608. #endif
  1609. /* (20) Write the curve order and curve length to N ,M registers */
  1610. for (i = 0; i < 18; i++)
  1611. {
  1612. crpt->ECC_N[i] = 0UL;
  1613. }
  1614. Hex2Reg(pCurve->Eorder, crpt->ECC_N);
  1615. /*
  1616. * (21) Write x1' to X1 registers
  1617. * (22) Write 0x0 to Y1 registers
  1618. */
  1619. for (i = 0; i < 18; i++)
  1620. {
  1621. crpt->ECC_X1[i] = temp_x[i];
  1622. crpt->ECC_Y1[i] = 0UL;
  1623. }
  1624. #if ENABLE_DEBUG
  1625. Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
  1626. CRPT_DBGMSG("5-(21) x' = %s\n", temp_hex_str);
  1627. Reg2Hex(pCurve->Echar, crpt->ECC_Y1, temp_hex_str);
  1628. CRPT_DBGMSG("5-(22) y' = %s\n", temp_hex_str);
  1629. #endif
  1630. run_ecc_codec(crpt, ECCOP_MODULE | MODOP_ADD);
  1631. /* (27) Read X1 registers to get x1' (mod n) */
  1632. Reg2Hex(pCurve->Echar, crpt->ECC_X1, temp_hex_str);
  1633. CRPT_DBGMSG("5-(27) x1' (mod n) = %s\n", temp_hex_str);
  1634. /* 6. The signature is valid if x1' = r, otherwise it is invalid */
  1635. /* Compare with test pattern to check if r is correct or not */
  1636. if (ecc_strcmp(temp_hex_str, R) != 0)
  1637. {
  1638. CRPT_DBGMSG("x1' (mod n) != R Test filed!!\n");
  1639. CRPT_DBGMSG("Signature R [%s] is not matched with expected R [%s]!\n", temp_hex_str, R);
  1640. ret = -2;
  1641. }
  1642. } /* ret == 0 */
  1643. return ret;
  1644. }
  1645. /*-----------------------------------------------------------------------------------------------*/
  1646. /* */
  1647. /* RSA */
  1648. /* */
  1649. /*-----------------------------------------------------------------------------------------------*/
  1650. /** @cond HIDDEN_SYMBOLS */
  1651. #define MAX_DIGIT 0xFFFFFFFFUL
  1652. #define MAX_HALF_DIGIT 0xFFFFUL /* NB 'L' */
  1653. #define BITS_PER_DIGIT 32
  1654. #define HIBITMASK 0x80000000UL
  1655. #define MAX_FIXED_BIT_LENGTH 8192
  1656. #define MAX_FIXED_DIGITS ((MAX_FIXED_BIT_LENGTH + BITS_PER_DIGIT - 1) / BITS_PER_DIGIT)
  1657. #ifndef max
  1658. #define max(a,b) (((a) > (b)) ? (a) : (b))
  1659. #endif
  1660. static uint32_t qq[MAX_FIXED_DIGITS * 2];
  1661. static uint32_t rr[MAX_FIXED_DIGITS * 2];
  1662. /** Returns number of significant digits in a */
  1663. static int mpSizeof(const uint32_t a[], int ndigits)
  1664. {
  1665. while (ndigits--)
  1666. {
  1667. if (a[ndigits] != 0)
  1668. return (++ndigits);
  1669. }
  1670. return 0;
  1671. }
  1672. static int mpBitLength(const uint32_t d[], int ndigits)
  1673. /* Returns no of significant bits in d */
  1674. {
  1675. int n, i, bits;
  1676. uint32_t mask;
  1677. if (!d || ndigits == 0)
  1678. return 0;
  1679. n = mpSizeof(d, ndigits);
  1680. if (0 == n) return 0;
  1681. for (i = 0, mask = HIBITMASK; mask > 0; mask >>= 1, i++)
  1682. {
  1683. if (d[n - 1] & mask)
  1684. break;
  1685. }
  1686. bits = n * BITS_PER_DIGIT - i;
  1687. return bits;
  1688. }
  1689. static int mpGetBit(const uint32_t a[], int ndigits, int ibit)
  1690. /* Returns value 1 or 0 of bit n (0..nbits-1); or -1 if out of range */
  1691. {
  1692. int idigit, bit_to_get;
  1693. uint32_t mask;
  1694. /* Which digit? (0-based) */
  1695. idigit = ibit / BITS_PER_DIGIT;
  1696. if (idigit >= ndigits)
  1697. return -1;
  1698. /* Set mask */
  1699. bit_to_get = ibit % BITS_PER_DIGIT;
  1700. mask = 0x01 << bit_to_get;
  1701. return ((a[idigit] & mask) ? 1 : 0);
  1702. }
  1703. static uint32_t mpSetZero(volatile uint32_t a[], int ndigits)
  1704. {
  1705. /* Sets a = 0 */
  1706. /* Prevent optimiser ignoring this */
  1707. volatile uint32_t optdummy;
  1708. volatile uint32_t *p = a;
  1709. while (ndigits--)
  1710. a[ndigits] = 0;
  1711. optdummy = *p;
  1712. return optdummy;
  1713. }
  1714. static void mpSetEqual(uint32_t a[], const uint32_t b[], int ndigits)
  1715. {
  1716. /* Sets a = b */
  1717. int i;
  1718. for (i = 0; i < ndigits; i++)
  1719. {
  1720. a[i] = b[i];
  1721. }
  1722. }
  1723. static void mpSetDigit(uint32_t a[], uint32_t d, int ndigits)
  1724. {
  1725. /* Sets a = d where d is a single digit */
  1726. int i;
  1727. for (i = 1; i < ndigits; i++)
  1728. {
  1729. a[i] = 0;
  1730. }
  1731. a[0] = d;
  1732. }
  1733. /** Returns sign of (a - b) as 0, +1 or -1. Not constant-time. */
  1734. static int mpCompare(const uint32_t a[], const uint32_t b[], int ndigits)
  1735. {
  1736. /* if (ndigits == 0) return 0; // deleted [v2.5] */
  1737. while (ndigits--)
  1738. {
  1739. if (a[ndigits] > b[ndigits])
  1740. return 1; /* GT */
  1741. if (a[ndigits] < b[ndigits])
  1742. return -1; /* LT */
  1743. }
  1744. return 0; /* EQ */
  1745. }
  1746. static uint32_t mpShiftLeft(uint32_t a[], const uint32_t *b,
  1747. int shift, int ndigits)
  1748. {
  1749. /* Computes a = b << shift */
  1750. /* [v2.1] Modified to cope with shift > BITS_PERDIGIT */
  1751. int i, y, nw, bits;
  1752. uint32_t mask, carry, nextcarry;
  1753. /* Do we shift whole digits? */
  1754. if (shift >= BITS_PER_DIGIT)
  1755. {
  1756. nw = shift / BITS_PER_DIGIT;
  1757. i = ndigits;
  1758. while (i--)
  1759. {
  1760. if (i >= nw)
  1761. a[i] = b[i - nw];
  1762. else
  1763. a[i] = 0;
  1764. }
  1765. /* Call again to shift bits inside digits */
  1766. bits = shift % BITS_PER_DIGIT;
  1767. carry = b[ndigits - nw] << bits;
  1768. if (bits)
  1769. carry |= mpShiftLeft(a, a, bits, ndigits);
  1770. return carry;
  1771. }
  1772. else
  1773. {
  1774. bits = shift;
  1775. }
  1776. /* Construct mask = high bits set */
  1777. mask = ~(~(uint32_t)0 >> bits);
  1778. y = BITS_PER_DIGIT - bits;
  1779. carry = 0;
  1780. for (i = 0; i < ndigits; i++)
  1781. {
  1782. nextcarry = (b[i] & mask) >> y;
  1783. a[i] = b[i] << bits | carry;
  1784. carry = nextcarry;
  1785. }
  1786. return carry;
  1787. }
  1788. static uint32_t mpShiftRight(uint32_t a[], const uint32_t b[], int shift, int ndigits)
  1789. {
  1790. /* Computes a = b >> shift */
  1791. /* [v2.1] Modified to cope with shift > BITS_PERDIGIT */
  1792. int i, y, nw, bits;
  1793. uint32_t mask, carry, nextcarry;
  1794. /* Do we shift whole digits? */
  1795. if (shift >= BITS_PER_DIGIT)
  1796. {
  1797. nw = shift / BITS_PER_DIGIT;
  1798. for (i = 0; i < ndigits; i++)
  1799. {
  1800. if ((i + nw) < ndigits)
  1801. a[i] = b[i + nw];
  1802. else
  1803. a[i] = 0;
  1804. }
  1805. /* Call again to shift bits inside digits */
  1806. bits = shift % BITS_PER_DIGIT;
  1807. carry = b[nw - 1] >> bits;
  1808. if (bits)
  1809. carry |= mpShiftRight(a, a, bits, ndigits);
  1810. return carry;
  1811. }
  1812. else
  1813. {
  1814. bits = shift;
  1815. }
  1816. /* Construct mask to set low bits */
  1817. /* (thanks to Jesse Chisholm for suggesting this improved technique) */
  1818. mask = ~(~(uint32_t)0 << bits);
  1819. y = BITS_PER_DIGIT - bits;
  1820. carry = 0;
  1821. i = ndigits;
  1822. while (i--)
  1823. {
  1824. nextcarry = (b[i] & mask) << y;
  1825. a[i] = b[i] >> bits | carry;
  1826. carry = nextcarry;
  1827. }
  1828. return carry;
  1829. }
  1830. static uint32_t spDivide(uint32_t *pq, uint32_t *pr, const uint32_t u[2], uint32_t v)
  1831. {
  1832. uint64_t uu, q;
  1833. uu = (uint64_t)u[1] << 32 | (uint64_t)u[0];
  1834. q = uu / (uint64_t)v;
  1835. //r = uu % (uint64_t)v;
  1836. *pr = (uint32_t)(uu - q * v);
  1837. *pq = (uint32_t)(q & 0xFFFFFFFF);
  1838. return (uint32_t)(q >> 32);
  1839. }
  1840. static int spMultiply(uint32_t p[2], uint32_t x, uint32_t y)
  1841. {
  1842. /* Use a 64-bit temp for product */
  1843. uint64_t t = (uint64_t)x * (uint64_t)y;
  1844. /* then split into two parts */
  1845. p[1] = (uint32_t)(t >> 32);
  1846. p[0] = (uint32_t)(t & 0xFFFFFFFF);
  1847. return 0;
  1848. }
  1849. static uint32_t mpMultSub(uint32_t wn, uint32_t w[], const uint32_t v[],
  1850. uint32_t q, int n)
  1851. {
  1852. /* Compute w = w - qv
  1853. where w = (WnW[n-1]...W[0])
  1854. return modified Wn.
  1855. */
  1856. uint32_t k, t[4];
  1857. int i;
  1858. if (q == 0) /* No change */
  1859. return wn;
  1860. k = 0;
  1861. for (i = 0; i < n; i++)
  1862. {
  1863. spMultiply(t, q, v[i]);
  1864. w[i] -= k;
  1865. if (w[i] > MAX_DIGIT - k)
  1866. k = 1;
  1867. else
  1868. k = 0;
  1869. w[i] -= t[0];
  1870. if (w[i] > MAX_DIGIT - t[0])
  1871. k++;
  1872. k += t[1];
  1873. }
  1874. /* Cope with Wn not stored in array w[0..n-1] */
  1875. wn -= k;
  1876. return wn;
  1877. }
  1878. static uint32_t mpShortDiv(uint32_t q[], const uint32_t u[], uint32_t v,
  1879. int ndigits)
  1880. {
  1881. /* Calculates quotient q = u div v
  1882. Returns remainder r = u mod v
  1883. where q, u are multiprecision integers of ndigits each
  1884. and r, v are single precision digits.
  1885. Makes no assumptions about normalisation.
  1886. Ref: Knuth Vol 2 Ch 4.3.1 Exercise 16 p625
  1887. */
  1888. int j;
  1889. uint32_t t[4], r;
  1890. int shift;
  1891. uint32_t bitmask, overflow, *uu;
  1892. if (ndigits == 0) return 0;
  1893. if (v == 0) return 0; /* Divide by zero error */
  1894. /* Normalise first */
  1895. /* Requires high bit of V
  1896. to be set, so find most signif. bit then shift left,
  1897. i.e. d = 2^shift, u' = u * d, v' = v * d.
  1898. */
  1899. bitmask = HIBITMASK;
  1900. for (shift = 0; shift < BITS_PER_DIGIT; shift++)
  1901. {
  1902. if (v & bitmask)
  1903. break;
  1904. bitmask >>= 1;
  1905. }
  1906. if (shift == BITS_PER_DIGIT) return 0; /* Avoid cppcheck false-alarm. */
  1907. v <<= shift;
  1908. overflow = mpShiftLeft(q, u, shift, ndigits);
  1909. uu = q;
  1910. /* Step S1 - modified for extra digit. */
  1911. r = overflow; /* New digit Un */
  1912. j = ndigits;
  1913. while (j--)
  1914. {
  1915. /* Step S2. */
  1916. t[1] = r;
  1917. t[0] = uu[j];
  1918. overflow = spDivide(&q[j], &r, t, v);
  1919. }
  1920. /* Unnormalise */
  1921. r >>= shift;
  1922. return r;
  1923. }
  1924. static int QhatTooBig(uint32_t qhat, uint32_t rhat,
  1925. uint32_t vn2, uint32_t ujn2)
  1926. {
  1927. /* Returns true if Qhat is too big
  1928. i.e. if (Qhat * Vn-2) > (b.Rhat + Uj+n-2)
  1929. */
  1930. uint32_t t[4];
  1931. spMultiply(t, qhat, vn2);
  1932. if (t[1] < rhat)
  1933. return 0;
  1934. else if (t[1] > rhat)
  1935. return 1;
  1936. else if (t[0] > ujn2)
  1937. return 1;
  1938. return 0;
  1939. }
  1940. static uint32_t mpAdd(uint32_t w[], const uint32_t u[], const uint32_t v[], int ndigits)
  1941. {
  1942. /* Calculates w = u + v
  1943. where w, u, v are multiprecision integers of ndigits each
  1944. Returns carry if overflow. Carry = 0 or 1.
  1945. Ref: Knuth Vol 2 Ch 4.3.1 p 266 Algorithm A.
  1946. */
  1947. uint32_t k;
  1948. int j;
  1949. // assert(w != v);
  1950. /* Step A1. Initialise */
  1951. k = 0;
  1952. for (j = 0; j < ndigits; j++)
  1953. {
  1954. /* Step A2. Add digits w_j = (u_j + v_j + k)
  1955. Set k = 1 if carry (overflow) occurs
  1956. */
  1957. w[j] = u[j] + k;
  1958. if (w[j] < k)
  1959. k = 1;
  1960. else
  1961. k = 0;
  1962. w[j] += v[j];
  1963. if (w[j] < v[j])
  1964. k++;
  1965. } /* Step A3. Loop on j */
  1966. return k; /* w_n = k */
  1967. }
  1968. static int mpDivide(uint32_t q[], uint32_t r[], const uint32_t u[],
  1969. int udigits, uint32_t v[], int vdigits)
  1970. {
  1971. /* Computes quotient q = u / v and remainder r = u mod v
  1972. where q, r, u are multiple precision digits
  1973. all of udigits and the divisor v is vdigits.
  1974. Ref: Knuth Vol 2 Ch 4.3.1 p 272 Algorithm D.
  1975. Do without extra storage space, i.e. use r[] for
  1976. normalised u[], unnormalise v[] at end, and cope with
  1977. extra digit Uj+n added to u after normalisation.
  1978. WARNING: this trashes q and r first, so cannot do
  1979. u = u / v or v = u mod v.
  1980. It also changes v temporarily so cannot make it const.
  1981. */
  1982. int shift;
  1983. int n, m, j;
  1984. uint32_t bitmask, overflow;
  1985. uint32_t qhat, rhat, t[4];
  1986. uint32_t *uu, *ww;
  1987. int qhatOK, cmp;
  1988. /* Clear q and r */
  1989. mpSetZero(q, udigits);
  1990. mpSetZero(r, udigits);
  1991. /* Work out exact sizes of u and v */
  1992. n = (int)mpSizeof(v, vdigits);
  1993. m = (int)mpSizeof(u, udigits);
  1994. m -= n;
  1995. /* Catch special cases */
  1996. if (n == 0)
  1997. return -1; /* Error: divide by zero */
  1998. if (n == 1)
  1999. {
  2000. /* Use short division instead */
  2001. r[0] = mpShortDiv(q, u, v[0], udigits);
  2002. return 0;
  2003. }
  2004. if (m < 0)
  2005. {
  2006. /* v > u, so just set q = 0 and r = u */
  2007. mpSetEqual(r, u, udigits);
  2008. return 0;
  2009. }
  2010. if (m == 0)
  2011. {
  2012. /* u and v are the same length */
  2013. cmp = mpCompare(u, v, (int)n);
  2014. if (cmp < 0)
  2015. {
  2016. /* v > u, as above */
  2017. mpSetEqual(r, u, udigits);
  2018. return 0;
  2019. }
  2020. else if (cmp == 0)
  2021. {
  2022. /* v == u, so set q = 1 and r = 0 */
  2023. mpSetDigit(q, 1, udigits);
  2024. return 0;
  2025. }
  2026. }
  2027. /* In Knuth notation, we have:
  2028. Given
  2029. u = (Um+n-1 ... U1U0)
  2030. v = (Vn-1 ... V1V0)
  2031. Compute
  2032. q = u/v = (QmQm-1 ... Q0)
  2033. r = u mod v = (Rn-1 ... R1R0)
  2034. */
  2035. /* Step D1. Normalise */
  2036. /* Requires high bit of Vn-1
  2037. to be set, so find most signif. bit then shift left,
  2038. i.e. d = 2^shift, u' = u * d, v' = v * d.
  2039. */
  2040. bitmask = HIBITMASK;
  2041. for (shift = 0; shift < BITS_PER_DIGIT; shift++)
  2042. {
  2043. if (v[n - 1] & bitmask)
  2044. break;
  2045. bitmask >>= 1;
  2046. }
  2047. /* Normalise v in situ - NB only shift non-zero digits */
  2048. overflow = mpShiftLeft(v, v, shift, n);
  2049. /* Copy normalised dividend u*d into r */
  2050. overflow = mpShiftLeft(r, u, shift, n + m);
  2051. uu = r; /* Use ptr to keep notation constant */
  2052. t[0] = overflow; /* Extra digit Um+n */
  2053. /* Step D2. Initialise j. Set j = m */
  2054. for (j = m; j >= 0; j--)
  2055. {
  2056. /* Step D3. Set Qhat = [(b.Uj+n + Uj+n-1)/Vn-1]
  2057. and Rhat = remainder */
  2058. qhatOK = 0;
  2059. t[1] = t[0]; /* This is Uj+n */
  2060. t[0] = uu[j + n - 1];
  2061. overflow = spDivide(&qhat, &rhat, t, v[n - 1]);
  2062. /* Test Qhat */
  2063. if (overflow)
  2064. {
  2065. /* Qhat == b so set Qhat = b - 1 */
  2066. qhat = MAX_DIGIT;
  2067. rhat = uu[j + n - 1];
  2068. rhat += v[n - 1];
  2069. if (rhat < v[n - 1]) /* Rhat >= b, so no re-test */
  2070. qhatOK = 1;
  2071. }
  2072. /* [VERSION 2: Added extra test "qhat && "] */
  2073. if (qhat && !qhatOK && QhatTooBig(qhat, rhat, v[n - 2], uu[j + n - 2]))
  2074. {
  2075. /* If Qhat.Vn-2 > b.Rhat + Uj+n-2
  2076. decrease Qhat by one, increase Rhat by Vn-1
  2077. */
  2078. qhat--;
  2079. rhat += v[n - 1];
  2080. /* Repeat this test if Rhat < b */
  2081. if (!(rhat < v[n - 1]))
  2082. if (QhatTooBig(qhat, rhat, v[n - 2], uu[j + n - 2]))
  2083. qhat--;
  2084. }
  2085. /* Step D4. Multiply and subtract */
  2086. ww = &uu[j];
  2087. overflow = mpMultSub(t[1], ww, v, qhat, (int)n);
  2088. /* Step D5. Test remainder. Set Qj = Qhat */
  2089. q[j] = qhat;
  2090. if (overflow)
  2091. {
  2092. /* Step D6. Add back if D4 was negative */
  2093. q[j]--;
  2094. overflow = mpAdd(ww, ww, v, (int)n);
  2095. }
  2096. t[0] = uu[j + n - 1]; /* Uj+n on next round */
  2097. } /* Step D7. Loop on j */
  2098. /* Clear high digits in uu */
  2099. for (j = n; j < m + n; j++)
  2100. uu[j] = 0;
  2101. /* Step D8. Unnormalise. */
  2102. mpShiftRight(r, r, shift, n);
  2103. mpShiftRight(v, v, shift, n);
  2104. return 0;
  2105. }
  2106. /***************************/
  2107. static int mpModulo(uint32_t r[], const uint32_t u[], int udigits,
  2108. uint32_t v[], int vdigits)
  2109. {
  2110. /* Computes r = u mod v
  2111. where r, v are multiprecision integers of length vdigits
  2112. and u is a multiprecision integer of length udigits.
  2113. r may overlap v.
  2114. Note that r here is only vdigits long,
  2115. whereas in mpDivide it is udigits long.
  2116. Use remainder from mpDivide function.
  2117. */
  2118. int nn = max(udigits, vdigits);
  2119. // [v2.6] increased to two times
  2120. if (nn > (MAX_FIXED_DIGITS * 2))
  2121. {
  2122. printf("Error!! mpModulo nn overflow!\n");
  2123. return -1;
  2124. }
  2125. /* rr[nn] = u mod v */
  2126. mpDivide(qq, rr, u, udigits, v, vdigits);
  2127. /* Final r is only vdigits long */
  2128. mpSetEqual(r, rr, vdigits);
  2129. return 0;
  2130. }
  2131. static void Hex2Binary(char *input, char *output)
  2132. {
  2133. int i, j, idx, n, klen;
  2134. char *p = (char *)input;
  2135. klen = strlen(input);
  2136. if ((klen + 3) > RSA_KBUF_HLEN)
  2137. {
  2138. printf("Hex2Binary overflow!! %d > %d\n", klen + 3, RSA_KBUF_HLEN);
  2139. }
  2140. klen = strlen(input) * 4;
  2141. memset(output, 0, RSA_KBUF_BLEN);
  2142. output[klen] = 0;
  2143. output[klen + 1] = 0;
  2144. idx = klen - 1;
  2145. for (i = 0; *p != 0; i++, p++)
  2146. {
  2147. if (input[i] <= '9')
  2148. {
  2149. n = input[i] - '0';
  2150. }
  2151. else if (input[i] >= 'a')
  2152. {
  2153. n = input[i] - 'a' + 10;
  2154. }
  2155. else
  2156. {
  2157. n = input[i] - 'A' + 10;
  2158. }
  2159. for (j = 3; j >= 0; j--)
  2160. {
  2161. output[idx--] = (n >> j) & 0x1;
  2162. }
  2163. }
  2164. if (idx != -1)
  2165. {
  2166. printf("Hex2Binary unexpected error!!\n");
  2167. }
  2168. }
  2169. static void Binary2Hex(int length, char *input, char *output)
  2170. {
  2171. int i, idx, n, slen;
  2172. memset(output, 0, RSA_KBUF_HLEN);
  2173. slen = length / 4;
  2174. idx = slen - 1;
  2175. for (i = 0; i < length; i += 4)
  2176. {
  2177. n = (input[i]) | (input[i + 1] << 1) | (input[i + 2] << 2) | (input[i + 3] << 3);
  2178. if (n >= 10)
  2179. output[idx] = n - 10 + 'A';
  2180. else
  2181. output[idx] = n + '0';
  2182. idx--;
  2183. }
  2184. if (idx != -1)
  2185. {
  2186. printf("Binary2Hex unecpected error! %d\n", idx);
  2187. }
  2188. }
  2189. #define Hardware_length (2096)
  2190. static uint32_t C_t[(2096 * 2) / 32];
  2191. static uint32_t N_t[(2096 * 2) / 32];
  2192. static char C[RSA_KBUF_BLEN], N[RSA_KBUF_BLEN];
  2193. /** @endcond HIDDEN_SYMBOLS */
  2194. /**
  2195. * @brief Calculate the constant value of Montgomery domain.
  2196. * @param[in] length RSA bit length.
  2197. * @param[in] rsa_N The base of modulus operation.
  2198. * @param[out] rsa_C The constant value of Montgomery domain required by NUC980 RSA engine.
  2199. */
  2200. void RSA_Calculate_C(int length, char *rsa_N, char *rsa_C)
  2201. {
  2202. int i, v, nbits;
  2203. uint32_t j;
  2204. int scale = (length + 2) * 2;
  2205. size_t word_size = (scale / 32) + 1;
  2206. memset(rsa_C, 0, length / 4 + 2);
  2207. Hex2Binary(rsa_N, N);
  2208. memset(C_t, 0, sizeof(C_t));
  2209. C_t[word_size - 1] = (uint32_t)(1 << scale - (32 * (word_size - 1)));
  2210. // convert char to uint32_t
  2211. memset(N_t, 0, sizeof(N_t));
  2212. j = 0;
  2213. for (i = 0; i < length; i++)
  2214. {
  2215. if (N[i])
  2216. {
  2217. j += 1 << (i % 32);
  2218. }
  2219. if ((i % 32) == 31)
  2220. {
  2221. N_t[(i / 32)] = j;
  2222. j = 0;
  2223. }
  2224. }
  2225. mpModulo(C_t, C_t, word_size, N_t, word_size);
  2226. // convert uint32_t to char
  2227. nbits = (int)mpBitLength(C_t, word_size);
  2228. for (i = Hardware_length; i >= 0; i--)
  2229. {
  2230. if (i > nbits)
  2231. C[i] = 0;
  2232. else
  2233. {
  2234. v = mpGetBit(C_t, word_size, i);
  2235. C[i] = v ? 1 : 0;
  2236. }
  2237. }
  2238. Binary2Hex(length, C, rsa_C);
  2239. }
  2240. /**
  2241. * @brief RSA digital signature generation.
  2242. * @param[in] crpt Reference to Crypto module.
  2243. * @param[in] rsa_len RSA key length
  2244. * @param[in] n The modulus for both the public and private keys
  2245. * @param[in] d (n,d) is the private key
  2246. * @param[in] C The constant value of Montgomery domain.
  2247. * @param[in] msg The message to be signed.
  2248. * @param[out] sig The output signature.
  2249. * @return 0 Success.
  2250. * @return -1 Error
  2251. */
  2252. int32_t RSA_GenerateSignature(CRPT_T *crpt, int rsa_len, char *n, char *d, char *C,
  2253. char *msg, char *sig)
  2254. {
  2255. int i;
  2256. for (i = 0; i < 128; i++)
  2257. {
  2258. crpt->RSA_N[i] = 0;
  2259. crpt->RSA_E[i] = 0;
  2260. crpt->RSA_M[i] = 0;
  2261. }
  2262. Hex2Reg(n, (uint32_t *)&crpt->RSA_N[0]);
  2263. Hex2Reg(d, (uint32_t *)&crpt->RSA_E[0]);
  2264. Hex2Reg(msg, (uint32_t *)&crpt->RSA_M[0]);
  2265. Hex2Reg(C, (uint32_t *)&crpt->RSA_C[0]);
  2266. CRPT->RSA_CTL = (rsa_len << CRPT_RSA_CTL_KEYLEN_Pos) | CRPT_RSA_CTL_START_Msk;
  2267. while (CRPT->RSA_STS & CRPT_RSA_STS_BUSY_Msk) ;
  2268. Reg2Hex(rsa_len / 4, (uint32_t *)CRPT->RSA_M, sig);
  2269. return 0;
  2270. }
  2271. /**
  2272. * @brief RSA digital signature generation.
  2273. * @param[in] crpt Reference to Crypto module.
  2274. * @param[in] rsa_len RSA key length
  2275. * @param[in] n The modulus for both the public and private keys
  2276. * @param[in] e (n,e) is the public key
  2277. * @param[in] C The constant value of Montgomery domain.
  2278. * @param[in] sig The signature to be verified.
  2279. * @param[out] msg The message to be compared.
  2280. * @return 0 Success.
  2281. * @return -1 Verify failed
  2282. */
  2283. int32_t RSA_VerifySignature(CRPT_T *crpt, int rsa_len, char *n, char *e, char *C,
  2284. char *sig, char *msg)
  2285. {
  2286. char output[RSA_KBUF_HLEN];
  2287. int i;
  2288. for (i = 0; i < 128; i++)
  2289. {
  2290. crpt->RSA_N[i] = 0;
  2291. crpt->RSA_E[i] = 0;
  2292. crpt->RSA_M[i] = 0;
  2293. }
  2294. Hex2Reg(n, (uint32_t *)&crpt->RSA_N[0]);
  2295. Hex2Reg(e, (uint32_t *)&crpt->RSA_E[0]);
  2296. Hex2Reg(sig, (uint32_t *)&crpt->RSA_M[0]);
  2297. Hex2Reg(C, (uint32_t *)&crpt->RSA_C[0]);
  2298. CRPT->RSA_CTL = (rsa_len << CRPT_RSA_CTL_KEYLEN_Pos) | CRPT_RSA_CTL_START_Msk;
  2299. while (CRPT->RSA_STS & CRPT_RSA_STS_BUSY_Msk) ;
  2300. Reg2Hex(rsa_len / 4, (uint32_t *)CRPT->RSA_M, output);
  2301. printf("RSA verify: %s\n", output);
  2302. if (ecc_strcmp(output, msg) != 0)
  2303. {
  2304. CRPT_DBGMSG("RSA verify output [%s] is not matched with expected [%s]!\n", output, msg);
  2305. return -1;
  2306. }
  2307. return 0;
  2308. }
  2309. /*@}*/ /* end of group CRYPTO_EXPORTED_FUNCTIONS */
  2310. /*@}*/ /* end of group CRYPTO_Driver */
  2311. /*@}*/ /* end of group Standard_Driver */
  2312. /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/