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.
 
 
 

447 lines
14 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_cryp_ex.c
  4. * @author MCD Application Team
  5. * @brief Extended CRYP HAL module driver
  6. * This file provides firmware functions to manage the following
  7. * functionalities of CRYP extension peripheral:
  8. * + Extended AES processing functions
  9. *
  10. @verbatim
  11. ==============================================================================
  12. ##### How to use this driver #####
  13. ==============================================================================
  14. [..]
  15. The CRYP extension HAL driver can be used after AES-GCM or AES-CCM
  16. Encryption/Decryption to get the authentication messages.
  17. @endverbatim
  18. ******************************************************************************
  19. * @attention
  20. *
  21. * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  22. * All rights reserved.</center></h2>
  23. *
  24. * This software component is licensed by ST under BSD 3-Clause license,
  25. * the "License"; You may not use this file except in compliance with the
  26. * License. You may obtain a copy of the License at:
  27. * opensource.org/licenses/BSD-3-Clause
  28. *
  29. ******************************************************************************
  30. */
  31. /* Includes ------------------------------------------------------------------*/
  32. #include "stm32h7xx_hal.h"
  33. /** @addtogroup STM32H7xx_HAL_Driver
  34. * @{
  35. */
  36. #if defined (CRYP)
  37. /** @defgroup CRYPEx CRYPEx
  38. * @brief CRYP Extension HAL module driver.
  39. * @{
  40. */
  41. #ifdef HAL_CRYP_MODULE_ENABLED
  42. /* Private typedef -----------------------------------------------------------*/
  43. /* Private define ------------------------------------------------------------*/
  44. /** @addtogroup CRYPEx_Private_Defines
  45. * @{
  46. */
  47. #define CRYP_PHASE_INIT 0x00000000U
  48. #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0
  49. #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1
  50. #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH
  51. #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U
  52. #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR
  53. #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
  54. #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
  55. /* CTR0 information to use in CCM algorithm */
  56. #define CRYP_CCM_CTR0_0 0x07FFFFFFU
  57. #define CRYP_CCM_CTR0_3 0xFFFFFF00U
  58. /**
  59. * @}
  60. */
  61. /* Private macro -------------------------------------------------------------*/
  62. /* Private variables ---------------------------------------------------------*/
  63. /* Private function prototypes -----------------------------------------------*/
  64. /* Exported functions---------------------------------------------------------*/
  65. /** @addtogroup CRYPEx_Exported_Functions
  66. * @{
  67. */
  68. /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
  69. * @brief CRYPEx Extended processing functions.
  70. *
  71. @verbatim
  72. ==============================================================================
  73. ##### Extended AES processing functions #####
  74. ==============================================================================
  75. [..] This section provides functions allowing to generate the authentication
  76. TAG in Polling mode
  77. (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG
  78. (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG
  79. they should be used after Encrypt/Decrypt operation.
  80. @endverbatim
  81. * @{
  82. */
  83. /**
  84. * @brief generate the GCM authentication TAG.
  85. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  86. * the configuration information for CRYP module
  87. * @param AuthTag: Pointer to the authentication buffer
  88. * @param Timeout: Timeout duration
  89. * @retval HAL status
  90. */
  91. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
  92. {
  93. uint32_t tickstart;
  94. uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
  95. uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* input length in bits */
  96. uint32_t tagaddr = (uint32_t)AuthTag;
  97. if (hcryp->State == HAL_CRYP_STATE_READY)
  98. {
  99. /* Process locked */
  100. __HAL_LOCK(hcryp);
  101. /* Change the CRYP peripheral state */
  102. hcryp->State = HAL_CRYP_STATE_BUSY;
  103. /* Check if initialization phase has already been performed */
  104. if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
  105. {
  106. /* Change the CRYP phase */
  107. hcryp->Phase = CRYPEx_PHASE_FINAL;
  108. }
  109. else /* Initialization phase has not been performed*/
  110. {
  111. /* Disable the Peripheral */
  112. __HAL_CRYP_DISABLE(hcryp);
  113. /* Sequence error code field */
  114. hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
  115. /* Change the CRYP peripheral state */
  116. hcryp->State = HAL_CRYP_STATE_READY;
  117. /* Process unlocked */
  118. __HAL_UNLOCK(hcryp);
  119. return HAL_ERROR;
  120. }
  121. /* Disable CRYP to start the final phase */
  122. __HAL_CRYP_DISABLE(hcryp);
  123. /* Select final phase */
  124. MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
  125. /*ALGODIR bit must be set to '0'.*/
  126. hcryp->Instance->CR &= ~CRYP_CR_ALGODIR;
  127. /* Enable the CRYP peripheral */
  128. __HAL_CRYP_ENABLE(hcryp);
  129. /* Write the number of bits in header (64 bits) followed by the number of bits
  130. in the payload */
  131. #if !defined (CRYP_VER_2_2)
  132. /* STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
  133. if (hcryp->Version >= REV_ID_B)
  134. #endif /*End of not defined CRYP_VER_2_2*/
  135. {
  136. hcryp->Instance->DIN = 0U;
  137. hcryp->Instance->DIN = (uint32_t)(headerlength);
  138. hcryp->Instance->DIN = 0U;
  139. hcryp->Instance->DIN = (uint32_t)(inputlength);
  140. }
  141. #if !defined (CRYP_VER_2_2)
  142. else/* data has to be swapped according to the DATATYPE */
  143. {
  144. if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
  145. {
  146. hcryp->Instance->DIN = 0U;
  147. hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
  148. hcryp->Instance->DIN = 0U;
  149. hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
  150. }
  151. else if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
  152. {
  153. hcryp->Instance->DIN = 0U;
  154. hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
  155. hcryp->Instance->DIN = 0U;
  156. hcryp->Instance->DIN = __REV((uint32_t)(inputlength));
  157. }
  158. else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
  159. {
  160. hcryp->Instance->DIN = 0U;
  161. hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
  162. hcryp->Instance->DIN = 0U;
  163. hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
  164. }
  165. else if (hcryp->Init.DataType == CRYP_DATATYPE_32B)
  166. {
  167. hcryp->Instance->DIN = 0U;
  168. hcryp->Instance->DIN = (uint32_t)(headerlength);
  169. hcryp->Instance->DIN = 0U;
  170. hcryp->Instance->DIN = (uint32_t)(inputlength);
  171. }
  172. else
  173. {
  174. /* Nothing to do */
  175. }
  176. }
  177. #endif /*End of not defined CRYP_VER_2_2*/
  178. /* Wait for OFNE flag to be raised */
  179. tickstart = HAL_GetTick();
  180. while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  181. {
  182. /* Check for the Timeout */
  183. if (Timeout != HAL_MAX_DELAY)
  184. {
  185. if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
  186. {
  187. /* Disable the CRYP Peripheral Clock */
  188. __HAL_CRYP_DISABLE(hcryp);
  189. /* Change state */
  190. hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
  191. hcryp->State = HAL_CRYP_STATE_READY;
  192. /* Process unlocked */
  193. __HAL_UNLOCK(hcryp);
  194. return HAL_ERROR;
  195. }
  196. }
  197. }
  198. /* Read the authentication TAG in the output FIFO */
  199. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  200. tagaddr += 4U;
  201. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  202. tagaddr += 4U;
  203. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  204. tagaddr += 4U;
  205. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  206. /* Disable the peripheral */
  207. __HAL_CRYP_DISABLE(hcryp);
  208. /* Change the CRYP peripheral state */
  209. hcryp->State = HAL_CRYP_STATE_READY;
  210. /* Process unlocked */
  211. __HAL_UNLOCK(hcryp);
  212. }
  213. else
  214. {
  215. /* Busy error code field */
  216. hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
  217. return HAL_ERROR;
  218. }
  219. /* Return function status */
  220. return HAL_OK;
  221. }
  222. /**
  223. * @brief AES CCM Authentication TAG generation.
  224. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  225. * the configuration information for CRYP module
  226. * @param AuthTag: Pointer to the authentication buffer
  227. * @param Timeout: Timeout duration
  228. * @retval HAL status
  229. */
  230. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
  231. {
  232. uint32_t tagaddr = (uint32_t)AuthTag;
  233. uint32_t ctr0 [4] = {0};
  234. uint32_t ctr0addr = (uint32_t)ctr0;
  235. uint32_t tickstart;
  236. if (hcryp->State == HAL_CRYP_STATE_READY)
  237. {
  238. /* Process locked */
  239. __HAL_LOCK(hcryp);
  240. /* Change the CRYP peripheral state */
  241. hcryp->State = HAL_CRYP_STATE_BUSY;
  242. /* Check if initialization phase has already been performed */
  243. if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
  244. {
  245. /* Change the CRYP phase */
  246. hcryp->Phase = CRYPEx_PHASE_FINAL;
  247. }
  248. else /* Initialization phase has not been performed*/
  249. {
  250. /* Disable the peripheral */
  251. __HAL_CRYP_DISABLE(hcryp);
  252. /* Sequence error code field */
  253. hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
  254. /* Change the CRYP peripheral state */
  255. hcryp->State = HAL_CRYP_STATE_READY;
  256. /* Process unlocked */
  257. __HAL_UNLOCK(hcryp);
  258. return HAL_ERROR;
  259. }
  260. /* Disable CRYP to start the final phase */
  261. __HAL_CRYP_DISABLE(hcryp);
  262. /* Select final phase & ALGODIR bit must be set to '0'. */
  263. MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT);
  264. /* Enable the CRYP peripheral */
  265. __HAL_CRYP_ENABLE(hcryp);
  266. /* Write the counter block in the IN FIFO, CTR0 information from B0
  267. data has to be swapped according to the DATATYPE*/
  268. ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
  269. ctr0[1] = hcryp->Init.B0[1];
  270. ctr0[2] = hcryp->Init.B0[2];
  271. ctr0[3] = hcryp->Init.B0[3] & CRYP_CCM_CTR0_3;
  272. #if !defined (CRYP_VER_2_2)
  273. /*STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
  274. if (hcryp->Version >= REV_ID_B)
  275. #endif /*End of not defined CRYP_VER_2_2*/
  276. {
  277. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  278. ctr0addr += 4U;
  279. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  280. ctr0addr += 4U;
  281. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  282. ctr0addr += 4U;
  283. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  284. }
  285. #if !defined (CRYP_VER_2_2)
  286. else /* data has to be swapped according to the DATATYPE */
  287. {
  288. if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
  289. {
  290. hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
  291. ctr0addr += 4U;
  292. hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
  293. ctr0addr += 4U;
  294. hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
  295. ctr0addr += 4U;
  296. hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
  297. }
  298. else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
  299. {
  300. hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
  301. ctr0addr += 4U;
  302. hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
  303. ctr0addr += 4U;
  304. hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
  305. ctr0addr += 4U;
  306. hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
  307. }
  308. else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
  309. {
  310. hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
  311. ctr0addr += 4U;
  312. hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
  313. ctr0addr += 4U;
  314. hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
  315. ctr0addr += 4U;
  316. hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
  317. }
  318. else
  319. {
  320. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  321. ctr0addr += 4U;
  322. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  323. ctr0addr += 4U;
  324. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  325. ctr0addr += 4U;
  326. hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
  327. }
  328. }
  329. #endif /*End of not defined CRYP_VER_2_2*/
  330. /* Wait for OFNE flag to be raised */
  331. tickstart = HAL_GetTick();
  332. while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  333. {
  334. /* Check for the Timeout */
  335. if (Timeout != HAL_MAX_DELAY)
  336. {
  337. if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
  338. {
  339. /* Disable the CRYP peripheral Clock */
  340. __HAL_CRYP_DISABLE(hcryp);
  341. /* Change state */
  342. hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
  343. hcryp->State = HAL_CRYP_STATE_READY;
  344. /* Process unlocked */
  345. __HAL_UNLOCK(hcryp);
  346. return HAL_ERROR;
  347. }
  348. }
  349. }
  350. /* Read the Auth TAG in the IN FIFO */
  351. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  352. tagaddr += 4U;
  353. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  354. tagaddr += 4U;
  355. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  356. tagaddr += 4U;
  357. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
  358. /* Change the CRYP peripheral state */
  359. hcryp->State = HAL_CRYP_STATE_READY;
  360. /* Process unlocked */
  361. __HAL_UNLOCK(hcryp);
  362. /* Disable CRYP */
  363. __HAL_CRYP_DISABLE(hcryp);
  364. }
  365. else
  366. {
  367. /* Busy error code field */
  368. hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
  369. return HAL_ERROR;
  370. }
  371. /* Return function status */
  372. return HAL_OK;
  373. }
  374. /**
  375. * @}
  376. */
  377. #endif /* HAL_CRYP_MODULE_ENABLED */
  378. /**
  379. * @}
  380. */
  381. #endif /* CRYP */
  382. /**
  383. * @}
  384. */
  385. /**
  386. * @}
  387. */
  388. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/