esp32_mp.c 109 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084
  1. /* esp32_mp.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /*
  22. * See ESP32 Technical Reference Manual - RSA Accelerator Chapter
  23. *
  24. * esp_mp_exptmod() Large Number Modular Exponentiation Z = X^Y mod M
  25. * esp_mp_mulmod() Large Number Modular Multiplication Z = X * Y mod M
  26. * esp_mp_mul() Large Number Multiplication Z = X * Y
  27. *
  28. * The ESP32 RSA Accelerator supports operand lengths of:
  29. * N in {512, 1024, 1536, 2048, 2560, 3072, 3584, 4096} bits. The bit length
  30. * of arguments Z, X, Y , M, and r can be any one from the N set, but all
  31. * numbers in a calculation must be of the same length.
  32. *
  33. * The bit length of M' is always 32.
  34. *
  35. * Also, beware: "we have uint32_t == unsigned long for both Xtensa and RISC-V"
  36. * see https://github.com/espressif/esp-idf/issues/9511#issuecomment-1207342464
  37. * https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/gcc.html
  38. */
  39. #ifdef HAVE_CONFIG_H
  40. #include <config.h>
  41. #endif
  42. /* Reminder: user_settings.h is needed and included from settings.h
  43. * Be sure to define WOLFSSL_USER_SETTINGS, typically in CMakeLists.txt */
  44. #include <wolfssl/wolfcrypt/settings.h>
  45. #if defined(WOLFSSL_ESPIDF) /* Entire file is only for Espressif EDP-IDF */
  46. #include "sdkconfig.h" /* programmatically generated from sdkconfig */
  47. #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
  48. #include <wolfssl/wolfcrypt/logging.h>
  49. #if !defined(NO_RSA) || defined(HAVE_ECC)
  50. #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && \
  51. !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI)
  52. #ifdef NO_INLINE
  53. #include <wolfssl/wolfcrypt/misc.h>
  54. #else
  55. #define WOLFSSL_MISC_INCLUDED
  56. #include <wolfcrypt/src/misc.c>
  57. #endif
  58. #include <wolfssl/wolfcrypt/wolfmath.h>
  59. #ifndef SINGLE_THREADED
  60. /* Espressif freeRTOS */
  61. #include <freertos/semphr.h>
  62. #endif
  63. #define ESP_HW_RSAMAX_BIT 4096
  64. #define ESP_HW_MULTI_RSAMAX_BITS 2048
  65. #define ESP_HW_RSAMIN_BIT 512
  66. /* (s+(4-1))/ 4 */
  67. #define BYTE_TO_WORDS(s) (((s+3)>>2))
  68. /* (s+(32-1))/ 8/ 4*/
  69. #define BITS_TO_WORDS(s) (((s+31)>>3)>>2)
  70. #define BITS_IN_ONE_WORD 32
  71. #ifndef ESP_RSA_MULM_BITS
  72. #define ESP_RSA_MULM_BITS 16
  73. #endif
  74. #ifndef ESP_RSA_EXPT_XBITS
  75. #define ESP_RSA_EXPT_XBITS 8
  76. #endif
  77. #ifndef ESP_RSA_EXPT_YBITS
  78. #define ESP_RSA_EXPT_YBITS 8
  79. #endif
  80. #define ESP_TIMEOUT(cnt) (cnt >= ESP_RSA_TIMEOUT_CNT)
  81. #if defined(CONFIG_IDF_TARGET_ESP32C3)
  82. #include <soc/system_reg.h>
  83. #include <soc/hwcrypto_reg.h>
  84. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  85. #include <soc/pcr_reg.h>
  86. #elif defined(CONFIG_IDF_TARGET_ESP32S2)
  87. #include <soc/system_reg.h>
  88. #include <soc/hwcrypto_reg.h>
  89. #endif
  90. static const char* const TAG = "wolfssl_esp32_mp";
  91. #ifdef DEBUG_WOLFSSL
  92. static int hw_validation = 0; /* validating HW and SW? (prevent HW call) */
  93. #define SET_HW_VALIDATION {hw_validation = 1;}
  94. #define CLR_HW_VALIDATION {hw_validation = 0;}
  95. #define IS_HW_VALIDATION (hw_validation == 1)
  96. #undef WOLFSSL_HW_METRICS
  97. /* usage metrics always on during debug */
  98. #define WOLFSSL_HW_METRICS
  99. #endif
  100. /* For esp_mp_exptmod and esp_mp_mulmod we need a variety of calculated helper
  101. ** values to properly setup the hardware. See esp_mp_montgomery_init() */
  102. struct esp_mp_helper
  103. {
  104. MATH_INT_T r_inv; /* result of calculated Montgomery helper */
  105. word32 exp;
  106. word32 Xs; /* how many bits in X operand */
  107. word32 Ys; /* how many bits in Y operand */
  108. word32 Ms; /* how many bits in M operand */
  109. word32 Rs; /* how many bits in R_inv calc */
  110. word32 maxWords_sz; /* maximum words expected */
  111. word32 hwWords_sz;
  112. mp_digit mp; /* result of calculated Montgomery M' helper */
  113. #ifdef DEBUG_WOLFSSL
  114. mp_digit mp2; /* optional compare to alternate Montgomery calc */
  115. #endif
  116. };
  117. static portMUX_TYPE wc_rsa_reg_lock = portMUX_INITIALIZER_UNLOCKED;
  118. /* usage metrics can be turned on independently of debugging */
  119. #ifdef WOLFSSL_HW_METRICS
  120. static unsigned long esp_mp_max_used = 0;
  121. static unsigned long esp_mp_mulmod_small_x_ct = 0;
  122. static unsigned long esp_mp_mulmod_small_y_ct = 0;
  123. static unsigned long esp_mp_max_timeout = 0;
  124. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
  125. static unsigned long esp_mp_mul_usage_ct = 0;
  126. static unsigned long esp_mp_mul_error_ct = 0;
  127. #endif /* !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
  128. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
  129. static unsigned long esp_mp_mulmod_usage_ct = 0;
  130. static unsigned long esp_mp_mulmod_fallback_ct = 0;
  131. static unsigned long esp_mp_mulmod_even_mod_ct = 0;
  132. static unsigned long esp_mp_mulmod_error_ct = 0;
  133. #endif /* !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
  134. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
  135. static unsigned long esp_mp_exptmod_usage_ct = 0;
  136. static unsigned long esp_mp_exptmod_error_ct = 0;
  137. static unsigned long esp_mp_exptmod_fallback_ct = 0;
  138. #endif /* !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
  139. #endif
  140. /* mutex */
  141. #ifdef SINGLE_THREADED
  142. int single_thread_locked = 0;
  143. #else
  144. static wolfSSL_Mutex mp_mutex;
  145. static int espmp_CryptHwMutexInit = 0;
  146. #endif
  147. #ifdef DEBUG_WOLFSSL
  148. /* when debugging, we'll double-check the mutex with call depth */
  149. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
  150. static int esp_mp_exptmod_depth_counter = 0;
  151. #endif /* NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
  152. #endif /* DEBUG_WOLFSSL */
  153. /*
  154. * check if the HW is ready before accessing it
  155. *
  156. * See 24.3.1 Initialization of ESP32 Technical Reference Manual
  157. * https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
  158. *
  159. * The RSA Accelerator is activated by enabling the corresponding peripheral
  160. * clock, and by clearing the DPORT_RSA_PD bit in the DPORT_RSA_PD_CTRL_REG
  161. * register. This releases the RSA Accelerator from reset.
  162. *
  163. * See esp_mp_hw_lock().
  164. *
  165. * Note we'll also keep track locally if the lock was called at all.
  166. * For instance, fallback to SW for very small operand and we won't lock HW.
  167. *
  168. * When the RSA Accelerator is released from reset, the register RSA_CLEAN_REG
  169. * reads 0 and an initialization process begins. Hardware initializes the four
  170. * memory blocks by setting them to 0. After initialization is complete,
  171. * RSA_CLEAN_REG reads 1. For this reason, software should query RSA_CLEAN_REG
  172. * after being released from reset, and before writing to any RSA Accelerator
  173. * memory blocks or registers for the first time.
  174. */
  175. static int esp_mp_hw_wait_clean(void)
  176. {
  177. int ret = MP_OKAY;
  178. word32 timeout = 0;
  179. #if defined(CONFIG_IDF_TARGET_ESP32)
  180. /* RSA_CLEAN_REG is now called RSA_QUERY_CLEAN_REG.
  181. ** hwcrypto_reg.h maintains RSA_CLEAN_REG for backwards compatibility:
  182. ** so this block _might_ not be needed in some circumstances. */
  183. ESP_EM__PRE_MP_HW_WAIT_CLEAN
  184. /* wait until ready,
  185. ** or timeout counter exceeds ESP_RSA_TIMEOUT_CNT in user_settings */
  186. while(!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(RSA_CLEAN_REG) == 0) {
  187. /* wait. expected delay 1 to 2 uS */
  188. ESP_EM__MP_HW_WAIT_CLEAN
  189. }
  190. #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
  191. ESP_EM__PRE_MP_HW_WAIT_CLEAN
  192. while (!ESP_TIMEOUT(++timeout) &&
  193. DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) {
  194. /* wait. expected delay 1 to 2 uS */
  195. ESP_EM__MP_HW_WAIT_CLEAN
  196. }
  197. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  198. ESP_EM__PRE_MP_HW_WAIT_CLEAN
  199. while (!ESP_TIMEOUT(++timeout) &&
  200. DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) {
  201. /* wait. expected delay 1 to 2 uS */
  202. ESP_EM__MP_HW_WAIT_CLEAN
  203. }
  204. #else
  205. /* no HW timeout if we don't know the platform. assumes no HW */
  206. #endif
  207. #if defined(WOLFSSL_HW_METRICS)
  208. {
  209. esp_mp_max_timeout = (timeout > esp_mp_max_timeout) ? timeout :
  210. esp_mp_max_timeout;
  211. }
  212. #endif
  213. if (ESP_TIMEOUT(timeout)) {
  214. ESP_LOGE(TAG, "esp_mp_hw_wait_clean waiting HW ready timed out.");
  215. ret = WC_HW_WAIT_E; /* hardware is busy, MP_HW_BUSY; */
  216. }
  217. return ret;
  218. }
  219. /*
  220. ** esp_mp_hw_islocked() - detect if we've locked the HW for use.
  221. **
  222. ** WARNING: this does *not* detect separate calls to the
  223. ** periph_module_disable() and periph_module_enable().
  224. */
  225. static int esp_mp_hw_islocked(void)
  226. {
  227. int ret = FALSE;
  228. #ifdef SINGLE_THREADED
  229. if (single_thread_locked == FALSE) {
  230. /* not in use */
  231. ESP_LOGV(TAG, "SINGLE_THREADED esp_mp_hw_islocked = false");
  232. }
  233. else {
  234. ESP_LOGV(TAG, "SINGLE_THREADED esp_mp_hw_islocked = true");
  235. ret = TRUE;
  236. }
  237. #else
  238. TaskHandle_t mutexHolder = xSemaphoreGetMutexHolder(mp_mutex);
  239. if (mutexHolder == NULL) {
  240. /* Mutex is not in use */
  241. ESP_LOGV(TAG, "multi-threaded esp_mp_hw_islocked = false");
  242. }
  243. else {
  244. ESP_LOGV(TAG, "multi-threaded esp_mp_hw_islocked = true");
  245. ret = TRUE;
  246. }
  247. #endif
  248. return ret;
  249. }
  250. /*
  251. * esp_mp_hw_lock()
  252. *
  253. * Lock HW engine.
  254. * This should be called before using engine.
  255. *
  256. * Returns 0 (ESP_OK) if the HW lock was initialized and mutex lock.
  257. *
  258. * See Chapter 24:
  259. * https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
  260. *
  261. * The RSA Accelerator is activated by enabling the corresponding peripheral
  262. * clock, and by clearing the DPORT_RSA_PD bit in the DPORT_RSA_PD_CTRL_REG
  263. * register. This releases the RSA Accelerator from reset.
  264. *
  265. * When the RSA Accelerator is released from reset, the register RSA_CLEAN_REG
  266. * reads 0 and an initialization process begins. Hardware initializes the four
  267. * memory blocks by setting them to 0. After initialization is complete,
  268. * RSA_CLEAN_REG reads 1. For this reason, software should query RSA_CLEAN_REG
  269. * after being released from reset, and before writing to any RSA Accelerator
  270. * memory blocks or registers for the first time.
  271. */
  272. static int esp_mp_hw_lock(void)
  273. {
  274. int ret = ESP_OK;
  275. ESP_LOGV(TAG, "enter esp_mp_hw_lock");
  276. #ifdef SINGLE_THREADED
  277. single_thread_locked = TRUE;
  278. #else
  279. if (espmp_CryptHwMutexInit == ESP_OK) {
  280. ret = esp_CryptHwMutexInit(&mp_mutex);
  281. if (ret == ESP_OK) {
  282. /* flag esp mp as initialized */
  283. espmp_CryptHwMutexInit = TRUE;
  284. }
  285. else {
  286. ESP_LOGE(TAG, "mp mutex initialization failed.");
  287. }
  288. }
  289. else {
  290. /* mp_mutex has already been initialized */
  291. }
  292. /* Set our mutex to indicate the HW is in use */
  293. if (ret == ESP_OK) {
  294. /* lock hardware; there should be exactly one instance
  295. * of esp_CryptHwMutexLock(&mp_mutex ...) in code */
  296. /* TODO - do we really want to wait?
  297. * probably not */
  298. ret = esp_CryptHwMutexLock(&mp_mutex, ESP_MP_HW_LOCK_MAX_DELAY);
  299. if (ret != ESP_OK) {
  300. ESP_LOGE(TAG, "mp engine lock failed.");
  301. ret = WC_HW_WAIT_E; /* caller is expected to fall back to SW */
  302. }
  303. }
  304. #endif /* not SINGLE_THREADED */
  305. #if defined(CONFIG_IDF_TARGET_ESP32)
  306. /* Enable RSA hardware */
  307. if (ret == ESP_OK) {
  308. periph_module_enable(PERIPH_RSA_MODULE);
  309. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  310. {
  311. /* clear bit to enable hardware operation; (set to disable) */
  312. DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
  313. ESP_EM__POST_SP_MP_HW_LOCK
  314. }
  315. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  316. }
  317. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  318. /* Activate the RSA accelerator. See 20.3 of ESP32-C3 technical manual.
  319. * periph_module_enable doesn't seem to be documented and in private folder
  320. * with v5 release. Maybe it will be deprecated?
  321. *
  322. * The ESP32-C3 RSA Accelerator is activated by:
  323. * setting the SYSTEM_CRYPTO_RSA_CLK_EN bit in the SYSTEM_PERIP_CLK_EN1_REG
  324. * register and:
  325. * clearing the SYSTEM_RSA_MEM_PD bit in the SYSTEM_RSA_PD_CTRL_REG reg.
  326. * This releases the RSA Accelerator from reset.*/
  327. if (ret == ESP_OK) {
  328. periph_module_enable(PERIPH_RSA_MODULE);
  329. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  330. {
  331. DPORT_REG_SET_BIT((volatile void *)(SYSTEM_PERIP_CLK_EN1_REG),
  332. SYSTEM_CRYPTO_RSA_CLK_EN );
  333. DPORT_REG_CLR_BIT((volatile void *)(SYSTEM_RSA_PD_CTRL_REG),
  334. SYSTEM_RSA_MEM_PD );
  335. }
  336. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  337. }
  338. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  339. /* See: 21.3 Functional Description
  340. *
  341. * The RSA accelerator is activated on the ESP32-C6 by:
  342. * setting the PCR_RSA_CLK_EN bit
  343. * and
  344. * clearing the PCR_RSA_RST_EN bit
  345. * in the PCR_RSA_CONF_REG register.
  346. *
  347. * Additionally, users also need to clear PCR_DS_RST_EN bit to
  348. * reset Digital Signature (DS).*/
  349. if (ret == ESP_OK) {
  350. periph_module_enable(PERIPH_RSA_MODULE);
  351. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  352. {
  353. /* TODO: When implementing DS (Digital Signature HW), need to
  354. * check if it is in use before disabling: */
  355. DPORT_REG_CLR_BIT((volatile void *)(PCR_DS_CONF_REG),
  356. PCR_DS_RST_EN );
  357. DPORT_REG_SET_BIT((volatile void *)(PCR_RSA_CONF_REG),
  358. PCR_RSA_CLK_EN );
  359. DPORT_REG_CLR_BIT((volatile void *)(PCR_RSA_CONF_REG),
  360. PCR_RSA_RST_EN );
  361. }
  362. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  363. }
  364. #elif defined(CONFIG_IDF_TARGET_ESP32S2)
  365. /* Activate the RSA accelerator. See 18.3 of ESP32-S2 technical manual.
  366. * periph_module_enable doesn't seem to be documented and in private folder
  367. * with v5 release. Maybe it will be deprecated? */
  368. if (ret == ESP_OK) {
  369. periph_module_enable(PERIPH_RSA_MODULE);
  370. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  371. {
  372. /* Note these names are different from those in the documentation!
  373. *
  374. * Documentation lists the same names as the ESP32-C3:
  375. *
  376. * DPORT_REG_SET_BIT((volatile void *)(SYSTEM_PERIP_CLK_EN1_REG),
  377. * SYSTEM_CRYPTO_RSA_CLK_EN );
  378. * DPORT_REG_CLR_BIT((volatile void *)(SYSTEM_RSA_PD_CTRL_REG),
  379. * SYSTEM_RSA_MEM_PD );
  380. *
  381. * However, in the sytem_reg.h, the names below were found:
  382. */
  383. DPORT_REG_SET_BIT((volatile void *)(DPORT_CPU_PERIP_CLK_EN1_REG),
  384. DPORT_CRYPTO_RSA_CLK_EN );
  385. DPORT_REG_CLR_BIT((volatile void *)(DPORT_RSA_PD_CTRL_REG),
  386. DPORT_RSA_MEM_PD );
  387. }
  388. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  389. }
  390. #elif defined(CONFIG_IDF_TARGET_ESP32S3)
  391. /* Activate the RSA accelerator. See 20.3 of ESP32-S3 technical manual.
  392. * periph_module_enable doesn't seem to be documented and in private folder
  393. * with v5 release. Maybe it will be deprecated? */
  394. if (ret == ESP_OK) {
  395. periph_module_enable(PERIPH_RSA_MODULE);
  396. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  397. {
  398. /* clear bit to enable hardware operation; (set to disable) */
  399. DPORT_REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
  400. }
  401. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  402. }
  403. #else
  404. /* when unknown or not implemented, assume there's no HW to lock */
  405. #endif
  406. /* reminder: wait until RSA_CLEAN_REG reads 1
  407. ** see esp_mp_hw_wait_clean() */
  408. ESP_LOGV(TAG, "leave esp_mp_hw_lock");
  409. return ret;
  410. }
  411. /*
  412. ** Release RSA HW engine
  413. */
  414. static int esp_mp_hw_unlock(void)
  415. {
  416. int ret = MP_OKAY;
  417. if (esp_mp_hw_islocked()) {
  418. #if defined(CONFIG_IDF_TARGET_ESP32)
  419. /* set bit to disabled hardware operation; (clear to enable) */
  420. DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
  421. /* Disable RSA hardware */
  422. periph_module_disable(PERIPH_RSA_MODULE);
  423. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  424. /* Deactivate the RSA accelerator.
  425. * See 20.3 of ESP32-C3 technical manual.
  426. * periph_module_enable doesn't seem to be documented and in private
  427. * folder with v5 release. Maybe it will be deprecated?
  428. * The ESP32-C3 RSA Accelerator is activated by:
  429. * setting the SYSTEM_CRYPTO_RSA_CLK_EN bit
  430. * in the SYSTEM_PERIP_CLK_EN1_REG register and:
  431. * clearing the SYSTEM_RSA_MEM_PD bit
  432. * in the SYSTEM_RSA_PD_CTRL_REG reg.
  433. * This releases the RSA Accelerator from reset.*/
  434. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  435. {
  436. DPORT_REG_CLR_BIT(
  437. (volatile void *)(DR_REG_RSA_BASE + SYSTEM_CRYPTO_RSA_CLK_EN),
  438. SYSTEM_PERIP_CLK_EN1_REG);
  439. DPORT_REG_SET_BIT(
  440. (volatile void *)(DR_REG_RSA_BASE + SYSTEM_RSA_MEM_PD),
  441. SYSTEM_RSA_PD_CTRL_REG);
  442. }
  443. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  444. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  445. /* TODO: When implementing DS (Digital Signature HW), need to
  446. * notify RSA HW is available. */
  447. portENTER_CRITICAL_SAFE(&wc_rsa_reg_lock);
  448. {
  449. DPORT_REG_SET_BIT((volatile void *)(PCR_RSA_CONF_REG),
  450. PCR_RSA_RST_EN);
  451. DPORT_REG_CLR_BIT((volatile void *)(PCR_RSA_CONF_REG),
  452. PCR_RSA_CLK_EN);
  453. }
  454. portEXIT_CRITICAL_SAFE(&wc_rsa_reg_lock);
  455. #elif defined(CONFIG_IDF_TARGET_ESP32S2)
  456. /* Deactivate the RSA accelerator.
  457. * See 20.3 of ESP32-S3 technical manual.
  458. * periph_module_enable doesn't seem to be documented and is
  459. * in private folder with v5 release. Maybe it will be deprecated? */
  460. DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD);
  461. periph_module_disable(PERIPH_RSA_MODULE);
  462. #elif defined(CONFIG_IDF_TARGET_ESP32S3)
  463. /* Deactivate the RSA accelerator.
  464. * See 20.3 of ESP32-S3 technical manual.
  465. * periph_module_enable doesn't seem to be documented and is
  466. * in private folder with v5 release. Maybe it will be deprecated? */
  467. DPORT_REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD);
  468. periph_module_disable(PERIPH_RSA_MODULE);
  469. #else
  470. /* unknown platform, assume no HW to unlock */
  471. ESP_LOGW(TAG, "Warning: esp_mp_hw_unlock called for unknown target");
  472. #endif /* per-SoC unlock */
  473. #if defined(SINGLE_THREADED)
  474. single_thread_locked = FALSE;
  475. #else
  476. esp_CryptHwMutexUnLock(&mp_mutex);
  477. #endif /* SINGLE_THREADED */
  478. ESP_LOGV(TAG, "exit esp_mp_hw_unlock");
  479. }
  480. else {
  481. ESP_LOGW(TAG, "Warning: esp_mp_hw_unlock called when not locked.");
  482. }
  483. return ret;
  484. }
  485. /* Only mulmod and mulexp_mod HW accelerator need Montgomery math prep: M' */
  486. #if !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD) \
  487. || \
  488. !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD)
  489. static int esp_calc_Mdash(MATH_INT_T *M, word32 k, mp_digit* md)
  490. {
  491. int ret = MP_OKAY;
  492. ESP_LOGV(TAG, "\nBegin esp_calc_Mdash \n");
  493. #ifdef USE_ALT_MPRIME
  494. /* M' = M^(-1) mod b; b = 2^32 */
  495. /* Call Large Number Modular Exponentiation
  496. *
  497. * Z = X^Y mod M
  498. *
  499. * mp_exptmod notation: Y = (G ^ X) mod P
  500. *
  501. * G is our parameter: M
  502. */
  503. MATH_INT_T X[1] = { };
  504. MATH_INT_T P[1] = { };
  505. MATH_INT_T Y[1] = { };
  506. word32 Xs;
  507. ESP_LOGV(TAG, "\nBegin esp_calc_Mdash USE_ALT_MPRIME\n");
  508. mp_init(X);
  509. mp_init(P);
  510. mp_init(Y);
  511. /* MATH_INT_T value of (-1) */
  512. X->dp[0] = 1;
  513. X->sign = MP_NEG;
  514. X->used = 1;
  515. Xs = mp_count_bits(X);
  516. /* MATH_INT_T value of 2^32 */
  517. P->dp[1] = 1;
  518. P->used = 2;
  519. /* this fails due to even P number; ((b & 1) == 0) in fp_montgomery_setup()
  520. * called from _fp_exptmod_ct, called from fp_exptmod */
  521. ret = mp_exptmod(M, X, P, Y);
  522. *md = Y->dp[0];
  523. ESP_LOGI(TAG, "esp_calc_Mdash %u", *md);
  524. #else
  525. /* this is based on an article by Cetin Kaya Koc,
  526. * A New Algorithm for Inversion: mod p^k, June 28 2017 */
  527. int i;
  528. int xi;
  529. int b0 = 1;
  530. int bi;
  531. word32 N = 0;
  532. word32 x;
  533. ESP_LOGV(TAG, "\nBegin esp_calc_Mdash\n");
  534. N = M->dp[0];
  535. bi = b0;
  536. x = 0;
  537. for (i = 0; i < k; i++) {
  538. xi = bi % 2;
  539. if (xi < 0) {
  540. xi *= -1;
  541. }
  542. bi = (bi - N * xi) / 2;
  543. x |= (xi << i);
  544. }
  545. /* 2's complement */
  546. *md = ~x + 1;
  547. #endif
  548. ESP_LOGV(TAG, "\nEnd esp_calc_Mdash \n");
  549. return ret;
  550. }
  551. #endif /* !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_[MULMOD/EXPTMOD] for M' */
  552. /* the result may need to have extra bytes zeroed or used length adjusted */
  553. static int esp_clean_result(MATH_INT_T* Z, int used_padding)
  554. {
  555. int ret = MP_OKAY;
  556. uint16_t this_extra;
  557. /* TODO remove this section if MP_SIZE accepted into sp_int.h
  558. ** See https://github.com/wolfSSL/wolfssl/pull/6565 */
  559. uint16_t dp_length = 0; (void) dp_length;
  560. #ifdef USE_FAST_MATH
  561. #undef MP_SIZE
  562. #define MP_SIZE FP_SIZE
  563. dp_length = FP_SIZE;
  564. #else
  565. #undef MP_SIZE
  566. #define MP_SIZE 128
  567. dp_length = SP_INT_DIGITS;
  568. #endif
  569. /* TODO end */
  570. this_extra = Z->used;
  571. if (this_extra > MP_SIZE) {
  572. ESP_LOGW(TAG, "Warning (Z->used: %d) > (MP_SIZE: %d); adjusting...",
  573. Z->used, MP_SIZE);
  574. this_extra = MP_SIZE;
  575. }
  576. while (Z->dp[this_extra] > 0 && (this_extra < MP_SIZE)) {
  577. ESP_LOGV(TAG, "Adjust! %d", this_extra);
  578. Z->dp[this_extra] = 0;
  579. this_extra++;
  580. }
  581. /* trim any trailing zeros and adjust z.used size */
  582. if (Z->used > 0) {
  583. ESP_LOGV(TAG, "ZTrim: Z->used = %d", Z->used);
  584. for (size_t i = Z->used; i > 0; i--) {
  585. if (Z->dp[i - 1] == 0) {
  586. /* last element in zero based array */
  587. Z->used = i - 1;
  588. }
  589. else {
  590. break; /* if not zero, nothing else to do */
  591. }
  592. }
  593. ESP_LOGV(TAG, "New Z->used = %d", Z->used);
  594. }
  595. else {
  596. ESP_LOGV(TAG, "no z-trim needed");
  597. }
  598. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  599. if (Z->sign != 0) {
  600. mp_setneg(Z); /* any value other than zero is assumed negative */
  601. }
  602. #endif
  603. /* a result of 1 is interesting */
  604. if ((Z->dp[0] == 1) && (Z->used == 1)) {
  605. /*
  606. * When the exponent is 0: In this case, the result of the modular
  607. * exponentiation operation will always be 1, regardless of the value
  608. * of the base.
  609. *
  610. * When the base is 1: If the base is equal to 1, then the result of
  611. * the modular exponentiation operation will always be 1, regardless
  612. * of the value of the exponent.
  613. *
  614. * When the exponent is equal to the totient of the modulus: If the
  615. * exponent is equal to the totient of the modulus, and the base is
  616. * relatively prime to the modulus, then the result of the modular
  617. * exponentiation operation will be 1.
  618. */
  619. ESP_LOGV(TAG, "Z->dp[0] == 1");
  620. }
  621. return ret;
  622. }
  623. /* Start HW process. Reg is SoC-specific register. */
  624. static int process_start(u_int32_t reg)
  625. {
  626. int ret = MP_OKAY;
  627. /* see 3.16 "software needs to always use the "volatile"
  628. ** attribute when accessing registers in these two address spaces. */
  629. DPORT_REG_WRITE((volatile word32*)reg, 1);
  630. ESP_EM__POST_PROCESS_START;
  631. return ret;
  632. }
  633. /* wait until RSA math register indicates operation completed */
  634. static int wait_until_done(word32 reg)
  635. {
  636. int ret = MP_OKAY;
  637. word32 timeout = 0;
  638. /* wait until done && not timeout */
  639. ESP_EM__MP_HW_WAIT_DONE;
  640. while (!ESP_TIMEOUT(++timeout) && DPORT_REG_READ(reg) != 1) {
  641. asm volatile("nop"); /* wait */
  642. }
  643. ESP_EM__DPORT_FIFO_READ;
  644. #if defined(CONFIG_IDF_TARGET_ESP32C6)
  645. /* Write 1 or 0 to the RSA_INT_ENA_REG register to
  646. * enable or disable the interrupt function. */
  647. DPORT_REG_WRITE(RSA_INT_CLR_REG, 1); /* write 1 to clear */
  648. DPORT_REG_WRITE(RSA_INT_ENA_REG, 0); /* disable */
  649. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  650. /* not currently clearing / disable on C3 */
  651. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
  652. #else
  653. /* clear interrupt */
  654. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
  655. #endif
  656. if (ESP_TIMEOUT(timeout)) {
  657. ESP_LOGE(TAG, "rsa operation timed out.");
  658. ret = WC_HW_E; /* MP_HW_ERROR; */
  659. }
  660. return ret;
  661. }
  662. /* read data from memory into mp_init */
  663. static int esp_memblock_to_mpint(const word32 mem_address,
  664. MATH_INT_T* mp,
  665. word32 numwords)
  666. {
  667. int ret = MP_OKAY;
  668. #ifdef USE_ESP_DPORT_ACCESS_READ_BUFFER
  669. esp_dport_access_read_buffer((word32*)mp->dp, mem_address, numwords);
  670. #else
  671. ESP_EM__PRE_DPORT_READ;
  672. DPORT_INTERRUPT_DISABLE();
  673. ESP_EM__READ_NON_FIFO_REG;
  674. for (volatile word32 i = 0; i < numwords; ++i) {
  675. ESP_EM__3_16;
  676. mp->dp[i] = DPORT_SEQUENCE_REG_READ(
  677. (volatile word32)(mem_address + i * 4));
  678. }
  679. DPORT_INTERRUPT_RESTORE();
  680. #endif
  681. mp->used = numwords;
  682. #if defined(ESP_VERIFY_MEMBLOCK)
  683. ret = XMEMCMP((const word32 *)mem_address, /* HW reg memory */
  684. (const word32 *)&mp->dp, /* our dp value */
  685. numwords * sizeof(word32));
  686. if (ret != ESP_OK) {
  687. ESP_LOGW(TAG, "Validation Failure esp_memblock_to_mpint.\n"
  688. "Reading %u Words at Address = 0x%08x",
  689. (int)(numwords * sizeof(word32)),
  690. (unsigned int)mem_address);
  691. ESP_LOGI(TAG, "Trying again... ");
  692. esp_dport_access_read_buffer((word32*)mp->dp, mem_address, numwords);
  693. mp->used = numwords;
  694. if (0 != XMEMCMP((const void *)mem_address,
  695. (const void *)&mp->dp,
  696. numwords * sizeof(word32))) {
  697. ESP_LOGE(TAG, "Validation Failure esp_memblock_to_mpint "
  698. "a second time. Giving up.");
  699. ret = MP_VAL;
  700. }
  701. else {
  702. ESP_LOGI(TAG, "Successfully re-read after Validation Failure.");
  703. ret = MP_VAL;
  704. }
  705. }
  706. #endif
  707. return ret;
  708. }
  709. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
  710. /* Write 0x00 to [wordSz] words of register memory starting at mem_address */
  711. #if defined(CONFIG_IDF_TARGET_ESP32)
  712. /* only the classic has memblock clear due to slightly different data layout */
  713. static int esp_zero_memblock(u_int32_t mem_address, int wordSz)
  714. {
  715. int ret = MP_OKAY;
  716. ESP_EM__PRE_DPORT_WRITE;
  717. DPORT_INTERRUPT_DISABLE();
  718. for (int i=0; i < wordSz; i++) {
  719. DPORT_REG_WRITE(
  720. (volatile u_int32_t *)(mem_address + (i * sizeof(word32))),
  721. (u_int32_t)(0) /* zero memory blocks [wordSz] words long */
  722. );
  723. }
  724. DPORT_INTERRUPT_RESTORE();
  725. return ret;
  726. }
  727. #endif /* CONFIG_IDF_TARGET_ESP32 */
  728. #endif /* not NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
  729. /* write MATH_INT_T mp value (dp[]) into memory block */
  730. static int esp_mpint_to_memblock(u_int32_t mem_address,
  731. const MATH_INT_T* mp,
  732. const word32 bits,
  733. const word32 hwords)
  734. {
  735. int ret = MP_OKAY;
  736. /* init */
  737. word32 i; /* memory offset counter */
  738. word32 len; /* actual number of words to write to register */
  739. len = (bits / 8 + ((bits & 7) != 0 ? 1 : 0));
  740. len = (len + sizeof(word32)-1) / sizeof(word32);
  741. /* write */
  742. ESP_EM__PRE_DPORT_WRITE;
  743. DPORT_INTERRUPT_DISABLE();
  744. for (i=0; i < hwords; i++) {
  745. if (i < len) {
  746. /* write our data */
  747. ESP_LOGV(TAG, "Write i = %d value.", i);
  748. DPORT_REG_WRITE(
  749. (volatile u_int32_t*)(mem_address + (i * sizeof(word32))),
  750. mp->dp[i]
  751. ); /* DPORT_REG_WRITE */
  752. }
  753. else {
  754. /* write zeros */
  755. /* TODO we may be able to skip zero in certain circumstances */
  756. if (i == 0) {
  757. ESP_LOGV(TAG, "esp_mpint_to_memblock zero?");
  758. }
  759. ESP_LOGV(TAG, "Write i = %d value = zero.", i);
  760. DPORT_REG_WRITE(
  761. (volatile u_int32_t*)(mem_address + (i * sizeof(word32))),
  762. (u_int32_t)0 /* writing 4 bytes of zero */
  763. ); /* DPORT_REG_WRITE */
  764. }
  765. }
  766. DPORT_INTERRUPT_RESTORE();
  767. /* optional re-read verify */
  768. #if defined(ESP_VERIFY_MEMBLOCK)
  769. len = XMEMCMP((const void *)mem_address, /* HW reg memory */
  770. (const void *)&mp->dp, /* our dp value */
  771. hwords * sizeof(word32)
  772. );
  773. if (len != 0) {
  774. ESP_LOGE(TAG, "esp_mpint_to_memblock compare fails at %d", len);
  775. #ifdef DEBUG_WOLFSSL
  776. esp_show_mp("mp", (MATH_INT_T*)mp);
  777. #endif
  778. ret = MP_VAL;
  779. }
  780. #endif
  781. return ret;
  782. }
  783. /* return needed HW words.
  784. * supported words length
  785. * words : { 16, 32, 48, 64, 80, 96, 112, 128}
  786. * bits : {512, 1024, 1536, 2048, 2560, 3072, 3584, 4096}
  787. */
  788. static word32 words2hwords(word32 wd)
  789. {
  790. const word32 bit_shift = 4;
  791. return (((wd + 0xf) >> bit_shift) << bit_shift);
  792. }
  793. /* count the number of words is needed for bits */
  794. static word32 bits2words(word32 bits)
  795. {
  796. /* 32 bits */
  797. const word32 d = sizeof(word32) * WOLFSSL_BIT_SIZE;
  798. return ((bits + (d - 1)) / d);
  799. }
  800. /* exptmod and mulmod helpers as needed */
  801. #if !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD) \
  802. || \
  803. !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD)
  804. /* rinv and M' only used for mulmod and mulexp_mod */
  805. /* get rinv */
  806. static int esp_get_rinv(MATH_INT_T *rinv, MATH_INT_T *M, word32 exp)
  807. {
  808. #ifdef DEBUG_WOLFSSL
  809. MATH_INT_T rinv2[1];
  810. MATH_INT_T M2[1];
  811. int reti = MP_OKAY;
  812. #endif
  813. int ret = MP_OKAY;
  814. ESP_LOGV(TAG, "\nBegin esp_get_rinv \n");
  815. #ifdef DEBUG_WOLFSSL
  816. mp_copy(M, M2); /* copy (src = M) to (dst = M2) */
  817. mp_copy(rinv, rinv2); /* copy (src = M) to (dst = M2) */
  818. #endif
  819. /* 2^(exp)
  820. *
  821. * rinv will have all zeros with a 1 in last word.
  822. * e.g. exp=2048 will have a 1 in dp[0x40] = dp[64]
  823. * this is the 65'th element (zero based)
  824. * Value for used = 0x41 = 65
  825. **/
  826. ret = mp_2expt(rinv, exp);
  827. if (ret == MP_OKAY) {
  828. ret = mp_mod(rinv, M, rinv);
  829. }
  830. else {
  831. ESP_LOGE(TAG, "failed to calculate mp_2expt()");
  832. }
  833. /* r_inv = R^2 mod M(=P) */
  834. if (ret == MP_OKAY) {
  835. ESP_LOGV(TAG, "esp_get_rinv compute success");
  836. }
  837. else {
  838. ESP_LOGE(TAG, "failed to calculate mp_mod()");
  839. }
  840. #ifdef DEBUG_WOLFSSL
  841. if (ret == MP_OKAY) {
  842. /* computes a = B**n mod b without division or multiplication useful for
  843. * normalizing numbers in a Montgomery system. */
  844. reti = mp_montgomery_calc_normalization(rinv2, M2);
  845. if (reti == MP_OKAY) {
  846. ESP_LOGV(TAG, "mp_montgomery_calc_normalization = %d", reti);
  847. }
  848. else {
  849. ESP_LOGW(TAG, "Error Montgomery calc M2 result = %d", reti);
  850. }
  851. }
  852. #endif
  853. ESP_LOGV(TAG, "\nEnd esp_get_rinv \n");
  854. return ret;
  855. }
  856. #endif /* ! xEXPTMOD || ! xMULMOD for rinv */
  857. /* during debug, we'll compare HW to SW results */
  858. int esp_hw_validation_active(void)
  859. {
  860. #ifdef DEBUG_WOLFSSL
  861. return IS_HW_VALIDATION;
  862. #else
  863. return 0; /* we're never validating when not debugging */
  864. #endif
  865. }
  866. /* useful during debugging and error display,
  867. * we can show all the mp helper calc values */
  868. int esp_show_mph(struct esp_mp_helper* mph)
  869. {
  870. int ret = MP_OKAY;
  871. if (mph == NULL) {
  872. /* if a bad mp helper passed, we cannot use HW */
  873. ESP_LOGE(TAG, "ERROR: Bad esp_mp_helper for esp_show_mph");
  874. return MP_VAL;
  875. }
  876. if (mph->Xs != 0)
  877. ESP_LOGI(TAG, "Xs %d", mph->Xs);
  878. if (mph->Ys != 0)
  879. ESP_LOGI(TAG, "Ys %d", mph->Ys);
  880. if (mph->Ms != 0)
  881. ESP_LOGI(TAG, "Ms %d", mph->Ms);
  882. if (mph->Rs != 0)
  883. ESP_LOGI(TAG, "Rs %d", mph->Rs);
  884. if (mph->maxWords_sz != 0)
  885. ESP_LOGI(TAG, "maxWords_sz %d", mph->maxWords_sz);
  886. if (mph->hwWords_sz != 0)
  887. ESP_LOGI(TAG, "hwWords_sz %d", mph->hwWords_sz);
  888. if (mph->mp != 0)
  889. ESP_LOGI(TAG, "mp %d", mph->mp);
  890. #ifdef DEBUG_WOLFSSL
  891. if (mph->mp2 != 0)
  892. ESP_LOGI(TAG, "mp2 %d", mph->mp2);
  893. #endif
  894. if (mph->r_inv.used != 0)
  895. esp_show_mp("r_inv", &(mph->r_inv));
  896. return ret;
  897. }
  898. #if !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD) \
  899. || \
  900. !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD)
  901. /* only when using exptmod or mulmod, we have some helper functions. */
  902. /* given X, Y, M - setup mp hardware and other helper values.*/
  903. int esp_mp_montgomery_init(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M,
  904. struct esp_mp_helper* mph)
  905. {
  906. int ret = MP_OKAY;
  907. int exp;
  908. if (mph == NULL) {
  909. /* if a bad mp helper passed, we cannot use HW */
  910. ESP_LOGE(TAG, "ERROR: Bad esp_mp_helper, falling back to SW");
  911. return MP_HW_FALLBACK;
  912. }
  913. if ((X == NULL) || (Y == NULL) || (M == NULL) ) {
  914. /* if a bad operand passed, we cannot use HW */
  915. ESP_LOGE(TAG, "ERROR: Bad Montgomery operand, falling back to SW");
  916. return MP_HW_FALLBACK;
  917. }
  918. XMEMSET(mph, 0, sizeof(struct esp_mp_helper));
  919. mph->Xs = mp_count_bits(X); /* X's = the number of bits needed */
  920. #if (ESP_PROHIBIT_SMALL_X == TRUE)
  921. /* optionally prohibit small X.
  922. ** note this is very common in ECC: [1] * [Y] mod [M] */
  923. if ((X->used == 1) && (X->dp[1] < (1 << 8))) {
  924. #ifdef WOLFSSL_HW_METRICS
  925. esp_mp_mulmod_small_x_ct++;
  926. #endif
  927. ESP_LOGW(TAG, "esp_mp_montgomery_init MP_HW_FALLBACK Xs = %d",
  928. mph->Xs);
  929. ret = MP_HW_FALLBACK;
  930. }
  931. #endif
  932. /* prohibit small Y */
  933. if (ret == MP_OKAY) {
  934. mph->Ys = mp_count_bits(Y); /* init Y's to pass to Montgomery init */
  935. if (mph->Xs <= ESP_RSA_EXPT_XBITS) {
  936. /* hard floor 8 bits, problematic in some older ESP32 chips */
  937. #ifdef WOLFSSL_HW_METRICS
  938. {
  939. /* track how many times we fall back */
  940. esp_mp_mulmod_small_x_ct++;
  941. }
  942. #endif
  943. ESP_LOGV(TAG,
  944. "esp_mp_montgomery_init MP_HW_FALLBACK Xs = %d",
  945. mph->Xs);
  946. ret = MP_HW_FALLBACK; /* fall back to software calc at exit */
  947. } /* mph->Xs <= ESP_RSA_EXPT_XBITS */
  948. else {
  949. if (mph->Ys <= ESP_RSA_EXPT_YBITS) {
  950. /* hard floor 8 bits, problematic in some older ESP32 chips */
  951. #ifdef WOLFSSL_HW_METRICS
  952. {
  953. /* track how many times we fall back */
  954. esp_mp_mulmod_small_y_ct++;
  955. }
  956. #endif
  957. ESP_LOGV(TAG,
  958. "esp_mp_montgomery_init MP_HW_FALLBACK Ys = %d",
  959. mph->Ys);
  960. ret = MP_HW_FALLBACK; /* fall back to software calc at exit */
  961. } /* Ys <= ESP_RSA_EXPT_YBITS */
  962. else {
  963. /* X and Y size ok, continue... */
  964. mph->Ms = mp_count_bits(M);
  965. /* maximum bits and words for writing to HW */
  966. mph->maxWords_sz = bits2words(max(mph->Xs,
  967. max(mph->Ys, mph->Ms)));
  968. mph->hwWords_sz = words2hwords(mph->maxWords_sz);
  969. if ((mph->hwWords_sz << 5) > ESP_HW_RSAMAX_BIT) {
  970. ESP_LOGW(TAG, "Warning: hwWords_sz = %d (%d bits)"
  971. " exceeds HW maximum bits (%d), "
  972. " falling back to SW.",
  973. mph->hwWords_sz,
  974. mph->hwWords_sz << 5,
  975. ESP_HW_RSAMAX_BIT);
  976. ret = MP_HW_FALLBACK;
  977. } /* hwWords_sz check */
  978. } /* X and Y size ok */
  979. } /* X size check */
  980. } /* Prior operation ok */
  981. ESP_LOGV(TAG, "hwWords_sz = %d", mph->hwWords_sz);
  982. /* calculate r_inv = R^2 mode M
  983. * where: R = b^n, and b = 2^32
  984. * accordingly R^2 = 2^(n*32*2)
  985. */
  986. #if defined(CONFIG_IDF_TARGET_ESP32)
  987. exp = mph->hwWords_sz << 6;
  988. #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
  989. exp = mph->maxWords_sz * BITS_IN_ONE_WORD * 2;
  990. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  991. exp = mph->maxWords_sz * BITS_IN_ONE_WORD * 2;
  992. #else
  993. exp = 0; /* no HW, no Montgomery HW init */
  994. #endif
  995. if (ret == MP_OKAY && (M != NULL)) {
  996. ret = mp_init((mp_int*)&(mph->r_inv));
  997. if (ret == MP_OKAY) {
  998. ret = esp_get_rinv( (mp_int*)&(mph->r_inv), M, exp);
  999. if (ret == MP_OKAY) {
  1000. mph->Rs = mp_count_bits((mp_int*)&(mph->r_inv));
  1001. }
  1002. else {
  1003. ESP_LOGE(TAG, "calculate r_inv failed.");
  1004. ret = MP_VAL;
  1005. } /* esp_get_rinv check */
  1006. } /* mp_init success */
  1007. else {
  1008. ESP_LOGE(TAG, "calculate r_inv failed mp_init.");
  1009. ret = MP_MEM;
  1010. } /* mp_init check */
  1011. } /* calculate r_inv */
  1012. /* if we were successful in r_inv, next get M' */
  1013. if (ret == MP_OKAY) {
  1014. #ifdef DEBUG_WOLFSSL
  1015. ret = mp_montgomery_setup(M, &(mph->mp2) );
  1016. #endif
  1017. /* calc M' */
  1018. /* if Pm is odd, uses mp_montgomery_setup() */
  1019. ret = esp_calc_Mdash(M, 32/* bits */, &(mph->mp));
  1020. if (ret != MP_OKAY) {
  1021. ESP_LOGE(TAG, "failed esp_calc_Mdash()");
  1022. }
  1023. }
  1024. #ifdef DEBUG_WOLFSSL
  1025. if (ret == MP_OKAY) {
  1026. if (mph->mp == mph->mp2) {
  1027. ESP_LOGV(TAG, "M' match esp_calc_Mdash vs mp_montgomery_setup "
  1028. "= %ul !", mph->mp);
  1029. }
  1030. else {
  1031. ESP_LOGW(TAG,
  1032. "\n\n"
  1033. "M' MISMATCH esp_calc_Mdash = 0x%08x = %d \n"
  1034. "vs mp_montgomery_setup = 0x%08x = %d \n\n",
  1035. mph->mp,
  1036. mph->mp,
  1037. mph->mp2,
  1038. mph->mp2);
  1039. mph->mp = mph->mp2;
  1040. }
  1041. }
  1042. else {
  1043. #if 0
  1044. esp_show_mp("X", X);
  1045. esp_show_mp("Y", Y);
  1046. esp_show_mp("M", M);
  1047. esp_show_mph(mph);
  1048. #endif
  1049. if (ret == MP_HW_FALLBACK) {
  1050. ESP_LOGV(TAG, "esp_mp_montgomery_init exit falling back.");
  1051. }
  1052. else {
  1053. ESP_LOGE(TAG, "esp_mp_montgomery_init failed: return code = %d",
  1054. ret);
  1055. }
  1056. }
  1057. #endif
  1058. return ret;
  1059. } /* esp_mp_montgomery_init */
  1060. #endif /* ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_[EXPTMOD|MULMOD] */
  1061. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
  1062. /* Large Number Multiplication
  1063. *
  1064. * See 24.3.3 of the ESP32 Technical Reference Manual
  1065. *
  1066. * Z = X * Y; */
  1067. int esp_mp_mul(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* Z)
  1068. {
  1069. /* During debug, we may be validating against SW result. */
  1070. #ifdef DEBUG_WOLFSSL
  1071. /* create a place to store copies to perform duplicate operations.
  1072. ** copies needed as some operations overwrite operands: e.g. X = X * Y */
  1073. MATH_INT_T X2[1];
  1074. MATH_INT_T Y2[1];
  1075. MATH_INT_T Z2[1];
  1076. MATH_INT_T PEEK[1];
  1077. #endif
  1078. int ret = MP_OKAY; /* assume success until proven wrong */
  1079. int mp_mul_lock_called = FALSE; /* May fall back to SW; track if locked */
  1080. /* we don't use the mph helper for mp_mul, so we'll calculate locally: */
  1081. word32 Xs;
  1082. word32 Ys;
  1083. word32 Zs;
  1084. word32 maxWords_sz = 0;
  1085. word32 hwWords_sz = 0;
  1086. word32 resultWords_sz = 0;
  1087. #if defined(CONFIG_IDF_TARGET_ESP32)
  1088. word32 left_pad_offset = 0;
  1089. #endif
  1090. /* if we are supporting negative numbers, check that first since operands
  1091. * may be later modified (e.g. Z = Z * X) */
  1092. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  1093. /* neg check: X*Y becomes negative */
  1094. int res_sign;
  1095. /* aka (X->sign == Y->sign) ? MP_ZPOS : MP_NEG; , but with mp_isneg(): */
  1096. res_sign = (mp_isneg(X) == mp_isneg(Y)) ? MP_ZPOS : MP_NEG;
  1097. if (res_sign) {
  1098. /* Negative numbers are relatively infrequent.
  1099. * May be interesting during verbose debugging: */
  1100. ESP_LOGV(TAG, "mp_isneg(X) = %d; mp_isneg(Y) = %d; neg = %d ",
  1101. mp_isneg(X), mp_isneg(Y), res_sign);
  1102. }
  1103. #endif
  1104. #ifdef WOLFSSL_HW_METRICS
  1105. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used : esp_mp_max_used;
  1106. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used : esp_mp_max_used;
  1107. #endif
  1108. /* if either operand is zero, there's nothing to do.
  1109. * Y checked first, as it was observed to be zero during
  1110. * wolfcrypt tests more often than X */
  1111. if (mp_iszero(Y) || mp_iszero(X)) {
  1112. mp_forcezero(Z);
  1113. return MP_OKAY;
  1114. }
  1115. #ifdef DEBUG_WOLFSSL
  1116. /* The caller should have checked if the call was for a SW validation.
  1117. * During debug, we'll return an error. */
  1118. if (esp_hw_validation_active()) {
  1119. return MP_HW_VALIDATION_ACTIVE;
  1120. }
  1121. /* these occur many times during RSA calcs */
  1122. if (X == Z) {
  1123. ESP_LOGV(TAG, "mp_mul X == Z");
  1124. }
  1125. if (Y == Z) {
  1126. ESP_LOGV(TAG, "mp_mul Y == Z");
  1127. }
  1128. mp_init(X2);
  1129. mp_init(Y2);
  1130. mp_init(Z2);
  1131. mp_copy(X, X2); /* copy (src = X) to (dst = X2) */
  1132. mp_copy(Y, Y2); /* copy (src = Y) to (dst = Y2) */
  1133. mp_copy(Z, Z2); /* copy (src = Z) to (dst = Z2) */
  1134. if (IS_HW_VALIDATION) {
  1135. ESP_LOGE(TAG, "Caller must not try HW when validation active.");
  1136. }
  1137. else {
  1138. SET_HW_VALIDATION; /* force next mp_mul to SW for compare */
  1139. mp_mul(X2, Y2, Z2);
  1140. CLR_HW_VALIDATION;
  1141. }
  1142. #endif /* DEBUG_WOLFSSL */
  1143. Xs = mp_count_bits(X);
  1144. Ys = mp_count_bits(Y);
  1145. Zs = Xs + Ys;
  1146. /* RSA Accelerator only supports Large Number Multiplication
  1147. * with operand length N = 32 * x,
  1148. * where x in {1, 2, 3, . . . , 64} */
  1149. if (Xs > 64 || Ys > 64) {
  1150. return MP_HW_FALLBACK; /* TODO add count metric on size fallback */
  1151. }
  1152. if (Zs <= sizeof(mp_digit)*8) {
  1153. Z->dp[0] = X->dp[0] * Y->dp[0];
  1154. Z->used = 1;
  1155. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  1156. Z->sign = res_sign; /* See above mp_isneg() for negative detection */
  1157. #endif
  1158. return MP_OKAY;
  1159. }
  1160. if (ret == MP_OKAY) {
  1161. /* maximum bits and words for writing to HW */
  1162. maxWords_sz = bits2words(max(Xs, Ys));
  1163. hwWords_sz = words2hwords(maxWords_sz);
  1164. resultWords_sz = bits2words(Xs + Ys);
  1165. /* sanity check */
  1166. if ( (hwWords_sz << 5) > ESP_HW_MULTI_RSAMAX_BITS) {
  1167. ESP_LOGW(TAG, "exceeds max bit length(2048) (a)");
  1168. ret = MP_HW_FALLBACK; /* Error: value is not able to be used. */
  1169. }
  1170. }
  1171. #if defined(CONFIG_IDF_TARGET_ESP32)
  1172. /* assumed to be regular ESP32 Xtensa here */
  1173. /*Steps to use HW in the following order:
  1174. * 1. wait until clean HW engine
  1175. * 2. Write(2*N/512bits - 1 + 8) to MULT_MODE_REG
  1176. * 3. Write X and Y to memory blocks
  1177. * need to write data to each memory block only according to the length
  1178. * of the number.
  1179. * 4. Write 1 to MUL_START_REG
  1180. * 5. Wait for the first operation to be done.
  1181. * Poll INTERRUPT_REG until it reads 1.
  1182. * (Or until the INTER interrupt is generated.)
  1183. * 6. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.
  1184. * 7. Read the Z from RSA_Z_MEM
  1185. * 8. Write 1 to RSA_INTERUPT_REG to clear the interrupt.
  1186. * 9. Release the HW engine
  1187. */
  1188. /* Y (left-extend)
  1189. * Accelerator supports large-number multiplication with only
  1190. * four operand lengths of N in {512, 1024, 1536, 2048} */
  1191. left_pad_offset = maxWords_sz << 2;
  1192. if (left_pad_offset <= 512 >> 3) {
  1193. left_pad_offset = 512 >> 3; /* 64 bytes (16 words) */
  1194. }
  1195. else {
  1196. if (left_pad_offset <= 1024 >> 3) {
  1197. left_pad_offset = 1024 >> 3; /* 128 bytes = 32 words */
  1198. }
  1199. else {
  1200. if (left_pad_offset <= 1536 >> 3) {
  1201. left_pad_offset = 1536 >> 3; /* 192 bytes = 48 words */
  1202. }
  1203. else {
  1204. if (left_pad_offset <= 2048 >> 3) {
  1205. left_pad_offset = 2048 >> 3; /* 256 bytes = 64 words */
  1206. }
  1207. else {
  1208. ret = MP_VAL;
  1209. ESP_LOGE(TAG, "Unsupported operand length: %d",
  1210. hwWords_sz);
  1211. }
  1212. }
  1213. }
  1214. }
  1215. /* lock HW for use, enable peripheral clock */
  1216. if (ret == MP_OKAY) {
  1217. mp_mul_lock_called = TRUE; /* we'll not try to unlock
  1218. * unless we locked it here. */
  1219. #ifdef WOLFSSL_HW_METRICS
  1220. {
  1221. /* Only track max values when using HW */
  1222. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used :
  1223. esp_mp_max_used;
  1224. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used :
  1225. esp_mp_max_used;
  1226. }
  1227. #endif
  1228. ret = esp_mp_hw_lock();
  1229. }
  1230. if (ret == MP_OKAY) {
  1231. ret = esp_mp_hw_wait_clean();
  1232. }
  1233. if (ret == MP_OKAY) {
  1234. /* step.1 (2*N/512) => N/256. 512 bits => 16 words */
  1235. /* Write 2*N/512 - 1 + 8 */
  1236. DPORT_REG_WRITE(RSA_MULT_MODE_REG,
  1237. (2 * left_pad_offset * 8 / 512) - 1 + 8);
  1238. /* step.2 write X into memory */
  1239. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  1240. X,
  1241. Xs,
  1242. hwWords_sz);
  1243. /* write zeros from RSA_MEM_Z_BLOCK_BASE to left_pad_offset - 1 */
  1244. esp_zero_memblock(RSA_MEM_Z_BLOCK_BASE,
  1245. (left_pad_offset - 1) / sizeof(int));
  1246. /* write the left-padded Y value into Z */
  1247. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + (left_pad_offset),
  1248. Y,
  1249. Ys,
  1250. hwWords_sz);
  1251. #ifdef DEBUG_WOLFSSL
  1252. /* save value to peek at the result stored in RSA_MEM_Z_BLOCK_BASE */
  1253. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE,
  1254. PEEK,
  1255. 128);
  1256. #endif
  1257. /* step.3 start process */
  1258. process_start(RSA_MULT_START_REG);
  1259. /* step.4,5 wait until done */
  1260. ret = wait_until_done(RSA_INTERRUPT_REG);
  1261. /* step.6 read the result form MEM_Z */
  1262. if (ret == MP_OKAY) {
  1263. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, resultWords_sz);
  1264. }
  1265. #ifndef DEBUG_WOLFSSL
  1266. else {
  1267. ESP_LOGE(TAG, "ERROR: wait_until_done failed in esp32_mp");
  1268. }
  1269. #endif
  1270. } /* end of processing */
  1271. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  1272. /* Unlike the ESP32 that is limited to only four operand lengths,
  1273. * the ESP32-C3 The RSA Accelerator supports large-number modular
  1274. * multiplication with operands of 128 different lengths.
  1275. *
  1276. * X & Y must be represented by the same number of bits. Must be
  1277. * enough to represent the larger one. */
  1278. /* Figure out how many words we need to
  1279. * represent each operand & the result. */
  1280. /* Make sure we are within capabilities of hardware. */
  1281. if ((hwWords_sz * BITS_IN_ONE_WORD) > ESP_HW_MULTI_RSAMAX_BITS) {
  1282. ESP_LOGW(TAG, "exceeds max bit length(%d)", ESP_HW_MULTI_RSAMAX_BITS);
  1283. ret = MP_HW_FALLBACK; /* let SW figure out how to deal with it */
  1284. }
  1285. if ((hwWords_sz * BITS_IN_ONE_WORD * 2) > ESP_HW_RSAMAX_BIT) {
  1286. ESP_LOGW(TAG, "result exceeds max bit length(%d)", ESP_HW_RSAMAX_BIT );
  1287. ret = MP_HW_FALLBACK; /* let SW figure out how to deal with it */
  1288. }
  1289. /* Steps to perform large number multiplication. Calculates Z = X * Y.
  1290. * The number of bits in the operands (X, Y) is N. N can be 32x, where
  1291. * x = {1,2,3,...64}, so the maximum number of bits in X and Y is 2048.
  1292. * See 20.3.3 of ESP32-S3 technical manual
  1293. * 1. Lock the hardware so no-one else uses it and wait until it is ready.
  1294. * 2. Enable/disable interrupt that signals completion
  1295. * -- we don't use the interrupt.
  1296. * 3. Write number of words required for result to the RSA_MODE_REG
  1297. * (now called RSA_LENGTH_REG).
  1298. * Number of words required for the result is 2 * words for operand - 1
  1299. * 4. Load X, Y operands to memory blocks.
  1300. * Note the Y value must be written to as right aligned.
  1301. * 5. Start the operation by writing 1 to RSA_MULT_START_REG,
  1302. * then wait for it to complete by monitoring RSA_IDLE_REG
  1303. * (which is now called RSA_QUERY_INTERRUPT_REG).
  1304. * 6. Read the result out.
  1305. * 7. Release the hardware lock so others can use it.
  1306. * x. Clear the interrupt flag, if you used it (we don't). */
  1307. /* 1. lock HW for use & wait until it is ready. */
  1308. /* lock HW for use, enable peripheral clock */
  1309. if (ret == MP_OKAY) {
  1310. mp_mul_lock_called = TRUE; /* Do not try to unlock unless we locked */
  1311. #ifdef WOLFSSL_HW_METRICS
  1312. {
  1313. /* Only track max values when using HW */
  1314. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used :
  1315. esp_mp_max_used;
  1316. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used :
  1317. esp_mp_max_used;
  1318. }
  1319. #endif
  1320. ret = esp_mp_hw_lock();
  1321. } /* the only thing we expect is success or busy */
  1322. if (ret == MP_OKAY) {
  1323. ret = esp_mp_hw_wait_clean();
  1324. }
  1325. /* HW multiply */
  1326. if (ret == MP_OKAY) {
  1327. /* 2. Disable completion interrupt signal; we don't use.
  1328. ** 0 => no interrupt; 1 => interrupt on completion. */
  1329. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0);
  1330. /* 3. Write number of words required for result. */
  1331. DPORT_REG_WRITE(RSA_LENGTH_REG, (hwWords_sz * 2 - 1));
  1332. /* 4. Load X, Y operands. Maximum is 64 words (64*8*4 = 2048 bits) */
  1333. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  1334. X,
  1335. Xs,
  1336. hwWords_sz);
  1337. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + hwWords_sz * 4,
  1338. Y,
  1339. Ys,
  1340. hwWords_sz);
  1341. /* 5. Start operation and wait until it completes. */
  1342. process_start(RSA_MULT_START_REG);
  1343. ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
  1344. }
  1345. if (ret == MP_OKAY) {
  1346. /* 6. read the result form MEM_Z */
  1347. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, resultWords_sz);
  1348. }
  1349. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  1350. /* Unlike the ESP32 that is limited to only four operand lengths,
  1351. * the ESP32-C6 The RSA Accelerator supports large-number modular
  1352. * multiplication with operands of 128 different lengths.
  1353. *
  1354. * X & Y must be represented by the same number of bits. Must be
  1355. * enough to represent the larger one. */
  1356. /* Figure out how many words we need to
  1357. * represent each operand & the result. */
  1358. /* Make sure we are within capabilities of hardware. */
  1359. if ((hwWords_sz * BITS_IN_ONE_WORD) > ESP_HW_MULTI_RSAMAX_BITS) {
  1360. ESP_LOGW(TAG, "exceeds max bit length(%d)", ESP_HW_MULTI_RSAMAX_BITS);
  1361. ret = MP_HW_FALLBACK; /* let SW figure out how to deal with it */
  1362. }
  1363. if ((hwWords_sz * BITS_IN_ONE_WORD * 2) > ESP_HW_RSAMAX_BIT) {
  1364. ESP_LOGW(TAG, "result exceeds max bit length(%d)", ESP_HW_RSAMAX_BIT );
  1365. ret = MP_HW_FALLBACK; /* let SW figure out how to deal with it */
  1366. }
  1367. /* Steps to perform large number multiplication. Calculates Z = X * Y.
  1368. * The number of bits in the operands (X, Y) is N.
  1369. * N can be 32x, where x = {1,2,3,...64},
  1370. * so the maximum number of bits in the X and Y is 2048.
  1371. * See 20.3.3 of ESP32-S3 technical manual
  1372. * 1. Lock the hardware so no-one else uses it and wait until it is ready.
  1373. * 2. Enable/disable interrupt that signals completion
  1374. * -- we don't use the interrupt.
  1375. * 3. Write number of words required for result to the RSA_MODE_REG
  1376. * (now called RSA_LENGTH_REG).
  1377. * Number of words required for the result is 2 * words for operand - 1
  1378. * 4. Load X, Y operands to memory blocks.
  1379. * Note the Y value must be written to right aligned.
  1380. * 5. Start the operation by writing 1 to RSA_MULT_START_REG,
  1381. * then wait for it to complete by monitoring RSA_IDLE_REG
  1382. * (which is now called RSA_QUERY_INTERRUPT_REG).
  1383. * 6. Read the result out.
  1384. * 7. Release the hardware lock so others can use it.
  1385. * x. Clear the interrupt flag, if you used it (we don't). */
  1386. /* 1. lock HW for use & wait until it is ready. */
  1387. /* lock HW for use, enable peripheral clock */
  1388. if (ret == MP_OKAY) {
  1389. mp_mul_lock_called = TRUE; /* Do not try to unlock unless we locked */
  1390. #ifdef WOLFSSL_HW_METRICS
  1391. {
  1392. /* Only track max values when using HW */
  1393. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used :
  1394. esp_mp_max_used;
  1395. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used :
  1396. esp_mp_max_used;
  1397. }
  1398. #endif
  1399. ret = esp_mp_hw_lock();
  1400. } /* the only thing we expect is success or busy */
  1401. if (ret == MP_OKAY) {
  1402. ret = esp_mp_hw_wait_clean();
  1403. }
  1404. /* HW multiply */
  1405. if (ret == MP_OKAY) {
  1406. /* 1. Disable completion interrupt signal; we don't use.
  1407. * Write 1 (enable) or 0 (disable) to the RSA_INT_ENA_REG register.
  1408. * 0 => no interrupt; 1 => interrupt on completion. */
  1409. DPORT_REG_WRITE(RSA_INT_ENA_REG, 0);
  1410. /* 2. Write number of words required for result. */
  1411. /* see 21.3.3 Write (/N16 - 1) to the RSA_MODE_REG register */
  1412. DPORT_REG_WRITE(RSA_MODE_REG, (hwWords_sz * 2 - 1));
  1413. /* 3. Write Xi and Yi for {0, 1, . . . , n - 1} to memory blocks
  1414. * RSA_X_MEM and RSA_Z_MEM
  1415. * Maximum is 64 words (64*8*4 = 2048 bits) */
  1416. esp_mpint_to_memblock(RSA_X_MEM,
  1417. X,
  1418. Xs,
  1419. hwWords_sz);
  1420. esp_mpint_to_memblock(RSA_Z_MEM + hwWords_sz * 4,
  1421. Y,
  1422. Ys,
  1423. hwWords_sz);
  1424. /* 4. Write 1 to the RSA_SET_START_MULT register */
  1425. ret = process_start(RSA_SET_START_MULT_REG);
  1426. }
  1427. /* 5. Wait for the completion of computation, which happens when the
  1428. * content of RSA_QUERY_IDLE becomes 1 or the RSA interrupt occurs. */
  1429. if (ret == MP_OKAY) {
  1430. ret = wait_until_done(RSA_QUERY_IDLE_REG);
  1431. }
  1432. if (ret == MP_OKAY) {
  1433. /* 6. read the result from MEM_Z */
  1434. esp_memblock_to_mpint(RSA_Z_MEM, Z, resultWords_sz);
  1435. }
  1436. /* end ESP32-C6 */
  1437. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  1438. /* Unlike the ESP32 that is limited to only four operand lengths,
  1439. * the ESP32-S3 The RSA Accelerator supports large-number modular
  1440. * multiplication with operands of 128 different lengths.
  1441. *
  1442. * X & Y must be represented by the same number of bits. Must be
  1443. * enough to represent the larger one. */
  1444. /* Figure out how many words we need to
  1445. * represent each operand & the result. */
  1446. /* Make sure we are within capabilities of hardware. */
  1447. if ((hwWords_sz * BITS_IN_ONE_WORD) > ESP_HW_MULTI_RSAMAX_BITS) {
  1448. ESP_LOGW(TAG, "exceeds max bit length(%d)", ESP_HW_MULTI_RSAMAX_BITS);
  1449. ret = MP_HW_FALLBACK; /* let SW figure out how to deal with it */
  1450. }
  1451. if ((hwWords_sz * BITS_IN_ONE_WORD * 2) > ESP_HW_RSAMAX_BIT) {
  1452. ESP_LOGW(TAG, "result exceeds max bit length(%d)", ESP_HW_RSAMAX_BIT );
  1453. ret = MP_HW_FALLBACK; /* let SW figure out how to deal with it */
  1454. }
  1455. /* Steps to perform large number multiplication. Calculates Z = X * Y.
  1456. * The number of bits in the operands (X, Y) is N.
  1457. * N can be 32x, where x = {1,2,3,...64},
  1458. * so the maximum number of bits in the X and Y is 2048.
  1459. * See 20.3.3 of ESP32-S3 technical manual
  1460. * 1. Lock the hardware so no-one else uses it and wait until it is ready.
  1461. * 2. Enable/disable interrupt that signals completion
  1462. * -- we don't use the interrupt.
  1463. * 3. Write number of words required for result to the RSA_MODE_REG
  1464. * (now called RSA_LENGTH_REG).
  1465. * Number of words required for the result is 2 * words for operand - 1
  1466. * 4. Load X, Y operands to memory blocks.
  1467. * Note the Y value must be written to right aligned.
  1468. * 5. Start the operation by writing 1 to RSA_MULT_START_REG,
  1469. * then wait for it to complete by monitoring RSA_IDLE_REG
  1470. * (which is now called RSA_QUERY_INTERRUPT_REG).
  1471. * 6. Read the result out.
  1472. * 7. Release the hardware lock so others can use it.
  1473. * x. Clear the interrupt flag, if you used it (we don't). */
  1474. /* 1. lock HW for use & wait until it is ready. */
  1475. if (ret == MP_OKAY) {
  1476. mp_mul_lock_called = TRUE; /* Don't try to unlock unless we locked. */
  1477. #ifdef WOLFSSL_HW_METRICS
  1478. {
  1479. /* Only track max values when using HW */
  1480. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used :
  1481. esp_mp_max_used;
  1482. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used :
  1483. esp_mp_max_used;
  1484. }
  1485. #endif
  1486. ret = esp_mp_hw_lock();
  1487. } /* the only thing we expect is success or busy */
  1488. if (ret == MP_OKAY) {
  1489. ret = esp_mp_hw_wait_clean();
  1490. }
  1491. /* HW multiply */
  1492. if (ret == MP_OKAY) {
  1493. /* 2. Disable completion interrupt signal; we don't use.
  1494. ** 0 => no interrupt; 1 => interrupt on completion. */
  1495. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0);
  1496. /* 3. Write number of words required for result. */
  1497. DPORT_REG_WRITE(RSA_LENGTH_REG, (hwWords_sz * 2 - 1));
  1498. /* 4. Load X, Y operands. Maximum is 64 words (64*8*4 = 2048 bits) */
  1499. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  1500. X,
  1501. Xs,
  1502. hwWords_sz);
  1503. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE + hwWords_sz * 4,
  1504. Y,
  1505. Ys,
  1506. hwWords_sz);
  1507. /* 5. Start operation and wait until it completes. */
  1508. process_start(RSA_MULT_START_REG);
  1509. ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
  1510. }
  1511. if (ret == MP_OKAY) {
  1512. /* 6. read the result form MEM_Z */
  1513. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, resultWords_sz);
  1514. }
  1515. /*
  1516. ** end if CONFIG_IDF_TARGET_ESP32S3
  1517. */
  1518. #else
  1519. ret = MP_HW_FALLBACK;
  1520. #endif /* target HW calcs*/
  1521. /* common exit for all chipset types */
  1522. /* step.7 clear and release HW */
  1523. if (mp_mul_lock_called) {
  1524. ret = esp_mp_hw_unlock();
  1525. }
  1526. else {
  1527. ESP_LOGV(TAG, "Lock not called");
  1528. }
  1529. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  1530. if (ret == MP_OKAY) {
  1531. if (!mp_iszero(Z) && res_sign) {
  1532. /* for non-zero negative numbers, set negative flag for our result:
  1533. * Z->sign = FP_NEG */
  1534. ESP_LOGV(TAG, "Setting Z to negative result!");
  1535. mp_setneg(Z);
  1536. }
  1537. else {
  1538. Z->sign = MP_ZPOS;
  1539. }
  1540. }
  1541. #endif
  1542. if (ret == MP_OKAY) {
  1543. /* never clean the result for anything other than success, as we may
  1544. * fall back to SW and we don't want to muck up operand values. */
  1545. esp_clean_result(Z, 0);
  1546. }
  1547. #ifdef DEBUG_WOLFSSL
  1548. if (mp_cmp(X, X2) != 0) {
  1549. /* this may be interesting when operands change (e.g. z=x*z mode m) */
  1550. /* ESP_LOGE(TAG, "mp_mul X vs X2 mismatch!"); */
  1551. }
  1552. if (mp_cmp(Y, Y2) != 0) {
  1553. /* this may be interesting when operands change (e.g. z=y*z mode m) */
  1554. /* ESP_LOGE(TAG, "mp_mul Y vs Y2 mismatch!"); */
  1555. }
  1556. if (mp_cmp(Z, Z2) != 0) {
  1557. int found_z_used = Z->used;
  1558. ESP_LOGE(TAG, "mp_mul Z vs Z2 mismatch!");
  1559. ESP_LOGI(TAG, "Xs = %d", Xs);
  1560. ESP_LOGI(TAG, "Ys = %d", Ys);
  1561. ESP_LOGI(TAG, "Zs = %d", Zs);
  1562. ESP_LOGI(TAG, "found_z_used = %d", found_z_used);
  1563. ESP_LOGI(TAG, "z.used = %d", Z->used);
  1564. ESP_LOGI(TAG, "hwWords_sz = %d", hwWords_sz);
  1565. ESP_LOGI(TAG, "maxWords_sz = %d", maxWords_sz);
  1566. #if defined(CONFIG_IDF_TARGET_ESP32)
  1567. ESP_LOGI(TAG, "left_pad_offset = %d", left_pad_offset);
  1568. #endif
  1569. ESP_LOGI(TAG, "hwWords_sz<<2 = %d", hwWords_sz << 2);
  1570. esp_show_mp("X", X2); /* show X2 copy, as X may have been clobbered */
  1571. esp_show_mp("Y", Y2); /* show Y2 copy, as Y may have been clobbered */
  1572. esp_show_mp("Peek Z", PEEK); /* this is the Z before start */
  1573. esp_show_mp("Z", Z); /* this is the HW result */
  1574. esp_show_mp("Z2", Z2); /* this is the SW result */
  1575. #ifndef NO_RECOVER_SOFTWARE_CALC
  1576. ESP_LOGW(TAG, "Recovering mp_mul error with software result");
  1577. mp_copy(Z2, Z); /* copy (src = Z2) to (dst = Z) */
  1578. #else
  1579. ret = MP_VAL;
  1580. #endif
  1581. }
  1582. #endif
  1583. #ifdef WOLFSSL_HW_METRICS
  1584. esp_mp_mul_usage_ct++;
  1585. esp_mp_max_used = (Z->used > esp_mp_max_used) ? Z->used : esp_mp_max_used;
  1586. if (ret != MP_OKAY) {
  1587. esp_mp_mul_error_ct++; /* includes fallback */
  1588. }
  1589. #endif
  1590. ESP_LOGV(TAG, "\nEnd esp_mp_mul \n");
  1591. return ret;
  1592. } /* esp_mp_mul() */
  1593. #endif /* Use HW mp_mul: ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL*/
  1594. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
  1595. /* Large Number Modular Multiplication
  1596. *
  1597. * See 24.3.3 of the ESP32 Technical Reference Manual
  1598. *
  1599. * Z = X * Y mod M */
  1600. int esp_mp_mulmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
  1601. {
  1602. struct esp_mp_helper mph[1]; /* we'll save some values in this mp helper */
  1603. MATH_INT_T tmpZ[1] = { };
  1604. #ifdef DEBUG_WOLFSSL
  1605. MATH_INT_T X2[1] = { };
  1606. MATH_INT_T Y2[1] = { };
  1607. MATH_INT_T M2[1] = { };
  1608. MATH_INT_T Z2[1] = { };
  1609. MATH_INT_T PEEK[1] = { };
  1610. (void) PEEK;
  1611. #endif
  1612. int ret = MP_OKAY;
  1613. int mulmod_lock_called = FALSE;
  1614. word32 zwords = 0;
  1615. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  1616. int negcheck = 0;
  1617. #endif
  1618. #ifdef DEBUG_WOLFSSL
  1619. int reti = 0; /* interim return value used only during HW==SW validation */
  1620. #endif
  1621. #if defined(CONFIG_IDF_TARGET_ESP32)
  1622. #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
  1623. word32 OperandBits;
  1624. int WordsForOperand;
  1625. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  1626. word32 OperandBits;
  1627. int WordsForOperand;
  1628. #else
  1629. ret = MP_HW_FALLBACK;
  1630. #endif
  1631. ESP_LOGV(TAG, "\nBegin esp_mp_mulmod \n");
  1632. /* do we have an even moduli? */
  1633. if ((M->dp[0] & 1) == 0) {
  1634. #ifndef NO_ESP_MP_MUL_EVEN_ALT_CALC
  1635. /* Z = X * Y mod M in mixed HW & SW*/
  1636. ret = esp_mp_mul(X, Y, tmpZ); /* HW X * Y */
  1637. if (ret == MP_OKAY) {
  1638. /* z = tmpZ mod M, 0 <= Z < M */
  1639. ret = mp_mod(tmpZ, M, Z); /* SW mod M */
  1640. }
  1641. ESP_LOGV(TAG, "alternate mp_mul calc!");
  1642. return ret;
  1643. #else
  1644. #ifdef WOLFSSL_HW_METRICS
  1645. esp_mp_mulmod_even_mod_ct++;
  1646. #endif
  1647. ESP_LOGV(TAG, "esp_mp_mulmod does not support even numbers");
  1648. ret = MP_HW_FALLBACK; /* let the software figure out what to do */
  1649. return ret;
  1650. #endif /* NO_ESP_MP_MUL_EVEN_ALTERNATE */
  1651. } /* even moduli check */
  1652. #ifdef DEBUG_WOLFSSL
  1653. /* we're only validating HW when in debug mode */
  1654. if (esp_hw_validation_active()) {
  1655. ESP_LOGV(TAG, "MP_HW_VALIDATION_ACTIVE");
  1656. return MP_HW_VALIDATION_ACTIVE;
  1657. }
  1658. #endif
  1659. #ifdef DEBUG_WOLFSSL
  1660. if (IS_HW_VALIDATION) {
  1661. ESP_LOGE(TAG, "Caller must not try HW when validation active.");
  1662. }
  1663. else {
  1664. /* when validating, save SW in [V]2 for later comparison to HW */
  1665. mp_init(X2);
  1666. mp_init(Y2);
  1667. mp_init(M2);
  1668. mp_init(Z2);
  1669. mp_copy(X, X2); /* copy (src = X) to (dst = X2) */
  1670. mp_copy(Y, Y2); /* copy (src = Y) to (dst = Y2) */
  1671. mp_copy(M, M2); /* copy (src = M) to (dst = M2) */
  1672. mp_copy(Z, Z2); /* copy (src = Z) to (dst = Z2) */
  1673. SET_HW_VALIDATION; /* for the next mulmod to be SW for HW validation */
  1674. reti = mp_mulmod(X2, Y2, M2, Z2);
  1675. if (reti == 0) {
  1676. ESP_LOGV(TAG, "wolfSSL mp_mulmod during validation success");
  1677. }
  1678. else {
  1679. ESP_LOGE(TAG, "wolfSSL mp_mulmod during validation failed");
  1680. }
  1681. CLR_HW_VALIDATION;
  1682. }
  1683. #endif /* DEBUG_WOLFSSL */
  1684. if (ret == MP_OKAY) {
  1685. /* neg check: X*Y becomes negative, we'll need adjustment */
  1686. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  1687. negcheck = mp_isneg(X) != mp_isneg(Y) ? 1 : 0;
  1688. #endif
  1689. /* calculate r_inv = R^2 mod M
  1690. * where: R = b^n, and b = 2^32
  1691. * accordingly R^2 = 2^(n*32*2)
  1692. */
  1693. ret = esp_mp_montgomery_init(X, Y, M, mph);
  1694. if (ret == MP_OKAY) {
  1695. ESP_LOGV(TAG, "esp_mp_exptmod esp_mp_montgomery_init success.");
  1696. }
  1697. else {
  1698. #ifdef WOLFSSL_HW_METRICS
  1699. if (ret == MP_HW_FALLBACK) {
  1700. esp_mp_mulmod_fallback_ct++;
  1701. }
  1702. else {
  1703. esp_mp_mulmod_error_ct++;
  1704. }
  1705. #endif
  1706. return ret;
  1707. }
  1708. zwords = bits2words(min(mph->Ms, mph->Xs + mph->Ys));
  1709. }
  1710. /* we'll use hardware only for a minimum number of bits */
  1711. if (mph->Xs <= ESP_RSA_MULM_BITS || mph->Ys <= ESP_RSA_MULM_BITS) {
  1712. #ifdef WOLFSSL_HW_METRICS
  1713. {
  1714. esp_mp_mulmod_small_y_ct++; /* track how many times we fall back */
  1715. }
  1716. #endif
  1717. ret = MP_HW_FALLBACK;
  1718. /* TODO add debug metrics */
  1719. #ifdef WOLFSSL_DEBUG_ESP_RSA_MULM_BITS
  1720. {
  1721. ESP_LOGV(TAG, "esp_mp_mulmod falling back for ESP_RSA_MULM_BITS!");
  1722. }
  1723. #endif
  1724. }
  1725. /* lock HW for use, enable peripheral clock */
  1726. if (ret == MP_OKAY) {
  1727. mulmod_lock_called = TRUE; /* Don't try to unlock unless we locked */
  1728. #ifdef WOLFSSL_HW_METRICS
  1729. {
  1730. /* Only track max values when using HW */
  1731. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used :
  1732. esp_mp_max_used;
  1733. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used :
  1734. esp_mp_max_used;
  1735. esp_mp_max_used = (M->used > esp_mp_max_used) ? M->used :
  1736. esp_mp_max_used;
  1737. }
  1738. #endif
  1739. ret = esp_mp_hw_lock();
  1740. }
  1741. #if defined(CONFIG_IDF_TARGET_ESP32)
  1742. /* Classic ESP32, non-S3 Xtensa */
  1743. /*Steps to use HW in the following order:
  1744. * prep: wait until clean HW engine
  1745. *
  1746. * 1. Write (N/512bits - 1) to MULT_MODE_REG
  1747. * 2. Write X,M(=G, X, P) to memory blocks
  1748. * need to write data to each memory block only according to the length
  1749. * of the number.
  1750. * 3. Write M' to M_PRIME_REG
  1751. * 4. Write 1 to MODEXP_START_REG
  1752. * 5. Wait for the first round of the operation to be completed.
  1753. * Poll RSA_INTERRUPT_REG until it reads 1,
  1754. * or until the RSA_INTR interrupt is generated.
  1755. * (Or until the INTER interrupt is generated.)
  1756. * 6. Write 1 to RSA_INTERRUPT_REG to clear the interrupt.
  1757. * 7. Write Yi (i in [0, n) intersect N) to RSA_X_MEM
  1758. * Users need to write to the memory block only according to the length
  1759. * of the number. Data beyond this length is ignored.
  1760. * 8. Write 1 to RSA_MULT_START_REG
  1761. * 9. Wait for the second operation to be completed.
  1762. * Poll INTERRUPT_REG until it reads 1.
  1763. * 10. Read the Zi (i in [0, n) intersect N) from RSA_Z_MEM
  1764. * 11. Write 1 to RSA_INTERUPT_REG to clear the interrupt.
  1765. *
  1766. * post: Release the HW engine
  1767. *
  1768. * After the operation, the RSA_MULT_MODE_REG register, and memory blocks
  1769. * RSA_M_MEM and RSA_M_PRIME_REG remain unchanged. Users do not need to
  1770. * refresh these registers or memory blocks if the values remain the same.
  1771. */
  1772. if (ret == MP_OKAY) {
  1773. /* Prep wait for the engine */
  1774. ret = esp_mp_hw_wait_clean();
  1775. }
  1776. if (ret == MP_OKAY) {
  1777. /* step.1
  1778. * Write (N/512bits - 1) to MULT_MODE_REG
  1779. * 512 bits => 16 words */
  1780. DPORT_REG_WRITE(RSA_MULT_MODE_REG, (mph->hwWords_sz >> 4) - 1);
  1781. #if defined(DEBUG_WOLFSSL)
  1782. ESP_LOGV(TAG, "RSA_MULT_MODE_REG = %d", (mph->hwWords_sz >> 4) - 1);
  1783. #endif /* WOLFSSL_DEBUG */
  1784. /* step.2 write X, M, and r_inv into memory.
  1785. * The capacity of each memory block is 128 words.
  1786. * The memory blocks use the little endian format for storage, i.e.
  1787. * the least significant digit of each number is in lowest address.*/
  1788. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  1789. X, mph->Xs, mph->hwWords_sz);
  1790. esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE,
  1791. M, mph->Ms, mph->hwWords_sz);
  1792. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE,
  1793. &(mph->r_inv), mph->Rs, mph->hwWords_sz);
  1794. /* step.3 write M' into memory */
  1795. /* confirmed that mp2 does not support even modulus.
  1796. * indeed we see a failure, but we can predict when modules is odd
  1797. * or when mp != mp2[0] */
  1798. DPORT_REG_WRITE(RSA_M_DASH_REG, mph->mp);
  1799. ESP_EM__3_16;
  1800. /* step.4 start process */
  1801. process_start(RSA_MULT_START_REG);
  1802. /* step.5,6 wait until done */
  1803. wait_until_done(RSA_INTERRUPT_REG);
  1804. /* step.7 Y to MEM_X */
  1805. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  1806. Y, mph->Ys,
  1807. mph->hwWords_sz);
  1808. #ifdef DEBUG_WOLFSSL
  1809. /* save value to peek at the result stored in RSA_MEM_Z_BLOCK_BASE */
  1810. esp_memblock_to_mpint(RSA_MEM_X_BLOCK_BASE,
  1811. PEEK,
  1812. 128);
  1813. esp_clean_result(PEEK, 0);
  1814. #endif /* DEBUG_WOLFSSL */
  1815. /* step.8 start process */
  1816. process_start(RSA_MULT_START_REG);
  1817. /* step.9,11 wait until done */
  1818. wait_until_done(RSA_INTERRUPT_REG);
  1819. /* step.12 read the result from MEM_Z */
  1820. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, tmpZ, zwords);
  1821. } /* step 1 .. 12 */
  1822. /* step.13 clear and release HW */
  1823. if (mulmod_lock_called) {
  1824. ret = esp_mp_hw_unlock();
  1825. }
  1826. else {
  1827. ESP_LOGV(TAG, "Lock not called");
  1828. }
  1829. /* end of ESP32 */
  1830. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  1831. /* Steps to perform large number modular multiplication.
  1832. * Calculates Z = (X * Y) modulo M.
  1833. * The number of bits in the operands (X, Y) is N. N can be 32x, where
  1834. * x = {1,2,3,...64}, so the maximum number of bits in the X and Y is 2048.
  1835. * We must use the same number of words to represent bits in X, Y and M.
  1836. * See 20.3.3 of ESP32-C3 technical manual
  1837. * 1. Wait until the hardware is ready.
  1838. * 2. Enable/disable interrupt that signals completion
  1839. * -- we don't use the interrupt.
  1840. * 3. Write the number of words required to represent the operands to the
  1841. * RSA_MODE_REG (now called RSA_LENGTH_REG).
  1842. * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
  1843. * 5. Load X, Y, M, r' operands to memory blocks.
  1844. * 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG,
  1845. * then wait for it to complete by monitoring RSA_IDLE_REG
  1846. * (which is now called RSA_QUERY_INTERRUPT_REG).
  1847. * 7. Read the result out.
  1848. * 8. Release the hardware lock so others can use it.
  1849. * x. Clear the interrupt flag, if you used it (we don't). */
  1850. /* 1. Wait until hardware is ready. */
  1851. if (ret == MP_OKAY) {
  1852. ret = esp_mp_hw_wait_clean();
  1853. }
  1854. if (ret == MP_OKAY) {
  1855. /* 2. Disable completion interrupt signal; we don't use.
  1856. ** 0 => no interrupt; 1 => interrupt on completion. */
  1857. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0);
  1858. /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
  1859. OperandBits = max(max(mph->Xs, mph->Ys), mph->Ms);
  1860. if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
  1861. ESP_LOGW(TAG, "result exceeds max bit length");
  1862. return MP_VAL; /* Error: value is not able to be used. */
  1863. }
  1864. WordsForOperand = bits2words(OperandBits);
  1865. /* alt inline calc:
  1866. * DPORT_REG_WRITE(RSA_MULT_MODE_REG, (mph->hwWords_sz >> 4) - 1); */
  1867. DPORT_REG_WRITE(RSA_LENGTH_REG, WordsForOperand - 1);
  1868. /* 4. Write M' value into RSA_M_PRIME_REG
  1869. * (now called RSA_M_DASH_REG) */
  1870. DPORT_REG_WRITE(RSA_M_DASH_REG, mph->mp);
  1871. /* Select acceleration options. */
  1872. DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0);
  1873. /* 5. Load X, Y, M, r' operands.
  1874. * Note RSA_MEM_RB_BLOCK_BASE == RSA_MEM_Z_BLOC_BASE on ESP32s3*/
  1875. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  1876. X,
  1877. mph->Xs,
  1878. mph->hwWords_sz);
  1879. esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE,
  1880. Y,
  1881. mph->Ys,
  1882. mph->hwWords_sz);
  1883. esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE,
  1884. M,
  1885. mph->Ms,
  1886. mph->hwWords_sz);
  1887. esp_mpint_to_memblock(RSA_MEM_RB_BLOCK_BASE,
  1888. &(mph->r_inv),
  1889. mph->Rs,
  1890. mph->hwWords_sz);
  1891. /* 6. Start operation and wait until it completes. */
  1892. process_start(RSA_MOD_MULT_START_REG); /* esp_mp_mulmod */
  1893. }
  1894. if (ret == MP_OKAY) {
  1895. ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
  1896. }
  1897. if (ret == MP_OKAY) {
  1898. /* 7. read the result from MEM_Z */
  1899. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, tmpZ, zwords);
  1900. }
  1901. /* 8. clear and release HW */
  1902. if (mulmod_lock_called) {
  1903. ret = esp_mp_hw_unlock();
  1904. }
  1905. else {
  1906. ESP_LOGV(TAG, "Lock not called, esp_mp_hw_unlock skipped");
  1907. }
  1908. /* end if CONFIG_IDF_TARGET_ESP32C3 */
  1909. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  1910. /* Steps to perform large number modular multiplication.
  1911. * Calculates Z = (X * Y) modulo M.
  1912. * The number of bits in the operands (X, Y) is N. N can be 32x,where
  1913. * x = {1,2,3,...64}, so the maximum number of bits in X and Y is 2048.
  1914. * We must use the same number of words to represent the bits X, Y and M.
  1915. * See 20.3.3 of ESP32-S3 technical manual
  1916. * 1. Wait until the hardware is ready.
  1917. * 2. Enable/disable interrupt that signals completion
  1918. * -- we don't use the interrupt.
  1919. * 3. Write the number of words required to represent the operands to the
  1920. * RSA_MODE_REG (now called RSA_LENGTH_REG).
  1921. * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
  1922. * 5. Load X, Y, M, r' operands to memory blocks.
  1923. * 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG,
  1924. * then wait for it to complete by monitoring RSA_IDLE_REG
  1925. * (which is now called RSA_QUERY_INTERRUPT_REG).
  1926. * 7. Read the result out.
  1927. * 8. Release the hardware lock so others can use it.
  1928. * x. Clear the interrupt flag, if you used it (we don't). */
  1929. /* 1. Wait until hardware is ready for esp_mp_mulmod. */
  1930. if (ret == MP_OKAY) {
  1931. ret = esp_mp_hw_wait_clean();
  1932. }
  1933. if (ret == MP_OKAY) {
  1934. /* 2. Disable completion interrupt signal; we don't use.
  1935. ** 0 => no interrupt; 1 => interrupt on completion. */
  1936. DPORT_REG_WRITE(RSA_INT_ENA_REG, 0);
  1937. /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
  1938. OperandBits = max(max(mph->Xs, mph->Ys), mph->Ms);
  1939. if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
  1940. ESP_LOGW(TAG, "result exceeds max bit length");
  1941. return MP_VAL; /* Error: value is not able to be used. */
  1942. }
  1943. WordsForOperand = bits2words(OperandBits);
  1944. /* alt inline calc:
  1945. * DPORT_REG_WRITE(RSA_MULT_MODE_REG, (mph->hwWords_sz >> 4) - 1); */
  1946. DPORT_REG_WRITE(RSA_MODE_REG, WordsForOperand - 1);
  1947. /* 4. Write M' value into RSA_M_PRIME_REG
  1948. * (now called RSA_M_DASH_REG) */
  1949. DPORT_REG_WRITE(RSA_M_PRIME_REG, mph->mp);
  1950. /* Select acceleration options. */
  1951. DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0);
  1952. DPORT_REG_WRITE(RSA_SEARCH_POS_REG, 0); /* or RSA_SEARCH_ENABLE */
  1953. /* 5. Load X, Y, M, r' operands.
  1954. * Note RSA_MEM_RB_BLOCK_BASE == RSA_M_MEM on ESP32-C6*/
  1955. esp_mpint_to_memblock(RSA_X_MEM,
  1956. X,
  1957. mph->Xs,
  1958. mph->hwWords_sz);
  1959. esp_mpint_to_memblock(RSA_Y_MEM,
  1960. Y,
  1961. mph->Ys,
  1962. mph->hwWords_sz);
  1963. esp_mpint_to_memblock(RSA_M_MEM,
  1964. M,
  1965. mph->Ms,
  1966. mph->hwWords_sz);
  1967. esp_mpint_to_memblock(RSA_Z_MEM,
  1968. &(mph->r_inv),
  1969. mph->Rs,
  1970. mph->hwWords_sz);
  1971. /* 6. Start operation and wait until it completes. */
  1972. process_start(RSA_SET_START_MODMULT_REG); /* reminder: esp_mp_mulmod */
  1973. }
  1974. /* 5. Wait for the completion of computation, which happens when the
  1975. * content of RSA_QUERY_IDLE becomes 1 or the RSA interrupt occurs. */
  1976. if (ret == MP_OKAY) {
  1977. ret = wait_until_done(RSA_QUERY_IDLE_REG);
  1978. }
  1979. if (ret == MP_OKAY) {
  1980. /* 7. read the result from MEM_Z */
  1981. esp_memblock_to_mpint(RSA_Z_MEM, tmpZ, zwords);
  1982. }
  1983. /* 8. clear and release HW */
  1984. if (mulmod_lock_called) {
  1985. ret = esp_mp_hw_unlock();
  1986. }
  1987. else {
  1988. ESP_LOGV(TAG, "Lock not called, esp_mp_hw_unlock skipped");
  1989. }
  1990. /* end if CONFIG_IDF_TARGET_ESP32C3 or CONFIG_IDF_TARGET_ESP32C6 */
  1991. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  1992. /* Steps to perform large number modular multiplication.
  1993. * Calculates Z = (X * Y) modulo M.
  1994. * The number of bits in the operands (X, Y) is N. N can be 32x, where
  1995. * x = {1,2,3,...64}, so the maximum number of bits in the X and Y is 2048.
  1996. * We must use the same number of words to represent bits in X, Y and M.
  1997. * See 20.3.3 of ESP32-S3 technical manual.
  1998. * 1. Wait until the hardware is ready.
  1999. * 2. Enable/disable interrupt that signals completion
  2000. * -- we don't use the interrupt.
  2001. * 3. Write the number of words required to represent the operands to the
  2002. * RSA_MODE_REG (now called RSA_LENGTH_REG).
  2003. * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
  2004. * 5. Load X, Y, M, r' operands to memory blocks.
  2005. * 6. Start the operation by writing 1 to RSA_MOD_MULT_START_REG,
  2006. * then wait for it to complete by monitoring RSA_IDLE_REG
  2007. * (which is now called RSA_QUERY_INTERRUPT_REG).
  2008. * 7. Read the result out.
  2009. * 8. Release the hardware lock so others can use it.
  2010. * x. Clear the interrupt flag, if you used it (we don't). */
  2011. /* 1. Wait until hardware is ready. */
  2012. if (ret == MP_OKAY) {
  2013. ret = esp_mp_hw_wait_clean();
  2014. }
  2015. if (ret == MP_OKAY) {
  2016. /* 2. Disable completion interrupt signal; we don't use.
  2017. ** 0 => no interrupt; 1 => interrupt on completion. */
  2018. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0);
  2019. /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
  2020. OperandBits = max(max(mph->Xs, mph->Ys), mph->Ms);
  2021. if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
  2022. ESP_LOGW(TAG, "result exceeds max bit length");
  2023. return MP_VAL; /* Error: value is not able to be used. */
  2024. }
  2025. WordsForOperand = bits2words(OperandBits);
  2026. /* alt inline calc:
  2027. * DPORT_REG_WRITE(RSA_MULT_MODE_REG, (mph->hwWords_sz >> 4) - 1); */
  2028. DPORT_REG_WRITE(RSA_LENGTH_REG, WordsForOperand - 1);
  2029. /* 4. Write M' value into RSA_M_PRIME_REG
  2030. * (now called RSA_M_DASH_REG) */
  2031. DPORT_REG_WRITE(RSA_M_DASH_REG, mph->mp);
  2032. /* Select acceleration options. */
  2033. DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0);
  2034. /* 5. Load X, Y, M, r' operands.
  2035. * Note RSA_MEM_RB_BLOCK_BASE == RSA_MEM_Z_BLOC_BASE on ESP32s3*/
  2036. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  2037. X,
  2038. mph->Xs,
  2039. mph->hwWords_sz);
  2040. esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE,
  2041. Y,
  2042. mph->Ys,
  2043. mph->hwWords_sz);
  2044. esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE,
  2045. M,
  2046. mph->Ms,
  2047. mph->hwWords_sz);
  2048. esp_mpint_to_memblock(RSA_MEM_RB_BLOCK_BASE,
  2049. &(mph->r_inv),
  2050. mph->Rs,
  2051. mph->hwWords_sz);
  2052. /* 6. Start operation and wait until it completes. */
  2053. process_start(RSA_MOD_MULT_START_REG); /* Reminder: esp_mp_mulmod() */
  2054. asm volatile("memw");
  2055. asm volatile("nop");
  2056. asm volatile("nop");
  2057. asm volatile("nop");
  2058. asm volatile("nop");
  2059. asm volatile("nop");
  2060. asm volatile("nop");
  2061. }
  2062. if (ret == MP_OKAY) {
  2063. ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
  2064. }
  2065. if (ret == MP_OKAY) {
  2066. /* 7. read the result from MEM_Z */
  2067. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, tmpZ, zwords);
  2068. }
  2069. /* 8. clear and release HW */
  2070. if (mulmod_lock_called) {
  2071. ret = esp_mp_hw_unlock();
  2072. }
  2073. else {
  2074. if (ret == MP_HW_FALLBACK) {
  2075. ESP_LOGV(TAG, "Lock not called due to no-lock MP_HW_FALLBACK");
  2076. }
  2077. else {
  2078. ESP_LOGW(TAG, "Lock unexpectedly not called");
  2079. }
  2080. }
  2081. /* end if CONFIG_IDF_TARGET_ESP32S3 */
  2082. #else
  2083. /* for all non-supported chipsets, fall back to SW calcs */
  2084. ret = MP_HW_FALLBACK;
  2085. #endif
  2086. if (ret == MP_OKAY) {
  2087. /* additional steps */
  2088. /* this is needed for known issue when Z is greater than M */
  2089. if (mp_cmp(tmpZ, M) == MP_GT) {
  2090. /* Z -= M */
  2091. mp_sub(tmpZ, M, tmpZ);
  2092. ESP_LOGV(TAG, "Z is greater than M");
  2093. }
  2094. #if defined(WOLFSSL_SP_INT_NEGATIVE) || defined(USE_FAST_MATH)
  2095. if (negcheck) {
  2096. mp_sub(M, tmpZ, tmpZ);
  2097. ESP_LOGV(TAG, "neg check adjustment");
  2098. }
  2099. #endif
  2100. mp_copy(tmpZ, Z); /* copy tmpZ to result Z */
  2101. esp_clean_result(Z, 0);
  2102. }
  2103. #ifdef WOLFSSL_HW_METRICS
  2104. esp_mp_mulmod_usage_ct++;
  2105. if (ret == MP_HW_FALLBACK) {
  2106. ESP_LOGV(TAG, "esp_mp_mulmod HW Fallback tick");
  2107. esp_mp_mulmod_fallback_ct++;
  2108. }
  2109. #endif
  2110. #ifdef DEBUG_WOLFSSL
  2111. if (ret == MP_HW_FALLBACK) {
  2112. ESP_LOGI(TAG, "HW Fallback");
  2113. }
  2114. else {
  2115. if (mp_cmp(X, X2) != 0) {
  2116. ESP_LOGV(TAG, "mp_mul X vs X2 mismatch!");
  2117. }
  2118. if (mp_cmp(Y, Y2) != 0) {
  2119. ESP_LOGV(TAG, "mp_mul Y vs Y2 mismatch!");
  2120. }
  2121. if (mp_cmp(Z, Z2) != 0) {
  2122. ESP_LOGE(TAG, "esp_mp_mulmod Z vs Z2 mismatch!");
  2123. esp_mp_mulmod_error_ct++;
  2124. int found_z_used = Z->used;
  2125. ESP_LOGI(TAG, "Xs = %d", mph->Xs);
  2126. ESP_LOGI(TAG, "Ys = %d", mph->Ys);
  2127. ESP_LOGI(TAG, "found_z_used = %d", found_z_used);
  2128. ESP_LOGI(TAG, "z.used = %d", Z->used);
  2129. ESP_LOGI(TAG, "hwWords_sz = %d", mph->hwWords_sz);
  2130. ESP_LOGI(TAG, "maxWords_sz = %d", mph->maxWords_sz);
  2131. ESP_LOGI(TAG, "hwWords_sz<<2 = %d", mph->hwWords_sz << 2);
  2132. /* parameters may have been collbered; Show cpied values */
  2133. esp_show_mp("X", X2);
  2134. esp_show_mp("Y", Y2);
  2135. esp_show_mp("M", M2);
  2136. ESP_LOGI(TAG, "Xs = %d", mph->Xs);
  2137. ESP_LOGI(TAG, "Ys = %d", mph->Ys);
  2138. ESP_LOGI(TAG, "found_z_used = %d", found_z_used);
  2139. ESP_LOGI(TAG, "z.used = %d", Z->used);
  2140. ESP_LOGI(TAG, "hwWords_sz = %d", mph->hwWords_sz);
  2141. ESP_LOGI(TAG, "maxWords_sz = %d", mph->maxWords_sz);
  2142. ESP_LOGI(TAG, "hwWords_sz<<2 = %d", mph->hwWords_sz << 2);
  2143. esp_show_mp("X", X2); /* X2 copy, as X may have been clobbered */
  2144. esp_show_mp("Y", Y2); /* Y2 copy, as Y may have been clobbered */
  2145. esp_show_mp("M", M2); /* M2 copy, as M may have been clobbered */
  2146. esp_show_mp("r_inv", &(mph->r_inv)); /*show r_inv */
  2147. ESP_LOGI(TAG, "mp = 0x%08x = %u", mph->mp, mph->mp);
  2148. if (mph->mp == mph->mp2) {
  2149. ESP_LOGI(TAG, "M' match esp_calc_Mdash vs mp_montgomery_setup"
  2150. " = %d !", mph->mp);
  2151. }
  2152. else {
  2153. ESP_LOGW(TAG,
  2154. "\n\n"
  2155. "M' MISMATCH esp_calc_Mdash = 0x%08x = %d \n"
  2156. "vs mp_montgomery_setup = 0x%08x = %d \n\n",
  2157. mph->mp,
  2158. mph->mp,
  2159. mph->mp2,
  2160. mph->mp2);
  2161. mph->mp = mph->mp2;
  2162. }
  2163. esp_show_mp("HW Z", Z); /* this is the HW result */
  2164. esp_show_mp("SW Z2", Z2); /* this is the SW result */
  2165. ESP_LOGI(TAG, "esp_mp_mulmod_usage_ct = %lu tries",
  2166. esp_mp_mulmod_usage_ct);
  2167. ESP_LOGI(TAG, "esp_mp_mulmod_error_ct = %lu failures",
  2168. esp_mp_mulmod_error_ct);
  2169. ESP_LOGI(TAG, WOLFSSL_ESPIDF_BLANKLINE_MESSAGE);
  2170. esp_show_mp("HW Z", Z); /* this is the HW result */
  2171. esp_show_mp("SW Z2", Z2); /* this is the SW result */
  2172. ESP_LOGI(TAG, "esp_mp_mulmod_usage_ct = %lu tries",
  2173. esp_mp_mulmod_usage_ct);
  2174. ESP_LOGI(TAG, "esp_mp_mulmod_error_ct = %lu failures",
  2175. esp_mp_mulmod_error_ct);
  2176. ESP_LOGI(TAG, WOLFSSL_ESPIDF_BLANKLINE_MESSAGE);
  2177. #ifndef NO_RECOVER_SOFTWARE_CALC
  2178. {
  2179. ESP_LOGW(TAG, "Recovering mp_mul error with software result");
  2180. mp_copy(Z2, Z); /* copy (src = Z2) to (dst = Z) */
  2181. }
  2182. #else
  2183. {
  2184. /* If we are not recovering, then we have an error. */
  2185. ret = MP_VAL;
  2186. }
  2187. #endif
  2188. }
  2189. else {
  2190. ESP_LOGV(TAG, "esp_mp_mulmod success!");
  2191. }
  2192. }
  2193. #endif /* DEBUG_WOLFSSL */
  2194. /* cleanup and exit */
  2195. mp_clear(tmpZ);
  2196. mp_clear(&(mph->r_inv));
  2197. ESP_LOGV(TAG, "\nEnd esp_mp_mulmod \n");
  2198. if (ret == MP_OKAY || ret == MP_HW_FALLBACK) {
  2199. ESP_LOGV(TAG, "esp_mp_mulmod exit success ");
  2200. }
  2201. else {
  2202. ESP_LOGW(TAG, "esp_mp_mulmod exit failed = %d", ret);
  2203. }
  2204. #ifdef WOLFSSL_HW_METRICS
  2205. /* calculate max used after any cleanup */
  2206. esp_mp_max_used = (Z->used > esp_mp_max_used) ? Z->used : esp_mp_max_used;
  2207. #endif
  2208. return ret;
  2209. } /* esp_mp_mulmod */
  2210. #endif /* Use HW mulmod: ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
  2211. #ifndef NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
  2212. /* Large Number Modular Exponentiation
  2213. *
  2214. * Z = X^Y mod M
  2215. *
  2216. * ESP32, Section 24.3.2 https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
  2217. * ESP32S3, Section 20.3.1, https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf
  2218. *
  2219. * The operation is based on Montgomery multiplication. Aside from the
  2220. * arguments X, Y , and M, two additional ones are needed -r and M'
  2221. .* These arguments are calculated in advance by software.
  2222. .*
  2223. .* The RSA Accelerator supports operand lengths of N in {512, 1024, 1536, 2048,
  2224. .* 2560, 3072, 3584, 4096} bits on the ESP32 and N in [32, 4096] bits
  2225. * on the ESP32s3.
  2226. .* The bit length of arguments Z, X, Y , M, and r can be any one from
  2227. * the N set, but all numbers in a calculation must be of the same length.
  2228. .* The bit length of M' is always 32.
  2229. .*
  2230. * Z = (X ^ Y) mod M : Espressif generic notation
  2231. * Y = (G ^ X) mod P : wolfSSL DH reference notation */
  2232. int esp_mp_exptmod(MATH_INT_T* X, MATH_INT_T* Y, MATH_INT_T* M, MATH_INT_T* Z)
  2233. {
  2234. /* Danger! Do not initialize any function parameters, not even the result Z.
  2235. * Some operations such as (rnd = rnd^e) will wipe out the rnd operand
  2236. * value upon initialization.
  2237. * (e.g. the address of X and Z could be the same when called) */
  2238. struct esp_mp_helper mph[1]; /* we'll save some mp helper data here */
  2239. int ret = MP_OKAY;
  2240. int exptmod_lock_called = FALSE;
  2241. #if defined(CONFIG_IDF_TARGET_ESP32)
  2242. /* different calc */
  2243. #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
  2244. word32 OperandBits;
  2245. word32 WordsForOperand;
  2246. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  2247. word32 OperandBits;
  2248. word32 WordsForOperand;
  2249. #else
  2250. /* no HW */
  2251. #endif
  2252. ESP_LOGV(TAG, "\nBegin esp_mp_exptmod \n");
  2253. #ifdef WOLFSSL_HW_METRICS
  2254. esp_mp_exptmod_usage_ct++;
  2255. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used : esp_mp_max_used;
  2256. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used : esp_mp_max_used;
  2257. esp_mp_max_used = (M->used > esp_mp_max_used) ? M->used : esp_mp_max_used;
  2258. #endif
  2259. if (mp_iszero(M)) {
  2260. #ifdef DEBUG_WOLFSSL
  2261. ESP_LOGI(TAG, "esp_mp_exptmod M is zero!");
  2262. #endif
  2263. #ifdef WOLFSSL_HW_METRICS
  2264. esp_mp_exptmod_fallback_ct++;
  2265. #endif
  2266. return MP_HW_FALLBACK; /* fall back and let SW decide how to handle */
  2267. }
  2268. if (mp_isone(M)) {
  2269. #ifdef DEBUG_WOLFSSL
  2270. ESP_LOGI(TAG, "esp_mp_exptmod M is one!");
  2271. #endif
  2272. mp_clear(Z);
  2273. return MP_OKAY; /* mod zero is zero */
  2274. }
  2275. ret = esp_mp_montgomery_init(X, Y, M, mph);
  2276. if (ret == MP_OKAY) {
  2277. ESP_LOGV(TAG, "esp_mp_exptmod esp_mp_montgomery_init success.");
  2278. }
  2279. else {
  2280. #ifdef WOLFSSL_HW_METRICS
  2281. if (ret == MP_HW_FALLBACK) {
  2282. esp_mp_exptmod_fallback_ct++;
  2283. }
  2284. else {
  2285. esp_mp_exptmod_error_ct++;
  2286. }
  2287. #endif
  2288. return ret;
  2289. }
  2290. #ifdef DEBUG_WOLFSSL
  2291. if (esp_hw_validation_active()) {
  2292. /* recall there's only one HW for all math accelerations */
  2293. return MP_HW_VALIDATION_ACTIVE;
  2294. }
  2295. if (esp_mp_exptmod_depth_counter != 0) {
  2296. ESP_LOGE(TAG, "esp_mp_exptmod Depth Counter Error!");
  2297. }
  2298. esp_mp_exptmod_depth_counter++;
  2299. #endif
  2300. /*
  2301. max bits = 0x400 = 1024 bits
  2302. 1024 / 8 = 128 bytes
  2303. 128 / 4 = 32 words (0x20)
  2304. */
  2305. /* lock and init the HW */
  2306. if (ret == MP_OKAY) {
  2307. exptmod_lock_called = TRUE; /* Don't try to unlock unless we locked */
  2308. #ifdef WOLFSSL_HW_METRICS
  2309. {
  2310. /* Only track max values when using HW */
  2311. esp_mp_max_used = (X->used > esp_mp_max_used) ? X->used :
  2312. esp_mp_max_used;
  2313. esp_mp_max_used = (Y->used > esp_mp_max_used) ? Y->used :
  2314. esp_mp_max_used;
  2315. }
  2316. #endif
  2317. ret = esp_mp_hw_lock();
  2318. if (ret != MP_OKAY) {
  2319. ESP_LOGE(TAG, "esp_mp_hw_lock failed");
  2320. #ifdef DEBUG_WOLFSSL
  2321. esp_mp_exptmod_depth_counter--;
  2322. #endif
  2323. }
  2324. } /* the only thing we expect is success or busy */
  2325. #if defined(CONFIG_IDF_TARGET_ESP32)
  2326. /* non-ESP32S3 Xtensa (regular ESP32) */
  2327. /* Steps to use HW in the following order:
  2328. * 1. Write(N/512bits - 1) to MODEXP_MODE_REG
  2329. * 2. Write X, Y, M and r_inv to memory blocks
  2330. * need to write data to each memory block only according to the length
  2331. * of the number.
  2332. * 3. Write M' to M_PRIME_REG
  2333. * 4. Write 1 to MODEXP_START_REG
  2334. * 5. Wait for the operation to be done. Poll INTERRUPT_REG until it reads 1.
  2335. * (Or until the INTER interrupt is generated.)
  2336. * 6. Read the result Z(=Y) from Z_MEM
  2337. * 7. Write 1 to INTERRUPT_REG to clear the interrupt.
  2338. */
  2339. if (ret == MP_OKAY) {
  2340. ret = esp_mp_hw_wait_clean();
  2341. #ifdef WOLFSSL_HW_METRICS
  2342. if (ret != MP_OKAY) {
  2343. esp_mp_exptmod_error_ct++;
  2344. }
  2345. #endif
  2346. }
  2347. if (ret == MP_OKAY) {
  2348. /* step.1 */
  2349. ESP_LOGV(TAG,
  2350. "hwWords_sz = %d, num = %d",
  2351. mph->hwWords_sz,
  2352. (mph->hwWords_sz >> 4) - 1
  2353. );
  2354. DPORT_REG_WRITE(RSA_MODEXP_MODE_REG, (mph->hwWords_sz >> 4) - 1);
  2355. /* step.2 write G, X, P, r_inv and M' into memory */
  2356. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  2357. X,
  2358. mph->Xs,
  2359. mph->hwWords_sz);
  2360. esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE,
  2361. Y, mph->Ys,
  2362. mph->hwWords_sz);
  2363. esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE,
  2364. M,
  2365. mph->Ms,
  2366. mph->hwWords_sz);
  2367. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE,
  2368. &(mph->r_inv),
  2369. mph->Rs,
  2370. mph->hwWords_sz);
  2371. /* step.3 write M' into memory */
  2372. ESP_LOGV(TAG, "M' = %d", mph->mp);
  2373. DPORT_REG_WRITE(RSA_M_DASH_REG, mph->mp);
  2374. ESP_EM__3_16;
  2375. /* step.4 start process */
  2376. process_start(RSA_MODEXP_START_REG); /* was RSA_START_MODEXP_REG;
  2377. * RSA_MODEXP_START_REG in docs? */
  2378. /* step.5 wait until done */
  2379. wait_until_done(RSA_INTERRUPT_REG);
  2380. /* step.6 read a result form memory */
  2381. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(mph->Ms));
  2382. }
  2383. /* step.7 clear and release expt_mod HW */
  2384. if (exptmod_lock_called) {
  2385. ret = esp_mp_hw_unlock();
  2386. }
  2387. else {
  2388. ESP_LOGV(TAG, "Lock not called");
  2389. }
  2390. #elif defined(CONFIG_IDF_TARGET_ESP32C3)
  2391. /* Steps to perform large number modular exponentiation.
  2392. * Calculates Z = (X ^ Y) modulo M.
  2393. * The number of bits in the operands (X, Y) is N. N can be 32x,
  2394. * where x = {1,2,3,...64}; maximum number of bits in the X and Y is 2048.
  2395. * See 20.3.3 of ESP32-S3 technical manual
  2396. * 1. Wait until the hardware is ready.
  2397. * 2. Enable/disable interrupt that signals completion
  2398. * -- we don't use the interrupt.
  2399. * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG
  2400. * (now called RSA_LENGTH_REG).
  2401. * Here N_bits is the maximum number of bits in X, Y and M.
  2402. * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
  2403. * 5. Load X, Y, M, r' operands to memory blocks.
  2404. * 6. Start the operation by writing 1 to RSA_MODEXP_START_REG,
  2405. * then wait for it to complete by monitoring RSA_IDLE_REG
  2406. * (which is now called RSA_QUERY_INTERRUPT_REG).
  2407. * 7. Read the result out.
  2408. * 8. Release the hardware lock so others can use it.
  2409. * x. Clear the interrupt flag, if you used it (we don't). */
  2410. /* 1. Wait until hardware is ready. */
  2411. if (ret == MP_OKAY) {
  2412. ret = esp_mp_hw_wait_clean();
  2413. }
  2414. if (ret == MP_OKAY) {
  2415. OperandBits = max(max(mph->Xs, mph->Ys), mph->Ms);
  2416. if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
  2417. ESP_LOGW(TAG, "result exceeds max bit length");
  2418. ret = MP_VAL; /* Error: value is not able to be used. */
  2419. }
  2420. else {
  2421. WordsForOperand = bits2words(OperandBits);
  2422. }
  2423. }
  2424. if (ret == MP_OKAY) {
  2425. /* 2. Disable completion interrupt signal; we don't use.
  2426. ** 0 => no interrupt; 1 => interrupt on completion. */
  2427. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0);
  2428. /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
  2429. DPORT_REG_WRITE(RSA_LENGTH_REG, WordsForOperand - 1);
  2430. /* 4. Write M' value into RSA_M_PRIME_REG
  2431. * (now called RSA_M_DASH_REG) */
  2432. DPORT_REG_WRITE(RSA_M_DASH_REG, mph->mp);
  2433. /* 5. Load X, Y, M, r' operands. */
  2434. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  2435. X,
  2436. mph->Xs,
  2437. mph->hwWords_sz);
  2438. esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE,
  2439. Y,
  2440. mph->Ys,
  2441. mph->hwWords_sz);
  2442. esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE,
  2443. M,
  2444. mph->Ms,
  2445. mph->hwWords_sz);
  2446. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE,
  2447. &(mph->r_inv),
  2448. mph->Rs,
  2449. mph->hwWords_sz);
  2450. /* 6. Start operation and wait until it completes. */
  2451. process_start(RSA_MODEXP_START_REG);
  2452. ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
  2453. }
  2454. if (MP_OKAY == ret) {
  2455. /* 7. read the result form MEM_Z */
  2456. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(mph->Ms));
  2457. }
  2458. /* 8. clear and release HW */
  2459. if (exptmod_lock_called) {
  2460. ret = esp_mp_hw_unlock();
  2461. }
  2462. else {
  2463. ESP_LOGV(TAG, "Lock not called");
  2464. }
  2465. /* end if CONFIG_IDF_TARGET_ESP32C3 */
  2466. #elif defined(CONFIG_IDF_TARGET_ESP32C6)
  2467. /* Steps to perform large number modular exponentiation.
  2468. * Calculates Z = (X ^ Y) modulo M.
  2469. * The number of bits in the operands (X, Y) is N. N can be 32x,
  2470. * where x = {1,2,3,...64}; maximum number of bits in the X and Y is 2048.
  2471. * See 20.3.3 of ESP32-S3 technical manual
  2472. * 1. Wait until the hardware is ready.
  2473. * 2. Enable/disable interrupt that signals completion
  2474. * -- we don't use the interrupt.
  2475. * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG
  2476. * (now called RSA_LENGTH_REG).
  2477. * Here N_bits is the maximum number of bits in X, Y and M.
  2478. * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
  2479. * 5. Load X, Y, M, r' operands to memory blocks.
  2480. * 6. Start the operation by writing 1 to RSA_MODEXP_START_REG,
  2481. * then wait for it to complete by monitoring RSA_IDLE_REG
  2482. * (which is now called RSA_QUERY_INTERRUPT_REG).
  2483. * 7. Read the result out.
  2484. * 8. Release the hardware lock so others can use it.
  2485. * x. Clear the interrupt flag, if you used it (we don't). */
  2486. /* 1. Wait until hardware is ready. */
  2487. if (ret == MP_OKAY) {
  2488. ret = esp_mp_hw_wait_clean();
  2489. }
  2490. if (ret == MP_OKAY) {
  2491. OperandBits = max(max(mph->Xs, mph->Ys), mph->Ms);
  2492. if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
  2493. ESP_LOGW(TAG, "result exceeds max bit length");
  2494. ret = MP_VAL; /* Error: value is not able to be used. */
  2495. }
  2496. else {
  2497. WordsForOperand = bits2words(OperandBits);
  2498. }
  2499. }
  2500. if (ret == MP_OKAY) {
  2501. /* 2. Disable completion interrupt signal; we don't use.
  2502. ** 0 => no interrupt; 1 => interrupt on completion. */
  2503. DPORT_REG_WRITE(RSA_INT_ENA_REG, 0);
  2504. /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
  2505. DPORT_REG_WRITE(RSA_MODE_REG, WordsForOperand - 1);
  2506. /* 4. Write M' value into RSA_M_PRIME_REG */
  2507. DPORT_REG_WRITE(RSA_M_PRIME_REG, mph->mp);
  2508. /* 5. Load X, Y, M, r' operands. */
  2509. esp_mpint_to_memblock(RSA_X_MEM,
  2510. X,
  2511. mph->Xs,
  2512. mph->hwWords_sz);
  2513. esp_mpint_to_memblock(RSA_Y_MEM,
  2514. Y,
  2515. mph->Ys,
  2516. mph->hwWords_sz);
  2517. esp_mpint_to_memblock(RSA_M_MEM,
  2518. M,
  2519. mph->Ms,
  2520. mph->hwWords_sz);
  2521. esp_mpint_to_memblock(RSA_Z_MEM,
  2522. &(mph->r_inv),
  2523. mph->Rs,
  2524. mph->hwWords_sz);
  2525. /* 6. Start operation and wait until it completes. */
  2526. /* Write 1 to the RSA_SET_START_MODEXP field of the
  2527. * RSA_SET_START_MODEXP_REG register to start computation.*/
  2528. process_start(RSA_SET_START_MODEXP_REG);
  2529. ret = wait_until_done(RSA_QUERY_IDLE_REG);
  2530. }
  2531. if (MP_OKAY == ret) {
  2532. /* 7. read the result form MEM_Z */
  2533. esp_memblock_to_mpint(RSA_Z_MEM, Z, BITS_TO_WORDS(mph->Ms));
  2534. }
  2535. /* 8. clear and release HW */
  2536. if (exptmod_lock_called) {
  2537. ret = esp_mp_hw_unlock();
  2538. }
  2539. else {
  2540. ESP_LOGV(TAG, "Lock not called");
  2541. }
  2542. /* end if CONFIG_IDF_TARGET_ESP32C6 */
  2543. #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
  2544. /* Steps to perform large number modular exponentiation.
  2545. * Calculates Z = (X ^ Y) modulo M.
  2546. * The number of bits in the operands (X, Y) is N. N can be 32x,
  2547. * where x = {1,2,3,...64}; the maximum number of bits in X and Y is 2048.
  2548. * See 20.3.3 of ESP32-S3 technical manual:
  2549. * 1. Wait until the hardware is ready.
  2550. * 2. Enable/disable interrupt that signals completion
  2551. * -- we don't use the interrupt.
  2552. * 3. Write (N_bits/32 - 1) to the RSA_MODE_REG
  2553. * (now called RSA_LENGTH_REG).
  2554. * Here N_bits is the maximum number of bits in X, Y and M.
  2555. * 4. Write M' value into RSA_M_PRIME_REG (now called RSA_M_DASH_REG).
  2556. * 5. Load X, Y, M, r' operands to memory blocks.
  2557. * 6. Start the operation by writing 1 to RSA_MODEXP_START_REG,
  2558. * then wait for it to complete by monitoring RSA_IDLE_REG
  2559. * (which is now called RSA_QUERY_INTERRUPT_REG).
  2560. * 7. Read the result out.
  2561. * 8. Release the hardware lock so others can use it.
  2562. * x. Clear the interrupt flag, if you used it (we don't). */
  2563. /* 1. Wait until hardware is ready. */
  2564. if (ret == MP_OKAY) {
  2565. ret = esp_mp_hw_wait_clean();
  2566. }
  2567. if (ret == MP_OKAY) {
  2568. OperandBits = max(max(mph->Xs, mph->Ys), mph->Ms);
  2569. if (OperandBits > ESP_HW_MULTI_RSAMAX_BITS) {
  2570. ESP_LOGW(TAG, "result exceeds max bit length");
  2571. ret = MP_VAL; /* Error: value is not able to be used. */
  2572. }
  2573. else {
  2574. WordsForOperand = bits2words(OperandBits);
  2575. }
  2576. }
  2577. if (ret == MP_OKAY) {
  2578. /* 2. Disable completion interrupt signal; we don't use.
  2579. ** 0 => no interrupt; 1 => interrupt on completion. */
  2580. DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0);
  2581. /* 3. Write (N_result_bits/32 - 1) to the RSA_MODE_REG. */
  2582. DPORT_REG_WRITE(RSA_LENGTH_REG, WordsForOperand - 1);
  2583. /* 4. Write M' value into RSA_M_PRIME_REG
  2584. * (now called RSA_M_DASH_REG) */
  2585. DPORT_REG_WRITE(RSA_M_DASH_REG, mph->mp);
  2586. /* 5. Load X, Y, M, r' operands. */
  2587. esp_mpint_to_memblock(RSA_MEM_X_BLOCK_BASE,
  2588. X,
  2589. mph->Xs,
  2590. mph->hwWords_sz);
  2591. esp_mpint_to_memblock(RSA_MEM_Y_BLOCK_BASE,
  2592. Y,
  2593. mph->Ys,
  2594. mph->hwWords_sz);
  2595. esp_mpint_to_memblock(RSA_MEM_M_BLOCK_BASE,
  2596. M,
  2597. mph->Ms,
  2598. mph->hwWords_sz);
  2599. esp_mpint_to_memblock(RSA_MEM_Z_BLOCK_BASE,
  2600. &(mph->r_inv),
  2601. mph->Rs,
  2602. mph->hwWords_sz);
  2603. /* 6. Start operation and wait until it completes. */
  2604. process_start(RSA_MODEXP_START_REG);
  2605. ret = wait_until_done(RSA_QUERY_INTERRUPT_REG);
  2606. }
  2607. if (MP_OKAY == ret) {
  2608. /* 7. read the result form MEM_Z */
  2609. esp_memblock_to_mpint(RSA_MEM_Z_BLOCK_BASE, Z, BITS_TO_WORDS(mph->Ms));
  2610. }
  2611. /* 8. clear and release HW */
  2612. if (exptmod_lock_called) {
  2613. ret = esp_mp_hw_unlock();
  2614. }
  2615. else {
  2616. ESP_LOGV(TAG, "Lock not called");
  2617. }
  2618. /* end if CONFIG_IDF_TARGET_ESP32S3 */
  2619. #else
  2620. /* unknown or unsupported targets fall back to SW */
  2621. ret = MP_HW_FALLBACK;
  2622. #endif
  2623. #ifdef DEBUG_WOLFSSL
  2624. if (esp_mp_exptmod_depth_counter != 1) {
  2625. ESP_LOGE(TAG, "esp_mp_exptmod exit Depth Counter Error!");
  2626. }
  2627. esp_mp_exptmod_depth_counter--;
  2628. #endif
  2629. /* never modify the result if we are falling back as the result
  2630. * may be the same as one of the operands! */
  2631. if (ret == MP_OKAY) {
  2632. esp_clean_result(Z, 0);
  2633. }
  2634. #ifdef WOLFSSL_HW_METRICS
  2635. esp_mp_max_used = (Z->used > esp_mp_max_used) ? Z->used : esp_mp_max_used;
  2636. #endif
  2637. return ret;
  2638. } /* esp_mp_exptmod */
  2639. #endif /* Use HW expmod: ! NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
  2640. #endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI) &&
  2641. * !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI */
  2642. #endif /* !NO_RSA || HAVE_ECC */
  2643. #if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI) && defined(WOLFSSL_HW_METRICS)
  2644. int esp_hw_show_mp_metrics(void)
  2645. {
  2646. int ret;
  2647. #if !defined(NO_ESP32_CRYPT) && defined(HW_MATH_ENABLED)
  2648. ret = MP_OKAY;
  2649. #if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL)
  2650. ESP_LOGI(TAG, "esp_mp_mul HW disabled with "
  2651. "NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL");
  2652. #else
  2653. /* Metrics: esp_mp_mul() */
  2654. ESP_LOGI(TAG, WOLFSSL_ESPIDF_BLANKLINE_MESSAGE); /* mul follows */
  2655. ESP_LOGI(TAG, "esp_mp_mul HW acceleration enabled.");
  2656. ESP_LOGI(TAG, "Number of calls to esp_mp_mul: %lu",
  2657. esp_mp_mul_usage_ct);
  2658. if (esp_mp_mul_error_ct == 0) {
  2659. ESP_LOGI(TAG, "Success: no esp_mp_mul() errors.");
  2660. }
  2661. else {
  2662. ESP_LOGW(TAG, "Number of esp_mp_mul failures: %lu",
  2663. esp_mp_mul_error_ct);
  2664. ret = MP_VAL;
  2665. }
  2666. #endif
  2667. #if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD)
  2668. ESP_LOGI(TAG, "esp_mp_mulmod HW disabled with "
  2669. "NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD");
  2670. #else
  2671. /* Metrics: esp_mp_mulmod() */
  2672. ESP_LOGI(TAG, WOLFSSL_ESPIDF_BLANKLINE_MESSAGE); /* mulmod follows */
  2673. ESP_LOGI(TAG, "esp_mp_mulmod HW acceleration enabled.");
  2674. /* Metrics: esp_mp_mulmod() */
  2675. ESP_LOGI(TAG, "Number of calls to esp_mp_mulmod: %lu",
  2676. esp_mp_mulmod_usage_ct);
  2677. ESP_LOGI(TAG, "Number of fallback to SW mp_mulmod: %lu",
  2678. esp_mp_mulmod_fallback_ct);
  2679. if (esp_mp_mulmod_error_ct == 0) {
  2680. ESP_LOGI(TAG, "Success: no esp_mp_mulmod errors.");
  2681. }
  2682. else {
  2683. ESP_LOGW(TAG, "Number of esp_mp_mulmod failures: %lu",
  2684. esp_mp_mulmod_error_ct);
  2685. ret = MP_VAL;
  2686. }
  2687. if (esp_mp_mulmod_even_mod_ct == 0) {
  2688. ESP_LOGI(TAG, "Success: no esp_mp_mulmod even mod.");
  2689. }
  2690. else {
  2691. ESP_LOGW(TAG, "Number of esp_mp_mulmod even mod: %lu",
  2692. esp_mp_mulmod_even_mod_ct);
  2693. }
  2694. if (esp_mp_mulmod_error_ct == 0) {
  2695. ESP_LOGI(TAG, "Success: no esp_mp_mulmod small x or y.");
  2696. }
  2697. else {
  2698. ESP_LOGW(TAG, "Number of esp_mp_mulmod small x: %lu",
  2699. esp_mp_mulmod_small_x_ct);
  2700. ESP_LOGW(TAG, "Number of esp_mp_mulmod small y: %lu",
  2701. esp_mp_mulmod_small_y_ct);
  2702. }
  2703. #endif /* MULMOD disabled: !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
  2704. #if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
  2705. ESP_LOGI(TAG, "esp_mp_exptmod HW disabled with "
  2706. "NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD");
  2707. #else
  2708. /* Metrics: sp_mp_exptmod() */
  2709. ESP_LOGI(TAG, WOLFSSL_ESPIDF_BLANKLINE_MESSAGE); /* exptmod follows */
  2710. ESP_LOGI(TAG, "Number of calls to esp_mp_exptmod: %lu",
  2711. esp_mp_exptmod_usage_ct);
  2712. ESP_LOGI(TAG, "Number of fallback to SW mp_exptmod: %lu",
  2713. esp_mp_exptmod_fallback_ct);
  2714. if (esp_mp_exptmod_error_ct == 0) {
  2715. ESP_LOGI(TAG, "Success: no esp_mp_exptmod errors.");
  2716. }
  2717. else {
  2718. ESP_LOGW(TAG, "Number of esp_mp_exptmod errors: %lu",
  2719. esp_mp_exptmod_error_ct);
  2720. ret = MP_VAL;
  2721. }
  2722. #endif /* EXPTMOD not disabled !NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
  2723. ESP_LOGI(TAG, "Max N->used: esp_mp_max_used = %lu", esp_mp_max_used);
  2724. ESP_LOGI(TAG, "Max timeout: esp_mp_max_timeout = %lu", esp_mp_max_timeout);
  2725. #else
  2726. /* no HW math, no HW math metrics */
  2727. ret = ESP_OK;
  2728. #endif /* HW_MATH_ENABLED */
  2729. return ret;
  2730. }
  2731. #endif /* WOLFSSL_HW_METRICS */
  2732. #endif /* WOLFSSL_ESPIDF */