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.
 
 
 

430 lines
14 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_cryp_ex.c
  4. * @author MCD Application Team
  5. * @version V1.2.0
  6. * @date 29-December-2017
  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 after AES-GCM or AES-CCM
  18. Encryption/Decryption to get the authentication messages.
  19. @endverbatim
  20. ******************************************************************************
  21. * @attention
  22. *
  23. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  24. *
  25. * Redistribution and use in source and binary forms, with or without modification,
  26. * are permitted provided that the following conditions are met:
  27. * 1. Redistributions of source code must retain the above copyright notice,
  28. * this list of conditions and the following disclaimer.
  29. * 2. Redistributions in binary form must reproduce the above copyright notice,
  30. * this list of conditions and the following disclaimer in the documentation
  31. * and/or other materials provided with the distribution.
  32. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  33. * may be used to endorse or promote products derived from this software
  34. * without specific prior written permission.
  35. *
  36. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  37. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  40. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  41. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  42. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  43. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  45. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46. *
  47. ******************************************************************************
  48. */
  49. /* Includes ------------------------------------------------------------------*/
  50. #include "stm32h7xx_hal.h"
  51. /** @addtogroup STM32H7xx_HAL_Driver
  52. * @{
  53. */
  54. #if defined (CRYP)
  55. /** @defgroup CRYPEx CRYPEx
  56. * @brief CRYP Extension HAL module driver.
  57. * @{
  58. */
  59. #ifdef HAL_CRYP_MODULE_ENABLED
  60. /* Private typedef -----------------------------------------------------------*/
  61. /* Private define ------------------------------------------------------------*/
  62. /** @addtogroup CRYPEx_Private_Defines
  63. * @{
  64. */
  65. #define CRYP_PHASE_INIT 0x00000000U
  66. #define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0
  67. #define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1
  68. #define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH
  69. #define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U
  70. #define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR
  71. #define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */
  72. #define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
  73. /* CTR0 information to use in CCM algorithm */
  74. #define CRYP_CCM_CTR0_0 0x07FFFFFFU
  75. #define CRYP_CCM_CTR0_3 0xFFFFFF00U
  76. /**
  77. * @}
  78. */
  79. /* Private macro -------------------------------------------------------------*/
  80. /* Private variables ---------------------------------------------------------*/
  81. /* Private function prototypes -----------------------------------------------*/
  82. /* Exported functions---------------------------------------------------------*/
  83. /** @addtogroup CRYPEx_Exported_Functions
  84. * @{
  85. */
  86. /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
  87. * @brief CRYPEx Extended processing functions.
  88. *
  89. @verbatim
  90. ==============================================================================
  91. ##### Extended AES processing functions #####
  92. ==============================================================================
  93. [..] This section provides functions allowing to generate the authentication
  94. TAG in Polling mode
  95. (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG
  96. (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG
  97. they should be used after Encrypt/Decrypt operation.
  98. @endverbatim
  99. * @{
  100. */
  101. /**
  102. * @brief generate the GCM authentication TAG.
  103. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  104. * the configuration information for CRYP module
  105. * @param AuthTag: Pointer to the authentication buffer
  106. * @param Timeout: Timeout duration
  107. * @retval HAL status
  108. */
  109. HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
  110. {
  111. uint32_t tickstart = 0U;
  112. uint64_t headerlength = hcryp->Init.HeaderSize * 32U; /* Header length in bits */
  113. uint64_t inputlength = (hcryp->Size) * 32U; /* input length in bits */
  114. uint32_t tagaddr = (uint32_t)AuthTag;
  115. if(hcryp->State == HAL_CRYP_STATE_READY)
  116. {
  117. /* Process locked */
  118. __HAL_LOCK(hcryp);
  119. /* Change the CRYP peripheral state */
  120. hcryp->State = HAL_CRYP_STATE_BUSY;
  121. /* Check if initialization phase has already been performed */
  122. if(hcryp->Phase == CRYPEx_PHASE_PROCESS)
  123. {
  124. /* Change the CRYP phase */
  125. hcryp->Phase = CRYPEx_PHASE_FINAL;
  126. }
  127. else /* Initialization phase has not been performed*/
  128. {
  129. /* Disable the Peripheral */
  130. __HAL_CRYP_DISABLE(hcryp);
  131. /* Sequence error code field */
  132. hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
  133. /* Change the CRYP peripheral state */
  134. hcryp->State = HAL_CRYP_STATE_READY;
  135. /* Process unlocked */
  136. __HAL_UNLOCK(hcryp);
  137. return HAL_ERROR;
  138. }
  139. /* Disable CRYP to start the final phase */
  140. __HAL_CRYP_DISABLE(hcryp);
  141. /* Select final phase */
  142. MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
  143. /*ALGODIR bit must be set to '0'.*/
  144. hcryp->Instance->CR &= ~CRYP_CR_ALGODIR;
  145. /* Enable the CRYP peripheral */
  146. __HAL_CRYP_ENABLE(hcryp);
  147. /* Write the number of bits in header (64 bits) followed by the number of bits
  148. in the payload */
  149. if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
  150. {
  151. hcryp->Instance->DIN = 0U;
  152. hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
  153. hcryp->Instance->DIN = 0U;
  154. hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
  155. }
  156. else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
  157. {
  158. hcryp->Instance->DIN = 0U;
  159. hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
  160. hcryp->Instance->DIN = 0U;
  161. hcryp->Instance->DIN = __REV((uint32_t)(inputlength));
  162. }
  163. else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
  164. {
  165. hcryp->Instance->DIN = 0U;
  166. hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
  167. hcryp->Instance->DIN = 0U;
  168. hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
  169. }
  170. else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
  171. {
  172. hcryp->Instance->DIN = 0U;
  173. hcryp->Instance->DIN = (uint32_t)(headerlength);
  174. hcryp->Instance->DIN = 0U;
  175. hcryp->Instance->DIN = (uint32_t)(inputlength);
  176. }
  177. /* Wait for OFNE flag to be raised */
  178. tickstart = HAL_GetTick();
  179. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  180. {
  181. /* Check for the Timeout */
  182. if(Timeout != HAL_MAX_DELAY)
  183. {
  184. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  185. {
  186. /* Disable the CRYP Peripheral Clock */
  187. __HAL_CRYP_DISABLE(hcryp);
  188. /* Change state */
  189. hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
  190. hcryp->State = HAL_CRYP_STATE_READY;
  191. /* Process unlocked */
  192. __HAL_UNLOCK(hcryp);
  193. return HAL_ERROR;
  194. }
  195. }
  196. }
  197. /* Read the authentication TAG in the output FIFO */
  198. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  199. tagaddr+=4U;
  200. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  201. tagaddr+=4U;
  202. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  203. tagaddr+=4U;
  204. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  205. /* Disable the peripheral */
  206. __HAL_CRYP_DISABLE(hcryp);
  207. /* Change the CRYP peripheral state */
  208. hcryp->State = HAL_CRYP_STATE_READY;
  209. /* Process unlocked */
  210. __HAL_UNLOCK(hcryp);
  211. }
  212. else
  213. {
  214. /* Busy error code field */
  215. hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
  216. return HAL_ERROR;
  217. }
  218. /* Return function status */
  219. return HAL_OK;
  220. }
  221. /**
  222. * @brief AES CCM Authentication TAG generation.
  223. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  224. * the configuration information for CRYP module
  225. * @param AuthTag: Pointer to the authentication buffer
  226. * @param Timeout: Timeout duration
  227. * @retval HAL status
  228. */
  229. HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
  230. {
  231. uint32_t tagaddr = (uint32_t)AuthTag;
  232. uint32_t ctr0 [4]={0};
  233. uint32_t ctr0addr = (uint32_t)ctr0;
  234. uint32_t tickstart = 0U;
  235. if(hcryp->State == HAL_CRYP_STATE_READY)
  236. {
  237. /* Process locked */
  238. __HAL_LOCK(hcryp);
  239. /* Change the CRYP peripheral state */
  240. hcryp->State = HAL_CRYP_STATE_BUSY;
  241. /* Check if initialization phase has already been performed */
  242. if(hcryp->Phase == CRYPEx_PHASE_PROCESS)
  243. {
  244. /* Change the CRYP phase */
  245. hcryp->Phase = CRYPEx_PHASE_FINAL;
  246. }
  247. else /* Initialization phase has not been performed*/
  248. {
  249. /* Disable the peripheral */
  250. __HAL_CRYP_DISABLE(hcryp);
  251. /* Sequence error code field */
  252. hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
  253. /* Change the CRYP peripheral state */
  254. hcryp->State = HAL_CRYP_STATE_READY;
  255. /* Process unlocked */
  256. __HAL_UNLOCK(hcryp);
  257. return HAL_ERROR;
  258. }
  259. /* Disable CRYP to start the final phase */
  260. __HAL_CRYP_DISABLE(hcryp);
  261. /* Select final phase & ALGODIR bit must be set to '0'. */
  262. MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH|CRYP_CR_ALGODIR, CRYP_PHASE_FINAL|CRYP_OPERATINGMODE_ENCRYPT);
  263. /* Enable the CRYP peripheral */
  264. __HAL_CRYP_ENABLE(hcryp);
  265. /* Write the counter block in the IN FIFO, CTR0 information from B0
  266. data has to be swapped according to the DATATYPE*/
  267. ctr0[0]=(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
  268. ctr0[1]=hcryp->Init.B0[1];
  269. ctr0[2]=hcryp->Init.B0[2];
  270. ctr0[3]=hcryp->Init.B0[3] & CRYP_CCM_CTR0_3;
  271. if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
  272. {
  273. hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
  274. ctr0addr+=4;
  275. hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
  276. ctr0addr+=4;
  277. hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
  278. ctr0addr+=4;
  279. hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
  280. }
  281. else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
  282. {
  283. hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
  284. ctr0addr+=4;
  285. hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
  286. ctr0addr+=4;
  287. hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
  288. ctr0addr+=4;
  289. hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
  290. }
  291. else if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
  292. {
  293. hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
  294. ctr0addr+=4;
  295. hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
  296. ctr0addr+=4;
  297. hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
  298. ctr0addr+=4;
  299. hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
  300. }
  301. else
  302. {
  303. hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
  304. ctr0addr+=4;
  305. hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
  306. ctr0addr+=4;
  307. hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
  308. ctr0addr+=4;
  309. hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);;
  310. }
  311. /* Wait for OFNE flag to be raised */
  312. tickstart = HAL_GetTick();
  313. while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
  314. {
  315. /* Check for the Timeout */
  316. if(Timeout != HAL_MAX_DELAY)
  317. {
  318. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  319. {
  320. /* Disable the CRYP peripheral Clock */
  321. __HAL_CRYP_DISABLE(hcryp);
  322. /* Change state */
  323. hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
  324. hcryp->State = HAL_CRYP_STATE_READY;
  325. /* Process unlocked */
  326. __HAL_UNLOCK(hcryp);
  327. return HAL_ERROR;
  328. }
  329. }
  330. }
  331. /* Read the Auth TAG in the IN FIFO */
  332. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  333. tagaddr+=4U;
  334. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  335. tagaddr+=4U;
  336. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  337. tagaddr+=4U;
  338. *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
  339. /* Change the CRYP peripheral state */
  340. hcryp->State = HAL_CRYP_STATE_READY;
  341. /* Process unlocked */
  342. __HAL_UNLOCK(hcryp);
  343. /* Disable CRYP */
  344. __HAL_CRYP_DISABLE(hcryp);
  345. }
  346. else
  347. {
  348. /* Busy error code field */
  349. hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
  350. return HAL_ERROR;
  351. }
  352. /* Return function status */
  353. return HAL_OK;
  354. }
  355. /**
  356. * @}
  357. */
  358. #endif /* HAL_CRYP_MODULE_ENABLED */
  359. /**
  360. * @}
  361. */
  362. #endif /* CRYP*/
  363. /**
  364. * @}
  365. */
  366. /**
  367. * @}
  368. */
  369. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/