stm32l4xx_hal_cryp_ex.c 113 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246
  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_hal_cryp_ex.c
  4. * @author MCD Application Team
  5. * @brief CRYPEx HAL module driver.
  6. * This file provides firmware functions to manage the extended
  7. * functionalities of the Cryptography (CRYP) peripheral.
  8. *
  9. ******************************************************************************
  10. * @attention
  11. *
  12. * Copyright (c) 2017 STMicroelectronics.
  13. * All rights reserved.
  14. *
  15. * This software is licensed under terms that can be found in the LICENSE file in
  16. * the root directory of this software component.
  17. * If no LICENSE file comes with this software, it is provided AS-IS.
  18. ******************************************************************************
  19. */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "stm32l4xx_hal.h"
  22. #ifdef HAL_CRYP_MODULE_ENABLED
  23. #if defined(AES)
  24. /** @addtogroup STM32L4xx_HAL_Driver
  25. * @{
  26. */
  27. /** @defgroup CRYPEx CRYPEx
  28. * @brief CRYP Extended HAL module driver
  29. * @{
  30. */
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* Private define ------------------------------------------------------------*/
  33. /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
  34. * @{
  35. */
  36. #define CRYP_CCF_TIMEOUTVALUE 22000 /*!< CCF flag raising time-out value */
  37. #define CRYP_BUSY_TIMEOUTVALUE 22000 /*!< BUSY flag reset time-out value */
  38. #define CRYP_POLLING_OFF 0x0 /*!< No polling when padding */
  39. #define CRYP_POLLING_ON 0x1 /*!< Polling when padding */
  40. #if defined(AES_CR_NPBLB)
  41. #define AES_POSITION_CR_NPBLB (uint32_t)POSITION_VAL(AES_CR_NPBLB) /*!< Required left shift to set background CLUT size */
  42. #endif
  43. /**
  44. * @}
  45. */
  46. /* Private macro -------------------------------------------------------------*/
  47. /* Private variables ---------------------------------------------------------*/
  48. /* Private function prototypes -----------------------------------------------*/
  49. /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
  50. * @{
  51. */
  52. static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
  53. static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
  54. static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
  55. static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
  56. static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma);
  57. static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma);
  58. static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma);
  59. static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
  60. static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout);
  61. static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
  62. static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
  63. static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
  64. static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
  65. /**
  66. * @}
  67. */
  68. /* Exported functions ---------------------------------------------------------*/
  69. /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
  70. * @{
  71. */
  72. /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
  73. * @brief Extended callback functions.
  74. *
  75. @verbatim
  76. ===============================================================================
  77. ##### Extended callback functions #####
  78. ===============================================================================
  79. [..] This section provides callback function:
  80. (+) Computation completed.
  81. @endverbatim
  82. * @{
  83. */
  84. /**
  85. * @brief Computation completed callbacks.
  86. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  87. * the configuration information for CRYP module
  88. * @retval None
  89. */
  90. __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
  91. {
  92. /* Prevent unused argument(s) compilation warning */
  93. UNUSED(hcryp);
  94. /* NOTE : This function should not be modified; when the callback is needed,
  95. the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
  96. */
  97. }
  98. /**
  99. * @}
  100. */
  101. /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
  102. * @brief Extended processing functions.
  103. *
  104. @verbatim
  105. ==============================================================================
  106. ##### AES extended processing functions #####
  107. ==============================================================================
  108. [..] This section provides functions allowing to:
  109. (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
  110. Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
  111. based on the processing type. Three processing types are available:
  112. (++) Polling mode
  113. (++) Interrupt mode
  114. (++) DMA mode
  115. (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
  116. algorithm in different chaining modes.
  117. Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
  118. so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
  119. Three processing types are available:
  120. (++) Polling mode
  121. (++) Interrupt mode
  122. (++) DMA mode
  123. @endverbatim
  124. * @{
  125. */
  126. /**
  127. * @brief Carry out in polling mode the ciphering or deciphering operation according to
  128. * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
  129. * chaining modes ECB, CBC and CTR are managed by this function in polling mode.
  130. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  131. * the configuration information for CRYP module
  132. * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
  133. * or key derivation+decryption.
  134. * Parameter is meaningless in case of key derivation.
  135. * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
  136. * Parameter is meaningless in case of key derivation.
  137. * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
  138. * decryption/key derivation+decryption, or pointer to the derivative keys in
  139. * case of key derivation only.
  140. * @param Timeout Specify Timeout value
  141. * @retval HAL status
  142. */
  143. HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
  144. {
  145. if (hcryp->State == HAL_CRYP_STATE_READY)
  146. {
  147. /* Check parameters setting */
  148. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
  149. {
  150. if (pOutputData == NULL)
  151. {
  152. return HAL_ERROR;
  153. }
  154. }
  155. else
  156. {
  157. if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
  158. {
  159. return HAL_ERROR;
  160. }
  161. }
  162. /* Process Locked */
  163. __HAL_LOCK(hcryp);
  164. /* Change the CRYP state */
  165. hcryp->State = HAL_CRYP_STATE_BUSY;
  166. /* Call CRYP_ReadKey() API if the operating mode is set to
  167. key derivation, CRYP_ProcessData() otherwise */
  168. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
  169. {
  170. if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
  171. {
  172. return HAL_TIMEOUT;
  173. }
  174. }
  175. else
  176. {
  177. if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
  178. {
  179. return HAL_TIMEOUT;
  180. }
  181. }
  182. /* If the state has not been set to SUSPENDED, set it to
  183. READY, otherwise keep it as it is */
  184. if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
  185. {
  186. hcryp->State = HAL_CRYP_STATE_READY;
  187. }
  188. /* Process Unlocked */
  189. __HAL_UNLOCK(hcryp);
  190. return HAL_OK;
  191. }
  192. else
  193. {
  194. return HAL_BUSY;
  195. }
  196. }
  197. /**
  198. * @brief Carry out in interrupt mode the ciphering or deciphering operation according to
  199. * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
  200. * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
  201. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  202. * the configuration information for CRYP module
  203. * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
  204. * or key derivation+decryption.
  205. * Parameter is meaningless in case of key derivation.
  206. * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
  207. * Parameter is meaningless in case of key derivation.
  208. * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
  209. * decryption/key derivation+decryption, or pointer to the derivative keys in
  210. * case of key derivation only.
  211. * @retval HAL status
  212. */
  213. HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
  214. {
  215. uint32_t inputaddr;
  216. if(hcryp->State == HAL_CRYP_STATE_READY)
  217. {
  218. /* Check parameters setting */
  219. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
  220. {
  221. if (pOutputData == NULL)
  222. {
  223. return HAL_ERROR;
  224. }
  225. }
  226. else
  227. {
  228. if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
  229. {
  230. return HAL_ERROR;
  231. }
  232. }
  233. /* Process Locked */
  234. __HAL_LOCK(hcryp);
  235. /* If operating mode is not limited to key derivation only,
  236. get the buffers addresses and sizes */
  237. if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
  238. {
  239. hcryp->CrypInCount = Size;
  240. hcryp->pCrypInBuffPtr = pInputData;
  241. hcryp->pCrypOutBuffPtr = pOutputData;
  242. hcryp->CrypOutCount = Size;
  243. }
  244. else
  245. {
  246. /* For key derivation, set output buffer only
  247. (will point at derivated key) */
  248. hcryp->pCrypOutBuffPtr = pOutputData;
  249. }
  250. /* Change the CRYP state */
  251. hcryp->State = HAL_CRYP_STATE_BUSY;
  252. /* Process Unlocked */
  253. __HAL_UNLOCK(hcryp);
  254. /* Enable Computation Complete Flag and Error Interrupts */
  255. __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  256. /* If operating mode is key derivation only, the input data have
  257. already been entered during the initialization process. For
  258. the other operating modes, they are fed to the CRYP hardware
  259. block at this point. */
  260. if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
  261. {
  262. /* Initiate the processing under interrupt in entering
  263. the first input data */
  264. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  265. /* Increment/decrement instance pointer/counter */
  266. hcryp->pCrypInBuffPtr += 16;
  267. hcryp->CrypInCount -= 16U;
  268. /* Write the first input block in the Data Input register */
  269. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  270. inputaddr+=4U;
  271. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  272. inputaddr+=4U;
  273. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  274. inputaddr+=4U;
  275. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  276. }
  277. /* Return function status */
  278. return HAL_OK;
  279. }
  280. else
  281. {
  282. return HAL_BUSY;
  283. }
  284. }
  285. /**
  286. * @brief Carry out in DMA mode the ciphering or deciphering operation according to
  287. * hcryp->Init structure fields.
  288. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  289. * the configuration information for CRYP module
  290. * @param pInputData Pointer to the plain text in case of encryption or cipher text in case of decryption
  291. * or key derivation+decryption.
  292. * @param Size Length of the input data buffer in bytes, must be a multiple of 16.
  293. * @param pOutputData Pointer to the cipher text in case of encryption or plain text in case of
  294. * decryption/key derivation+decryption.
  295. * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
  296. * @note Supported operating modes are encryption, decryption and key derivation with decryption.
  297. * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
  298. * registers must be done by software.
  299. * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
  300. * registers must be done by software through HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
  301. * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
  302. * @retval HAL status
  303. */
  304. HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
  305. {
  306. uint32_t inputaddr;
  307. uint32_t outputaddr;
  308. if (hcryp->State == HAL_CRYP_STATE_READY)
  309. {
  310. /* Check parameters setting */
  311. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
  312. {
  313. /* no DMA channel is provided for key derivation operating mode,
  314. access to AES_KEYRx registers must be done by software */
  315. return HAL_ERROR;
  316. }
  317. else
  318. {
  319. if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
  320. {
  321. return HAL_ERROR;
  322. }
  323. }
  324. /* Process Locked */
  325. __HAL_LOCK(hcryp);
  326. inputaddr = (uint32_t)pInputData;
  327. outputaddr = (uint32_t)pOutputData;
  328. /* Change the CRYP state */
  329. hcryp->State = HAL_CRYP_STATE_BUSY;
  330. /* Set the input and output addresses and start DMA transfer */
  331. CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
  332. /* Process Unlocked */
  333. __HAL_UNLOCK(hcryp);
  334. /* Return function status */
  335. return HAL_OK;
  336. }
  337. else
  338. {
  339. return HAL_BUSY;
  340. }
  341. }
  342. /**
  343. * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
  344. * operation according to hcryp->Init structure fields.
  345. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  346. * the configuration information for CRYP module
  347. * @param pInputData
  348. * - pointer to payload data in GCM or CCM payload phase,
  349. * - pointer to B0 block in CMAC header phase,
  350. * - pointer to C block in CMAC final phase.
  351. * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
  352. * @param Size
  353. * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
  354. * - length of B0 block (in bytes) in CMAC header phase,
  355. * - length of C block (in bytes) in CMAC final phase.
  356. * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  357. * - Parameter is meaningless in case of CCM final phase.
  358. * - Parameter is message length in bytes in case of GCM final phase.
  359. * - Parameter must be set to zero in case of GMAC final phase.
  360. * @param pOutputData
  361. * - pointer to plain or cipher text in GCM/CCM payload phase,
  362. * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
  363. * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  364. * - Parameter is meaningless in case of CMAC header phase.
  365. * @param Timeout Specify Timeout value
  366. * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
  367. * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
  368. * can be skipped by the user if so required.
  369. * @retval HAL status
  370. */
  371. HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
  372. {
  373. uint32_t index ;
  374. uint32_t inputaddr ;
  375. uint32_t outputaddr ;
  376. uint32_t tagaddr ;
  377. uint64_t headerlength ;
  378. uint64_t inputlength ;
  379. uint64_t payloadlength ;
  380. uint32_t difflength = 0;
  381. uint32_t addhoc_process = 0;
  382. if (hcryp->State == HAL_CRYP_STATE_READY)
  383. {
  384. /* input/output parameters check */
  385. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  386. {
  387. /* No processing required */
  388. }
  389. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  390. {
  391. if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
  392. ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
  393. {
  394. return HAL_ERROR;
  395. }
  396. #if defined(AES_CR_NPBLB)
  397. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
  398. #else
  399. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  400. #endif
  401. {
  402. /* In case of CMAC or CCM (when applicable) header phase resumption, we can have pInputData = NULL and Size = 0 */
  403. if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
  404. {
  405. return HAL_ERROR;
  406. }
  407. }
  408. }
  409. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  410. {
  411. if (((pInputData == NULL) && (Size != 0U)) || \
  412. ((pInputData != NULL) && (Size == 0U)) || \
  413. ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL)))
  414. {
  415. return HAL_ERROR;
  416. }
  417. }
  418. else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
  419. {
  420. if (pOutputData == NULL)
  421. {
  422. return HAL_ERROR;
  423. }
  424. #if !defined(AES_CR_NPBLB)
  425. if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
  426. {
  427. return HAL_ERROR;
  428. }
  429. #endif
  430. }
  431. else
  432. {
  433. /* Unspecified Phase */
  434. return HAL_ERROR;
  435. }
  436. /* Process Locked */
  437. __HAL_LOCK(hcryp);
  438. /* Change the CRYP state */
  439. hcryp->State = HAL_CRYP_STATE_BUSY;
  440. /*==============================================*/
  441. /* GCM/GMAC (or CCM when applicable) init phase */
  442. /*==============================================*/
  443. /* In case of init phase, the input data (Key and Initialization Vector) have
  444. already been entered during the initialization process. Therefore, the
  445. API just waits for the CCF flag to be set. */
  446. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  447. {
  448. /* just wait for hash computation */
  449. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  450. {
  451. hcryp->State = HAL_CRYP_STATE_READY;
  452. __HAL_UNLOCK(hcryp);
  453. return HAL_TIMEOUT;
  454. }
  455. /* Clear CCF Flag */
  456. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  457. /* Mark that the initialization phase is over */
  458. hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
  459. }
  460. /*=======================================================*/
  461. /* GCM/GMAC or (CCM / CMAC when applicable) header phase */
  462. /*=======================================================*/
  463. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  464. {
  465. #if !defined(AES_CR_NPBLB)
  466. /* Set header phase; for GCM or GMAC, set data-byte at this point */
  467. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
  468. {
  469. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
  470. }
  471. else
  472. #endif
  473. {
  474. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
  475. }
  476. /* Enable the Peripheral */
  477. __HAL_CRYP_ENABLE(hcryp);
  478. #if !defined(AES_CR_NPBLB)
  479. /* in case of CMAC, enter B0 block in header phase, before the header itself. */
  480. /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
  481. skip these steps and go directly to header buffer feeding to the HW */
  482. if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
  483. {
  484. uint64_t index_test;
  485. inputaddr = (uint32_t)pInputData;
  486. for(index=0U ; (index < Size); index += 16U)
  487. {
  488. /* Write the Input block in the Data Input register */
  489. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  490. inputaddr+=4U;
  491. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  492. inputaddr+=4U;
  493. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  494. inputaddr+=4U;
  495. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  496. inputaddr+=4U;
  497. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  498. {
  499. hcryp->State = HAL_CRYP_STATE_READY;
  500. __HAL_UNLOCK(hcryp);
  501. return HAL_TIMEOUT;
  502. }
  503. /* Clear CCF Flag */
  504. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  505. /* If the suspension flag has been raised and if the processing is not about
  506. to end, suspend processing */
  507. index_test = (uint64_t)index + 16U;
  508. if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_test < Size))
  509. {
  510. /* reset SuspendRequest */
  511. hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  512. /* Change the CRYP state */
  513. hcryp->State = HAL_CRYP_STATE_SUSPENDED;
  514. /* Mark that the header phase is over */
  515. hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
  516. /* Save current reading and writing locations of Input and Output buffers */
  517. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  518. /* Save the total number of bytes (B blocks + header) that remain to be
  519. processed at this point */
  520. hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize + Size - index_test);
  521. /* Process Unlocked */
  522. __HAL_UNLOCK(hcryp);
  523. return HAL_OK;
  524. }
  525. } /* for(index=0; (index < Size); index += 16) */
  526. }
  527. #endif /* !defined(AES_CR_NPBLB) */
  528. /* Enter header */
  529. inputaddr = (uint32_t)hcryp->Init.Header;
  530. /* Local variable headerlength is a number of bytes multiple of 128 bits,
  531. remaining header data (if any) are handled after this loop */
  532. headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
  533. if ((hcryp->Init.HeaderSize % 16U) != 0U)
  534. {
  535. difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
  536. }
  537. for(index=0U ; index < headerlength; index += 16U)
  538. {
  539. uint64_t index_temp;
  540. /* Write the Input block in the Data Input register */
  541. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  542. inputaddr+=4U;
  543. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  544. inputaddr+=4U;
  545. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  546. inputaddr+=4U;
  547. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  548. inputaddr+=4U;
  549. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  550. {
  551. hcryp->State = HAL_CRYP_STATE_READY;
  552. __HAL_UNLOCK(hcryp);
  553. return HAL_TIMEOUT;
  554. }
  555. /* Clear CCF Flag */
  556. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  557. /* If the suspension flag has been raised and if the processing is not about
  558. to end, suspend processing */
  559. index_temp = (uint64_t)index + 16U;
  560. if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < headerlength))
  561. {
  562. /* reset SuspendRequest */
  563. hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  564. /* Change the CRYP state */
  565. hcryp->State = HAL_CRYP_STATE_SUSPENDED;
  566. /* Mark that the header phase is over */
  567. hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
  568. /* Save current reading and writing locations of Input and Output buffers */
  569. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  570. /* Save the total number of bytes that remain to be processed at this point */
  571. hcryp->CrypInCount = (uint32_t) (hcryp->Init.HeaderSize - index_temp);
  572. /* Process Unlocked */
  573. __HAL_UNLOCK(hcryp);
  574. return HAL_OK;
  575. }
  576. }
  577. /* Case header length is not a multiple of 16 bytes */
  578. if (difflength != 0U)
  579. {
  580. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  581. CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
  582. }
  583. /* Mark that the header phase is over */
  584. hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  585. }
  586. /*============================================*/
  587. /* GCM (or CCM when applicable) payload phase */
  588. /*============================================*/
  589. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  590. {
  591. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
  592. /* if the header phase has been bypassed, AES must be enabled again */
  593. if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
  594. {
  595. __HAL_CRYP_ENABLE(hcryp);
  596. }
  597. inputaddr = (uint32_t)pInputData;
  598. outputaddr = (uint32_t)pOutputData;
  599. /* Enter payload */
  600. /* Specific handling to manage payload last block size less than 128 bits */
  601. if ((Size % 16U) != 0U)
  602. {
  603. payloadlength = (Size/16U) * 16U;
  604. difflength = (uint32_t) (Size - payloadlength);
  605. addhoc_process = 1;
  606. }
  607. else
  608. {
  609. payloadlength = Size;
  610. }
  611. /* Feed payload */
  612. for(index=0U ; index < payloadlength; index += 16U)
  613. {
  614. uint64_t index_temp;
  615. /* Write the Input block in the Data Input register */
  616. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  617. inputaddr+=4U;
  618. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  619. inputaddr+=4U;
  620. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  621. inputaddr+=4U;
  622. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  623. inputaddr+=4U;
  624. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  625. {
  626. hcryp->State = HAL_CRYP_STATE_READY;
  627. __HAL_UNLOCK(hcryp);
  628. return HAL_TIMEOUT;
  629. }
  630. /* Clear CCF Flag */
  631. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  632. /* Retrieve output data: read the output block
  633. from the Data Output Register */
  634. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  635. outputaddr+=4U;
  636. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  637. outputaddr+=4U;
  638. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  639. outputaddr+=4U;
  640. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  641. outputaddr+=4U;
  642. /* If the suspension flag has been raised and if the processing is not about
  643. to end, suspend processing */
  644. index_temp = (uint64_t)index + 16U;
  645. if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && (index_temp < payloadlength))
  646. {
  647. /* no flag waiting under IRQ handling */
  648. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
  649. {
  650. /* Ensure that Busy flag is reset */
  651. if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
  652. {
  653. hcryp->State = HAL_CRYP_STATE_READY;
  654. __HAL_UNLOCK(hcryp);
  655. return HAL_TIMEOUT;
  656. }
  657. }
  658. /* reset SuspendRequest */
  659. hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  660. /* Change the CRYP state */
  661. hcryp->State = HAL_CRYP_STATE_SUSPENDED;
  662. /* Mark that the header phase is over */
  663. hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
  664. /* Save current reading and writing locations of Input and Output buffers */
  665. hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
  666. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  667. /* Save the number of bytes that remain to be processed at this point */
  668. hcryp->CrypInCount = (uint32_t) (Size - index_temp);
  669. /* Process Unlocked */
  670. __HAL_UNLOCK(hcryp);
  671. return HAL_OK;
  672. }
  673. }
  674. /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
  675. payload last block size less than 128 bits */
  676. if (addhoc_process == 1U)
  677. {
  678. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  679. hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
  680. CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
  681. } /* (addhoc_process == 1) */
  682. /* Mark that the payload phase is over */
  683. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  684. }
  685. /*==================================*/
  686. /* GCM/GMAC/CCM or CMAC final phase */
  687. /*==================================*/
  688. else
  689. {
  690. tagaddr = (uint32_t)pOutputData;
  691. #if defined(AES_CR_NPBLB)
  692. /* By default, clear NPBLB field */
  693. CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
  694. #endif
  695. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
  696. /* if the header and payload phases have been bypassed, AES must be enabled again */
  697. if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
  698. {
  699. __HAL_CRYP_ENABLE(hcryp);
  700. }
  701. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
  702. {
  703. headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
  704. inputlength = Size * 8U; /* input length in bits */
  705. #if !defined(AES_CR_NPBLB)
  706. if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
  707. {
  708. hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
  709. hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
  710. hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
  711. hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
  712. }
  713. else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
  714. {
  715. hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
  716. hcryp->Instance->DINR = __REV((uint32_t)headerlength);
  717. hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
  718. hcryp->Instance->DINR = __REV((uint32_t)inputlength);
  719. }
  720. else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
  721. {
  722. hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
  723. hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
  724. hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
  725. hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
  726. }
  727. else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
  728. {
  729. hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
  730. hcryp->Instance->DINR = (uint32_t)(headerlength);
  731. hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
  732. hcryp->Instance->DINR = (uint32_t)(inputlength);
  733. }
  734. else
  735. {
  736. /* Unspecified Data Type */
  737. return HAL_ERROR;
  738. }
  739. #else
  740. hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
  741. hcryp->Instance->DINR = (uint32_t)(headerlength);
  742. hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
  743. hcryp->Instance->DINR = (uint32_t)(inputlength);
  744. #endif
  745. }
  746. #if !defined(AES_CR_NPBLB)
  747. else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  748. {
  749. inputaddr = (uint32_t)pInputData;
  750. /* Enter the last block made of a 128-bit value formatted
  751. from the original B0 packet. */
  752. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  753. inputaddr+=4U;
  754. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  755. inputaddr+=4U;
  756. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  757. inputaddr+=4U;
  758. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  759. }
  760. else
  761. {
  762. /* Unspecified Chaining Mode */
  763. return HAL_ERROR;
  764. }
  765. #endif
  766. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  767. {
  768. hcryp->State = HAL_CRYP_STATE_READY;
  769. __HAL_UNLOCK(hcryp);
  770. return HAL_TIMEOUT;
  771. }
  772. /* Read the Auth TAG in the Data Out register */
  773. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  774. tagaddr+=4U;
  775. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  776. tagaddr+=4U;
  777. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  778. tagaddr+=4U;
  779. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  780. /* Clear CCF Flag */
  781. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  782. /* Mark that the final phase is over */
  783. hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
  784. /* Disable the Peripheral */
  785. __HAL_CRYP_DISABLE(hcryp);
  786. }
  787. /* Change the CRYP state */
  788. hcryp->State = HAL_CRYP_STATE_READY;
  789. /* Process Unlocked */
  790. __HAL_UNLOCK(hcryp);
  791. return HAL_OK;
  792. }
  793. else
  794. {
  795. return HAL_BUSY;
  796. }
  797. }
  798. /**
  799. * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
  800. * operation according to hcryp->Init structure fields.
  801. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  802. * the configuration information for CRYP module
  803. * @param pInputData
  804. * - pointer to payload data in GCM or CCM payload phase,
  805. * - pointer to B0 block in CMAC header phase,
  806. * - pointer to C block in CMAC final phase.
  807. * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
  808. * @param Size
  809. * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
  810. * - length of B0 block (in bytes) in CMAC header phase,
  811. * - length of C block (in bytes) in CMAC final phase.
  812. * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  813. * - Parameter is meaningless in case of CCM final phase.
  814. * - Parameter is message length in bytes in case of GCM final phase.
  815. * - Parameter must be set to zero in case of GMAC final phase.
  816. * @param pOutputData
  817. * - pointer to plain or cipher text in GCM/CCM payload phase,
  818. * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
  819. * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  820. * - Parameter is meaningless in case of CMAC header phase.
  821. * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
  822. * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
  823. * can be skipped by the user if so required.
  824. * @retval HAL status
  825. */
  826. HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
  827. {
  828. uint32_t inputaddr ;
  829. uint64_t headerlength ;
  830. uint64_t inputlength ;
  831. uint32_t index ;
  832. uint32_t addhoc_process = 0;
  833. uint32_t difflength = 0;
  834. uint32_t difflengthmod4 = 0;
  835. uint32_t mask[4][3];
  836. uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
  837. mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
  838. mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
  839. mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
  840. mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
  841. if (hcryp->State == HAL_CRYP_STATE_READY)
  842. {
  843. /* input/output parameters check */
  844. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  845. {
  846. /* No processing required */
  847. }
  848. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  849. {
  850. if (((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U)) ||
  851. ((hcryp->Init.Header == NULL) && (hcryp->Init.HeaderSize != 0U)))
  852. {
  853. return HAL_ERROR;
  854. }
  855. #if defined(AES_CR_NPBLB)
  856. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
  857. #else
  858. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  859. #endif
  860. {
  861. /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */
  862. if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
  863. {
  864. return HAL_ERROR;
  865. }
  866. }
  867. }
  868. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  869. {
  870. if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
  871. {
  872. return HAL_ERROR;
  873. }
  874. }
  875. else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
  876. {
  877. if (pOutputData == NULL)
  878. {
  879. return HAL_ERROR;
  880. }
  881. #if !defined(AES_CR_NPBLB)
  882. if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
  883. {
  884. return HAL_ERROR;
  885. }
  886. #endif
  887. }
  888. else
  889. {
  890. /* Unspecified Phase */
  891. return HAL_ERROR;
  892. }
  893. /* Process Locked */
  894. __HAL_LOCK(hcryp);
  895. /* Change the CRYP state */
  896. hcryp->State = HAL_CRYP_STATE_BUSY;
  897. /* Process Unlocked */
  898. __HAL_UNLOCK(hcryp);
  899. /* Enable Computation Complete Flag and Error Interrupts */
  900. __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  901. /*==============================================*/
  902. /* GCM/GMAC (or CCM when applicable) init phase */
  903. /*==============================================*/
  904. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  905. {
  906. /* In case of init phase, the input data (Key and Initialization Vector) have
  907. already been entered during the initialization process. Therefore, the
  908. software just waits for the CCF interrupt to be raised and which will
  909. be handled by CRYP_AES_Auth_IT() API. */
  910. }
  911. /*===================================*/
  912. /* GCM/GMAC/CCM or CMAC header phase */
  913. /*===================================*/
  914. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  915. {
  916. #if defined(AES_CR_NPBLB)
  917. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
  918. #else
  919. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  920. #endif
  921. {
  922. /* In case of CMAC, B blocks are first entered, before the header.
  923. Therefore, B blocks and the header are entered back-to-back
  924. as if it was only one single block.
  925. However, in case of resumption after suspension, if all the
  926. B blocks have been entered (in that case, Size = 0), only the
  927. remainder of the non-processed header bytes are entered. */
  928. if (Size != 0U)
  929. {
  930. hcryp->CrypInCount = (uint32_t)(Size + hcryp->Init.HeaderSize);
  931. hcryp->pCrypInBuffPtr = pInputData;
  932. }
  933. else
  934. {
  935. hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
  936. hcryp->pCrypInBuffPtr = hcryp->Init.Header;
  937. }
  938. }
  939. else
  940. {
  941. /* Get the header addresses and sizes */
  942. hcryp->CrypInCount = (uint32_t)hcryp->Init.HeaderSize;
  943. hcryp->pCrypInBuffPtr = hcryp->Init.Header;
  944. }
  945. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  946. #if !defined(AES_CR_NPBLB)
  947. /* Set header phase; for GCM or GMAC, set data-byte at this point */
  948. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
  949. {
  950. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
  951. }
  952. else
  953. #endif
  954. {
  955. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
  956. }
  957. /* Enable the Peripheral */
  958. __HAL_CRYP_ENABLE(hcryp);
  959. /* Increment/decrement instance pointer/counter */
  960. if (hcryp->CrypInCount == 0U)
  961. {
  962. /* Case of no header */
  963. hcryp->State = HAL_CRYP_STATE_READY;
  964. /* Mark that the header phase is over */
  965. hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  966. return HAL_OK;
  967. }
  968. else if (hcryp->CrypInCount < 16U)
  969. {
  970. hcryp->CrypInCount = 0;
  971. addhoc_process = 1;
  972. difflength = (uint32_t) (hcryp->Init.HeaderSize);
  973. difflengthmod4 = difflength%4U;
  974. }
  975. else
  976. {
  977. hcryp->pCrypInBuffPtr += 16;
  978. hcryp->CrypInCount -= 16U;
  979. }
  980. #if defined(AES_CR_NPBLB)
  981. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
  982. #else
  983. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  984. #endif
  985. {
  986. if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
  987. {
  988. /* All B blocks will have been entered after the next
  989. four DINR writing, so point at header buffer for
  990. the next iteration */
  991. hcryp->pCrypInBuffPtr = hcryp->Init.Header;
  992. }
  993. }
  994. /* Enter header first block to initiate the process
  995. in the Data Input register */
  996. if (addhoc_process == 0U)
  997. {
  998. /* Header has size equal or larger than 128 bits */
  999. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1000. inputaddr+=4U;
  1001. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1002. inputaddr+=4U;
  1003. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1004. inputaddr+=4U;
  1005. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1006. }
  1007. else
  1008. {
  1009. /* Header has size less than 128 bits */
  1010. /* Enter complete words when possible */
  1011. for(index=0U ; index < (difflength/4U); index ++)
  1012. {
  1013. /* Write the Input block in the Data Input register */
  1014. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1015. inputaddr+=4U;
  1016. }
  1017. /* Enter incomplete word padded with zeroes if applicable
  1018. (case of header length not a multiple of 32-bits) */
  1019. if (difflengthmod4 != 0U)
  1020. {
  1021. hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
  1022. }
  1023. /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
  1024. for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
  1025. {
  1026. hcryp->Instance->DINR = 0;
  1027. }
  1028. }
  1029. }
  1030. /*============================================*/
  1031. /* GCM (or CCM when applicable) payload phase */
  1032. /*============================================*/
  1033. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  1034. {
  1035. /* Get the buffer addresses and sizes */
  1036. hcryp->CrypInCount = (uint32_t)Size;
  1037. hcryp->pCrypInBuffPtr = pInputData;
  1038. hcryp->pCrypOutBuffPtr = pOutputData;
  1039. hcryp->CrypOutCount = (uint32_t)Size;
  1040. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  1041. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
  1042. /* if the header phase has been bypassed, AES must be enabled again */
  1043. if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
  1044. {
  1045. __HAL_CRYP_ENABLE(hcryp);
  1046. }
  1047. /* No payload case */
  1048. if (pInputData == NULL)
  1049. {
  1050. hcryp->State = HAL_CRYP_STATE_READY;
  1051. /* Mark that the header phase is over */
  1052. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  1053. /* Process Unlocked */
  1054. __HAL_UNLOCK(hcryp);
  1055. return HAL_OK;
  1056. }
  1057. /* Specific handling to manage payload size less than 128 bits */
  1058. if (Size < 16U)
  1059. {
  1060. difflength = (uint32_t) (Size);
  1061. #if defined(AES_CR_NPBLB)
  1062. /* In case of GCM encryption or CCM decryption, specify the number of padding
  1063. bytes in last block of payload */
  1064. if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
  1065. {
  1066. uint32_t cr_temp = hcryp->Instance->CR;
  1067. if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
  1068. || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
  1069. {
  1070. /* Set NPBLB field in writing the number of padding bytes
  1071. for the last block of payload */
  1072. MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
  1073. }
  1074. }
  1075. #else
  1076. /* Software workaround applied to GCM encryption only */
  1077. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
  1078. {
  1079. /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
  1080. __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
  1081. }
  1082. #endif
  1083. /* Set hcryp->CrypInCount to 0 (no more data to enter) */
  1084. hcryp->CrypInCount = 0;
  1085. /* Insert the last block (which size is inferior to 128 bits) padded with zeroes,
  1086. to have a complete block of 128 bits */
  1087. difflengthmod4 = difflength%4U;
  1088. /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
  1089. to have a complete block of 128 bits */
  1090. for(index=0U; index < (difflength/4U); index ++)
  1091. {
  1092. /* Write the Input block in the Data Input register */
  1093. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1094. inputaddr+=4U;
  1095. }
  1096. /* If required, manage input data size not multiple of 32 bits */
  1097. if (difflengthmod4 != 0U)
  1098. {
  1099. hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
  1100. }
  1101. /* Wrap-up in padding with zero-words if applicable */
  1102. for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
  1103. {
  1104. hcryp->Instance->DINR = 0;
  1105. }
  1106. }
  1107. else
  1108. {
  1109. /* Increment/decrement instance pointer/counter */
  1110. hcryp->pCrypInBuffPtr += 16;
  1111. hcryp->CrypInCount -= 16U;
  1112. /* Enter payload first block to initiate the process
  1113. in the Data Input register */
  1114. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1115. inputaddr+=4U;
  1116. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1117. inputaddr+=4U;
  1118. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1119. inputaddr+=4U;
  1120. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1121. }
  1122. }
  1123. /*==================================*/
  1124. /* GCM/GMAC/CCM or CMAC final phase */
  1125. /*==================================*/
  1126. else
  1127. {
  1128. hcryp->pCrypOutBuffPtr = pOutputData;
  1129. #if defined(AES_CR_NPBLB)
  1130. /* By default, clear NPBLB field */
  1131. CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
  1132. #endif
  1133. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
  1134. /* if the header and payload phases have been bypassed, AES must be enabled again */
  1135. if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
  1136. {
  1137. __HAL_CRYP_ENABLE(hcryp);
  1138. }
  1139. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
  1140. {
  1141. headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
  1142. inputlength = Size * 8U; /* Input length in bits */
  1143. /* Write the number of bits in the header on 64 bits followed by the number
  1144. of bits in the payload on 64 bits as well */
  1145. #if !defined(AES_CR_NPBLB)
  1146. if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
  1147. {
  1148. hcryp->Instance->DINR = __RBIT((uint32_t)((headerlength)>>32));
  1149. hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
  1150. hcryp->Instance->DINR = __RBIT((uint32_t)((inputlength)>>32));
  1151. hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
  1152. }
  1153. else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
  1154. {
  1155. hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
  1156. hcryp->Instance->DINR = __REV((uint32_t)headerlength);
  1157. hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
  1158. hcryp->Instance->DINR = __REV((uint32_t)inputlength);
  1159. }
  1160. else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
  1161. {
  1162. hcryp->Instance->DINR = __ROR((uint32_t)((headerlength)>>32), 16);
  1163. hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
  1164. hcryp->Instance->DINR = __ROR((uint32_t)((inputlength)>>32), 16);
  1165. hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
  1166. }
  1167. else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
  1168. {
  1169. hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
  1170. hcryp->Instance->DINR = (uint32_t)(headerlength);
  1171. hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
  1172. hcryp->Instance->DINR = (uint32_t)(inputlength);
  1173. }
  1174. else
  1175. {
  1176. /* Unspecified Data Type */
  1177. return HAL_ERROR;
  1178. }
  1179. #else
  1180. hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
  1181. hcryp->Instance->DINR = (uint32_t)(headerlength);
  1182. hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
  1183. hcryp->Instance->DINR = (uint32_t)(inputlength);
  1184. #endif
  1185. }
  1186. #if !defined(AES_CR_NPBLB)
  1187. else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  1188. {
  1189. inputaddr = (uint32_t)pInputData;
  1190. /* Enter the last block made of a 128-bit value formatted
  1191. from the original B0 packet. */
  1192. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1193. inputaddr+=4U;
  1194. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1195. inputaddr+=4U;
  1196. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1197. inputaddr+=4U;
  1198. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1199. }
  1200. else
  1201. {
  1202. /* Unspecified Chaining Mode */
  1203. return HAL_ERROR;
  1204. }
  1205. #endif
  1206. }
  1207. return HAL_OK;
  1208. }
  1209. else
  1210. {
  1211. return HAL_BUSY;
  1212. }
  1213. }
  1214. /**
  1215. * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
  1216. * operation according to hcryp->Init structure fields.
  1217. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1218. * the configuration information for CRYP module
  1219. * @param pInputData
  1220. * - pointer to payload data in GCM or CCM payload phase,
  1221. * - pointer to B0 block in CMAC header phase,
  1222. * - pointer to C block in CMAC final phase.
  1223. * - Parameter is meaningless in case of GCM/GMAC/CCM init, header and final phases.
  1224. * @param Size
  1225. * - length of the input payload data buffer in bytes in GCM or CCM payload phase,
  1226. * - length of B0 block (in bytes) in CMAC header phase,
  1227. * - length of C block (in bytes) in CMAC final phase.
  1228. * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  1229. * - Parameter is meaningless in case of CCM final phase.
  1230. * - Parameter is message length in bytes in case of GCM final phase.
  1231. * - Parameter must be set to zero in case of GMAC final phase.
  1232. * @param pOutputData
  1233. * - pointer to plain or cipher text in GCM/CCM payload phase,
  1234. * - pointer to authentication tag in GCM/GMAC/CCM/CMAC final phase.
  1235. * - Parameter is meaningless in case of GCM/GMAC/CCM init and header phases.
  1236. * - Parameter is meaningless in case of CMAC header phase.
  1237. * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
  1238. * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
  1239. * can be skipped by the user if so required.
  1240. * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
  1241. * @retval HAL status
  1242. */
  1243. HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
  1244. {
  1245. uint32_t inputaddr ;
  1246. uint32_t outputaddr ;
  1247. uint32_t tagaddr ;
  1248. uint64_t headerlength ;
  1249. uint64_t inputlength ;
  1250. uint64_t payloadlength ;
  1251. if (hcryp->State == HAL_CRYP_STATE_READY)
  1252. {
  1253. /* input/output parameters check */
  1254. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  1255. {
  1256. /* No processing required */
  1257. }
  1258. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  1259. {
  1260. if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
  1261. {
  1262. return HAL_ERROR;
  1263. }
  1264. #if defined(AES_CR_NPBLB)
  1265. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
  1266. {
  1267. /* In case of CMAC or CCM header phase resumption, we can have pInputData = NULL and Size = 0 */
  1268. if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
  1269. {
  1270. return HAL_ERROR;
  1271. }
  1272. }
  1273. #else
  1274. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  1275. {
  1276. if ((pInputData == NULL) || (Size == 0U))
  1277. {
  1278. return HAL_ERROR;
  1279. }
  1280. }
  1281. #endif
  1282. }
  1283. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  1284. {
  1285. if ((pInputData != NULL) && (Size != 0U) && (pOutputData == NULL))
  1286. {
  1287. return HAL_ERROR;
  1288. }
  1289. }
  1290. else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
  1291. {
  1292. if (pOutputData == NULL)
  1293. {
  1294. return HAL_ERROR;
  1295. }
  1296. #if !defined(AES_CR_NPBLB)
  1297. if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
  1298. {
  1299. return HAL_ERROR;
  1300. }
  1301. #endif
  1302. }
  1303. else
  1304. {
  1305. /* Unspecified Phase */
  1306. return HAL_ERROR;
  1307. }
  1308. /* Process Locked */
  1309. __HAL_LOCK(hcryp);
  1310. /* Change the CRYP state */
  1311. hcryp->State = HAL_CRYP_STATE_BUSY;
  1312. /*==============================================*/
  1313. /* GCM/GMAC (or CCM when applicable) init phase */
  1314. /*==============================================*/
  1315. /* In case of init phase, the input data (Key and Initialization Vector) have
  1316. already been entered during the initialization process. No DMA transfer is
  1317. required at that point therefore, the software just waits for the CCF flag
  1318. to be raised. */
  1319. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  1320. {
  1321. /* just wait for hash computation */
  1322. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  1323. {
  1324. hcryp->State = HAL_CRYP_STATE_READY;
  1325. __HAL_UNLOCK(hcryp);
  1326. return HAL_TIMEOUT;
  1327. }
  1328. /* Clear CCF Flag */
  1329. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1330. /* Mark that the initialization phase is over */
  1331. hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
  1332. hcryp->State = HAL_CRYP_STATE_READY;
  1333. }
  1334. /*====================================*/
  1335. /* GCM/GMAC/ CCM or CMAC header phase */
  1336. /*====================================*/
  1337. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  1338. {
  1339. #if !defined(AES_CR_NPBLB)
  1340. /* Set header phase; for GCM or GMAC, set data-byte at this point */
  1341. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
  1342. {
  1343. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
  1344. }
  1345. else
  1346. #endif
  1347. {
  1348. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
  1349. }
  1350. /* Enable the CRYP peripheral */
  1351. __HAL_CRYP_ENABLE(hcryp);
  1352. #if !defined(AES_CR_NPBLB)
  1353. /* enter first B0 block in polling mode (no DMA transfer for B0) */
  1354. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  1355. {
  1356. inputaddr = (uint32_t)pInputData;
  1357. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1358. inputaddr+=4U;
  1359. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1360. inputaddr+=4U;
  1361. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1362. inputaddr+=4U;
  1363. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1364. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  1365. {
  1366. hcryp->State = HAL_CRYP_STATE_READY;
  1367. __HAL_UNLOCK(hcryp);
  1368. return HAL_TIMEOUT;
  1369. }
  1370. /* Clear CCF Flag */
  1371. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1372. }
  1373. #endif
  1374. /* No header case */
  1375. if (hcryp->Init.Header == NULL)
  1376. {
  1377. hcryp->State = HAL_CRYP_STATE_READY;
  1378. /* Mark that the header phase is over */
  1379. hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  1380. /* Process Unlocked */
  1381. __HAL_UNLOCK(hcryp);
  1382. return HAL_OK;
  1383. }
  1384. inputaddr = (uint32_t)hcryp->Init.Header;
  1385. if ((hcryp->Init.HeaderSize % 16U) != 0U)
  1386. {
  1387. if (hcryp->Init.HeaderSize < 16U)
  1388. {
  1389. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  1390. CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
  1391. hcryp->State = HAL_CRYP_STATE_READY;
  1392. /* Mark that the header phase is over */
  1393. hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  1394. /* CCF flag indicating header phase AES processing completion
  1395. will be checked at the start of the next phase:
  1396. - payload phase (GCM / CCM when applicable)
  1397. - final phase (GMAC or CMAC when applicable). */
  1398. }
  1399. else
  1400. {
  1401. /* Local variable headerlength is a number of bytes multiple of 128 bits,
  1402. remaining header data (if any) are handled after this loop */
  1403. headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
  1404. /* Store the ending transfer point */
  1405. hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
  1406. hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
  1407. /* Set the input and output addresses and start DMA transfer */
  1408. /* (incomplete DMA transfer, will be wrapped up after completion of
  1409. the first one (initiated here) with data padding */
  1410. CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)headerlength, 0);
  1411. }
  1412. }
  1413. else
  1414. {
  1415. hcryp->CrypInCount = 0;
  1416. /* Set the input address and start DMA transfer */
  1417. CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)hcryp->Init.HeaderSize, 0);
  1418. }
  1419. }
  1420. /*============================================*/
  1421. /* GCM (or CCM when applicable) payload phase */
  1422. /*============================================*/
  1423. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  1424. {
  1425. /* Coming from header phase, wait for CCF flag to be raised
  1426. if header present and fed to the IP in the previous phase */
  1427. if (hcryp->Init.Header != NULL)
  1428. {
  1429. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  1430. {
  1431. hcryp->State = HAL_CRYP_STATE_READY;
  1432. __HAL_UNLOCK(hcryp);
  1433. return HAL_TIMEOUT;
  1434. }
  1435. }
  1436. else
  1437. {
  1438. /* Enable the Peripheral since wasn't in header phase (no header case) */
  1439. __HAL_CRYP_ENABLE(hcryp);
  1440. }
  1441. /* Clear CCF Flag */
  1442. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1443. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
  1444. /* No payload case */
  1445. if (pInputData == NULL)
  1446. {
  1447. hcryp->State = HAL_CRYP_STATE_READY;
  1448. /* Mark that the header phase is over */
  1449. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  1450. /* Process Unlocked */
  1451. __HAL_UNLOCK(hcryp);
  1452. return HAL_OK;
  1453. }
  1454. /* Specific handling to manage payload size less than 128 bits */
  1455. if ((Size % 16U) != 0U)
  1456. {
  1457. inputaddr = (uint32_t)pInputData;
  1458. outputaddr = (uint32_t)pOutputData;
  1459. if (Size < 16U)
  1460. {
  1461. /* Block is now entered in polling mode, no actual gain in resorting to DMA */
  1462. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  1463. hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
  1464. CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
  1465. /* Change the CRYP state to ready */
  1466. hcryp->State = HAL_CRYP_STATE_READY;
  1467. /* Mark that the payload phase is over */
  1468. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  1469. /* Call output data transfer complete callback */
  1470. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  1471. hcryp->OutCpltCallback(hcryp);
  1472. #else
  1473. HAL_CRYP_OutCpltCallback(hcryp);
  1474. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  1475. }
  1476. else
  1477. {
  1478. payloadlength = (Size/16U) * 16U;
  1479. /* Store the ending transfer points */
  1480. hcryp->pCrypInBuffPtr = pInputData;
  1481. hcryp->pCrypInBuffPtr += payloadlength;
  1482. hcryp->pCrypOutBuffPtr = pOutputData;
  1483. hcryp->pCrypOutBuffPtr += payloadlength;
  1484. hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
  1485. /* Set the input and output addresses and start DMA transfer */
  1486. /* (incomplete DMA transfer, will be wrapped up with data padding
  1487. after completion of the one initiated here) */
  1488. CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)payloadlength, outputaddr);
  1489. }
  1490. }
  1491. else
  1492. {
  1493. hcryp->CrypInCount = 0;
  1494. inputaddr = (uint32_t)pInputData;
  1495. outputaddr = (uint32_t)pOutputData;
  1496. /* Set the input and output addresses and start DMA transfer */
  1497. CRYP_Authentication_SetDMAConfig(hcryp, inputaddr, (uint16_t)Size, outputaddr);
  1498. }
  1499. }
  1500. /*==================================*/
  1501. /* GCM/GMAC/CCM or CMAC final phase */
  1502. /*==================================*/
  1503. else
  1504. {
  1505. /* If coming from header phase (GMAC or CMAC case when applicable),
  1506. wait for CCF flag to be raised */
  1507. if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
  1508. {
  1509. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  1510. {
  1511. hcryp->State = HAL_CRYP_STATE_READY;
  1512. __HAL_UNLOCK(hcryp);
  1513. return HAL_TIMEOUT;
  1514. }
  1515. /* Clear CCF Flag */
  1516. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1517. }
  1518. tagaddr = (uint32_t)pOutputData;
  1519. #if defined(AES_CR_NPBLB)
  1520. /* By default, clear NPBLB field */
  1521. CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
  1522. #endif
  1523. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
  1524. /* if the header and payload phases have been bypassed, AES must be enabled again */
  1525. if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
  1526. {
  1527. __HAL_CRYP_ENABLE(hcryp);
  1528. }
  1529. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
  1530. {
  1531. headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
  1532. inputlength = Size * 8U; /* input length in bits */
  1533. /* Write the number of bits in the header on 64 bits followed by the number
  1534. of bits in the payload on 64 bits as well */
  1535. #if !defined(AES_CR_NPBLB)
  1536. if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
  1537. {
  1538. hcryp->Instance->DINR = __RBIT((uint32_t)(headerlength>>32));
  1539. hcryp->Instance->DINR = __RBIT((uint32_t)headerlength);
  1540. hcryp->Instance->DINR = __RBIT((uint32_t)(inputlength>>32));
  1541. hcryp->Instance->DINR = __RBIT((uint32_t)inputlength);
  1542. }
  1543. else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
  1544. {
  1545. hcryp->Instance->DINR = __REV((uint32_t)(headerlength>>32));
  1546. hcryp->Instance->DINR = __REV((uint32_t)headerlength);
  1547. hcryp->Instance->DINR = __REV((uint32_t)(inputlength>>32));
  1548. hcryp->Instance->DINR = __REV((uint32_t)inputlength);
  1549. }
  1550. else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
  1551. {
  1552. hcryp->Instance->DINR = __ROR((uint32_t)(headerlength>>32), 16);
  1553. hcryp->Instance->DINR = __ROR((uint32_t)headerlength, 16);
  1554. hcryp->Instance->DINR = __ROR((uint32_t)(inputlength>>32), 16);
  1555. hcryp->Instance->DINR = __ROR((uint32_t)inputlength, 16);
  1556. }
  1557. else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
  1558. {
  1559. hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
  1560. hcryp->Instance->DINR = (uint32_t)(headerlength);
  1561. hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
  1562. hcryp->Instance->DINR = (uint32_t)(inputlength);
  1563. }
  1564. else
  1565. {
  1566. /* Unspecified Data Type */
  1567. return HAL_ERROR;
  1568. }
  1569. #else
  1570. hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
  1571. hcryp->Instance->DINR = (uint32_t)(headerlength);
  1572. hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
  1573. hcryp->Instance->DINR = (uint32_t)(inputlength);
  1574. #endif
  1575. }
  1576. #if !defined(AES_CR_NPBLB)
  1577. else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  1578. {
  1579. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1580. inputaddr = (uint32_t)pInputData;
  1581. /* Enter the last block made of a 128-bit value formatted
  1582. from the original B0 packet. */
  1583. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1584. inputaddr+=4U;
  1585. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1586. inputaddr+=4U;
  1587. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1588. inputaddr+=4U;
  1589. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  1590. }
  1591. else
  1592. {
  1593. /* Unspecified Chaining Mode */
  1594. return HAL_ERROR;
  1595. }
  1596. #endif
  1597. /* No DMA transfer is required at that point therefore, the software
  1598. just waits for the CCF flag to be raised. */
  1599. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  1600. {
  1601. hcryp->State = HAL_CRYP_STATE_READY;
  1602. __HAL_UNLOCK(hcryp);
  1603. return HAL_TIMEOUT;
  1604. }
  1605. /* Read the Auth TAG in the IN FIFO */
  1606. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  1607. tagaddr+=4U;
  1608. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  1609. tagaddr+=4U;
  1610. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  1611. tagaddr+=4U;
  1612. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
  1613. /* Clear CCF Flag */
  1614. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1615. /* Mark that the final phase is over */
  1616. hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
  1617. hcryp->State = HAL_CRYP_STATE_READY;
  1618. /* Disable the Peripheral */
  1619. __HAL_CRYP_DISABLE(hcryp);
  1620. }
  1621. /* Process Unlocked */
  1622. __HAL_UNLOCK(hcryp);
  1623. return HAL_OK;
  1624. }
  1625. else
  1626. {
  1627. return HAL_BUSY;
  1628. }
  1629. }
  1630. /**
  1631. * @}
  1632. */
  1633. /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
  1634. * @brief Extended processing functions.
  1635. *
  1636. @verbatim
  1637. ==============================================================================
  1638. ##### AES extended suspension and resumption functions #####
  1639. ==============================================================================
  1640. [..] This section provides functions allowing to:
  1641. (+) save in memory the Initialization Vector, the Key registers, the Control register or
  1642. the Suspend registers when a process is suspended by a higher priority message
  1643. (+) write back in CRYP hardware block the saved values listed above when the suspended
  1644. lower priority message processing is resumed.
  1645. @endverbatim
  1646. * @{
  1647. */
  1648. /**
  1649. * @brief In case of message processing suspension, read the Initialization Vector.
  1650. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1651. * the configuration information for CRYP module.
  1652. * @param Output Pointer to the buffer containing the saved Initialization Vector.
  1653. * @note This value has to be stored for reuse by writing the AES_IVRx registers
  1654. * as soon as the interrupted processing has to be resumed.
  1655. * Applicable to all chaining modes.
  1656. * @note AES must be disabled when reading or resetting the IV values.
  1657. * @retval None
  1658. */
  1659. void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
  1660. {
  1661. uint32_t outputaddr = (uint32_t)Output;
  1662. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
  1663. outputaddr+=4U;
  1664. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
  1665. outputaddr+=4U;
  1666. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
  1667. outputaddr+=4U;
  1668. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
  1669. }
  1670. /**
  1671. * @brief In case of message processing resumption, rewrite the Initialization
  1672. * Vector in the AES_IVRx registers.
  1673. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1674. * the configuration information for CRYP module.
  1675. * @param Input Pointer to the buffer containing the saved Initialization Vector to
  1676. * write back in the CRYP hardware block.
  1677. * @note Applicable to all chaining modes.
  1678. * @note AES must be disabled when reading or resetting the IV values.
  1679. * @retval None
  1680. */
  1681. void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
  1682. {
  1683. uint32_t ivaddr = (uint32_t)Input;
  1684. hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
  1685. ivaddr+=4U;
  1686. hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
  1687. ivaddr+=4U;
  1688. hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
  1689. ivaddr+=4U;
  1690. hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
  1691. }
  1692. /**
  1693. * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension,
  1694. * read the Suspend Registers.
  1695. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1696. * the configuration information for CRYP module.
  1697. * @param Output Pointer to the buffer containing the saved Suspend Registers.
  1698. * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
  1699. * as soon as the interrupted processing has to be resumed.
  1700. * @retval None
  1701. */
  1702. void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
  1703. {
  1704. uint32_t outputaddr = (uint32_t)Output;
  1705. /* In case of GCM payload phase encryption, check that suspension can be carried out */
  1706. if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD|AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
  1707. {
  1708. /* Ensure that Busy flag is reset */
  1709. if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
  1710. {
  1711. hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
  1712. hcryp->State = HAL_CRYP_STATE_ERROR;
  1713. /* Process Unlocked */
  1714. __HAL_UNLOCK(hcryp);
  1715. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  1716. hcryp->ErrorCallback(hcryp);
  1717. #else
  1718. HAL_CRYP_ErrorCallback(hcryp);
  1719. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  1720. return ;
  1721. }
  1722. }
  1723. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
  1724. outputaddr+=4U;
  1725. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
  1726. outputaddr+=4U;
  1727. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
  1728. outputaddr+=4U;
  1729. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
  1730. outputaddr+=4U;
  1731. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
  1732. outputaddr+=4U;
  1733. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
  1734. outputaddr+=4U;
  1735. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
  1736. outputaddr+=4U;
  1737. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
  1738. }
  1739. /**
  1740. * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Suspend
  1741. * Registers in the AES_SUSPxR registers.
  1742. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1743. * the configuration information for CRYP module.
  1744. * @param Input Pointer to the buffer containing the saved suspend registers to
  1745. * write back in the CRYP hardware block.
  1746. * @retval None
  1747. */
  1748. void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
  1749. {
  1750. uint32_t ivaddr = (uint32_t)Input;
  1751. hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
  1752. ivaddr+=4U;
  1753. hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
  1754. ivaddr+=4U;
  1755. hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
  1756. ivaddr+=4U;
  1757. hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
  1758. ivaddr+=4U;
  1759. hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
  1760. ivaddr+=4U;
  1761. hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
  1762. ivaddr+=4U;
  1763. hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
  1764. ivaddr+=4U;
  1765. hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
  1766. }
  1767. /**
  1768. * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Key Registers.
  1769. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1770. * the configuration information for CRYP module.
  1771. * @param Output Pointer to the buffer containing the saved Key Registers.
  1772. * @param KeySize Indicates the key size (128 or 256 bits).
  1773. * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
  1774. * as soon as the interrupted processing has to be resumed.
  1775. * @retval None
  1776. */
  1777. void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
  1778. {
  1779. uint32_t keyaddr = (uint32_t)Output;
  1780. if (KeySize == CRYP_KEYSIZE_256B)
  1781. {
  1782. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
  1783. keyaddr+=4U;
  1784. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
  1785. keyaddr+=4U;
  1786. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
  1787. keyaddr+=4U;
  1788. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
  1789. keyaddr+=4U;
  1790. }
  1791. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
  1792. keyaddr+=4U;
  1793. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
  1794. keyaddr+=4U;
  1795. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
  1796. keyaddr+=4U;
  1797. *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
  1798. }
  1799. /**
  1800. * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key
  1801. * Registers in the AES_KEYRx registers.
  1802. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1803. * the configuration information for CRYP module.
  1804. * @param Input Pointer to the buffer containing the saved key registers to
  1805. * write back in the CRYP hardware block.
  1806. * @param KeySize Indicates the key size (128 or 256 bits)
  1807. * @retval None
  1808. */
  1809. void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
  1810. {
  1811. uint32_t keyaddr = (uint32_t)Input;
  1812. if (KeySize == CRYP_KEYSIZE_256B)
  1813. {
  1814. hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
  1815. keyaddr+=4U;
  1816. hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
  1817. keyaddr+=4U;
  1818. hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
  1819. keyaddr+=4U;
  1820. hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
  1821. keyaddr+=4U;
  1822. }
  1823. hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
  1824. keyaddr+=4U;
  1825. hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
  1826. keyaddr+=4U;
  1827. hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
  1828. keyaddr+=4U;
  1829. hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
  1830. }
  1831. /**
  1832. * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing suspension, read the Control Register.
  1833. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1834. * the configuration information for CRYP module.
  1835. * @param Output Pointer to the buffer containing the saved Control Register.
  1836. * @note This values has to be stored for reuse by writing back the AES_CR register
  1837. * as soon as the interrupted processing has to be resumed.
  1838. * @retval None
  1839. */
  1840. void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
  1841. {
  1842. *(uint32_t*)(void *)(Output) = hcryp->Instance->CR; /* Derogation MisraC2012 R.11.5 */
  1843. }
  1844. /**
  1845. * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Control
  1846. * Registers in the AES_CR register.
  1847. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1848. * the configuration information for CRYP module.
  1849. * @param Input Pointer to the buffer containing the saved Control Register to
  1850. * write back in the CRYP hardware block.
  1851. * @retval None
  1852. */
  1853. void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
  1854. {
  1855. hcryp->Instance->CR = *(uint32_t*)(void *)(Input); /* Derogation MisraC2012 R.11.5 */
  1856. /* At the same time, set handle state back to READY to be able to resume the AES calculations
  1857. without the processing APIs returning HAL_BUSY when called. */
  1858. hcryp->State = HAL_CRYP_STATE_READY;
  1859. }
  1860. /**
  1861. * @brief Request CRYP processing suspension when in polling or interruption mode.
  1862. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1863. * the configuration information for CRYP module.
  1864. * @note Set the handle field SuspendRequest to the appropriate value so that
  1865. * the on-going CRYP processing is suspended as soon as the required
  1866. * conditions are met.
  1867. * @note It is advised not to suspend the CRYP processing when the DMA controller
  1868. * is managing the data transfer
  1869. * @retval None
  1870. */
  1871. void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
  1872. {
  1873. /* Set Handle Suspend Request field */
  1874. hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
  1875. }
  1876. /**
  1877. * @}
  1878. */
  1879. /**
  1880. * @}
  1881. */
  1882. /** @addtogroup CRYPEx_Private_Functions
  1883. * @{
  1884. */
  1885. /**
  1886. * @brief DMA CRYP Input Data process complete callback
  1887. * for GCM, GMAC, CCM or CMAC chaining modes.
  1888. * @note Specific setting of hcryp fields are required only
  1889. * in the case of header phase where no output data DMA
  1890. * transfer is on-going (only input data transfer is enabled
  1891. * in such a case).
  1892. * @param hdma DMA handle.
  1893. * @retval None
  1894. */
  1895. static void CRYP_Authentication_DMAInCplt(DMA_HandleTypeDef *hdma)
  1896. {
  1897. uint32_t difflength;
  1898. CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
  1899. /* Disable the DMA transfer for input request */
  1900. CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
  1901. if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  1902. {
  1903. if (hcryp->CrypInCount != 0U)
  1904. {
  1905. /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
  1906. difflength = hcryp->CrypInCount;
  1907. hcryp->CrypInCount = 0;
  1908. CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
  1909. }
  1910. hcryp->State = HAL_CRYP_STATE_READY;
  1911. /* Mark that the header phase is over */
  1912. hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  1913. }
  1914. /* CCF flag indicating header phase AES processing completion
  1915. will be checked at the start of the next phase:
  1916. - payload phase (GCM or CCM when applicable)
  1917. - final phase (GMAC or CMAC).
  1918. This allows to avoid the Wait on Flag within the IRQ handling. */
  1919. /* Call input data transfer complete callback */
  1920. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  1921. hcryp->InCpltCallback(hcryp);
  1922. #else
  1923. HAL_CRYP_InCpltCallback(hcryp);
  1924. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  1925. }
  1926. /**
  1927. * @brief DMA CRYP Output Data process complete callback
  1928. * for GCM, GMAC, CCM or CMAC chaining modes.
  1929. * @note This callback is called only in the payload phase.
  1930. * @param hdma DMA handle.
  1931. * @retval None
  1932. */
  1933. static void CRYP_Authentication_DMAOutCplt(DMA_HandleTypeDef *hdma)
  1934. {
  1935. uint32_t difflength;
  1936. CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
  1937. /* Disable the DMA transfer for output request */
  1938. CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
  1939. /* Clear CCF Flag */
  1940. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  1941. /* Initiate additional transfer to wrap-up data feeding to the IP */
  1942. if (hcryp->CrypInCount != 0U)
  1943. {
  1944. /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
  1945. difflength = hcryp->CrypInCount;
  1946. hcryp->CrypInCount = 0;
  1947. CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
  1948. }
  1949. /* Change the CRYP state to ready */
  1950. hcryp->State = HAL_CRYP_STATE_READY;
  1951. /* Mark that the payload phase is over */
  1952. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  1953. /* Call output data transfer complete callback */
  1954. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  1955. hcryp->OutCpltCallback(hcryp);
  1956. #else
  1957. HAL_CRYP_OutCpltCallback(hcryp);
  1958. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  1959. }
  1960. /**
  1961. * @brief DMA CRYP communication error callback
  1962. * for GCM, GMAC, CCM or CMAC chaining modes.
  1963. * @param hdma DMA handle
  1964. * @retval None
  1965. */
  1966. static void CRYP_Authentication_DMAError(DMA_HandleTypeDef *hdma)
  1967. {
  1968. CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
  1969. hcryp->State= HAL_CRYP_STATE_ERROR;
  1970. hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
  1971. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  1972. hcryp->ErrorCallback(hcryp);
  1973. #else
  1974. HAL_CRYP_ErrorCallback(hcryp);
  1975. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  1976. /* Clear Error Flag */
  1977. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
  1978. }
  1979. /**
  1980. * @brief Handle CRYP block input/output data handling under interruption
  1981. * for GCM, GMAC, CCM or CMAC chaining modes.
  1982. * @note The function is called under interruption only, once
  1983. * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
  1984. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  1985. * the configuration information for CRYP module
  1986. * @retval HAL status
  1987. */
  1988. HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
  1989. {
  1990. uint32_t inputaddr ;
  1991. uint32_t outputaddr ;
  1992. uint32_t index ;
  1993. uint32_t addhoc_process = 0;
  1994. uint32_t difflength = 0;
  1995. uint32_t difflengthmod4 = 0;
  1996. uint32_t mask[4][3] ;
  1997. uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
  1998. uint32_t intermediate_data[4] = {0};
  1999. mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
  2000. mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
  2001. mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
  2002. mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
  2003. if(hcryp->State == HAL_CRYP_STATE_BUSY)
  2004. {
  2005. /*===========================*/
  2006. /* GCM/GMAC(/CCM) init phase */
  2007. /*===========================*/
  2008. if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
  2009. {
  2010. /* Clear Computation Complete Flag */
  2011. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2012. /* Disable Computation Complete Flag and Errors Interrupts */
  2013. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2014. /* Change the CRYP state */
  2015. hcryp->State = HAL_CRYP_STATE_READY;
  2016. /* Mark that the initialization phase is over */
  2017. hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
  2018. /* Process Unlocked */
  2019. __HAL_UNLOCK(hcryp);
  2020. /* Call computation complete callback */
  2021. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2022. hcryp->CompCpltCallback(hcryp);
  2023. #else
  2024. HAL_CRYPEx_ComputationCpltCallback(hcryp);
  2025. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2026. return HAL_OK;
  2027. }
  2028. /*========================================*/
  2029. /* GCM/GMAC (or CCM or CMAC) header phase */
  2030. /*========================================*/
  2031. else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
  2032. {
  2033. /* Check if all input header data have been entered */
  2034. if (hcryp->CrypInCount == 0U)
  2035. {
  2036. /* Clear Computation Complete Flag */
  2037. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2038. /* Disable Computation Complete Flag and Errors Interrupts */
  2039. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2040. /* Change the CRYP state */
  2041. hcryp->State = HAL_CRYP_STATE_READY;
  2042. /* Mark that the header phase is over */
  2043. hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
  2044. /* Process Unlocked */
  2045. __HAL_UNLOCK(hcryp);
  2046. /* Call computation complete callback */
  2047. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2048. hcryp->CompCpltCallback(hcryp);
  2049. #else
  2050. HAL_CRYPEx_ComputationCpltCallback(hcryp);
  2051. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2052. return HAL_OK;
  2053. }
  2054. /* If suspension flag has been raised, suspend processing */
  2055. else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
  2056. {
  2057. /* Clear CCF Flag */
  2058. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2059. /* reset SuspendRequest */
  2060. hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  2061. /* Disable Computation Complete Flag and Errors Interrupts */
  2062. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2063. /* Change the CRYP state */
  2064. hcryp->State = HAL_CRYP_STATE_SUSPENDED;
  2065. /* Mark that the header phase is suspended */
  2066. hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
  2067. /* Process Unlocked */
  2068. __HAL_UNLOCK(hcryp);
  2069. return HAL_OK;
  2070. }
  2071. else /* Carry on feeding input data to the CRYP hardware block */
  2072. {
  2073. /* Clear Computation Complete Flag */
  2074. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2075. /* Get the last Input data address */
  2076. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  2077. /* Increment/decrement instance pointer/counter */
  2078. if (hcryp->CrypInCount < 16U)
  2079. {
  2080. difflength = hcryp->CrypInCount;
  2081. hcryp->CrypInCount = 0;
  2082. addhoc_process = 1;
  2083. difflengthmod4 = difflength%4U;
  2084. }
  2085. else
  2086. {
  2087. hcryp->pCrypInBuffPtr += 16;
  2088. hcryp->CrypInCount -= 16U;
  2089. }
  2090. #if defined(AES_CR_NPBLB)
  2091. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM)
  2092. #else
  2093. if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
  2094. #endif
  2095. {
  2096. if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
  2097. {
  2098. /* All B blocks will have been entered after the next
  2099. four DINR writing, so point at header buffer for
  2100. the next iteration */
  2101. hcryp->pCrypInBuffPtr = hcryp->Init.Header;
  2102. }
  2103. }
  2104. /* Write the Input block in the Data Input register */
  2105. if (addhoc_process == 0U)
  2106. {
  2107. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2108. inputaddr+=4U;
  2109. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2110. inputaddr+=4U;
  2111. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2112. inputaddr+=4U;
  2113. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2114. }
  2115. else
  2116. {
  2117. /* Header remainder has size less than 128 bits */
  2118. /* Enter complete words when possible */
  2119. for(index=0U ; index < (difflength/4U); index ++)
  2120. {
  2121. /* Write the Input block in the Data Input register */
  2122. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2123. inputaddr+=4U;
  2124. }
  2125. /* Enter incomplete word padded with zeroes if applicable
  2126. (case of header length not a multiple of 32-bits) */
  2127. if (difflengthmod4 != 0U)
  2128. {
  2129. hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
  2130. }
  2131. /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
  2132. for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
  2133. {
  2134. hcryp->Instance->DINR = 0;
  2135. }
  2136. }
  2137. return HAL_OK;
  2138. }
  2139. }
  2140. /*=======================*/
  2141. /* GCM/CCM payload phase */
  2142. /*=======================*/
  2143. else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  2144. {
  2145. /* Get the last output data address */
  2146. outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  2147. /* Specific handling to manage payload size less than 128 bits
  2148. when GCM (or CCM when applicable) encryption or decryption is selected.
  2149. Check here if the last block output data are read */
  2150. #if defined(AES_CR_NPBLB)
  2151. if ((hcryp->CrypOutCount < 16U) && \
  2152. (hcryp->CrypOutCount > 0U))
  2153. #else
  2154. if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
  2155. (hcryp->CrypOutCount < 16U) && \
  2156. (hcryp->CrypOutCount > 0U))
  2157. #endif
  2158. {
  2159. difflength = hcryp->CrypOutCount;
  2160. difflengthmod4 = difflength%4U;
  2161. hcryp->CrypOutCount = 0; /* mark that no more output data will be needed */
  2162. /* Retrieve intermediate data */
  2163. for(index=0U ; index < 4U; index ++)
  2164. {
  2165. intermediate_data[index] = hcryp->Instance->DOUTR;
  2166. }
  2167. /* Retrieve last words of cyphered data */
  2168. /* First, retrieve complete output words */
  2169. for(index=0U ; index < (difflength/4U); index ++)
  2170. {
  2171. *(uint32_t*)(outputaddr) = intermediate_data[index];
  2172. outputaddr+=4U;
  2173. }
  2174. /* Next, retrieve partial output word if applicable;
  2175. at the same time, start masking intermediate data
  2176. with a mask of zeros of same size than the padding
  2177. applied to the last block of payload */
  2178. if (difflengthmod4 != 0U)
  2179. {
  2180. intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
  2181. *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
  2182. }
  2183. #if !defined(AES_CR_NPBLB)
  2184. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
  2185. {
  2186. /* Change again CHMOD configuration to GCM mode */
  2187. __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
  2188. /* Select FINAL phase */
  2189. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
  2190. /* Before inserting the intermediate data, carry on masking operation
  2191. with a mask of zeros of same size than the padding applied to the last block of payload */
  2192. for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
  2193. {
  2194. intermediate_data[((difflength+3U)/4U)+index] = 0;
  2195. }
  2196. /* Insert intermediate data to trigger an additional DOUTR reading round */
  2197. /* Clear Computation Complete Flag before entering new block */
  2198. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2199. for(index=0U ; index < 4U; index ++)
  2200. {
  2201. hcryp->Instance->DINR = intermediate_data[index];
  2202. }
  2203. }
  2204. else
  2205. #endif
  2206. {
  2207. /* Payload phase is now over */
  2208. /* Clear Computation Complete Flag */
  2209. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2210. /* Disable Computation Complete Flag and Errors Interrupts */
  2211. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2212. /* Change the CRYP state */
  2213. hcryp->State = HAL_CRYP_STATE_READY;
  2214. /* Mark that the payload phase is over */
  2215. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  2216. /* Process Unlocked */
  2217. __HAL_UNLOCK(hcryp);
  2218. /* Call computation complete callback */
  2219. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2220. hcryp->CompCpltCallback(hcryp);
  2221. #else
  2222. HAL_CRYPEx_ComputationCpltCallback(hcryp);
  2223. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2224. }
  2225. return HAL_OK;
  2226. }
  2227. else
  2228. {
  2229. if (hcryp->CrypOutCount != 0U)
  2230. {
  2231. /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
  2232. /* Retrieve the last block available from the CRYP hardware block:
  2233. read the output block from the Data Output Register */
  2234. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2235. outputaddr+=4U;
  2236. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2237. outputaddr+=4U;
  2238. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2239. outputaddr+=4U;
  2240. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2241. /* Increment/decrement instance pointer/counter */
  2242. hcryp->pCrypOutBuffPtr += 16;
  2243. hcryp->CrypOutCount -= 16U;
  2244. }
  2245. #if !defined(AES_CR_NPBLB)
  2246. else
  2247. {
  2248. /* Software work-around: additional DOUTR reading round to discard the data */
  2249. for(index=0U ; index < 4U; index ++)
  2250. {
  2251. intermediate_data[index] = hcryp->Instance->DOUTR;
  2252. }
  2253. }
  2254. #endif
  2255. }
  2256. /* Check if all output text has been retrieved */
  2257. if (hcryp->CrypOutCount == 0U)
  2258. {
  2259. /* Clear Computation Complete Flag */
  2260. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2261. /* Disable Computation Complete Flag and Errors Interrupts */
  2262. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2263. /* Change the CRYP state */
  2264. hcryp->State = HAL_CRYP_STATE_READY;
  2265. /* Mark that the payload phase is over */
  2266. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
  2267. /* Process Unlocked */
  2268. __HAL_UNLOCK(hcryp);
  2269. /* Call computation complete callback */
  2270. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2271. hcryp->CompCpltCallback(hcryp);
  2272. #else
  2273. HAL_CRYPEx_ComputationCpltCallback(hcryp);
  2274. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2275. return HAL_OK;
  2276. }
  2277. /* If suspension flag has been raised, suspend processing */
  2278. else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
  2279. {
  2280. /* Clear CCF Flag */
  2281. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2282. /* reset SuspendRequest */
  2283. hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  2284. /* Disable Computation Complete Flag and Errors Interrupts */
  2285. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2286. /* Change the CRYP state */
  2287. hcryp->State = HAL_CRYP_STATE_SUSPENDED;
  2288. /* Mark that the payload phase is suspended */
  2289. hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_SUSPENDED;
  2290. /* Process Unlocked */
  2291. __HAL_UNLOCK(hcryp);
  2292. return HAL_OK;
  2293. }
  2294. else /* Output data are still expected, carry on feeding the CRYP
  2295. hardware block with input data */
  2296. {
  2297. /* Clear Computation Complete Flag */
  2298. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2299. /* Get the last Input data address */
  2300. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  2301. /* Usual input data feeding case */
  2302. if (hcryp->CrypInCount < 16U)
  2303. {
  2304. difflength = (uint32_t) (hcryp->CrypInCount);
  2305. difflengthmod4 = difflength%4U;
  2306. hcryp->CrypInCount = 0;
  2307. #if defined(AES_CR_NPBLB)
  2308. /* In case of GCM encryption or CCM decryption, specify the number of padding
  2309. bytes in last block of payload */
  2310. {
  2311. uint32_t cr_temp = hcryp->Instance->CR;
  2312. if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
  2313. || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
  2314. {
  2315. /* Set NPBLB field in writing the number of padding bytes
  2316. for the last block of payload */
  2317. MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
  2318. }
  2319. }
  2320. #else
  2321. /* Software workaround applied to GCM encryption only */
  2322. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
  2323. {
  2324. /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
  2325. __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
  2326. }
  2327. #endif
  2328. /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
  2329. to have a complete block of 128 bits */
  2330. for(index=0U ; index < (difflength/4U); index ++)
  2331. {
  2332. /* Write the Input block in the Data Input register */
  2333. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2334. inputaddr+=4U;
  2335. }
  2336. /* If required, manage input data size not multiple of 32 bits */
  2337. if (difflengthmod4 != 0U)
  2338. {
  2339. hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
  2340. }
  2341. /* Wrap-up in padding with zero-words if applicable */
  2342. for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
  2343. {
  2344. hcryp->Instance->DINR = 0;
  2345. }
  2346. }
  2347. else
  2348. {
  2349. hcryp->pCrypInBuffPtr += 16;
  2350. hcryp->CrypInCount -= 16U;
  2351. /* Write the Input block in the Data Input register */
  2352. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2353. inputaddr+=4U;
  2354. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2355. inputaddr+=4U;
  2356. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2357. inputaddr+=4U;
  2358. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2359. }
  2360. return HAL_OK;
  2361. }
  2362. }
  2363. /*=======================================*/
  2364. /* GCM/GMAC (or CCM or CMAC) final phase */
  2365. /*=======================================*/
  2366. else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
  2367. {
  2368. /* Clear Computation Complete Flag */
  2369. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2370. /* Get the last output data address */
  2371. outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  2372. /* Retrieve the last expected data from the CRYP hardware block:
  2373. read the output block from the Data Output Register */
  2374. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2375. outputaddr+=4U;
  2376. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2377. outputaddr+=4U;
  2378. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2379. outputaddr+=4U;
  2380. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2381. /* Disable Computation Complete Flag and Errors Interrupts */
  2382. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE|CRYP_IT_ERRIE);
  2383. /* Change the CRYP state */
  2384. hcryp->State = HAL_CRYP_STATE_READY;
  2385. /* Mark that the header phase is over */
  2386. hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
  2387. /* Disable the Peripheral */
  2388. __HAL_CRYP_DISABLE(hcryp);
  2389. /* Process Unlocked */
  2390. __HAL_UNLOCK(hcryp);
  2391. /* Call computation complete callback */
  2392. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2393. hcryp->CompCpltCallback(hcryp);
  2394. #else
  2395. HAL_CRYPEx_ComputationCpltCallback(hcryp);
  2396. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2397. return HAL_OK;
  2398. }
  2399. else
  2400. {
  2401. /* Clear Computation Complete Flag */
  2402. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2403. hcryp->State = HAL_CRYP_STATE_ERROR;
  2404. __HAL_UNLOCK(hcryp);
  2405. return HAL_ERROR;
  2406. }
  2407. }
  2408. else
  2409. {
  2410. return HAL_BUSY;
  2411. }
  2412. }
  2413. /**
  2414. * @brief Set the DMA configuration and start the DMA transfer
  2415. * for GCM, GMAC, CCM or CMAC chaining modes.
  2416. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2417. * the configuration information for CRYP module.
  2418. * @param inputaddr Address of the Input buffer.
  2419. * @param Size Size of the Input buffer un bytes, must be a multiple of 16.
  2420. * @param outputaddr Address of the Output buffer, null pointer when no output DMA stream
  2421. * has to be configured.
  2422. * @retval None
  2423. */
  2424. static void CRYP_Authentication_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
  2425. {
  2426. /* Set the input CRYP DMA transfer complete callback */
  2427. hcryp->hdmain->XferCpltCallback = CRYP_Authentication_DMAInCplt;
  2428. /* Set the DMA error callback */
  2429. hcryp->hdmain->XferErrorCallback = CRYP_Authentication_DMAError;
  2430. if (outputaddr != 0U)
  2431. {
  2432. /* Set the output CRYP DMA transfer complete callback */
  2433. hcryp->hdmaout->XferCpltCallback = CRYP_Authentication_DMAOutCplt;
  2434. /* Set the DMA error callback */
  2435. hcryp->hdmaout->XferErrorCallback = CRYP_Authentication_DMAError;
  2436. }
  2437. /* Enable the CRYP peripheral */
  2438. __HAL_CRYP_ENABLE(hcryp);
  2439. /* Enable the DMA input stream */
  2440. if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
  2441. {
  2442. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2443. hcryp->ErrorCallback(hcryp);
  2444. #else
  2445. HAL_CRYP_ErrorCallback(hcryp);
  2446. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2447. }
  2448. /* Enable the DMA input request */
  2449. SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
  2450. if (outputaddr != 0U)
  2451. {
  2452. /* Enable the DMA output stream */
  2453. if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
  2454. {
  2455. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2456. hcryp->ErrorCallback(hcryp);
  2457. #else
  2458. HAL_CRYP_ErrorCallback(hcryp);
  2459. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2460. }
  2461. /* Enable the DMA output request */
  2462. SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
  2463. }
  2464. }
  2465. /**
  2466. * @brief Write/read input/output data in polling mode.
  2467. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2468. * the configuration information for CRYP module.
  2469. * @param Input Pointer to the Input buffer.
  2470. * @param Ilength Length of the Input buffer in bytes, must be a multiple of 16.
  2471. * @param Output Pointer to the returned buffer.
  2472. * @param Timeout Specify Timeout value.
  2473. * @retval HAL status
  2474. */
  2475. static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
  2476. {
  2477. uint32_t index;
  2478. uint32_t inputaddr = (uint32_t)Input;
  2479. uint32_t outputaddr = (uint32_t)Output;
  2480. for(index=0U ; (index < Ilength); index += 16U)
  2481. {
  2482. /* Write the Input block in the Data Input register */
  2483. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2484. inputaddr+=4U;
  2485. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2486. inputaddr+=4U;
  2487. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2488. inputaddr+=4U;
  2489. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2490. inputaddr+=4U;
  2491. /* Wait for CCF flag to be raised */
  2492. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  2493. {
  2494. hcryp->State = HAL_CRYP_STATE_READY;
  2495. __HAL_UNLOCK(hcryp);
  2496. return HAL_TIMEOUT;
  2497. }
  2498. /* Clear CCF Flag */
  2499. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2500. /* Read the Output block from the Data Output Register */
  2501. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2502. outputaddr+=4U;
  2503. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2504. outputaddr+=4U;
  2505. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2506. outputaddr+=4U;
  2507. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
  2508. outputaddr+=4U;
  2509. /* If the suspension flag has been raised and if the processing is not about
  2510. to end, suspend processing */
  2511. if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
  2512. {
  2513. /* Reset SuspendRequest */
  2514. hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  2515. /* Save current reading and writing locations of Input and Output buffers */
  2516. hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
  2517. hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
  2518. /* Save the number of bytes that remain to be processed at this point */
  2519. hcryp->CrypInCount = Ilength - (index+16U);
  2520. /* Change the CRYP state */
  2521. hcryp->State = HAL_CRYP_STATE_SUSPENDED;
  2522. return HAL_OK;
  2523. }
  2524. }
  2525. /* Return function status */
  2526. return HAL_OK;
  2527. }
  2528. /**
  2529. * @brief Read derivative key in polling mode when CRYP hardware block is set
  2530. * in key derivation operating mode (mode 2).
  2531. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2532. * the configuration information for CRYP module.
  2533. * @param Output Pointer to the returned buffer.
  2534. * @param Timeout Specify Timeout value.
  2535. * @retval HAL status
  2536. */
  2537. static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
  2538. {
  2539. uint32_t outputaddr = (uint32_t)Output;
  2540. /* Wait for CCF flag to be raised */
  2541. if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
  2542. {
  2543. hcryp->State = HAL_CRYP_STATE_READY;
  2544. __HAL_UNLOCK(hcryp);
  2545. return HAL_TIMEOUT;
  2546. }
  2547. /* Clear CCF Flag */
  2548. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2549. /* Read the derivative key from the AES_KEYRx registers */
  2550. if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
  2551. {
  2552. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
  2553. outputaddr+=4U;
  2554. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
  2555. outputaddr+=4U;
  2556. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
  2557. outputaddr+=4U;
  2558. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
  2559. outputaddr+=4U;
  2560. }
  2561. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
  2562. outputaddr+=4U;
  2563. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
  2564. outputaddr+=4U;
  2565. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
  2566. outputaddr+=4U;
  2567. *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
  2568. /* Return function status */
  2569. return HAL_OK;
  2570. }
  2571. /**
  2572. * @brief Set the DMA configuration and start the DMA transfer.
  2573. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2574. * the configuration information for CRYP module.
  2575. * @param inputaddr Address of the Input buffer.
  2576. * @param Size Size of the Input buffer in bytes, must be a multiple of 16.
  2577. * @param outputaddr Address of the Output buffer.
  2578. * @retval None
  2579. */
  2580. static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
  2581. {
  2582. /* Set the CRYP DMA transfer complete callback */
  2583. hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
  2584. /* Set the DMA error callback */
  2585. hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
  2586. /* Set the CRYP DMA transfer complete callback */
  2587. hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
  2588. /* Set the DMA error callback */
  2589. hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
  2590. /* Enable the DMA input stream */
  2591. if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, ((uint32_t)Size)/4U) != HAL_OK)
  2592. {
  2593. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2594. hcryp->ErrorCallback(hcryp);
  2595. #else
  2596. HAL_CRYP_ErrorCallback(hcryp);
  2597. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2598. }
  2599. /* Enable the DMA output stream */
  2600. if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, ((uint32_t)Size)/4U) != HAL_OK)
  2601. {
  2602. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2603. hcryp->ErrorCallback(hcryp);
  2604. #else
  2605. HAL_CRYP_ErrorCallback(hcryp);
  2606. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2607. }
  2608. /* Enable In and Out DMA requests */
  2609. SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
  2610. /* Enable the CRYP peripheral */
  2611. __HAL_CRYP_ENABLE(hcryp);
  2612. }
  2613. /**
  2614. * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
  2615. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2616. * the configuration information for CRYP module.
  2617. * @param Timeout Timeout duration.
  2618. * @retval HAL status
  2619. */
  2620. static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
  2621. {
  2622. uint32_t tickstart;
  2623. /* Get timeout */
  2624. tickstart = HAL_GetTick();
  2625. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
  2626. {
  2627. /* Check for the Timeout */
  2628. if(Timeout != HAL_MAX_DELAY)
  2629. {
  2630. if((HAL_GetTick() - tickstart ) > Timeout)
  2631. {
  2632. return HAL_TIMEOUT;
  2633. }
  2634. }
  2635. }
  2636. return HAL_OK;
  2637. }
  2638. /**
  2639. * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
  2640. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2641. * the configuration information for CRYP module.
  2642. * @param Timeout Timeout duration.
  2643. * @retval HAL status
  2644. */
  2645. static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef const * const hcryp, uint32_t Timeout)
  2646. {
  2647. uint32_t tickstart;
  2648. /* Get timeout */
  2649. tickstart = HAL_GetTick();
  2650. while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
  2651. {
  2652. /* Check for the Timeout */
  2653. if(Timeout != HAL_MAX_DELAY)
  2654. {
  2655. if((HAL_GetTick() - tickstart ) > Timeout)
  2656. {
  2657. return HAL_TIMEOUT;
  2658. }
  2659. }
  2660. }
  2661. return HAL_OK;
  2662. }
  2663. /**
  2664. * @brief DMA CRYP Input Data process complete callback.
  2665. * @param hdma DMA handle.
  2666. * @retval None
  2667. */
  2668. static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
  2669. {
  2670. CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
  2671. /* Disable the DMA transfer for input request */
  2672. CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
  2673. /* Call input data transfer complete callback */
  2674. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2675. hcryp->InCpltCallback(hcryp);
  2676. #else
  2677. HAL_CRYP_InCpltCallback(hcryp);
  2678. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2679. }
  2680. /**
  2681. * @brief DMA CRYP Output Data process complete callback.
  2682. * @param hdma DMA handle.
  2683. * @retval None
  2684. */
  2685. static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
  2686. {
  2687. CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
  2688. /* Disable the DMA transfer for output request */
  2689. CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
  2690. /* Clear CCF Flag */
  2691. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2692. /* Disable CRYP */
  2693. __HAL_CRYP_DISABLE(hcryp);
  2694. /* Change the CRYP state to ready */
  2695. hcryp->State = HAL_CRYP_STATE_READY;
  2696. /* Call output data transfer complete callback */
  2697. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2698. hcryp->OutCpltCallback(hcryp);
  2699. #else
  2700. HAL_CRYP_OutCpltCallback(hcryp);
  2701. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2702. }
  2703. /**
  2704. * @brief DMA CRYP communication error callback.
  2705. * @param hdma DMA handle.
  2706. * @retval None
  2707. */
  2708. static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
  2709. {
  2710. CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; /* Derogation MisraC2012 R.11.5 */
  2711. hcryp->State= HAL_CRYP_STATE_ERROR;
  2712. hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
  2713. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2714. hcryp->ErrorCallback(hcryp);
  2715. #else
  2716. HAL_CRYP_ErrorCallback(hcryp);
  2717. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2718. /* Clear Error Flag */
  2719. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_ERR_CLEAR);
  2720. }
  2721. /**
  2722. * @brief Last header or payload block padding when size is not a multiple of 128 bits.
  2723. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  2724. * the configuration information for CRYP module.
  2725. * @param difflength size remainder after having fed all complete 128-bit blocks.
  2726. * @param polling specifies whether or not polling on CCF must be done after having
  2727. * entered a complete block.
  2728. * @retval None
  2729. */
  2730. static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
  2731. {
  2732. uint32_t index;
  2733. uint32_t difflengthmod4 = difflength%4U;
  2734. uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  2735. uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  2736. uint32_t mask[4][3];
  2737. uint32_t mask_index = hcryp->Init.DataType >> AES_CR_DATATYPE_Pos;
  2738. uint32_t intermediate_data[4] = {0};
  2739. mask[0][0] = 0xFF000000U; mask[0][1] = 0xFFFF0000U; mask[0][2] = 0xFFFFFF00U; /* 32-bit data */
  2740. mask[1][0] = 0x0000FF00U; mask[1][1] = 0x0000FFFFU; mask[1][2] = 0xFF00FFFFU; /* 16-bit data */
  2741. mask[2][0] = 0x000000FFU; mask[2][1] = 0x0000FFFFU; mask[2][2] = 0x00FFFFFFU; /* 8-bit data */
  2742. mask[3][0] = 0x000000FFU; mask[3][1] = 0x0000FFFFU; mask[3][2] = 0x00FFFFFFU; /* Bit data */
  2743. #if defined(AES_CR_NPBLB)
  2744. /* In case of GCM encryption or CCM decryption, specify the number of padding
  2745. bytes in last block of payload */
  2746. if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
  2747. {
  2748. uint32_t cr_temp = hcryp->Instance->CR;
  2749. if (((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_GCM_GMAC|CRYP_ALGOMODE_ENCRYPT))
  2750. || ((cr_temp & (AES_CR_CHMOD|AES_CR_MODE)) == (CRYP_CHAINMODE_AES_CCM|CRYP_ALGOMODE_DECRYPT)))
  2751. {
  2752. /* Set NPBLB field in writing the number of padding bytes
  2753. for the last block of payload */
  2754. MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, (16U - difflength) << AES_POSITION_CR_NPBLB);
  2755. }
  2756. }
  2757. #else
  2758. /* Software workaround applied to GCM encryption only */
  2759. if ((hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) &&
  2760. (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
  2761. {
  2762. /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
  2763. __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_CTR);
  2764. }
  2765. #endif
  2766. /* Wrap-up entering header or payload data */
  2767. /* Enter complete words when possible */
  2768. for(index=0U ; index < (difflength/4U); index ++)
  2769. {
  2770. /* Write the Input block in the Data Input register */
  2771. hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
  2772. inputaddr+=4U;
  2773. }
  2774. /* Enter incomplete word padded with zeroes if applicable
  2775. (case of header length not a multiple of 32-bits) */
  2776. if (difflengthmod4 != 0U)
  2777. {
  2778. hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[mask_index][difflengthmod4-1U]);
  2779. }
  2780. /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
  2781. for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
  2782. {
  2783. hcryp->Instance->DINR = 0;
  2784. }
  2785. if (polling == (uint32_t)CRYP_POLLING_ON)
  2786. {
  2787. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  2788. {
  2789. hcryp->State = HAL_CRYP_STATE_READY;
  2790. __HAL_UNLOCK(hcryp);
  2791. #if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
  2792. hcryp->ErrorCallback(hcryp);
  2793. #else
  2794. HAL_CRYP_ErrorCallback(hcryp);
  2795. #endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
  2796. }
  2797. /* Clear CCF Flag */
  2798. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2799. }
  2800. /* if payload */
  2801. if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
  2802. {
  2803. /* Retrieve intermediate data */
  2804. for(index=0U ; index < 4U; index ++)
  2805. {
  2806. intermediate_data[index] = hcryp->Instance->DOUTR;
  2807. }
  2808. /* Retrieve last words of cyphered data */
  2809. /* First, retrieve complete output words */
  2810. for(index=0U ; index < (difflength/4U); index ++)
  2811. {
  2812. *(uint32_t*)(outputaddr) = intermediate_data[index];
  2813. outputaddr+=4U;
  2814. }
  2815. /* Next, retrieve partial output word if applicable;
  2816. at the same time, start masking intermediate data
  2817. with a mask of zeros of same size than the padding
  2818. applied to the last block of payload */
  2819. if (difflengthmod4 != 0U)
  2820. {
  2821. intermediate_data[difflength/4U] &= mask[mask_index][difflengthmod4-1U];
  2822. *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
  2823. }
  2824. #if !defined(AES_CR_NPBLB)
  2825. /* Software workaround applied to GCM encryption only,
  2826. applicable for AES IP v2 version (where NPBLB is not defined) */
  2827. if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
  2828. {
  2829. /* Change again CHMOD configuration to GCM mode */
  2830. __HAL_CRYP_SET_CHAININGMODE(hcryp, CRYP_CHAINMODE_AES_GCM_GMAC);
  2831. /* Select FINAL phase */
  2832. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
  2833. /* Before inserting the intermediate data, carry on masking operation
  2834. with a mask of zeros of same size than the padding applied to the last block of payload */
  2835. for(index=0U ; index < (4U - ((difflength+3U)/4U)); index ++)
  2836. {
  2837. intermediate_data[((difflength+3U)/4U)+index] = 0;
  2838. }
  2839. /* Insert intermediate data */
  2840. for(index=0U ; index < 4U; index ++)
  2841. {
  2842. hcryp->Instance->DINR = intermediate_data[index];
  2843. }
  2844. /* Wait for completion, and read data on DOUT. This data is to discard. */
  2845. if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
  2846. {
  2847. hcryp->State = HAL_CRYP_STATE_READY;
  2848. __HAL_UNLOCK(hcryp);
  2849. HAL_CRYP_ErrorCallback(hcryp);
  2850. }
  2851. /* Read data to discard */
  2852. /* Clear CCF Flag */
  2853. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  2854. for(index=0U ; index < 4U; index ++)
  2855. {
  2856. intermediate_data[index] = hcryp->Instance->DOUTR;
  2857. }
  2858. } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
  2859. #endif /* !defined(AES_CR_NPBLB) */
  2860. } /* if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE) */
  2861. }
  2862. /**
  2863. * @}
  2864. */
  2865. /**
  2866. * @}
  2867. */
  2868. /**
  2869. * @}
  2870. */
  2871. #endif /* AES */
  2872. #endif /* HAL_CRYP_MODULE_ENABLED */