You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

3045 lines
98 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_hal_cryp_ex.c
  4. * @author MCD Application Team
  5. * @version V1.1.2
  6. * @date 23-September-2016
  7. * @brief Extended CRYP HAL module driver
  8. * This file provides firmware functions to manage the following
  9. * functionalities of CRYP extension peripheral:
  10. * + Extended AES processing functions
  11. *
  12. @verbatim
  13. ==============================================================================
  14. ##### How to use this driver #####
  15. ==============================================================================
  16. [..]
  17. The CRYP Extension HAL driver can be used as follows:
  18. (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
  19. (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
  20. (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
  21. (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
  22. (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
  23. (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
  24. (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
  25. (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
  26. (+++) Configure and enable two DMA streams one for managing data transfer from
  27. memory to peripheral (input stream) and another stream for managing data
  28. transfer from peripheral to memory (output stream)
  29. (+++) Associate the initialized DMA handle to the CRYP DMA handle
  30. using __HAL_LINKDMA()
  31. (+++) Configure the priority and enable the NVIC for the transfer complete
  32. interrupt on the two DMA Streams. The output stream should have higher
  33. priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
  34. (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
  35. (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
  36. (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
  37. (##) The encryption/decryption key. Its size depends on the algorithm
  38. used for encryption/decryption
  39. (##) The initialization vector (counter). It is not used ECB mode.
  40. (#)Three processing (encryption/decryption) functions are available:
  41. (##) Polling mode: encryption and decryption APIs are blocking functions
  42. i.e. they process the data and wait till the processing is finished
  43. e.g. HAL_CRYPEx_AESGCM_Encrypt()
  44. (##) Interrupt mode: encryption and decryption APIs are not blocking functions
  45. i.e. they process the data under interrupt
  46. e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
  47. (##) DMA mode: encryption and decryption APIs are not blocking functions
  48. i.e. the data transfer is ensured by DMA
  49. e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
  50. (#)When the processing function is called at first time after HAL_CRYP_Init()
  51. the CRYP peripheral is initialized and processes the buffer in input.
  52. At second call, the processing function performs an append of the already
  53. processed buffer.
  54. When a new data block is to be processed, call HAL_CRYP_Init() then the
  55. processing function.
  56. (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
  57. which provide authentication messages.
  58. HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
  59. authentication messages.
  60. Call those functions after the processing ones (polling, interrupt or DMA).
  61. e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
  62. then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
  63. -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version.
  64. -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length
  65. (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D).
  66. (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
  67. @endverbatim
  68. ******************************************************************************
  69. * @attention
  70. *
  71. * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  72. *
  73. * Redistribution and use in source and binary forms, with or without modification,
  74. * are permitted provided that the following conditions are met:
  75. * 1. Redistributions of source code must retain the above copyright notice,
  76. * this list of conditions and the following disclaimer.
  77. * 2. Redistributions in binary form must reproduce the above copyright notice,
  78. * this list of conditions and the following disclaimer in the documentation
  79. * and/or other materials provided with the distribution.
  80. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  81. * may be used to endorse or promote products derived from this software
  82. * without specific prior written permission.
  83. *
  84. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  85. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  87. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  88. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  89. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  90. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  91. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  92. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  93. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  94. *
  95. ******************************************************************************
  96. */
  97. /* Includes ------------------------------------------------------------------*/
  98. #include "stm32f7xx_hal.h"
  99. /** @addtogroup STM32F7xx_HAL_Driver
  100. * @{
  101. */
  102. /** @defgroup CRYPEx CRYPEx
  103. * @brief CRYP Extension HAL module driver.
  104. * @{
  105. */
  106. #ifdef HAL_CRYP_MODULE_ENABLED
  107. #if defined (CRYP)
  108. /* Private typedef -----------------------------------------------------------*/
  109. /* Private define ------------------------------------------------------------*/
  110. /** @addtogroup CRYPEx_Private_define
  111. * @{
  112. */
  113. #define CRYPEx_TIMEOUT_VALUE 1
  114. /**
  115. * @}
  116. */
  117. /* Private macro -------------------------------------------------------------*/
  118. /* Private variables ---------------------------------------------------------*/
  119. /* Private function prototypes -----------------------------------------------*/
  120. /** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes
  121. * @{
  122. */
  123. static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector);
  124. static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
  125. static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
  126. static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
  127. static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
  128. static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
  129. static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
  130. static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
  131. /**
  132. * @}
  133. */
  134. /* Private functions ---------------------------------------------------------*/
  135. /** @addtogroup CRYPEx_Private_Functions
  136. * @{
  137. */
  138. /**
  139. * @brief DMA CRYP Input Data process complete callback.
  140. * @param hdma: DMA handle
  141. * @retval None
  142. */
  143. static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)
  144. {
  145. CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  146. /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
  147. in the DMACR register */
  148. hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
  149. /* Call input data transfer complete callback */
  150. HAL_CRYP_InCpltCallback(hcryp);
  151. }
  152. /**
  153. * @brief DMA CRYP Output Data process complete callback.
  154. * @param hdma: DMA handle
  155. * @retval None
  156. */
  157. static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
  158. {
  159. CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  160. /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
  161. in the DMACR register */
  162. hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
  163. /* Enable the CRYP peripheral */
  164. __HAL_CRYP_DISABLE(hcryp);
  165. /* Change the CRYP peripheral state */
  166. hcryp->State = HAL_CRYP_STATE_READY;
  167. /* Call output data transfer complete callback */
  168. HAL_CRYP_OutCpltCallback(hcryp);
  169. }
  170. /**
  171. * @brief DMA CRYP communication error callback.
  172. * @param hdma: DMA handle
  173. * @retval None
  174. */
  175. static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
  176. {
  177. CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  178. hcryp->State= HAL_CRYP_STATE_READY;
  179. HAL_CRYP_ErrorCallback(hcryp);
  180. }
  181. /**
  182. * @brief Writes the Key in Key registers.
  183. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  184. * the configuration information for CRYP module
  185. * @param Key: Pointer to Key buffer
  186. * @param KeySize: Size of Key
  187. * @retval None
  188. */
  189. static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
  190. {
  191. uint32_t keyaddr = (uint32_t)Key;
  192. switch(KeySize)
  193. {
  194. case CRYP_KEYSIZE_256B:
  195. /* Key Initialisation */
  196. hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr));
  197. keyaddr+=4;
  198. hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr));
  199. keyaddr+=4;
  200. hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
  201. keyaddr+=4;
  202. hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
  203. keyaddr+=4;
  204. hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
  205. keyaddr+=4;
  206. hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
  207. keyaddr+=4;
  208. hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
  209. keyaddr+=4;
  210. hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
  211. break;
  212. case CRYP_KEYSIZE_192B:
  213. hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
  214. keyaddr+=4;
  215. hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
  216. keyaddr+=4;
  217. hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
  218. keyaddr+=4;
  219. hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
  220. keyaddr+=4;
  221. hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
  222. keyaddr+=4;
  223. hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
  224. break;
  225. case CRYP_KEYSIZE_128B:
  226. hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
  227. keyaddr+=4;
  228. hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
  229. keyaddr+=4;
  230. hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
  231. keyaddr+=4;
  232. hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
  233. break;
  234. default:
  235. break;
  236. }
  237. }
  238. /**
  239. * @brief Writes the InitVector/InitCounter in IV registers.
  240. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  241. * the configuration information for CRYP module
  242. * @param InitVector: Pointer to InitVector/InitCounter buffer
  243. * @retval None
  244. */
  245. static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector)
  246. {
  247. uint32_t ivaddr = (uint32_t)InitVector;
  248. hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr));
  249. ivaddr+=4;
  250. hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr));
  251. ivaddr+=4;
  252. hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr));
  253. ivaddr+=4;
  254. hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr));
  255. }
  256. /**
  257. * @brief Process Data: Writes Input data in polling mode and read the Output data.
  258. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  259. * the configuration information for CRYP module
  260. * @param Input: Pointer to the Input buffer.
  261. * @param Ilength: Length of the Input buffer, must be a multiple of 16
  262. * @param Output: Pointer to the returned buffer
  263. * @param Timeout: Timeout value
  264. * @retval None
  265. */
  266. static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
  267. {
  268. uint32_t tickstart = 0;
  269. uint32_t i = 0;
  270. uint32_t inputaddr = (uint32_t)Input;
  271. uint32_t outputaddr = (uint32_t)Output;
  272. for(i=0; (i < Ilength); i+=16)
  273. {
  274. /* Write the Input block in the IN FIFO */
  275. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  276. inputaddr+=4;
  277. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  278. inputaddr+=4;
  279. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  280. inputaddr+=4;
  281. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  282. inputaddr+=4;
  283. /* Get tick */
  284. tickstart = HAL_GetTick();
  285. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  286. {
  287. /* Check for the Timeout */
  288. if(Timeout != HAL_MAX_DELAY)
  289. {
  290. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  291. {
  292. /* Change state */
  293. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  294. /* Process Unlocked */
  295. __HAL_UNLOCK(hcryp);
  296. return HAL_TIMEOUT;
  297. }
  298. }
  299. }
  300. /* Read the Output block from the OUT FIFO */
  301. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  302. outputaddr+=4;
  303. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  304. outputaddr+=4;
  305. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  306. outputaddr+=4;
  307. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  308. outputaddr+=4;
  309. }
  310. /* Return function status */
  311. return HAL_OK;
  312. }
  313. /**
  314. * @brief Sets the header phase
  315. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  316. * the configuration information for CRYP module
  317. * @param Input: Pointer to the Input buffer.
  318. * @param Ilength: Length of the Input buffer, must be a multiple of 16
  319. * @param Timeout: Timeout value
  320. * @retval None
  321. */
  322. static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
  323. {
  324. uint32_t tickstart = 0;
  325. uint32_t loopcounter = 0;
  326. uint32_t headeraddr = (uint32_t)Input;
  327. /***************************** Header phase *********************************/
  328. if(hcryp->Init.HeaderSize != 0)
  329. {
  330. /* Select header phase */
  331. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  332. /* Enable the CRYP peripheral */
  333. __HAL_CRYP_ENABLE(hcryp);
  334. for(loopcounter = 0; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16)
  335. {
  336. /* Get tick */
  337. tickstart = HAL_GetTick();
  338. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  339. {
  340. /* Check for the Timeout */
  341. if(Timeout != HAL_MAX_DELAY)
  342. {
  343. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  344. {
  345. /* Change state */
  346. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  347. /* Process Unlocked */
  348. __HAL_UNLOCK(hcryp);
  349. return HAL_TIMEOUT;
  350. }
  351. }
  352. }
  353. /* Write the Input block in the IN FIFO */
  354. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  355. headeraddr+=4;
  356. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  357. headeraddr+=4;
  358. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  359. headeraddr+=4;
  360. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  361. headeraddr+=4;
  362. }
  363. /* Wait until the complete message has been processed */
  364. /* Get tick */
  365. tickstart = HAL_GetTick();
  366. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  367. {
  368. /* Check for the Timeout */
  369. if(Timeout != HAL_MAX_DELAY)
  370. {
  371. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  372. {
  373. /* Change state */
  374. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  375. /* Process Unlocked */
  376. __HAL_UNLOCK(hcryp);
  377. return HAL_TIMEOUT;
  378. }
  379. }
  380. }
  381. }
  382. /* Return function status */
  383. return HAL_OK;
  384. }
  385. /**
  386. * @brief Sets the DMA configuration and start the DMA transfer.
  387. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  388. * the configuration information for CRYP module
  389. * @param inputaddr: Address of the Input buffer
  390. * @param Size: Size of the Input buffer, must be a multiple of 16
  391. * @param outputaddr: Address of the Output buffer
  392. * @retval None
  393. */
  394. static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
  395. {
  396. /* Set the CRYP DMA transfer complete callback */
  397. hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
  398. /* Set the DMA error callback */
  399. hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
  400. /* Set the CRYP DMA transfer complete callback */
  401. hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
  402. /* Set the DMA error callback */
  403. hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
  404. /* Enable the CRYP peripheral */
  405. __HAL_CRYP_ENABLE(hcryp);
  406. /* Enable the DMA In DMA Stream */
  407. HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4);
  408. /* Enable In DMA request */
  409. hcryp->Instance->DMACR = CRYP_DMACR_DIEN;
  410. /* Enable the DMA Out DMA Stream */
  411. HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4);
  412. /* Enable Out DMA request */
  413. hcryp->Instance->DMACR |= CRYP_DMACR_DOEN;
  414. }
  415. /**
  416. * @}
  417. */
  418. /* Exported functions---------------------------------------------------------*/
  419. /** @addtogroup CRYPEx_Exported_Functions
  420. * @{
  421. */
  422. /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
  423. * @brief Extended processing functions.
  424. *
  425. @verbatim
  426. ==============================================================================
  427. ##### Extended AES processing functions #####
  428. ==============================================================================
  429. [..] This section provides functions allowing to:
  430. (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
  431. (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
  432. (+) Finish the processing. This function is available only for GCM and CCM
  433. [..] Three processing methods are available:
  434. (+) Polling mode
  435. (+) Interrupt mode
  436. (+) DMA mode
  437. @endverbatim
  438. * @{
  439. */
  440. /**
  441. * @brief Initializes the CRYP peripheral in AES CCM encryption mode then
  442. * encrypt pPlainData. The cypher data are available in pCypherData.
  443. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  444. * the configuration information for CRYP module
  445. * @param pPlainData: Pointer to the plaintext buffer
  446. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  447. * @param pCypherData: Pointer to the cyphertext buffer
  448. * @param Timeout: Timeout duration
  449. * @retval HAL status
  450. */
  451. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
  452. {
  453. uint32_t tickstart = 0;
  454. uint32_t headersize = hcryp->Init.HeaderSize;
  455. uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
  456. uint32_t loopcounter = 0;
  457. uint32_t bufferidx = 0;
  458. uint8_t blockb0[16] = {0};/* Block B0 */
  459. uint8_t ctr[16] = {0}; /* Counter */
  460. uint32_t b0addr = (uint32_t)blockb0;
  461. /* Process Locked */
  462. __HAL_LOCK(hcryp);
  463. /* Change the CRYP peripheral state */
  464. hcryp->State = HAL_CRYP_STATE_BUSY;
  465. /* Check if initialization phase has already been performed */
  466. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  467. {
  468. /************************ Formatting the header block *********************/
  469. if(headersize != 0)
  470. {
  471. /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
  472. if(headersize < 65280)
  473. {
  474. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
  475. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
  476. headersize += 2;
  477. }
  478. else
  479. {
  480. /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
  481. hcryp->Init.pScratch[bufferidx++] = 0xFF;
  482. hcryp->Init.pScratch[bufferidx++] = 0xFE;
  483. hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
  484. hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
  485. hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
  486. hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
  487. headersize += 6;
  488. }
  489. /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
  490. for(loopcounter = 0; loopcounter < headersize; loopcounter++)
  491. {
  492. hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
  493. }
  494. /* Check if the header size is modulo 16 */
  495. if ((headersize % 16) != 0)
  496. {
  497. /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
  498. for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
  499. {
  500. hcryp->Init.pScratch[loopcounter] = 0;
  501. }
  502. /* Set the header size to modulo 16 */
  503. headersize = ((headersize/16) + 1) * 16;
  504. }
  505. /* Set the pointer headeraddr to hcryp->Init.pScratch */
  506. headeraddr = (uint32_t)hcryp->Init.pScratch;
  507. }
  508. /*********************** Formatting the block B0 **************************/
  509. if(headersize != 0)
  510. {
  511. blockb0[0] = 0x40;
  512. }
  513. /* Flags byte */
  514. /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
  515. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
  516. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
  517. for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
  518. {
  519. blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
  520. }
  521. for ( ; loopcounter < 13; loopcounter++)
  522. {
  523. blockb0[loopcounter+1] = 0;
  524. }
  525. blockb0[14] = (Size >> 8);
  526. blockb0[15] = (Size & 0xFF);
  527. /************************* Formatting the initial counter *****************/
  528. /* Byte 0:
  529. Bits 7 and 6 are reserved and shall be set to 0
  530. Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
  531. are distinct from B0
  532. Bits 0, 1, and 2 contain the same encoding of q as in B0
  533. */
  534. ctr[0] = blockb0[0] & 0x07;
  535. /* byte 1 to NonceSize is the IV (Nonce) */
  536. for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
  537. {
  538. ctr[loopcounter] = blockb0[loopcounter];
  539. }
  540. /* Set the LSB to 1 */
  541. ctr[15] |= 0x01;
  542. /* Set the key */
  543. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  544. /* Set the CRYP peripheral in AES CCM mode */
  545. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
  546. /* Set the Initialization Vector */
  547. CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
  548. /* Select init phase */
  549. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
  550. b0addr = (uint32_t)blockb0;
  551. /* Write the blockb0 block in the IN FIFO */
  552. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  553. b0addr+=4;
  554. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  555. b0addr+=4;
  556. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  557. b0addr+=4;
  558. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  559. /* Enable the CRYP peripheral */
  560. __HAL_CRYP_ENABLE(hcryp);
  561. /* Get tick */
  562. tickstart = HAL_GetTick();
  563. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  564. {
  565. /* Check for the Timeout */
  566. if(Timeout != HAL_MAX_DELAY)
  567. {
  568. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  569. {
  570. /* Change state */
  571. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  572. /* Process Unlocked */
  573. __HAL_UNLOCK(hcryp);
  574. return HAL_TIMEOUT;
  575. }
  576. }
  577. }
  578. /***************************** Header phase *******************************/
  579. if(headersize != 0)
  580. {
  581. /* Select header phase */
  582. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  583. /* Enable the CRYP peripheral */
  584. __HAL_CRYP_ENABLE(hcryp);
  585. for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
  586. {
  587. /* Get tick */
  588. tickstart = HAL_GetTick();
  589. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  590. {
  591. {
  592. /* Check for the Timeout */
  593. if(Timeout != HAL_MAX_DELAY)
  594. {
  595. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  596. {
  597. /* Change state */
  598. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  599. /* Process Unlocked */
  600. __HAL_UNLOCK(hcryp);
  601. return HAL_TIMEOUT;
  602. }
  603. }
  604. }
  605. }
  606. /* Write the header block in the IN FIFO */
  607. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  608. headeraddr+=4;
  609. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  610. headeraddr+=4;
  611. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  612. headeraddr+=4;
  613. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  614. headeraddr+=4;
  615. }
  616. /* Get tick */
  617. tickstart = HAL_GetTick();
  618. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  619. {
  620. /* Check for the Timeout */
  621. if(Timeout != HAL_MAX_DELAY)
  622. {
  623. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  624. {
  625. /* Change state */
  626. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  627. /* Process Unlocked */
  628. __HAL_UNLOCK(hcryp);
  629. return HAL_TIMEOUT;
  630. }
  631. }
  632. }
  633. }
  634. /* Save formatted counter into the scratch buffer pScratch */
  635. for(loopcounter = 0; (loopcounter < 16); loopcounter++)
  636. {
  637. hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
  638. }
  639. /* Reset bit 0 */
  640. hcryp->Init.pScratch[15] &= 0xfe;
  641. /* Select payload phase once the header phase is performed */
  642. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  643. /* Flush FIFO */
  644. __HAL_CRYP_FIFO_FLUSH(hcryp);
  645. /* Enable the CRYP peripheral */
  646. __HAL_CRYP_ENABLE(hcryp);
  647. /* Set the phase */
  648. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  649. }
  650. /* Write Plain Data and Get Cypher Data */
  651. if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
  652. {
  653. return HAL_TIMEOUT;
  654. }
  655. /* Change the CRYP peripheral state */
  656. hcryp->State = HAL_CRYP_STATE_READY;
  657. /* Process Unlocked */
  658. __HAL_UNLOCK(hcryp);
  659. /* Return function status */
  660. return HAL_OK;
  661. }
  662. /**
  663. * @brief Initializes the CRYP peripheral in AES GCM encryption mode then
  664. * encrypt pPlainData. The cypher data are available in pCypherData.
  665. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  666. * the configuration information for CRYP module
  667. * @param pPlainData: Pointer to the plaintext buffer
  668. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  669. * @param pCypherData: Pointer to the cyphertext buffer
  670. * @param Timeout: Timeout duration
  671. * @retval HAL status
  672. */
  673. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
  674. {
  675. uint32_t tickstart = 0;
  676. /* Process Locked */
  677. __HAL_LOCK(hcryp);
  678. /* Change the CRYP peripheral state */
  679. hcryp->State = HAL_CRYP_STATE_BUSY;
  680. /* Check if initialization phase has already been performed */
  681. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  682. {
  683. /* Set the key */
  684. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  685. /* Set the CRYP peripheral in AES GCM mode */
  686. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
  687. /* Set the Initialization Vector */
  688. CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
  689. /* Flush FIFO */
  690. __HAL_CRYP_FIFO_FLUSH(hcryp);
  691. /* Enable the CRYP peripheral */
  692. __HAL_CRYP_ENABLE(hcryp);
  693. /* Get tick */
  694. tickstart = HAL_GetTick();
  695. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  696. {
  697. /* Check for the Timeout */
  698. if(Timeout != HAL_MAX_DELAY)
  699. {
  700. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  701. {
  702. /* Change state */
  703. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  704. /* Process Unlocked */
  705. __HAL_UNLOCK(hcryp);
  706. return HAL_TIMEOUT;
  707. }
  708. }
  709. }
  710. /* Set the header phase */
  711. if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
  712. {
  713. return HAL_TIMEOUT;
  714. }
  715. /* Disable the CRYP peripheral */
  716. __HAL_CRYP_DISABLE(hcryp);
  717. /* Select payload phase once the header phase is performed */
  718. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  719. /* Flush FIFO */
  720. __HAL_CRYP_FIFO_FLUSH(hcryp);
  721. /* Enable the CRYP peripheral */
  722. __HAL_CRYP_ENABLE(hcryp);
  723. /* Set the phase */
  724. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  725. }
  726. /* Write Plain Data and Get Cypher Data */
  727. if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
  728. {
  729. return HAL_TIMEOUT;
  730. }
  731. /* Change the CRYP peripheral state */
  732. hcryp->State = HAL_CRYP_STATE_READY;
  733. /* Process Unlocked */
  734. __HAL_UNLOCK(hcryp);
  735. /* Return function status */
  736. return HAL_OK;
  737. }
  738. /**
  739. * @brief Initializes the CRYP peripheral in AES GCM decryption mode then
  740. * decrypted pCypherData. The cypher data are available in pPlainData.
  741. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  742. * the configuration information for CRYP module
  743. * @param pCypherData: Pointer to the cyphertext buffer
  744. * @param Size: Length of the cyphertext buffer, must be a multiple of 16
  745. * @param pPlainData: Pointer to the plaintext buffer
  746. * @param Timeout: Timeout duration
  747. * @retval HAL status
  748. */
  749. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
  750. {
  751. uint32_t tickstart = 0;
  752. /* Process Locked */
  753. __HAL_LOCK(hcryp);
  754. /* Change the CRYP peripheral state */
  755. hcryp->State = HAL_CRYP_STATE_BUSY;
  756. /* Check if initialization phase has already been performed */
  757. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  758. {
  759. /* Set the key */
  760. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  761. /* Set the CRYP peripheral in AES GCM decryption mode */
  762. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
  763. /* Set the Initialization Vector */
  764. CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
  765. /* Flush FIFO */
  766. __HAL_CRYP_FIFO_FLUSH(hcryp);
  767. /* Enable the CRYP peripheral */
  768. __HAL_CRYP_ENABLE(hcryp);
  769. /* Get tick */
  770. tickstart = HAL_GetTick();
  771. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  772. {
  773. /* Check for the Timeout */
  774. if(Timeout != HAL_MAX_DELAY)
  775. {
  776. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  777. {
  778. /* Change state */
  779. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  780. /* Process Unlocked */
  781. __HAL_UNLOCK(hcryp);
  782. return HAL_TIMEOUT;
  783. }
  784. }
  785. }
  786. /* Set the header phase */
  787. if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
  788. {
  789. return HAL_TIMEOUT;
  790. }
  791. /* Disable the CRYP peripheral */
  792. __HAL_CRYP_DISABLE(hcryp);
  793. /* Select payload phase once the header phase is performed */
  794. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  795. /* Enable the CRYP peripheral */
  796. __HAL_CRYP_ENABLE(hcryp);
  797. /* Set the phase */
  798. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  799. }
  800. /* Write Plain Data and Get Cypher Data */
  801. if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
  802. {
  803. return HAL_TIMEOUT;
  804. }
  805. /* Change the CRYP peripheral state */
  806. hcryp->State = HAL_CRYP_STATE_READY;
  807. /* Process Unlocked */
  808. __HAL_UNLOCK(hcryp);
  809. /* Return function status */
  810. return HAL_OK;
  811. }
  812. /**
  813. * @brief Computes the authentication TAG.
  814. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  815. * the configuration information for CRYP module
  816. * @param Size: Total length of the plain/cyphertext buffer
  817. * @param AuthTag: Pointer to the authentication buffer
  818. * @param Timeout: Timeout duration
  819. * @retval HAL status
  820. */
  821. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout)
  822. {
  823. uint32_t tickstart = 0;
  824. uint64_t headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
  825. uint64_t inputlength = Size * 8; /* input length in bits */
  826. uint32_t tagaddr = (uint32_t)AuthTag;
  827. /* Process Locked */
  828. __HAL_LOCK(hcryp);
  829. /* Change the CRYP peripheral state */
  830. hcryp->State = HAL_CRYP_STATE_BUSY;
  831. /* Check if initialization phase has already been performed */
  832. if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
  833. {
  834. /* Change the CRYP phase */
  835. hcryp->Phase = HAL_CRYP_PHASE_FINAL;
  836. /* Disable CRYP to start the final phase */
  837. __HAL_CRYP_DISABLE(hcryp);
  838. /* Select final phase */
  839. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
  840. /* Enable the CRYP peripheral */
  841. __HAL_CRYP_ENABLE(hcryp);
  842. /* Write the number of bits in header (64 bits) followed by the number of bits
  843. in the payload */
  844. if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
  845. {
  846. hcryp->Instance->DR = __RBIT(headerlength >> 32);
  847. hcryp->Instance->DR = __RBIT(headerlength);
  848. hcryp->Instance->DR = __RBIT(inputlength >> 32);
  849. hcryp->Instance->DR = __RBIT(inputlength);
  850. }
  851. else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
  852. {
  853. hcryp->Instance->DR = __REV(headerlength >> 32);
  854. hcryp->Instance->DR = __REV(headerlength);
  855. hcryp->Instance->DR = __REV(inputlength >> 32);
  856. hcryp->Instance->DR = __REV(inputlength);
  857. }
  858. else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
  859. {
  860. hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32), 16);
  861. hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16);
  862. hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32), 16);
  863. hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16);
  864. }
  865. else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
  866. {
  867. hcryp->Instance->DR = (uint32_t)(headerlength >> 32);
  868. hcryp->Instance->DR = (uint32_t)(headerlength);
  869. hcryp->Instance->DR = (uint32_t)(inputlength >> 32);
  870. hcryp->Instance->DR = (uint32_t)(inputlength);
  871. }
  872. /* Get tick */
  873. tickstart = HAL_GetTick();
  874. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  875. {
  876. /* Check for the Timeout */
  877. if(Timeout != HAL_MAX_DELAY)
  878. {
  879. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  880. {
  881. /* Change state */
  882. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  883. /* Process Unlocked */
  884. __HAL_UNLOCK(hcryp);
  885. return HAL_TIMEOUT;
  886. }
  887. }
  888. }
  889. /* Read the Auth TAG in the IN FIFO */
  890. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  891. tagaddr+=4;
  892. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  893. tagaddr+=4;
  894. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  895. tagaddr+=4;
  896. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  897. }
  898. /* Change the CRYP peripheral state */
  899. hcryp->State = HAL_CRYP_STATE_READY;
  900. /* Process Unlocked */
  901. __HAL_UNLOCK(hcryp);
  902. /* Return function status */
  903. return HAL_OK;
  904. }
  905. /**
  906. * @brief Computes the authentication TAG for AES CCM mode.
  907. * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()
  908. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  909. * the configuration information for CRYP module
  910. * @param AuthTag: Pointer to the authentication buffer
  911. * @param Timeout: Timeout duration
  912. * @retval HAL status
  913. */
  914. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
  915. {
  916. uint32_t tickstart = 0;
  917. uint32_t tagaddr = (uint32_t)AuthTag;
  918. uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
  919. uint32_t temptag[4] = {0}; /* Temporary TAG (MAC) */
  920. uint32_t loopcounter;
  921. /* Process Locked */
  922. __HAL_LOCK(hcryp);
  923. /* Change the CRYP peripheral state */
  924. hcryp->State = HAL_CRYP_STATE_BUSY;
  925. /* Check if initialization phase has already been performed */
  926. if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
  927. {
  928. /* Change the CRYP phase */
  929. hcryp->Phase = HAL_CRYP_PHASE_FINAL;
  930. /* Disable CRYP to start the final phase */
  931. __HAL_CRYP_DISABLE(hcryp);
  932. /* Select final phase */
  933. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
  934. /* Enable the CRYP peripheral */
  935. __HAL_CRYP_ENABLE(hcryp);
  936. /* Write the counter block in the IN FIFO */
  937. hcryp->Instance->DR = *(uint32_t*)ctraddr;
  938. ctraddr+=4;
  939. hcryp->Instance->DR = *(uint32_t*)ctraddr;
  940. ctraddr+=4;
  941. hcryp->Instance->DR = *(uint32_t*)ctraddr;
  942. ctraddr+=4;
  943. hcryp->Instance->DR = *(uint32_t*)ctraddr;
  944. /* Get tick */
  945. tickstart = HAL_GetTick();
  946. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  947. {
  948. /* Check for the Timeout */
  949. if(Timeout != HAL_MAX_DELAY)
  950. {
  951. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  952. {
  953. /* Change state */
  954. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  955. /* Process Unlocked */
  956. __HAL_UNLOCK(hcryp);
  957. return HAL_TIMEOUT;
  958. }
  959. }
  960. }
  961. /* Read the Auth TAG in the IN FIFO */
  962. temptag[0] = hcryp->Instance->DOUT;
  963. temptag[1] = hcryp->Instance->DOUT;
  964. temptag[2] = hcryp->Instance->DOUT;
  965. temptag[3] = hcryp->Instance->DOUT;
  966. }
  967. /* Copy temporary authentication TAG in user TAG buffer */
  968. for(loopcounter = 0; loopcounter < hcryp->Init.TagSize ; loopcounter++)
  969. {
  970. /* Set the authentication TAG buffer */
  971. *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
  972. }
  973. /* Change the CRYP peripheral state */
  974. hcryp->State = HAL_CRYP_STATE_READY;
  975. /* Process Unlocked */
  976. __HAL_UNLOCK(hcryp);
  977. /* Return function status */
  978. return HAL_OK;
  979. }
  980. /**
  981. * @brief Initializes the CRYP peripheral in AES CCM decryption mode then
  982. * decrypted pCypherData. The cypher data are available in pPlainData.
  983. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  984. * the configuration information for CRYP module
  985. * @param pPlainData: Pointer to the plaintext buffer
  986. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  987. * @param pCypherData: Pointer to the cyphertext buffer
  988. * @param Timeout: Timeout duration
  989. * @retval HAL status
  990. */
  991. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
  992. {
  993. uint32_t tickstart = 0;
  994. uint32_t headersize = hcryp->Init.HeaderSize;
  995. uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
  996. uint32_t loopcounter = 0;
  997. uint32_t bufferidx = 0;
  998. uint8_t blockb0[16] = {0};/* Block B0 */
  999. uint8_t ctr[16] = {0}; /* Counter */
  1000. uint32_t b0addr = (uint32_t)blockb0;
  1001. /* Process Locked */
  1002. __HAL_LOCK(hcryp);
  1003. /* Change the CRYP peripheral state */
  1004. hcryp->State = HAL_CRYP_STATE_BUSY;
  1005. /* Check if initialization phase has already been performed */
  1006. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  1007. {
  1008. /************************ Formatting the header block *********************/
  1009. if(headersize != 0)
  1010. {
  1011. /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
  1012. if(headersize < 65280)
  1013. {
  1014. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
  1015. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
  1016. headersize += 2;
  1017. }
  1018. else
  1019. {
  1020. /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
  1021. hcryp->Init.pScratch[bufferidx++] = 0xFFU;
  1022. hcryp->Init.pScratch[bufferidx++] = 0xFEU;
  1023. hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
  1024. hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
  1025. hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
  1026. hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
  1027. headersize += 6;
  1028. }
  1029. /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
  1030. for(loopcounter = 0; loopcounter < headersize; loopcounter++)
  1031. {
  1032. hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
  1033. }
  1034. /* Check if the header size is modulo 16 */
  1035. if ((headersize % 16) != 0)
  1036. {
  1037. /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
  1038. for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
  1039. {
  1040. hcryp->Init.pScratch[loopcounter] = 0;
  1041. }
  1042. /* Set the header size to modulo 16 */
  1043. headersize = ((headersize/16) + 1) * 16;
  1044. }
  1045. /* Set the pointer headeraddr to hcryp->Init.pScratch */
  1046. headeraddr = (uint32_t)hcryp->Init.pScratch;
  1047. }
  1048. /*********************** Formatting the block B0 **************************/
  1049. if(headersize != 0)
  1050. {
  1051. blockb0[0] = 0x40;
  1052. }
  1053. /* Flags byte */
  1054. /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
  1055. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
  1056. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
  1057. for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
  1058. {
  1059. blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
  1060. }
  1061. for ( ; loopcounter < 13; loopcounter++)
  1062. {
  1063. blockb0[loopcounter+1] = 0;
  1064. }
  1065. blockb0[14] = (Size >> 8);
  1066. blockb0[15] = (Size & 0xFF);
  1067. /************************* Formatting the initial counter *****************/
  1068. /* Byte 0:
  1069. Bits 7 and 6 are reserved and shall be set to 0
  1070. Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
  1071. blocks are distinct from B0
  1072. Bits 0, 1, and 2 contain the same encoding of q as in B0
  1073. */
  1074. ctr[0] = blockb0[0] & 0x07;
  1075. /* byte 1 to NonceSize is the IV (Nonce) */
  1076. for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
  1077. {
  1078. ctr[loopcounter] = blockb0[loopcounter];
  1079. }
  1080. /* Set the LSB to 1 */
  1081. ctr[15] |= 0x01;
  1082. /* Set the key */
  1083. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  1084. /* Set the CRYP peripheral in AES CCM mode */
  1085. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
  1086. /* Set the Initialization Vector */
  1087. CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
  1088. /* Select init phase */
  1089. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
  1090. b0addr = (uint32_t)blockb0;
  1091. /* Write the blockb0 block in the IN FIFO */
  1092. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1093. b0addr+=4;
  1094. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1095. b0addr+=4;
  1096. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1097. b0addr+=4;
  1098. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1099. /* Enable the CRYP peripheral */
  1100. __HAL_CRYP_ENABLE(hcryp);
  1101. /* Get tick */
  1102. tickstart = HAL_GetTick();
  1103. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  1104. {
  1105. /* Check for the Timeout */
  1106. if(Timeout != HAL_MAX_DELAY)
  1107. {
  1108. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  1109. {
  1110. /* Change state */
  1111. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1112. /* Process Unlocked */
  1113. __HAL_UNLOCK(hcryp);
  1114. return HAL_TIMEOUT;
  1115. }
  1116. }
  1117. }
  1118. /***************************** Header phase *******************************/
  1119. if(headersize != 0)
  1120. {
  1121. /* Select header phase */
  1122. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  1123. /* Enable Crypto processor */
  1124. __HAL_CRYP_ENABLE(hcryp);
  1125. for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
  1126. {
  1127. /* Get tick */
  1128. tickstart = HAL_GetTick();
  1129. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  1130. {
  1131. /* Check for the Timeout */
  1132. if(Timeout != HAL_MAX_DELAY)
  1133. {
  1134. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  1135. {
  1136. /* Change state */
  1137. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1138. /* Process Unlocked */
  1139. __HAL_UNLOCK(hcryp);
  1140. return HAL_TIMEOUT;
  1141. }
  1142. }
  1143. }
  1144. /* Write the header block in the IN FIFO */
  1145. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1146. headeraddr+=4;
  1147. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1148. headeraddr+=4;
  1149. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1150. headeraddr+=4;
  1151. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1152. headeraddr+=4;
  1153. }
  1154. /* Get tick */
  1155. tickstart = HAL_GetTick();
  1156. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  1157. {
  1158. /* Check for the Timeout */
  1159. if(Timeout != HAL_MAX_DELAY)
  1160. {
  1161. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  1162. {
  1163. /* Change state */
  1164. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1165. /* Process Unlocked */
  1166. __HAL_UNLOCK(hcryp);
  1167. return HAL_TIMEOUT;
  1168. }
  1169. }
  1170. }
  1171. }
  1172. /* Save formatted counter into the scratch buffer pScratch */
  1173. for(loopcounter = 0; (loopcounter < 16); loopcounter++)
  1174. {
  1175. hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
  1176. }
  1177. /* Reset bit 0 */
  1178. hcryp->Init.pScratch[15] &= 0xfe;
  1179. /* Select payload phase once the header phase is performed */
  1180. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  1181. /* Flush FIFO */
  1182. __HAL_CRYP_FIFO_FLUSH(hcryp);
  1183. /* Enable the CRYP peripheral */
  1184. __HAL_CRYP_ENABLE(hcryp);
  1185. /* Set the phase */
  1186. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  1187. }
  1188. /* Write Plain Data and Get Cypher Data */
  1189. if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
  1190. {
  1191. return HAL_TIMEOUT;
  1192. }
  1193. /* Change the CRYP peripheral state */
  1194. hcryp->State = HAL_CRYP_STATE_READY;
  1195. /* Process Unlocked */
  1196. __HAL_UNLOCK(hcryp);
  1197. /* Return function status */
  1198. return HAL_OK;
  1199. }
  1200. /**
  1201. * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT.
  1202. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  1203. * the configuration information for CRYP module
  1204. * @param pPlainData: Pointer to the plaintext buffer
  1205. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  1206. * @param pCypherData: Pointer to the cyphertext buffer
  1207. * @retval HAL status
  1208. */
  1209. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
  1210. {
  1211. uint32_t tickstart = 0;
  1212. uint32_t inputaddr;
  1213. uint32_t outputaddr;
  1214. if(hcryp->State == HAL_CRYP_STATE_READY)
  1215. {
  1216. /* Process Locked */
  1217. __HAL_LOCK(hcryp);
  1218. /* Get the buffer addresses and sizes */
  1219. hcryp->CrypInCount = Size;
  1220. hcryp->pCrypInBuffPtr = pPlainData;
  1221. hcryp->pCrypOutBuffPtr = pCypherData;
  1222. hcryp->CrypOutCount = Size;
  1223. /* Change the CRYP peripheral state */
  1224. hcryp->State = HAL_CRYP_STATE_BUSY;
  1225. /* Check if initialization phase has already been performed */
  1226. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  1227. {
  1228. /* Set the key */
  1229. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  1230. /* Set the CRYP peripheral in AES GCM mode */
  1231. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
  1232. /* Set the Initialization Vector */
  1233. CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
  1234. /* Flush FIFO */
  1235. __HAL_CRYP_FIFO_FLUSH(hcryp);
  1236. /* Enable CRYP to start the init phase */
  1237. __HAL_CRYP_ENABLE(hcryp);
  1238. /* Get tick */
  1239. tickstart = HAL_GetTick();
  1240. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  1241. {
  1242. /* Check for the Timeout */
  1243. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1244. {
  1245. /* Change state */
  1246. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1247. /* Process Unlocked */
  1248. __HAL_UNLOCK(hcryp);
  1249. return HAL_TIMEOUT;
  1250. }
  1251. }
  1252. /* Set the header phase */
  1253. if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
  1254. {
  1255. return HAL_TIMEOUT;
  1256. }
  1257. /* Disable the CRYP peripheral */
  1258. __HAL_CRYP_DISABLE(hcryp);
  1259. /* Select payload phase once the header phase is performed */
  1260. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  1261. /* Flush FIFO */
  1262. __HAL_CRYP_FIFO_FLUSH(hcryp);
  1263. /* Set the phase */
  1264. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  1265. }
  1266. if(Size != 0)
  1267. {
  1268. /* Enable Interrupts */
  1269. __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
  1270. /* Enable the CRYP peripheral */
  1271. __HAL_CRYP_ENABLE(hcryp);
  1272. }
  1273. else
  1274. {
  1275. /* Process Locked */
  1276. __HAL_UNLOCK(hcryp);
  1277. /* Change the CRYP state and phase */
  1278. hcryp->State = HAL_CRYP_STATE_READY;
  1279. }
  1280. /* Return function status */
  1281. return HAL_OK;
  1282. }
  1283. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
  1284. {
  1285. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  1286. /* Write the Input block in the IN FIFO */
  1287. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1288. inputaddr+=4;
  1289. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1290. inputaddr+=4;
  1291. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1292. inputaddr+=4;
  1293. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1294. hcryp->pCrypInBuffPtr += 16;
  1295. hcryp->CrypInCount -= 16;
  1296. if(hcryp->CrypInCount == 0)
  1297. {
  1298. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
  1299. /* Call the Input data transfer complete callback */
  1300. HAL_CRYP_InCpltCallback(hcryp);
  1301. }
  1302. }
  1303. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
  1304. {
  1305. outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  1306. /* Read the Output block from the Output FIFO */
  1307. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1308. outputaddr+=4;
  1309. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1310. outputaddr+=4;
  1311. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1312. outputaddr+=4;
  1313. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1314. hcryp->pCrypOutBuffPtr += 16;
  1315. hcryp->CrypOutCount -= 16;
  1316. if(hcryp->CrypOutCount == 0)
  1317. {
  1318. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
  1319. /* Process Unlocked */
  1320. __HAL_UNLOCK(hcryp);
  1321. /* Change the CRYP peripheral state */
  1322. hcryp->State = HAL_CRYP_STATE_READY;
  1323. /* Call Input transfer complete callback */
  1324. HAL_CRYP_OutCpltCallback(hcryp);
  1325. }
  1326. }
  1327. /* Return function status */
  1328. return HAL_OK;
  1329. }
  1330. /**
  1331. * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
  1332. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  1333. * the configuration information for CRYP module
  1334. * @param pPlainData: Pointer to the plaintext buffer
  1335. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  1336. * @param pCypherData: Pointer to the cyphertext buffer
  1337. * @retval HAL status
  1338. */
  1339. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
  1340. {
  1341. uint32_t tickstart = 0;
  1342. uint32_t inputaddr;
  1343. uint32_t outputaddr;
  1344. uint32_t headersize = hcryp->Init.HeaderSize;
  1345. uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
  1346. uint32_t loopcounter = 0;
  1347. uint32_t bufferidx = 0;
  1348. uint8_t blockb0[16] = {0};/* Block B0 */
  1349. uint8_t ctr[16] = {0}; /* Counter */
  1350. uint32_t b0addr = (uint32_t)blockb0;
  1351. if(hcryp->State == HAL_CRYP_STATE_READY)
  1352. {
  1353. /* Process Locked */
  1354. __HAL_LOCK(hcryp);
  1355. hcryp->CrypInCount = Size;
  1356. hcryp->pCrypInBuffPtr = pPlainData;
  1357. hcryp->pCrypOutBuffPtr = pCypherData;
  1358. hcryp->CrypOutCount = Size;
  1359. /* Change the CRYP peripheral state */
  1360. hcryp->State = HAL_CRYP_STATE_BUSY;
  1361. /* Check if initialization phase has already been performed */
  1362. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  1363. {
  1364. /************************ Formatting the header block *******************/
  1365. if(headersize != 0)
  1366. {
  1367. /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
  1368. if(headersize < 65280)
  1369. {
  1370. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
  1371. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
  1372. headersize += 2;
  1373. }
  1374. else
  1375. {
  1376. /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
  1377. hcryp->Init.pScratch[bufferidx++] = 0xFFU;
  1378. hcryp->Init.pScratch[bufferidx++] = 0xFEU;
  1379. hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
  1380. hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
  1381. hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
  1382. hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
  1383. headersize += 6;
  1384. }
  1385. /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
  1386. for(loopcounter = 0; loopcounter < headersize; loopcounter++)
  1387. {
  1388. hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
  1389. }
  1390. /* Check if the header size is modulo 16 */
  1391. if ((headersize % 16) != 0)
  1392. {
  1393. /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
  1394. for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
  1395. {
  1396. hcryp->Init.pScratch[loopcounter] = 0;
  1397. }
  1398. /* Set the header size to modulo 16 */
  1399. headersize = ((headersize/16) + 1) * 16;
  1400. }
  1401. /* Set the pointer headeraddr to hcryp->Init.pScratch */
  1402. headeraddr = (uint32_t)hcryp->Init.pScratch;
  1403. }
  1404. /*********************** Formatting the block B0 ************************/
  1405. if(headersize != 0)
  1406. {
  1407. blockb0[0] = 0x40;
  1408. }
  1409. /* Flags byte */
  1410. /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
  1411. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
  1412. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
  1413. for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
  1414. {
  1415. blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
  1416. }
  1417. for ( ; loopcounter < 13; loopcounter++)
  1418. {
  1419. blockb0[loopcounter+1] = 0;
  1420. }
  1421. blockb0[14] = (Size >> 8);
  1422. blockb0[15] = (Size & 0xFF);
  1423. /************************* Formatting the initial counter ***************/
  1424. /* Byte 0:
  1425. Bits 7 and 6 are reserved and shall be set to 0
  1426. Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
  1427. blocks are distinct from B0
  1428. Bits 0, 1, and 2 contain the same encoding of q as in B0
  1429. */
  1430. ctr[0] = blockb0[0] & 0x07;
  1431. /* byte 1 to NonceSize is the IV (Nonce) */
  1432. for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
  1433. {
  1434. ctr[loopcounter] = blockb0[loopcounter];
  1435. }
  1436. /* Set the LSB to 1 */
  1437. ctr[15] |= 0x01;
  1438. /* Set the key */
  1439. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  1440. /* Set the CRYP peripheral in AES CCM mode */
  1441. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
  1442. /* Set the Initialization Vector */
  1443. CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
  1444. /* Select init phase */
  1445. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
  1446. b0addr = (uint32_t)blockb0;
  1447. /* Write the blockb0 block in the IN FIFO */
  1448. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1449. b0addr+=4;
  1450. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1451. b0addr+=4;
  1452. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1453. b0addr+=4;
  1454. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1455. /* Enable the CRYP peripheral */
  1456. __HAL_CRYP_ENABLE(hcryp);
  1457. /* Get tick */
  1458. tickstart = HAL_GetTick();
  1459. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  1460. {
  1461. /* Check for the Timeout */
  1462. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1463. {
  1464. /* Change state */
  1465. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1466. /* Process Unlocked */
  1467. __HAL_UNLOCK(hcryp);
  1468. return HAL_TIMEOUT;
  1469. }
  1470. }
  1471. /***************************** Header phase *****************************/
  1472. if(headersize != 0)
  1473. {
  1474. /* Select header phase */
  1475. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  1476. /* Enable Crypto processor */
  1477. __HAL_CRYP_ENABLE(hcryp);
  1478. for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
  1479. {
  1480. /* Get tick */
  1481. tickstart = HAL_GetTick();
  1482. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  1483. {
  1484. /* Check for the Timeout */
  1485. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1486. {
  1487. /* Change state */
  1488. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1489. /* Process Unlocked */
  1490. __HAL_UNLOCK(hcryp);
  1491. return HAL_TIMEOUT;
  1492. }
  1493. }
  1494. /* Write the header block in the IN FIFO */
  1495. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1496. headeraddr+=4;
  1497. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1498. headeraddr+=4;
  1499. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1500. headeraddr+=4;
  1501. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1502. headeraddr+=4;
  1503. }
  1504. /* Get tick */
  1505. tickstart = HAL_GetTick();
  1506. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  1507. {
  1508. /* Check for the Timeout */
  1509. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1510. {
  1511. /* Change state */
  1512. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1513. /* Process Unlocked */
  1514. __HAL_UNLOCK(hcryp);
  1515. return HAL_TIMEOUT;
  1516. }
  1517. }
  1518. }
  1519. /* Save formatted counter into the scratch buffer pScratch */
  1520. for(loopcounter = 0; (loopcounter < 16); loopcounter++)
  1521. {
  1522. hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
  1523. }
  1524. /* Reset bit 0 */
  1525. hcryp->Init.pScratch[15] &= 0xfe;
  1526. /* Select payload phase once the header phase is performed */
  1527. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  1528. /* Flush FIFO */
  1529. __HAL_CRYP_FIFO_FLUSH(hcryp);
  1530. /* Set the phase */
  1531. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  1532. }
  1533. if(Size != 0)
  1534. {
  1535. /* Enable Interrupts */
  1536. __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
  1537. /* Enable the CRYP peripheral */
  1538. __HAL_CRYP_ENABLE(hcryp);
  1539. }
  1540. else
  1541. {
  1542. /* Change the CRYP state and phase */
  1543. hcryp->State = HAL_CRYP_STATE_READY;
  1544. }
  1545. /* Return function status */
  1546. return HAL_OK;
  1547. }
  1548. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
  1549. {
  1550. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  1551. /* Write the Input block in the IN FIFO */
  1552. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1553. inputaddr+=4;
  1554. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1555. inputaddr+=4;
  1556. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1557. inputaddr+=4;
  1558. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1559. hcryp->pCrypInBuffPtr += 16;
  1560. hcryp->CrypInCount -= 16;
  1561. if(hcryp->CrypInCount == 0)
  1562. {
  1563. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
  1564. /* Call Input transfer complete callback */
  1565. HAL_CRYP_InCpltCallback(hcryp);
  1566. }
  1567. }
  1568. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
  1569. {
  1570. outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  1571. /* Read the Output block from the Output FIFO */
  1572. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1573. outputaddr+=4;
  1574. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1575. outputaddr+=4;
  1576. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1577. outputaddr+=4;
  1578. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1579. hcryp->pCrypOutBuffPtr += 16;
  1580. hcryp->CrypOutCount -= 16;
  1581. if(hcryp->CrypOutCount == 0)
  1582. {
  1583. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
  1584. /* Process Unlocked */
  1585. __HAL_UNLOCK(hcryp);
  1586. /* Change the CRYP peripheral state */
  1587. hcryp->State = HAL_CRYP_STATE_READY;
  1588. /* Call Input transfer complete callback */
  1589. HAL_CRYP_OutCpltCallback(hcryp);
  1590. }
  1591. }
  1592. /* Return function status */
  1593. return HAL_OK;
  1594. }
  1595. /**
  1596. * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT.
  1597. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  1598. * the configuration information for CRYP module
  1599. * @param pCypherData: Pointer to the cyphertext buffer
  1600. * @param Size: Length of the cyphertext buffer, must be a multiple of 16
  1601. * @param pPlainData: Pointer to the plaintext buffer
  1602. * @retval HAL status
  1603. */
  1604. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
  1605. {
  1606. uint32_t tickstart = 0;
  1607. uint32_t inputaddr;
  1608. uint32_t outputaddr;
  1609. if(hcryp->State == HAL_CRYP_STATE_READY)
  1610. {
  1611. /* Process Locked */
  1612. __HAL_LOCK(hcryp);
  1613. /* Get the buffer addresses and sizes */
  1614. hcryp->CrypInCount = Size;
  1615. hcryp->pCrypInBuffPtr = pCypherData;
  1616. hcryp->pCrypOutBuffPtr = pPlainData;
  1617. hcryp->CrypOutCount = Size;
  1618. /* Change the CRYP peripheral state */
  1619. hcryp->State = HAL_CRYP_STATE_BUSY;
  1620. /* Check if initialization phase has already been performed */
  1621. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  1622. {
  1623. /* Set the key */
  1624. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  1625. /* Set the CRYP peripheral in AES GCM decryption mode */
  1626. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
  1627. /* Set the Initialization Vector */
  1628. CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
  1629. /* Flush FIFO */
  1630. __HAL_CRYP_FIFO_FLUSH(hcryp);
  1631. /* Enable CRYP to start the init phase */
  1632. __HAL_CRYP_ENABLE(hcryp);
  1633. /* Get tick */
  1634. tickstart = HAL_GetTick();
  1635. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  1636. {
  1637. /* Check for the Timeout */
  1638. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1639. {
  1640. /* Change state */
  1641. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1642. /* Process Unlocked */
  1643. __HAL_UNLOCK(hcryp);
  1644. return HAL_TIMEOUT;
  1645. }
  1646. }
  1647. /* Set the header phase */
  1648. if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
  1649. {
  1650. return HAL_TIMEOUT;
  1651. }
  1652. /* Disable the CRYP peripheral */
  1653. __HAL_CRYP_DISABLE(hcryp);
  1654. /* Select payload phase once the header phase is performed */
  1655. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  1656. /* Set the phase */
  1657. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  1658. }
  1659. if(Size != 0)
  1660. {
  1661. /* Enable Interrupts */
  1662. __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
  1663. /* Enable the CRYP peripheral */
  1664. __HAL_CRYP_ENABLE(hcryp);
  1665. }
  1666. else
  1667. {
  1668. /* Process Locked */
  1669. __HAL_UNLOCK(hcryp);
  1670. /* Change the CRYP state and phase */
  1671. hcryp->State = HAL_CRYP_STATE_READY;
  1672. }
  1673. /* Return function status */
  1674. return HAL_OK;
  1675. }
  1676. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
  1677. {
  1678. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  1679. /* Write the Input block in the IN FIFO */
  1680. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1681. inputaddr+=4;
  1682. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1683. inputaddr+=4;
  1684. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1685. inputaddr+=4;
  1686. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1687. hcryp->pCrypInBuffPtr += 16;
  1688. hcryp->CrypInCount -= 16;
  1689. if(hcryp->CrypInCount == 0)
  1690. {
  1691. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
  1692. /* Call the Input data transfer complete callback */
  1693. HAL_CRYP_InCpltCallback(hcryp);
  1694. }
  1695. }
  1696. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
  1697. {
  1698. outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  1699. /* Read the Output block from the Output FIFO */
  1700. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1701. outputaddr+=4;
  1702. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1703. outputaddr+=4;
  1704. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1705. outputaddr+=4;
  1706. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1707. hcryp->pCrypOutBuffPtr += 16;
  1708. hcryp->CrypOutCount -= 16;
  1709. if(hcryp->CrypOutCount == 0)
  1710. {
  1711. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
  1712. /* Process Unlocked */
  1713. __HAL_UNLOCK(hcryp);
  1714. /* Change the CRYP peripheral state */
  1715. hcryp->State = HAL_CRYP_STATE_READY;
  1716. /* Call Input transfer complete callback */
  1717. HAL_CRYP_OutCpltCallback(hcryp);
  1718. }
  1719. }
  1720. /* Return function status */
  1721. return HAL_OK;
  1722. }
  1723. /**
  1724. * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
  1725. * then decrypted pCypherData. The cypher data are available in pPlainData.
  1726. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  1727. * the configuration information for CRYP module
  1728. * @param pCypherData: Pointer to the cyphertext buffer
  1729. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  1730. * @param pPlainData: Pointer to the plaintext buffer
  1731. * @retval HAL status
  1732. */
  1733. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
  1734. {
  1735. uint32_t inputaddr;
  1736. uint32_t outputaddr;
  1737. uint32_t tickstart = 0;
  1738. uint32_t headersize = hcryp->Init.HeaderSize;
  1739. uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
  1740. uint32_t loopcounter = 0;
  1741. uint32_t bufferidx = 0;
  1742. uint8_t blockb0[16] = {0};/* Block B0 */
  1743. uint8_t ctr[16] = {0}; /* Counter */
  1744. uint32_t b0addr = (uint32_t)blockb0;
  1745. if(hcryp->State == HAL_CRYP_STATE_READY)
  1746. {
  1747. /* Process Locked */
  1748. __HAL_LOCK(hcryp);
  1749. hcryp->CrypInCount = Size;
  1750. hcryp->pCrypInBuffPtr = pCypherData;
  1751. hcryp->pCrypOutBuffPtr = pPlainData;
  1752. hcryp->CrypOutCount = Size;
  1753. /* Change the CRYP peripheral state */
  1754. hcryp->State = HAL_CRYP_STATE_BUSY;
  1755. /* Check if initialization phase has already been performed */
  1756. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  1757. {
  1758. /************************ Formatting the header block *******************/
  1759. if(headersize != 0)
  1760. {
  1761. /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
  1762. if(headersize < 65280)
  1763. {
  1764. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
  1765. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
  1766. headersize += 2;
  1767. }
  1768. else
  1769. {
  1770. /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
  1771. hcryp->Init.pScratch[bufferidx++] = 0xFFU;
  1772. hcryp->Init.pScratch[bufferidx++] = 0xFEU;
  1773. hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
  1774. hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
  1775. hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
  1776. hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
  1777. headersize += 6;
  1778. }
  1779. /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
  1780. for(loopcounter = 0; loopcounter < headersize; loopcounter++)
  1781. {
  1782. hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
  1783. }
  1784. /* Check if the header size is modulo 16 */
  1785. if ((headersize % 16) != 0)
  1786. {
  1787. /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
  1788. for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
  1789. {
  1790. hcryp->Init.pScratch[loopcounter] = 0;
  1791. }
  1792. /* Set the header size to modulo 16 */
  1793. headersize = ((headersize/16) + 1) * 16;
  1794. }
  1795. /* Set the pointer headeraddr to hcryp->Init.pScratch */
  1796. headeraddr = (uint32_t)hcryp->Init.pScratch;
  1797. }
  1798. /*********************** Formatting the block B0 ************************/
  1799. if(headersize != 0)
  1800. {
  1801. blockb0[0] = 0x40;
  1802. }
  1803. /* Flags byte */
  1804. /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
  1805. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
  1806. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
  1807. for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
  1808. {
  1809. blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
  1810. }
  1811. for ( ; loopcounter < 13; loopcounter++)
  1812. {
  1813. blockb0[loopcounter+1] = 0;
  1814. }
  1815. blockb0[14] = (Size >> 8);
  1816. blockb0[15] = (Size & 0xFF);
  1817. /************************* Formatting the initial counter ***************/
  1818. /* Byte 0:
  1819. Bits 7 and 6 are reserved and shall be set to 0
  1820. Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
  1821. blocks are distinct from B0
  1822. Bits 0, 1, and 2 contain the same encoding of q as in B0
  1823. */
  1824. ctr[0] = blockb0[0] & 0x07;
  1825. /* byte 1 to NonceSize is the IV (Nonce) */
  1826. for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
  1827. {
  1828. ctr[loopcounter] = blockb0[loopcounter];
  1829. }
  1830. /* Set the LSB to 1 */
  1831. ctr[15] |= 0x01;
  1832. /* Set the key */
  1833. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  1834. /* Set the CRYP peripheral in AES CCM mode */
  1835. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
  1836. /* Set the Initialization Vector */
  1837. CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
  1838. /* Select init phase */
  1839. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
  1840. b0addr = (uint32_t)blockb0;
  1841. /* Write the blockb0 block in the IN FIFO */
  1842. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1843. b0addr+=4;
  1844. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1845. b0addr+=4;
  1846. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1847. b0addr+=4;
  1848. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  1849. /* Enable the CRYP peripheral */
  1850. __HAL_CRYP_ENABLE(hcryp);
  1851. /* Get tick */
  1852. tickstart = HAL_GetTick();
  1853. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  1854. {
  1855. /* Check for the Timeout */
  1856. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1857. {
  1858. /* Change state */
  1859. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1860. /* Process Unlocked */
  1861. __HAL_UNLOCK(hcryp);
  1862. return HAL_TIMEOUT;
  1863. }
  1864. }
  1865. /***************************** Header phase *****************************/
  1866. if(headersize != 0)
  1867. {
  1868. /* Select header phase */
  1869. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  1870. /* Enable Crypto processor */
  1871. __HAL_CRYP_ENABLE(hcryp);
  1872. for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
  1873. {
  1874. /* Get tick */
  1875. tickstart = HAL_GetTick();
  1876. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  1877. {
  1878. /* Check for the Timeout */
  1879. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1880. {
  1881. /* Change state */
  1882. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1883. /* Process Unlocked */
  1884. __HAL_UNLOCK(hcryp);
  1885. return HAL_TIMEOUT;
  1886. }
  1887. }
  1888. /* Write the header block in the IN FIFO */
  1889. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1890. headeraddr+=4;
  1891. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1892. headeraddr+=4;
  1893. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1894. headeraddr+=4;
  1895. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  1896. headeraddr+=4;
  1897. }
  1898. /* Get tick */
  1899. tickstart = HAL_GetTick();
  1900. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  1901. {
  1902. /* Check for the Timeout */
  1903. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  1904. {
  1905. /* Change state */
  1906. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  1907. /* Process Unlocked */
  1908. __HAL_UNLOCK(hcryp);
  1909. return HAL_TIMEOUT;
  1910. }
  1911. }
  1912. }
  1913. /* Save formatted counter into the scratch buffer pScratch */
  1914. for(loopcounter = 0; (loopcounter < 16); loopcounter++)
  1915. {
  1916. hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
  1917. }
  1918. /* Reset bit 0 */
  1919. hcryp->Init.pScratch[15] &= 0xfe;
  1920. /* Select payload phase once the header phase is performed */
  1921. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  1922. /* Flush FIFO */
  1923. __HAL_CRYP_FIFO_FLUSH(hcryp);
  1924. /* Set the phase */
  1925. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  1926. }
  1927. /* Enable Interrupts */
  1928. __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
  1929. /* Enable the CRYP peripheral */
  1930. __HAL_CRYP_ENABLE(hcryp);
  1931. /* Return function status */
  1932. return HAL_OK;
  1933. }
  1934. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
  1935. {
  1936. inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
  1937. /* Write the Input block in the IN FIFO */
  1938. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1939. inputaddr+=4;
  1940. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1941. inputaddr+=4;
  1942. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1943. inputaddr+=4;
  1944. hcryp->Instance->DR = *(uint32_t*)(inputaddr);
  1945. hcryp->pCrypInBuffPtr += 16;
  1946. hcryp->CrypInCount -= 16;
  1947. if(hcryp->CrypInCount == 0)
  1948. {
  1949. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
  1950. /* Call the Input data transfer complete callback */
  1951. HAL_CRYP_InCpltCallback(hcryp);
  1952. }
  1953. }
  1954. else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
  1955. {
  1956. outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
  1957. /* Read the Output block from the Output FIFO */
  1958. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1959. outputaddr+=4;
  1960. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1961. outputaddr+=4;
  1962. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1963. outputaddr+=4;
  1964. *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
  1965. hcryp->pCrypOutBuffPtr += 16;
  1966. hcryp->CrypOutCount -= 16;
  1967. if(hcryp->CrypOutCount == 0)
  1968. {
  1969. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
  1970. /* Process Unlocked */
  1971. __HAL_UNLOCK(hcryp);
  1972. /* Change the CRYP peripheral state */
  1973. hcryp->State = HAL_CRYP_STATE_READY;
  1974. /* Call Input transfer complete callback */
  1975. HAL_CRYP_OutCpltCallback(hcryp);
  1976. }
  1977. }
  1978. /* Return function status */
  1979. return HAL_OK;
  1980. }
  1981. /**
  1982. * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
  1983. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  1984. * the configuration information for CRYP module
  1985. * @param pPlainData: Pointer to the plaintext buffer
  1986. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  1987. * @param pCypherData: Pointer to the cyphertext buffer
  1988. * @retval HAL status
  1989. */
  1990. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
  1991. {
  1992. uint32_t tickstart = 0;
  1993. uint32_t inputaddr;
  1994. uint32_t outputaddr;
  1995. if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
  1996. {
  1997. /* Process Locked */
  1998. __HAL_LOCK(hcryp);
  1999. inputaddr = (uint32_t)pPlainData;
  2000. outputaddr = (uint32_t)pCypherData;
  2001. /* Change the CRYP peripheral state */
  2002. hcryp->State = HAL_CRYP_STATE_BUSY;
  2003. /* Check if initialization phase has already been performed */
  2004. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  2005. {
  2006. /* Set the key */
  2007. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  2008. /* Set the CRYP peripheral in AES GCM mode */
  2009. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
  2010. /* Set the Initialization Vector */
  2011. CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
  2012. /* Flush FIFO */
  2013. __HAL_CRYP_FIFO_FLUSH(hcryp);
  2014. /* Enable CRYP to start the init phase */
  2015. __HAL_CRYP_ENABLE(hcryp);
  2016. /* Get tick */
  2017. tickstart = HAL_GetTick();
  2018. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  2019. {
  2020. /* Check for the Timeout */
  2021. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2022. {
  2023. /* Change state */
  2024. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2025. /* Process Unlocked */
  2026. __HAL_UNLOCK(hcryp);
  2027. return HAL_TIMEOUT;
  2028. }
  2029. }
  2030. /* Flush FIFO */
  2031. __HAL_CRYP_FIFO_FLUSH(hcryp);
  2032. /* Set the header phase */
  2033. if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
  2034. {
  2035. return HAL_TIMEOUT;
  2036. }
  2037. /* Disable the CRYP peripheral */
  2038. __HAL_CRYP_DISABLE(hcryp);
  2039. /* Select payload phase once the header phase is performed */
  2040. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  2041. /* Flush FIFO */
  2042. __HAL_CRYP_FIFO_FLUSH(hcryp);
  2043. /* Set the phase */
  2044. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  2045. }
  2046. /* Set the input and output addresses and start DMA transfer */
  2047. CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
  2048. /* Unlock process */
  2049. __HAL_UNLOCK(hcryp);
  2050. /* Return function status */
  2051. return HAL_OK;
  2052. }
  2053. else
  2054. {
  2055. return HAL_ERROR;
  2056. }
  2057. }
  2058. /**
  2059. * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
  2060. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  2061. * the configuration information for CRYP module
  2062. * @param pPlainData: Pointer to the plaintext buffer
  2063. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  2064. * @param pCypherData: Pointer to the cyphertext buffer
  2065. * @retval HAL status
  2066. */
  2067. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
  2068. {
  2069. uint32_t tickstart = 0;
  2070. uint32_t inputaddr;
  2071. uint32_t outputaddr;
  2072. uint32_t headersize;
  2073. uint32_t headeraddr;
  2074. uint32_t loopcounter = 0;
  2075. uint32_t bufferidx = 0;
  2076. uint8_t blockb0[16] = {0};/* Block B0 */
  2077. uint8_t ctr[16] = {0}; /* Counter */
  2078. uint32_t b0addr = (uint32_t)blockb0;
  2079. if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
  2080. {
  2081. /* Process Locked */
  2082. __HAL_LOCK(hcryp);
  2083. inputaddr = (uint32_t)pPlainData;
  2084. outputaddr = (uint32_t)pCypherData;
  2085. headersize = hcryp->Init.HeaderSize;
  2086. headeraddr = (uint32_t)hcryp->Init.Header;
  2087. hcryp->CrypInCount = Size;
  2088. hcryp->pCrypInBuffPtr = pPlainData;
  2089. hcryp->pCrypOutBuffPtr = pCypherData;
  2090. hcryp->CrypOutCount = Size;
  2091. /* Change the CRYP peripheral state */
  2092. hcryp->State = HAL_CRYP_STATE_BUSY;
  2093. /* Check if initialization phase has already been performed */
  2094. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  2095. {
  2096. /************************ Formatting the header block *******************/
  2097. if(headersize != 0)
  2098. {
  2099. /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
  2100. if(headersize < 65280)
  2101. {
  2102. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
  2103. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
  2104. headersize += 2;
  2105. }
  2106. else
  2107. {
  2108. /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
  2109. hcryp->Init.pScratch[bufferidx++] = 0xFFU;
  2110. hcryp->Init.pScratch[bufferidx++] = 0xFEU;
  2111. hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
  2112. hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
  2113. hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
  2114. hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
  2115. headersize += 6;
  2116. }
  2117. /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
  2118. for(loopcounter = 0; loopcounter < headersize; loopcounter++)
  2119. {
  2120. hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
  2121. }
  2122. /* Check if the header size is modulo 16 */
  2123. if ((headersize % 16) != 0)
  2124. {
  2125. /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
  2126. for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
  2127. {
  2128. hcryp->Init.pScratch[loopcounter] = 0;
  2129. }
  2130. /* Set the header size to modulo 16 */
  2131. headersize = ((headersize/16) + 1) * 16;
  2132. }
  2133. /* Set the pointer headeraddr to hcryp->Init.pScratch */
  2134. headeraddr = (uint32_t)hcryp->Init.pScratch;
  2135. }
  2136. /*********************** Formatting the block B0 ************************/
  2137. if(headersize != 0)
  2138. {
  2139. blockb0[0] = 0x40;
  2140. }
  2141. /* Flags byte */
  2142. /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
  2143. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
  2144. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
  2145. for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
  2146. {
  2147. blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
  2148. }
  2149. for ( ; loopcounter < 13; loopcounter++)
  2150. {
  2151. blockb0[loopcounter+1] = 0;
  2152. }
  2153. blockb0[14] = (Size >> 8);
  2154. blockb0[15] = (Size & 0xFF);
  2155. /************************* Formatting the initial counter ***************/
  2156. /* Byte 0:
  2157. Bits 7 and 6 are reserved and shall be set to 0
  2158. Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
  2159. blocks are distinct from B0
  2160. Bits 0, 1, and 2 contain the same encoding of q as in B0
  2161. */
  2162. ctr[0] = blockb0[0] & 0x07;
  2163. /* byte 1 to NonceSize is the IV (Nonce) */
  2164. for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
  2165. {
  2166. ctr[loopcounter] = blockb0[loopcounter];
  2167. }
  2168. /* Set the LSB to 1 */
  2169. ctr[15] |= 0x01;
  2170. /* Set the key */
  2171. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  2172. /* Set the CRYP peripheral in AES CCM mode */
  2173. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
  2174. /* Set the Initialization Vector */
  2175. CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
  2176. /* Select init phase */
  2177. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
  2178. b0addr = (uint32_t)blockb0;
  2179. /* Write the blockb0 block in the IN FIFO */
  2180. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2181. b0addr+=4;
  2182. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2183. b0addr+=4;
  2184. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2185. b0addr+=4;
  2186. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2187. /* Enable the CRYP peripheral */
  2188. __HAL_CRYP_ENABLE(hcryp);
  2189. /* Get tick */
  2190. tickstart = HAL_GetTick();
  2191. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  2192. {
  2193. /* Check for the Timeout */
  2194. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2195. {
  2196. /* Change state */
  2197. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2198. /* Process Unlocked */
  2199. __HAL_UNLOCK(hcryp);
  2200. return HAL_TIMEOUT;
  2201. }
  2202. }
  2203. /***************************** Header phase *****************************/
  2204. if(headersize != 0)
  2205. {
  2206. /* Select header phase */
  2207. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  2208. /* Enable Crypto processor */
  2209. __HAL_CRYP_ENABLE(hcryp);
  2210. for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
  2211. {
  2212. /* Get tick */
  2213. tickstart = HAL_GetTick();
  2214. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  2215. {
  2216. /* Check for the Timeout */
  2217. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2218. {
  2219. /* Change state */
  2220. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2221. /* Process Unlocked */
  2222. __HAL_UNLOCK(hcryp);
  2223. return HAL_TIMEOUT;
  2224. }
  2225. }
  2226. /* Write the header block in the IN FIFO */
  2227. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2228. headeraddr+=4;
  2229. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2230. headeraddr+=4;
  2231. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2232. headeraddr+=4;
  2233. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2234. headeraddr+=4;
  2235. }
  2236. /* Get tick */
  2237. tickstart = HAL_GetTick();
  2238. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  2239. {
  2240. /* Check for the Timeout */
  2241. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2242. {
  2243. /* Change state */
  2244. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2245. /* Process Unlocked */
  2246. __HAL_UNLOCK(hcryp);
  2247. return HAL_TIMEOUT;
  2248. }
  2249. }
  2250. }
  2251. /* Save formatted counter into the scratch buffer pScratch */
  2252. for(loopcounter = 0; (loopcounter < 16); loopcounter++)
  2253. {
  2254. hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
  2255. }
  2256. /* Reset bit 0 */
  2257. hcryp->Init.pScratch[15] &= 0xfe;
  2258. /* Select payload phase once the header phase is performed */
  2259. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  2260. /* Flush FIFO */
  2261. __HAL_CRYP_FIFO_FLUSH(hcryp);
  2262. /* Set the phase */
  2263. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  2264. }
  2265. /* Set the input and output addresses and start DMA transfer */
  2266. CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
  2267. /* Unlock process */
  2268. __HAL_UNLOCK(hcryp);
  2269. /* Return function status */
  2270. return HAL_OK;
  2271. }
  2272. else
  2273. {
  2274. return HAL_ERROR;
  2275. }
  2276. }
  2277. /**
  2278. * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
  2279. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  2280. * the configuration information for CRYP module
  2281. * @param pCypherData: Pointer to the cyphertext buffer.
  2282. * @param Size: Length of the cyphertext buffer, must be a multiple of 16
  2283. * @param pPlainData: Pointer to the plaintext buffer
  2284. * @retval HAL status
  2285. */
  2286. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
  2287. {
  2288. uint32_t tickstart = 0;
  2289. uint32_t inputaddr;
  2290. uint32_t outputaddr;
  2291. if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
  2292. {
  2293. /* Process Locked */
  2294. __HAL_LOCK(hcryp);
  2295. inputaddr = (uint32_t)pCypherData;
  2296. outputaddr = (uint32_t)pPlainData;
  2297. /* Change the CRYP peripheral state */
  2298. hcryp->State = HAL_CRYP_STATE_BUSY;
  2299. /* Check if initialization phase has already been performed */
  2300. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  2301. {
  2302. /* Set the key */
  2303. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  2304. /* Set the CRYP peripheral in AES GCM decryption mode */
  2305. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
  2306. /* Set the Initialization Vector */
  2307. CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
  2308. /* Enable CRYP to start the init phase */
  2309. __HAL_CRYP_ENABLE(hcryp);
  2310. /* Get tick */
  2311. tickstart = HAL_GetTick();
  2312. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  2313. {
  2314. /* Check for the Timeout */
  2315. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2316. {
  2317. /* Change state */
  2318. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2319. /* Process Unlocked */
  2320. __HAL_UNLOCK(hcryp);
  2321. return HAL_TIMEOUT;
  2322. }
  2323. }
  2324. /* Set the header phase */
  2325. if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK)
  2326. {
  2327. return HAL_TIMEOUT;
  2328. }
  2329. /* Disable the CRYP peripheral */
  2330. __HAL_CRYP_DISABLE(hcryp);
  2331. /* Select payload phase once the header phase is performed */
  2332. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  2333. /* Set the phase */
  2334. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  2335. }
  2336. /* Set the input and output addresses and start DMA transfer */
  2337. CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
  2338. /* Unlock process */
  2339. __HAL_UNLOCK(hcryp);
  2340. /* Return function status */
  2341. return HAL_OK;
  2342. }
  2343. else
  2344. {
  2345. return HAL_ERROR;
  2346. }
  2347. }
  2348. /**
  2349. * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA
  2350. * then decrypted pCypherData. The cypher data are available in pPlainData.
  2351. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  2352. * the configuration information for CRYP module
  2353. * @param pCypherData: Pointer to the cyphertext buffer
  2354. * @param Size: Length of the plaintext buffer, must be a multiple of 16
  2355. * @param pPlainData: Pointer to the plaintext buffer
  2356. * @retval HAL status
  2357. */
  2358. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
  2359. {
  2360. uint32_t tickstart = 0;
  2361. uint32_t inputaddr;
  2362. uint32_t outputaddr;
  2363. uint32_t headersize;
  2364. uint32_t headeraddr;
  2365. uint32_t loopcounter = 0;
  2366. uint32_t bufferidx = 0;
  2367. uint8_t blockb0[16] = {0};/* Block B0 */
  2368. uint8_t ctr[16] = {0}; /* Counter */
  2369. uint32_t b0addr = (uint32_t)blockb0;
  2370. if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
  2371. {
  2372. /* Process Locked */
  2373. __HAL_LOCK(hcryp);
  2374. inputaddr = (uint32_t)pCypherData;
  2375. outputaddr = (uint32_t)pPlainData;
  2376. headersize = hcryp->Init.HeaderSize;
  2377. headeraddr = (uint32_t)hcryp->Init.Header;
  2378. hcryp->CrypInCount = Size;
  2379. hcryp->pCrypInBuffPtr = pCypherData;
  2380. hcryp->pCrypOutBuffPtr = pPlainData;
  2381. hcryp->CrypOutCount = Size;
  2382. /* Change the CRYP peripheral state */
  2383. hcryp->State = HAL_CRYP_STATE_BUSY;
  2384. /* Check if initialization phase has already been performed */
  2385. if(hcryp->Phase == HAL_CRYP_PHASE_READY)
  2386. {
  2387. /************************ Formatting the header block *******************/
  2388. if(headersize != 0)
  2389. {
  2390. /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
  2391. if(headersize < 65280)
  2392. {
  2393. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFFU);
  2394. hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFFU);
  2395. headersize += 2;
  2396. }
  2397. else
  2398. {
  2399. /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
  2400. hcryp->Init.pScratch[bufferidx++] = 0xFFU;
  2401. hcryp->Init.pScratch[bufferidx++] = 0xFEU;
  2402. hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
  2403. hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
  2404. hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
  2405. hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
  2406. headersize += 6;
  2407. }
  2408. /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
  2409. for(loopcounter = 0; loopcounter < headersize; loopcounter++)
  2410. {
  2411. hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
  2412. }
  2413. /* Check if the header size is modulo 16 */
  2414. if ((headersize % 16) != 0)
  2415. {
  2416. /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
  2417. for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++)
  2418. {
  2419. hcryp->Init.pScratch[loopcounter] = 0;
  2420. }
  2421. /* Set the header size to modulo 16 */
  2422. headersize = ((headersize/16) + 1) * 16;
  2423. }
  2424. /* Set the pointer headeraddr to hcryp->Init.pScratch */
  2425. headeraddr = (uint32_t)hcryp->Init.pScratch;
  2426. }
  2427. /*********************** Formatting the block B0 ************************/
  2428. if(headersize != 0)
  2429. {
  2430. blockb0[0] = 0x40;
  2431. }
  2432. /* Flags byte */
  2433. /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */
  2434. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3);
  2435. blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
  2436. for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++)
  2437. {
  2438. blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter];
  2439. }
  2440. for ( ; loopcounter < 13; loopcounter++)
  2441. {
  2442. blockb0[loopcounter+1] = 0;
  2443. }
  2444. blockb0[14] = (Size >> 8);
  2445. blockb0[15] = (Size & 0xFF);
  2446. /************************* Formatting the initial counter ***************/
  2447. /* Byte 0:
  2448. Bits 7 and 6 are reserved and shall be set to 0
  2449. Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
  2450. blocks are distinct from B0
  2451. Bits 0, 1, and 2 contain the same encoding of q as in B0
  2452. */
  2453. ctr[0] = blockb0[0] & 0x07;
  2454. /* byte 1 to NonceSize is the IV (Nonce) */
  2455. for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++)
  2456. {
  2457. ctr[loopcounter] = blockb0[loopcounter];
  2458. }
  2459. /* Set the LSB to 1 */
  2460. ctr[15] |= 0x01;
  2461. /* Set the key */
  2462. CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
  2463. /* Set the CRYP peripheral in AES CCM mode */
  2464. __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
  2465. /* Set the Initialization Vector */
  2466. CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
  2467. /* Select init phase */
  2468. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
  2469. b0addr = (uint32_t)blockb0;
  2470. /* Write the blockb0 block in the IN FIFO */
  2471. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2472. b0addr+=4;
  2473. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2474. b0addr+=4;
  2475. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2476. b0addr+=4;
  2477. hcryp->Instance->DR = *(uint32_t*)(b0addr);
  2478. /* Enable the CRYP peripheral */
  2479. __HAL_CRYP_ENABLE(hcryp);
  2480. /* Get tick */
  2481. tickstart = HAL_GetTick();
  2482. while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
  2483. {
  2484. /* Check for the Timeout */
  2485. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2486. {
  2487. /* Change state */
  2488. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2489. /* Process Unlocked */
  2490. __HAL_UNLOCK(hcryp);
  2491. return HAL_TIMEOUT;
  2492. }
  2493. }
  2494. /***************************** Header phase *****************************/
  2495. if(headersize != 0)
  2496. {
  2497. /* Select header phase */
  2498. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
  2499. /* Enable Crypto processor */
  2500. __HAL_CRYP_ENABLE(hcryp);
  2501. for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16)
  2502. {
  2503. /* Get tick */
  2504. tickstart = HAL_GetTick();
  2505. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
  2506. {
  2507. /* Check for the Timeout */
  2508. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2509. {
  2510. /* Change state */
  2511. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2512. /* Process Unlocked */
  2513. __HAL_UNLOCK(hcryp);
  2514. return HAL_TIMEOUT;
  2515. }
  2516. }
  2517. /* Write the header block in the IN FIFO */
  2518. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2519. headeraddr+=4;
  2520. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2521. headeraddr+=4;
  2522. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2523. headeraddr+=4;
  2524. hcryp->Instance->DR = *(uint32_t*)(headeraddr);
  2525. headeraddr+=4;
  2526. }
  2527. /* Get tick */
  2528. tickstart = HAL_GetTick();
  2529. while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
  2530. {
  2531. /* Check for the Timeout */
  2532. if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
  2533. {
  2534. /* Change state */
  2535. hcryp->State = HAL_CRYP_STATE_TIMEOUT;
  2536. /* Process Unlocked */
  2537. __HAL_UNLOCK(hcryp);
  2538. return HAL_TIMEOUT;
  2539. }
  2540. }
  2541. }
  2542. /* Save formatted counter into the scratch buffer pScratch */
  2543. for(loopcounter = 0; (loopcounter < 16); loopcounter++)
  2544. {
  2545. hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
  2546. }
  2547. /* Reset bit 0 */
  2548. hcryp->Init.pScratch[15] &= 0xfe;
  2549. /* Select payload phase once the header phase is performed */
  2550. __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
  2551. /* Flush FIFO */
  2552. __HAL_CRYP_FIFO_FLUSH(hcryp);
  2553. /* Set the phase */
  2554. hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
  2555. }
  2556. /* Set the input and output addresses and start DMA transfer */
  2557. CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
  2558. /* Unlock process */
  2559. __HAL_UNLOCK(hcryp);
  2560. /* Return function status */
  2561. return HAL_OK;
  2562. }
  2563. else
  2564. {
  2565. return HAL_ERROR;
  2566. }
  2567. }
  2568. /**
  2569. * @}
  2570. */
  2571. /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management
  2572. * @brief CRYPEx IRQ handler.
  2573. *
  2574. @verbatim
  2575. ==============================================================================
  2576. ##### CRYPEx IRQ handler management #####
  2577. ==============================================================================
  2578. [..] This section provides CRYPEx IRQ handler function.
  2579. @endverbatim
  2580. * @{
  2581. */
  2582. /**
  2583. * @brief This function handles CRYPEx interrupt request.
  2584. * @param hcryp: pointer to a CRYPEx_HandleTypeDef structure that contains
  2585. * the configuration information for CRYP module
  2586. * @retval None
  2587. */
  2588. void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
  2589. {
  2590. switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
  2591. {
  2592. case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
  2593. HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0, NULL);
  2594. break;
  2595. case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
  2596. HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0, NULL);
  2597. break;
  2598. case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
  2599. HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0, NULL);
  2600. break;
  2601. case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
  2602. HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0, NULL);
  2603. break;
  2604. default:
  2605. break;
  2606. }
  2607. }
  2608. /**
  2609. * @}
  2610. */
  2611. /**
  2612. * @}
  2613. */
  2614. #endif /* CRYP */
  2615. #endif /* HAL_CRYP_MODULE_ENABLED */
  2616. /**
  2617. * @}
  2618. */
  2619. /**
  2620. * @}
  2621. */
  2622. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/