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.
 
 
 

390 lines
12 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32wbxx_hal_cryp_ex.c
  4. * @author MCD Application Team
  5. * @brief CRYPEx HAL module driver.
  6. * This file provides firmware functions to manage the extended
  7. * functionalities of the Cryptography (CRYP) peripheral.
  8. *
  9. ******************************************************************************
  10. * @attention
  11. *
  12. * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  13. * All rights reserved.</center></h2>
  14. *
  15. * This software component is licensed by ST under BSD 3-Clause license,
  16. * the "License"; You may not use this file except in compliance with the
  17. * License. You may obtain a copy of the License at:
  18. * opensource.org/licenses/BSD-3-Clause
  19. *
  20. ******************************************************************************
  21. */
  22. /* Includes ------------------------------------------------------------------*/
  23. #include "stm32wbxx_hal.h"
  24. /** @addtogroup STM32WBxx_HAL_Driver
  25. * @{
  26. */
  27. /** @addtogroup CRYPEx
  28. * @{
  29. */
  30. #ifdef HAL_CRYP_MODULE_ENABLED
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* Private define ------------------------------------------------------------*/
  33. /** @addtogroup CRYPEx_Private_Defines
  34. * @{
  35. */
  36. #define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
  37. #define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */
  38. #define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */
  39. #define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */
  40. #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
  41. #define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions */
  42. #define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption */
  43. #define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT AES_CR_MODE /*!< Key derivation and decryption only used when performing ECB and CBC decryptions */
  44. #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
  45. #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
  46. /* CTR0 information to use in CCM algorithm */
  47. #define CRYP_CCM_CTR0_0 0x07FFFFFFU
  48. #define CRYP_CCM_CTR0_3 0xFFFFFF00U
  49. /**
  50. * @}
  51. */
  52. /* Private macro -------------------------------------------------------------*/
  53. /* Private variables ---------------------------------------------------------*/
  54. /* Private function prototypes -----------------------------------------------*/
  55. /* Exported functions---------------------------------------------------------*/
  56. /** @addtogroup CRYPEx_Exported_Functions
  57. * @{
  58. */
  59. /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
  60. * @brief Extended processing functions.
  61. *
  62. @verbatim
  63. ==============================================================================
  64. ##### Extended AES processing functions #####
  65. ==============================================================================
  66. [..] This section provides functions allowing to generate the authentication
  67. TAG in Polling mode
  68. (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG
  69. (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG
  70. they should be used after Encrypt/Decrypt operation.
  71. @endverbatim
  72. * @{
  73. */
  74. /**
  75. * @brief generate the GCM authentication TAG.
  76. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  77. * the configuration information for CRYP module
  78. * @param AuthTag Pointer to the authentication buffer
  79. * @param Timeout Timeout duration
  80. * @retval HAL status
  81. */
  82. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
  83. {
  84. uint32_t tickstart;
  85. /* Assume first Init.HeaderSize is in words */
  86. uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */
  87. uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
  88. uint32_t tagaddr = (uint32_t)AuthTag;
  89. /* Correct headerlength if Init.HeaderSize is actually in bytes */
  90. if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
  91. {
  92. headerlength /= 4U;
  93. }
  94. if (hcryp->State == HAL_CRYP_STATE_READY)
  95. {
  96. /* Process locked */
  97. __HAL_LOCK(hcryp);
  98. /* Change the CRYP peripheral state */
  99. hcryp->State = HAL_CRYP_STATE_BUSY;
  100. /* Check if initialization phase has already been performed */
  101. if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
  102. {
  103. /* Change the CRYP phase */
  104. hcryp->Phase = CRYPEx_PHASE_FINAL;
  105. }
  106. else /* Initialization phase has not been performed*/
  107. {
  108. /* Disable the Peripheral */
  109. __HAL_CRYP_DISABLE(hcryp);
  110. /* Sequence error code field */
  111. hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
  112. /* Change the CRYP peripheral state */
  113. hcryp->State = HAL_CRYP_STATE_READY;
  114. /* Process unlocked */
  115. __HAL_UNLOCK(hcryp);
  116. return HAL_ERROR;
  117. }
  118. /* Select final phase */
  119. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
  120. /* Set the encrypt operating mode*/
  121. MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
  122. /*TinyAES peripheral from V3.1.1 : data has to be inserted normally (no swapping)*/
  123. /* Write into the AES_DINR register the number of bits in header (64 bits)
  124. followed by the number of bits in the payload */
  125. hcryp->Instance->DINR = 0U;
  126. hcryp->Instance->DINR = (uint32_t)(headerlength);
  127. hcryp->Instance->DINR = 0U;
  128. hcryp->Instance->DINR = (uint32_t)(inputlength);
  129. /* Wait for CCF flag to be raised */
  130. tickstart = HAL_GetTick();
  131. while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
  132. {
  133. /* Check for the Timeout */
  134. if (Timeout != HAL_MAX_DELAY)
  135. {
  136. if (((HAL_GetTick() - tickstart) > Timeout)||(Timeout == 0U))
  137. {
  138. /* Disable the CRYP peripheral clock */
  139. __HAL_CRYP_DISABLE(hcryp);
  140. /* Change state */
  141. hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
  142. hcryp->State = HAL_CRYP_STATE_READY;
  143. /* Process unlocked */
  144. __HAL_UNLOCK(hcryp);
  145. return HAL_ERROR;
  146. }
  147. }
  148. }
  149. /* Read the authentication TAG in the output FIFO */
  150. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  151. tagaddr += 4U;
  152. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  153. tagaddr += 4U;
  154. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  155. tagaddr += 4U;
  156. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  157. /* Clear CCF flag */
  158. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  159. /* Disable the peripheral */
  160. __HAL_CRYP_DISABLE(hcryp);
  161. /* Change the CRYP peripheral state */
  162. hcryp->State = HAL_CRYP_STATE_READY;
  163. /* Process unlocked */
  164. __HAL_UNLOCK(hcryp);
  165. }
  166. else
  167. {
  168. /* Busy error code field */
  169. hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
  170. return HAL_ERROR;
  171. }
  172. /* Return function status */
  173. return HAL_OK;
  174. }
  175. /**
  176. * @brief AES CCM Authentication TAG generation.
  177. * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains
  178. * the configuration information for CRYP module
  179. * @param AuthTag Pointer to the authentication buffer
  180. * @param Timeout Timeout duration
  181. * @retval HAL status
  182. */
  183. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
  184. {
  185. uint32_t tagaddr = (uint32_t)AuthTag;
  186. uint32_t tickstart;
  187. if (hcryp->State == HAL_CRYP_STATE_READY)
  188. {
  189. /* Process locked */
  190. __HAL_LOCK(hcryp);
  191. /* Disable interrupts in case they were kept enabled to proceed
  192. a single message in several iterations */
  193. __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_ERRIE);
  194. /* Change the CRYP peripheral state */
  195. hcryp->State = HAL_CRYP_STATE_BUSY;
  196. /* Check if initialization phase has already been performed */
  197. if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
  198. {
  199. /* Change the CRYP phase */
  200. hcryp->Phase = CRYPEx_PHASE_FINAL;
  201. }
  202. else /* Initialization phase has not been performed*/
  203. {
  204. /* Disable the peripheral */
  205. __HAL_CRYP_DISABLE(hcryp);
  206. /* Sequence error code field */
  207. hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
  208. /* Change the CRYP peripheral state */
  209. hcryp->State = HAL_CRYP_STATE_READY;
  210. /* Process unlocked */
  211. __HAL_UNLOCK(hcryp);
  212. return HAL_ERROR;
  213. }
  214. /* Select final phase */
  215. MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL);
  216. /* Set encrypt operating mode*/
  217. MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT);
  218. /* Wait for CCF flag to be raised */
  219. tickstart = HAL_GetTick();
  220. while (HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
  221. {
  222. /* Check for the Timeout */
  223. if (Timeout != HAL_MAX_DELAY)
  224. {
  225. if (((HAL_GetTick() - tickstart) > Timeout) ||(Timeout == 0U))
  226. {
  227. /* Disable the CRYP peripheral Clock */
  228. __HAL_CRYP_DISABLE(hcryp);
  229. /* Change state */
  230. hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
  231. hcryp->State = HAL_CRYP_STATE_READY;
  232. /* Process unlocked */
  233. __HAL_UNLOCK(hcryp);
  234. return HAL_ERROR;
  235. }
  236. }
  237. }
  238. /* Read the authentication TAG in the output FIFO */
  239. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  240. tagaddr += 4U;
  241. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  242. tagaddr += 4U;
  243. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  244. tagaddr += 4U;
  245. *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR;
  246. /* Clear CCF Flag */
  247. __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CCF_CLEAR);
  248. /* Change the CRYP peripheral state */
  249. hcryp->State = HAL_CRYP_STATE_READY;
  250. /* Process unlocked */
  251. __HAL_UNLOCK(hcryp);
  252. /* Disable CRYP */
  253. __HAL_CRYP_DISABLE(hcryp);
  254. }
  255. else
  256. {
  257. /* Busy error code field */
  258. hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
  259. return HAL_ERROR;
  260. }
  261. /* Return function status */
  262. return HAL_OK;
  263. }
  264. /**
  265. * @}
  266. */
  267. /** @defgroup CRYPEx_Exported_Functions_Group2 Extended AES Key Derivations functions
  268. * @brief Extended Key Derivations functions.
  269. *
  270. @verbatim
  271. ==============================================================================
  272. ##### Key Derivation functions #####
  273. ==============================================================================
  274. [..] This section provides functions allowing to Enable or Disable the
  275. the AutoKeyDerivation parameter in CRYP_HandleTypeDef structure
  276. These function are allowed only in TinyAES peripheral.
  277. @endverbatim
  278. * @{
  279. */
  280. /**
  281. * @brief AES enable key derivation functions
  282. * @param hcryp pointer to a CRYP_HandleTypeDef structure.
  283. */
  284. void HAL_CRYPEx_EnableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
  285. {
  286. if (hcryp->State == HAL_CRYP_STATE_READY)
  287. {
  288. hcryp->AutoKeyDerivation = ENABLE;
  289. }
  290. else
  291. {
  292. /* Busy error code field */
  293. hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
  294. }
  295. }
  296. /**
  297. * @brief AES disable key derivation functions
  298. * @param hcryp pointer to a CRYP_HandleTypeDef structure.
  299. */
  300. void HAL_CRYPEx_DisableAutoKeyDerivation(CRYP_HandleTypeDef *hcryp)
  301. {
  302. if (hcryp->State == HAL_CRYP_STATE_READY)
  303. {
  304. hcryp->AutoKeyDerivation = DISABLE;
  305. }
  306. else
  307. {
  308. /* Busy error code field */
  309. hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
  310. }
  311. }
  312. /**
  313. * @}
  314. */
  315. /**
  316. * @}
  317. */
  318. #endif /* HAL_CRYP_MODULE_ENABLED */
  319. /**
  320. * @}
  321. */
  322. /**
  323. * @}
  324. */
  325. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/