001

Committer:
ganlikun
Date:
Sun Jun 12 14:02:44 2022 +0000
Revision:
0:13413ea9a877
00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ganlikun 0:13413ea9a877 1 /**
ganlikun 0:13413ea9a877 2 ******************************************************************************
ganlikun 0:13413ea9a877 3 * @file stm32f4xx_hal_cryp_ex.c
ganlikun 0:13413ea9a877 4 * @author MCD Application Team
ganlikun 0:13413ea9a877 5 * @version V1.7.1
ganlikun 0:13413ea9a877 6 * @date 14-April-2017
ganlikun 0:13413ea9a877 7 * @brief Extended CRYP HAL module driver
ganlikun 0:13413ea9a877 8 * This file provides firmware functions to manage the following
ganlikun 0:13413ea9a877 9 * functionalities of CRYP extension peripheral:
ganlikun 0:13413ea9a877 10 * + Extended AES processing functions
ganlikun 0:13413ea9a877 11 *
ganlikun 0:13413ea9a877 12 @verbatim
ganlikun 0:13413ea9a877 13 ==============================================================================
ganlikun 0:13413ea9a877 14 ##### How to use this driver #####
ganlikun 0:13413ea9a877 15 ==============================================================================
ganlikun 0:13413ea9a877 16 [..]
ganlikun 0:13413ea9a877 17 The CRYP Extension HAL driver can be used as follows:
ganlikun 0:13413ea9a877 18 (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
ganlikun 0:13413ea9a877 19 (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
ganlikun 0:13413ea9a877 20 (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT())
ganlikun 0:13413ea9a877 21 (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
ganlikun 0:13413ea9a877 22 (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
ganlikun 0:13413ea9a877 23 (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
ganlikun 0:13413ea9a877 24 (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA())
ganlikun 0:13413ea9a877 25 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
ganlikun 0:13413ea9a877 26 (+++) Configure and enable two DMA streams one for managing data transfer from
ganlikun 0:13413ea9a877 27 memory to peripheral (input stream) and another stream for managing data
ganlikun 0:13413ea9a877 28 transfer from peripheral to memory (output stream)
ganlikun 0:13413ea9a877 29 (+++) Associate the initialized DMA handle to the CRYP DMA handle
ganlikun 0:13413ea9a877 30 using __HAL_LINKDMA()
ganlikun 0:13413ea9a877 31 (+++) Configure the priority and enable the NVIC for the transfer complete
ganlikun 0:13413ea9a877 32 interrupt on the two DMA Streams. The output stream should have higher
ganlikun 0:13413ea9a877 33 priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
ganlikun 0:13413ea9a877 34 (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly:
ganlikun 0:13413ea9a877 35 (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit
ganlikun 0:13413ea9a877 36 (##) The key size: 128, 192 and 256. This parameter is relevant only for AES
ganlikun 0:13413ea9a877 37 (##) The encryption/decryption key. Its size depends on the algorithm
ganlikun 0:13413ea9a877 38 used for encryption/decryption
ganlikun 0:13413ea9a877 39 (##) The initialization vector (counter). It is not used ECB mode.
ganlikun 0:13413ea9a877 40 (#)Three processing (encryption/decryption) functions are available:
ganlikun 0:13413ea9a877 41 (##) Polling mode: encryption and decryption APIs are blocking functions
ganlikun 0:13413ea9a877 42 i.e. they process the data and wait till the processing is finished
ganlikun 0:13413ea9a877 43 e.g. HAL_CRYPEx_AESGCM_Encrypt()
ganlikun 0:13413ea9a877 44 (##) Interrupt mode: encryption and decryption APIs are not blocking functions
ganlikun 0:13413ea9a877 45 i.e. they process the data under interrupt
ganlikun 0:13413ea9a877 46 e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()
ganlikun 0:13413ea9a877 47 (##) DMA mode: encryption and decryption APIs are not blocking functions
ganlikun 0:13413ea9a877 48 i.e. the data transfer is ensured by DMA
ganlikun 0:13413ea9a877 49 e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA()
ganlikun 0:13413ea9a877 50 (#)When the processing function is called at first time after HAL_CRYP_Init()
ganlikun 0:13413ea9a877 51 the CRYP peripheral is initialized and processes the buffer in input.
ganlikun 0:13413ea9a877 52 At second call, the processing function performs an append of the already
ganlikun 0:13413ea9a877 53 processed buffer.
ganlikun 0:13413ea9a877 54 When a new data block is to be processed, call HAL_CRYP_Init() then the
ganlikun 0:13413ea9a877 55 processing function.
ganlikun 0:13413ea9a877 56 (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms
ganlikun 0:13413ea9a877 57 which provide authentication messages.
ganlikun 0:13413ea9a877 58 HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those
ganlikun 0:13413ea9a877 59 authentication messages.
ganlikun 0:13413ea9a877 60 Call those functions after the processing ones (polling, interrupt or DMA).
ganlikun 0:13413ea9a877 61 e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data
ganlikun 0:13413ea9a877 62 then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message
ganlikun 0:13413ea9a877 63 -@- For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version.
ganlikun 0:13413ea9a877 64 -@- The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length
ganlikun 0:13413ea9a877 65 (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D).
ganlikun 0:13413ea9a877 66 (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
ganlikun 0:13413ea9a877 67
ganlikun 0:13413ea9a877 68 @endverbatim
ganlikun 0:13413ea9a877 69 ******************************************************************************
ganlikun 0:13413ea9a877 70 * @attention
ganlikun 0:13413ea9a877 71 *
ganlikun 0:13413ea9a877 72 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
ganlikun 0:13413ea9a877 73 *
ganlikun 0:13413ea9a877 74 * Redistribution and use in source and binary forms, with or without modification,
ganlikun 0:13413ea9a877 75 * are permitted provided that the following conditions are met:
ganlikun 0:13413ea9a877 76 * 1. Redistributions of source code must retain the above copyright notice,
ganlikun 0:13413ea9a877 77 * this list of conditions and the following disclaimer.
ganlikun 0:13413ea9a877 78 * 2. Redistributions in binary form must reproduce the above copyright notice,
ganlikun 0:13413ea9a877 79 * this list of conditions and the following disclaimer in the documentation
ganlikun 0:13413ea9a877 80 * and/or other materials provided with the distribution.
ganlikun 0:13413ea9a877 81 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ganlikun 0:13413ea9a877 82 * may be used to endorse or promote products derived from this software
ganlikun 0:13413ea9a877 83 * without specific prior written permission.
ganlikun 0:13413ea9a877 84 *
ganlikun 0:13413ea9a877 85 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ganlikun 0:13413ea9a877 86 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ganlikun 0:13413ea9a877 87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ganlikun 0:13413ea9a877 88 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ganlikun 0:13413ea9a877 89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ganlikun 0:13413ea9a877 90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ganlikun 0:13413ea9a877 91 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ganlikun 0:13413ea9a877 92 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ganlikun 0:13413ea9a877 93 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ganlikun 0:13413ea9a877 94 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ganlikun 0:13413ea9a877 95 *
ganlikun 0:13413ea9a877 96 ******************************************************************************
ganlikun 0:13413ea9a877 97 */
ganlikun 0:13413ea9a877 98
ganlikun 0:13413ea9a877 99 /* Includes ------------------------------------------------------------------*/
ganlikun 0:13413ea9a877 100 #include "stm32f4xx_hal.h"
ganlikun 0:13413ea9a877 101
ganlikun 0:13413ea9a877 102 /** @addtogroup STM32F4xx_HAL_Driver
ganlikun 0:13413ea9a877 103 * @{
ganlikun 0:13413ea9a877 104 */
ganlikun 0:13413ea9a877 105
ganlikun 0:13413ea9a877 106 /** @defgroup CRYPEx CRYPEx
ganlikun 0:13413ea9a877 107 * @brief CRYP Extension HAL module driver.
ganlikun 0:13413ea9a877 108 * @{
ganlikun 0:13413ea9a877 109 */
ganlikun 0:13413ea9a877 110
ganlikun 0:13413ea9a877 111 #ifdef HAL_CRYP_MODULE_ENABLED
ganlikun 0:13413ea9a877 112
ganlikun 0:13413ea9a877 113 #if defined(CRYP)
ganlikun 0:13413ea9a877 114
ganlikun 0:13413ea9a877 115 /* Private typedef -----------------------------------------------------------*/
ganlikun 0:13413ea9a877 116 /* Private define ------------------------------------------------------------*/
ganlikun 0:13413ea9a877 117 /** @addtogroup CRYPEx_Private_define
ganlikun 0:13413ea9a877 118 * @{
ganlikun 0:13413ea9a877 119 */
ganlikun 0:13413ea9a877 120 #define CRYPEx_TIMEOUT_VALUE 1U
ganlikun 0:13413ea9a877 121 /**
ganlikun 0:13413ea9a877 122 * @}
ganlikun 0:13413ea9a877 123 */
ganlikun 0:13413ea9a877 124
ganlikun 0:13413ea9a877 125 /* Private macro -------------------------------------------------------------*/
ganlikun 0:13413ea9a877 126 /* Private variables ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 127 /* Private function prototypes -----------------------------------------------*/
ganlikun 0:13413ea9a877 128 /** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes
ganlikun 0:13413ea9a877 129 * @{
ganlikun 0:13413ea9a877 130 */
ganlikun 0:13413ea9a877 131 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector);
ganlikun 0:13413ea9a877 132 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize);
ganlikun 0:13413ea9a877 133 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout);
ganlikun 0:13413ea9a877 134 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout);
ganlikun 0:13413ea9a877 135 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 136 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 137 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 138 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
ganlikun 0:13413ea9a877 139 /**
ganlikun 0:13413ea9a877 140 * @}
ganlikun 0:13413ea9a877 141 */
ganlikun 0:13413ea9a877 142
ganlikun 0:13413ea9a877 143 /* Private functions ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 144 /** @addtogroup CRYPEx_Private_Functions
ganlikun 0:13413ea9a877 145 * @{
ganlikun 0:13413ea9a877 146 */
ganlikun 0:13413ea9a877 147
ganlikun 0:13413ea9a877 148 /**
ganlikun 0:13413ea9a877 149 * @brief DMA CRYP Input Data process complete callback.
ganlikun 0:13413ea9a877 150 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 151 * @retval None
ganlikun 0:13413ea9a877 152 */
ganlikun 0:13413ea9a877 153 static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 154 {
ganlikun 0:13413ea9a877 155 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 156
ganlikun 0:13413ea9a877 157 /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit
ganlikun 0:13413ea9a877 158 in the DMACR register */
ganlikun 0:13413ea9a877 159 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
ganlikun 0:13413ea9a877 160
ganlikun 0:13413ea9a877 161 /* Call input data transfer complete callback */
ganlikun 0:13413ea9a877 162 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 163 }
ganlikun 0:13413ea9a877 164
ganlikun 0:13413ea9a877 165 /**
ganlikun 0:13413ea9a877 166 * @brief DMA CRYP Output Data process complete callback.
ganlikun 0:13413ea9a877 167 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 168 * @retval None
ganlikun 0:13413ea9a877 169 */
ganlikun 0:13413ea9a877 170 static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 171 {
ganlikun 0:13413ea9a877 172 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 173
ganlikun 0:13413ea9a877 174 /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit
ganlikun 0:13413ea9a877 175 in the DMACR register */
ganlikun 0:13413ea9a877 176 hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
ganlikun 0:13413ea9a877 177
ganlikun 0:13413ea9a877 178 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 179 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 180
ganlikun 0:13413ea9a877 181 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 182 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 183
ganlikun 0:13413ea9a877 184 /* Call output data transfer complete callback */
ganlikun 0:13413ea9a877 185 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 186 }
ganlikun 0:13413ea9a877 187
ganlikun 0:13413ea9a877 188 /**
ganlikun 0:13413ea9a877 189 * @brief DMA CRYP communication error callback.
ganlikun 0:13413ea9a877 190 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 191 * @retval None
ganlikun 0:13413ea9a877 192 */
ganlikun 0:13413ea9a877 193 static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 194 {
ganlikun 0:13413ea9a877 195 CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 196 hcryp->State= HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 197 HAL_CRYP_ErrorCallback(hcryp);
ganlikun 0:13413ea9a877 198 }
ganlikun 0:13413ea9a877 199
ganlikun 0:13413ea9a877 200 /**
ganlikun 0:13413ea9a877 201 * @brief Writes the Key in Key registers.
ganlikun 0:13413ea9a877 202 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 203 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 204 * @param Key: Pointer to Key buffer
ganlikun 0:13413ea9a877 205 * @param KeySize: Size of Key
ganlikun 0:13413ea9a877 206 * @retval None
ganlikun 0:13413ea9a877 207 */
ganlikun 0:13413ea9a877 208 static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize)
ganlikun 0:13413ea9a877 209 {
ganlikun 0:13413ea9a877 210 uint32_t keyaddr = (uint32_t)Key;
ganlikun 0:13413ea9a877 211
ganlikun 0:13413ea9a877 212 switch(KeySize)
ganlikun 0:13413ea9a877 213 {
ganlikun 0:13413ea9a877 214 case CRYP_KEYSIZE_256B:
ganlikun 0:13413ea9a877 215 /* Key Initialisation */
ganlikun 0:13413ea9a877 216 hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 217 keyaddr+=4U;
ganlikun 0:13413ea9a877 218 hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 219 keyaddr+=4U;
ganlikun 0:13413ea9a877 220 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 221 keyaddr+=4U;
ganlikun 0:13413ea9a877 222 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 223 keyaddr+=4U;
ganlikun 0:13413ea9a877 224 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 225 keyaddr+=4U;
ganlikun 0:13413ea9a877 226 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 227 keyaddr+=4U;
ganlikun 0:13413ea9a877 228 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 229 keyaddr+=4U;
ganlikun 0:13413ea9a877 230 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 231 break;
ganlikun 0:13413ea9a877 232 case CRYP_KEYSIZE_192B:
ganlikun 0:13413ea9a877 233 hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 234 keyaddr+=4U;
ganlikun 0:13413ea9a877 235 hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 236 keyaddr+=4U;
ganlikun 0:13413ea9a877 237 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 238 keyaddr+=4U;
ganlikun 0:13413ea9a877 239 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 240 keyaddr+=4U;
ganlikun 0:13413ea9a877 241 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 242 keyaddr+=4U;
ganlikun 0:13413ea9a877 243 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 244 break;
ganlikun 0:13413ea9a877 245 case CRYP_KEYSIZE_128B:
ganlikun 0:13413ea9a877 246 hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 247 keyaddr+=4U;
ganlikun 0:13413ea9a877 248 hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 249 keyaddr+=4U;
ganlikun 0:13413ea9a877 250 hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 251 keyaddr+=4U;
ganlikun 0:13413ea9a877 252 hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 253 break;
ganlikun 0:13413ea9a877 254 default:
ganlikun 0:13413ea9a877 255 break;
ganlikun 0:13413ea9a877 256 }
ganlikun 0:13413ea9a877 257 }
ganlikun 0:13413ea9a877 258
ganlikun 0:13413ea9a877 259 /**
ganlikun 0:13413ea9a877 260 * @brief Writes the InitVector/InitCounter in IV registers.
ganlikun 0:13413ea9a877 261 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 262 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 263 * @param InitVector: Pointer to InitVector/InitCounter buffer
ganlikun 0:13413ea9a877 264 * @retval None
ganlikun 0:13413ea9a877 265 */
ganlikun 0:13413ea9a877 266 static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector)
ganlikun 0:13413ea9a877 267 {
ganlikun 0:13413ea9a877 268 uint32_t ivaddr = (uint32_t)InitVector;
ganlikun 0:13413ea9a877 269
ganlikun 0:13413ea9a877 270 hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 271 ivaddr+=4U;
ganlikun 0:13413ea9a877 272 hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 273 ivaddr+=4U;
ganlikun 0:13413ea9a877 274 hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 275 ivaddr+=4U;
ganlikun 0:13413ea9a877 276 hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 277 }
ganlikun 0:13413ea9a877 278
ganlikun 0:13413ea9a877 279 /**
ganlikun 0:13413ea9a877 280 * @brief Process Data: Writes Input data in polling mode and read the Output data.
ganlikun 0:13413ea9a877 281 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 282 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 283 * @param Input: Pointer to the Input buffer.
ganlikun 0:13413ea9a877 284 * @param Ilength: Length of the Input buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 285 * @param Output: Pointer to the returned buffer
ganlikun 0:13413ea9a877 286 * @param Timeout: Timeout value
ganlikun 0:13413ea9a877 287 * @retval None
ganlikun 0:13413ea9a877 288 */
ganlikun 0:13413ea9a877 289 static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout)
ganlikun 0:13413ea9a877 290 {
ganlikun 0:13413ea9a877 291 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 292 uint32_t i = 0U;
ganlikun 0:13413ea9a877 293 uint32_t inputaddr = (uint32_t)Input;
ganlikun 0:13413ea9a877 294 uint32_t outputaddr = (uint32_t)Output;
ganlikun 0:13413ea9a877 295
ganlikun 0:13413ea9a877 296 for(i=0U; (i < Ilength); i+=16U)
ganlikun 0:13413ea9a877 297 {
ganlikun 0:13413ea9a877 298 /* Write the Input block in the IN FIFO */
ganlikun 0:13413ea9a877 299 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 300 inputaddr+=4U;
ganlikun 0:13413ea9a877 301 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 302 inputaddr+=4U;
ganlikun 0:13413ea9a877 303 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 304 inputaddr+=4U;
ganlikun 0:13413ea9a877 305 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 306 inputaddr+=4U;
ganlikun 0:13413ea9a877 307
ganlikun 0:13413ea9a877 308 /* Get tick */
ganlikun 0:13413ea9a877 309 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 310
ganlikun 0:13413ea9a877 311 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
ganlikun 0:13413ea9a877 312 {
ganlikun 0:13413ea9a877 313 /* Check for the Timeout */
ganlikun 0:13413ea9a877 314 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 315 {
ganlikun 0:13413ea9a877 316 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 317 {
ganlikun 0:13413ea9a877 318 /* Change state */
ganlikun 0:13413ea9a877 319 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 320
ganlikun 0:13413ea9a877 321 /* Process Unlocked */
ganlikun 0:13413ea9a877 322 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 323
ganlikun 0:13413ea9a877 324 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 325 }
ganlikun 0:13413ea9a877 326 }
ganlikun 0:13413ea9a877 327 }
ganlikun 0:13413ea9a877 328 /* Read the Output block from the OUT FIFO */
ganlikun 0:13413ea9a877 329 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 330 outputaddr+=4U;
ganlikun 0:13413ea9a877 331 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 332 outputaddr+=4U;
ganlikun 0:13413ea9a877 333 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 334 outputaddr+=4U;
ganlikun 0:13413ea9a877 335 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 336 outputaddr+=4U;
ganlikun 0:13413ea9a877 337 }
ganlikun 0:13413ea9a877 338 /* Return function status */
ganlikun 0:13413ea9a877 339 return HAL_OK;
ganlikun 0:13413ea9a877 340 }
ganlikun 0:13413ea9a877 341
ganlikun 0:13413ea9a877 342 /**
ganlikun 0:13413ea9a877 343 * @brief Sets the header phase
ganlikun 0:13413ea9a877 344 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 345 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 346 * @param Input: Pointer to the Input buffer.
ganlikun 0:13413ea9a877 347 * @param Ilength: Length of the Input buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 348 * @param Timeout: Timeout value
ganlikun 0:13413ea9a877 349 * @retval None
ganlikun 0:13413ea9a877 350 */
ganlikun 0:13413ea9a877 351 static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout)
ganlikun 0:13413ea9a877 352 {
ganlikun 0:13413ea9a877 353 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 354 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 355 uint32_t headeraddr = (uint32_t)Input;
ganlikun 0:13413ea9a877 356
ganlikun 0:13413ea9a877 357 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 358 UNUSED(Ilength);
ganlikun 0:13413ea9a877 359
ganlikun 0:13413ea9a877 360 /***************************** Header phase *********************************/
ganlikun 0:13413ea9a877 361 if(hcryp->Init.HeaderSize != 0U)
ganlikun 0:13413ea9a877 362 {
ganlikun 0:13413ea9a877 363 /* Select header phase */
ganlikun 0:13413ea9a877 364 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 365 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 366 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 367
ganlikun 0:13413ea9a877 368 for(loopcounter = 0U; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16U)
ganlikun 0:13413ea9a877 369 {
ganlikun 0:13413ea9a877 370 /* Get tick */
ganlikun 0:13413ea9a877 371 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 372
ganlikun 0:13413ea9a877 373 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 374 {
ganlikun 0:13413ea9a877 375 /* Check for the Timeout */
ganlikun 0:13413ea9a877 376 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 377 {
ganlikun 0:13413ea9a877 378 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 379 {
ganlikun 0:13413ea9a877 380 /* Change state */
ganlikun 0:13413ea9a877 381 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 382
ganlikun 0:13413ea9a877 383 /* Process Unlocked */
ganlikun 0:13413ea9a877 384 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 385
ganlikun 0:13413ea9a877 386 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 387 }
ganlikun 0:13413ea9a877 388 }
ganlikun 0:13413ea9a877 389 }
ganlikun 0:13413ea9a877 390 /* Write the Input block in the IN FIFO */
ganlikun 0:13413ea9a877 391 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 392 headeraddr+=4U;
ganlikun 0:13413ea9a877 393 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 394 headeraddr+=4U;
ganlikun 0:13413ea9a877 395 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 396 headeraddr+=4U;
ganlikun 0:13413ea9a877 397 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 398 headeraddr+=4U;
ganlikun 0:13413ea9a877 399 }
ganlikun 0:13413ea9a877 400
ganlikun 0:13413ea9a877 401 /* Wait until the complete message has been processed */
ganlikun 0:13413ea9a877 402
ganlikun 0:13413ea9a877 403 /* Get tick */
ganlikun 0:13413ea9a877 404 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 405
ganlikun 0:13413ea9a877 406 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 407 {
ganlikun 0:13413ea9a877 408 /* Check for the Timeout */
ganlikun 0:13413ea9a877 409 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 410 {
ganlikun 0:13413ea9a877 411 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 412 {
ganlikun 0:13413ea9a877 413 /* Change state */
ganlikun 0:13413ea9a877 414 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 415
ganlikun 0:13413ea9a877 416 /* Process Unlocked */
ganlikun 0:13413ea9a877 417 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 418
ganlikun 0:13413ea9a877 419 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 420 }
ganlikun 0:13413ea9a877 421 }
ganlikun 0:13413ea9a877 422 }
ganlikun 0:13413ea9a877 423 }
ganlikun 0:13413ea9a877 424 /* Return function status */
ganlikun 0:13413ea9a877 425 return HAL_OK;
ganlikun 0:13413ea9a877 426 }
ganlikun 0:13413ea9a877 427
ganlikun 0:13413ea9a877 428 /**
ganlikun 0:13413ea9a877 429 * @brief Sets the DMA configuration and start the DMA transfer.
ganlikun 0:13413ea9a877 430 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 431 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 432 * @param inputaddr: Address of the Input buffer
ganlikun 0:13413ea9a877 433 * @param Size: Size of the Input buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 434 * @param outputaddr: Address of the Output buffer
ganlikun 0:13413ea9a877 435 * @retval None
ganlikun 0:13413ea9a877 436 */
ganlikun 0:13413ea9a877 437 static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
ganlikun 0:13413ea9a877 438 {
ganlikun 0:13413ea9a877 439 /* Set the CRYP DMA transfer complete callback */
ganlikun 0:13413ea9a877 440 hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt;
ganlikun 0:13413ea9a877 441 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 442 hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
ganlikun 0:13413ea9a877 443
ganlikun 0:13413ea9a877 444 /* Set the CRYP DMA transfer complete callback */
ganlikun 0:13413ea9a877 445 hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt;
ganlikun 0:13413ea9a877 446 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 447 hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError;
ganlikun 0:13413ea9a877 448
ganlikun 0:13413ea9a877 449 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 450 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 451
ganlikun 0:13413ea9a877 452 /* Enable the DMA In DMA Stream */
ganlikun 0:13413ea9a877 453 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4U);
ganlikun 0:13413ea9a877 454
ganlikun 0:13413ea9a877 455 /* Enable In DMA request */
ganlikun 0:13413ea9a877 456 hcryp->Instance->DMACR = CRYP_DMACR_DIEN;
ganlikun 0:13413ea9a877 457
ganlikun 0:13413ea9a877 458 /* Enable the DMA Out DMA Stream */
ganlikun 0:13413ea9a877 459 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4U);
ganlikun 0:13413ea9a877 460
ganlikun 0:13413ea9a877 461 /* Enable Out DMA request */
ganlikun 0:13413ea9a877 462 hcryp->Instance->DMACR |= CRYP_DMACR_DOEN;
ganlikun 0:13413ea9a877 463 }
ganlikun 0:13413ea9a877 464
ganlikun 0:13413ea9a877 465 /**
ganlikun 0:13413ea9a877 466 * @}
ganlikun 0:13413ea9a877 467 */
ganlikun 0:13413ea9a877 468
ganlikun 0:13413ea9a877 469 /* Exported functions---------------------------------------------------------*/
ganlikun 0:13413ea9a877 470 /** @addtogroup CRYPEx_Exported_Functions
ganlikun 0:13413ea9a877 471 * @{
ganlikun 0:13413ea9a877 472 */
ganlikun 0:13413ea9a877 473
ganlikun 0:13413ea9a877 474 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
ganlikun 0:13413ea9a877 475 * @brief Extended processing functions.
ganlikun 0:13413ea9a877 476 *
ganlikun 0:13413ea9a877 477 @verbatim
ganlikun 0:13413ea9a877 478 ==============================================================================
ganlikun 0:13413ea9a877 479 ##### Extended AES processing functions #####
ganlikun 0:13413ea9a877 480 ==============================================================================
ganlikun 0:13413ea9a877 481 [..] This section provides functions allowing to:
ganlikun 0:13413ea9a877 482 (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes
ganlikun 0:13413ea9a877 483 (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes
ganlikun 0:13413ea9a877 484 (+) Finish the processing. This function is available only for GCM and CCM
ganlikun 0:13413ea9a877 485 [..] Three processing methods are available:
ganlikun 0:13413ea9a877 486 (+) Polling mode
ganlikun 0:13413ea9a877 487 (+) Interrupt mode
ganlikun 0:13413ea9a877 488 (+) DMA mode
ganlikun 0:13413ea9a877 489
ganlikun 0:13413ea9a877 490 @endverbatim
ganlikun 0:13413ea9a877 491 * @{
ganlikun 0:13413ea9a877 492 */
ganlikun 0:13413ea9a877 493
ganlikun 0:13413ea9a877 494
ganlikun 0:13413ea9a877 495 /**
ganlikun 0:13413ea9a877 496 * @brief Initializes the CRYP peripheral in AES CCM encryption mode then
ganlikun 0:13413ea9a877 497 * encrypt pPlainData. The cypher data are available in pCypherData.
ganlikun 0:13413ea9a877 498 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 499 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 500 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 501 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 502 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 503 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 504 * @retval HAL status
ganlikun 0:13413ea9a877 505 */
ganlikun 0:13413ea9a877 506 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
ganlikun 0:13413ea9a877 507 {
ganlikun 0:13413ea9a877 508 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 509 uint32_t headersize = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 510 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 511 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 512 uint32_t bufferidx = 0U;
ganlikun 0:13413ea9a877 513 uint8_t blockb0[16U] = {0};/* Block B0 */
ganlikun 0:13413ea9a877 514 uint8_t ctr[16U] = {0}; /* Counter */
ganlikun 0:13413ea9a877 515 uint32_t b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 516
ganlikun 0:13413ea9a877 517 /* Process Locked */
ganlikun 0:13413ea9a877 518 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 519
ganlikun 0:13413ea9a877 520 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 521 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 522
ganlikun 0:13413ea9a877 523 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 524 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 525 {
ganlikun 0:13413ea9a877 526 /************************ Formatting the header block *********************/
ganlikun 0:13413ea9a877 527 if(headersize != 0U)
ganlikun 0:13413ea9a877 528 {
ganlikun 0:13413ea9a877 529 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
ganlikun 0:13413ea9a877 530 if(headersize < 65280U)
ganlikun 0:13413ea9a877 531 {
ganlikun 0:13413ea9a877 532 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
ganlikun 0:13413ea9a877 533 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
ganlikun 0:13413ea9a877 534 headersize += 2U;
ganlikun 0:13413ea9a877 535 }
ganlikun 0:13413ea9a877 536 else
ganlikun 0:13413ea9a877 537 {
ganlikun 0:13413ea9a877 538 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
ganlikun 0:13413ea9a877 539 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
ganlikun 0:13413ea9a877 540 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
ganlikun 0:13413ea9a877 541 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
ganlikun 0:13413ea9a877 542 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
ganlikun 0:13413ea9a877 543 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
ganlikun 0:13413ea9a877 544 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
ganlikun 0:13413ea9a877 545 headersize += 6U;
ganlikun 0:13413ea9a877 546 }
ganlikun 0:13413ea9a877 547 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
ganlikun 0:13413ea9a877 548 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
ganlikun 0:13413ea9a877 549 {
ganlikun 0:13413ea9a877 550 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
ganlikun 0:13413ea9a877 551 }
ganlikun 0:13413ea9a877 552 /* Check if the header size is modulo 16 */
ganlikun 0:13413ea9a877 553 if ((headersize % 16U) != 0U)
ganlikun 0:13413ea9a877 554 {
ganlikun 0:13413ea9a877 555 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
ganlikun 0:13413ea9a877 556 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
ganlikun 0:13413ea9a877 557 {
ganlikun 0:13413ea9a877 558 hcryp->Init.pScratch[loopcounter] = 0U;
ganlikun 0:13413ea9a877 559 }
ganlikun 0:13413ea9a877 560 /* Set the header size to modulo 16 */
ganlikun 0:13413ea9a877 561 headersize = ((headersize/16U) + 1U) * 16U;
ganlikun 0:13413ea9a877 562 }
ganlikun 0:13413ea9a877 563 /* Set the pointer headeraddr to hcryp->Init.pScratch */
ganlikun 0:13413ea9a877 564 headeraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 565 }
ganlikun 0:13413ea9a877 566 /*********************** Formatting the block B0 **************************/
ganlikun 0:13413ea9a877 567 if(headersize != 0U)
ganlikun 0:13413ea9a877 568 {
ganlikun 0:13413ea9a877 569 blockb0[0U] = 0x40U;
ganlikun 0:13413ea9a877 570 }
ganlikun 0:13413ea9a877 571 /* Flags byte */
ganlikun 0:13413ea9a877 572 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
ganlikun 0:13413ea9a877 573 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
ganlikun 0:13413ea9a877 574 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
ganlikun 0:13413ea9a877 575
ganlikun 0:13413ea9a877 576 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
ganlikun 0:13413ea9a877 577 {
ganlikun 0:13413ea9a877 578 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
ganlikun 0:13413ea9a877 579 }
ganlikun 0:13413ea9a877 580 for ( ; loopcounter < 13U; loopcounter++)
ganlikun 0:13413ea9a877 581 {
ganlikun 0:13413ea9a877 582 blockb0[loopcounter+1U] = 0U;
ganlikun 0:13413ea9a877 583 }
ganlikun 0:13413ea9a877 584
ganlikun 0:13413ea9a877 585 blockb0[14U] = (Size >> 8U);
ganlikun 0:13413ea9a877 586 blockb0[15U] = (Size & 0xFFU);
ganlikun 0:13413ea9a877 587
ganlikun 0:13413ea9a877 588 /************************* Formatting the initial counter *****************/
ganlikun 0:13413ea9a877 589 /* Byte 0:
ganlikun 0:13413ea9a877 590 Bits 7 and 6 are reserved and shall be set to 0
ganlikun 0:13413ea9a877 591 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks
ganlikun 0:13413ea9a877 592 are distinct from B0
ganlikun 0:13413ea9a877 593 Bits 0, 1, and 2 contain the same encoding of q as in B0
ganlikun 0:13413ea9a877 594 */
ganlikun 0:13413ea9a877 595 ctr[0U] = blockb0[0U] & 0x07U;
ganlikun 0:13413ea9a877 596 /* byte 1 to NonceSize is the IV (Nonce) */
ganlikun 0:13413ea9a877 597 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
ganlikun 0:13413ea9a877 598 {
ganlikun 0:13413ea9a877 599 ctr[loopcounter] = blockb0[loopcounter];
ganlikun 0:13413ea9a877 600 }
ganlikun 0:13413ea9a877 601 /* Set the LSB to 1 */
ganlikun 0:13413ea9a877 602 ctr[15U] |= 0x01U;
ganlikun 0:13413ea9a877 603
ganlikun 0:13413ea9a877 604 /* Set the key */
ganlikun 0:13413ea9a877 605 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 606
ganlikun 0:13413ea9a877 607 /* Set the CRYP peripheral in AES CCM mode */
ganlikun 0:13413ea9a877 608 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
ganlikun 0:13413ea9a877 609
ganlikun 0:13413ea9a877 610 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 611 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
ganlikun 0:13413ea9a877 612
ganlikun 0:13413ea9a877 613 /* Select init phase */
ganlikun 0:13413ea9a877 614 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
ganlikun 0:13413ea9a877 615
ganlikun 0:13413ea9a877 616 b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 617 /* Write the blockb0 block in the IN FIFO */
ganlikun 0:13413ea9a877 618 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 619 b0addr+=4U;
ganlikun 0:13413ea9a877 620 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 621 b0addr+=4U;
ganlikun 0:13413ea9a877 622 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 623 b0addr+=4U;
ganlikun 0:13413ea9a877 624 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 625
ganlikun 0:13413ea9a877 626 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 627 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 628
ganlikun 0:13413ea9a877 629 /* Get tick */
ganlikun 0:13413ea9a877 630 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 631
ganlikun 0:13413ea9a877 632 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 633 {
ganlikun 0:13413ea9a877 634 /* Check for the Timeout */
ganlikun 0:13413ea9a877 635 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 636 {
ganlikun 0:13413ea9a877 637 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 638 {
ganlikun 0:13413ea9a877 639 /* Change state */
ganlikun 0:13413ea9a877 640 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 641
ganlikun 0:13413ea9a877 642 /* Process Unlocked */
ganlikun 0:13413ea9a877 643 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 644
ganlikun 0:13413ea9a877 645 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 646 }
ganlikun 0:13413ea9a877 647 }
ganlikun 0:13413ea9a877 648 }
ganlikun 0:13413ea9a877 649 /***************************** Header phase *******************************/
ganlikun 0:13413ea9a877 650 if(headersize != 0U)
ganlikun 0:13413ea9a877 651 {
ganlikun 0:13413ea9a877 652 /* Select header phase */
ganlikun 0:13413ea9a877 653 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 654
ganlikun 0:13413ea9a877 655 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 656 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 657
ganlikun 0:13413ea9a877 658 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
ganlikun 0:13413ea9a877 659 {
ganlikun 0:13413ea9a877 660 /* Get tick */
ganlikun 0:13413ea9a877 661 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 662
ganlikun 0:13413ea9a877 663 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 664 {
ganlikun 0:13413ea9a877 665 {
ganlikun 0:13413ea9a877 666 /* Check for the Timeout */
ganlikun 0:13413ea9a877 667 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 668 {
ganlikun 0:13413ea9a877 669 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 670 {
ganlikun 0:13413ea9a877 671 /* Change state */
ganlikun 0:13413ea9a877 672 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 673
ganlikun 0:13413ea9a877 674 /* Process Unlocked */
ganlikun 0:13413ea9a877 675 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 676
ganlikun 0:13413ea9a877 677 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 678 }
ganlikun 0:13413ea9a877 679 }
ganlikun 0:13413ea9a877 680 }
ganlikun 0:13413ea9a877 681 }
ganlikun 0:13413ea9a877 682 /* Write the header block in the IN FIFO */
ganlikun 0:13413ea9a877 683 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 684 headeraddr+=4U;
ganlikun 0:13413ea9a877 685 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 686 headeraddr+=4U;
ganlikun 0:13413ea9a877 687 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 688 headeraddr+=4U;
ganlikun 0:13413ea9a877 689 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 690 headeraddr+=4U;
ganlikun 0:13413ea9a877 691 }
ganlikun 0:13413ea9a877 692
ganlikun 0:13413ea9a877 693 /* Get tick */
ganlikun 0:13413ea9a877 694 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 695
ganlikun 0:13413ea9a877 696 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 697 {
ganlikun 0:13413ea9a877 698 /* Check for the Timeout */
ganlikun 0:13413ea9a877 699 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 700 {
ganlikun 0:13413ea9a877 701 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 702 {
ganlikun 0:13413ea9a877 703 /* Change state */
ganlikun 0:13413ea9a877 704 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 705
ganlikun 0:13413ea9a877 706 /* Process Unlocked */
ganlikun 0:13413ea9a877 707 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 708
ganlikun 0:13413ea9a877 709 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 710 }
ganlikun 0:13413ea9a877 711 }
ganlikun 0:13413ea9a877 712 }
ganlikun 0:13413ea9a877 713 }
ganlikun 0:13413ea9a877 714 /* Save formatted counter into the scratch buffer pScratch */
ganlikun 0:13413ea9a877 715 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
ganlikun 0:13413ea9a877 716 {
ganlikun 0:13413ea9a877 717 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
ganlikun 0:13413ea9a877 718 }
ganlikun 0:13413ea9a877 719 /* Reset bit 0 */
ganlikun 0:13413ea9a877 720 hcryp->Init.pScratch[15U] &= 0xFEU;
ganlikun 0:13413ea9a877 721
ganlikun 0:13413ea9a877 722 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 723 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 724
ganlikun 0:13413ea9a877 725 /* Flush FIFO */
ganlikun 0:13413ea9a877 726 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 727
ganlikun 0:13413ea9a877 728 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 729 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 730
ganlikun 0:13413ea9a877 731 /* Set the phase */
ganlikun 0:13413ea9a877 732 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 733 }
ganlikun 0:13413ea9a877 734
ganlikun 0:13413ea9a877 735 /* Write Plain Data and Get Cypher Data */
ganlikun 0:13413ea9a877 736 if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 737 {
ganlikun 0:13413ea9a877 738 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 739 }
ganlikun 0:13413ea9a877 740
ganlikun 0:13413ea9a877 741 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 742 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 743
ganlikun 0:13413ea9a877 744 /* Process Unlocked */
ganlikun 0:13413ea9a877 745 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 746
ganlikun 0:13413ea9a877 747 /* Return function status */
ganlikun 0:13413ea9a877 748 return HAL_OK;
ganlikun 0:13413ea9a877 749 }
ganlikun 0:13413ea9a877 750
ganlikun 0:13413ea9a877 751 /**
ganlikun 0:13413ea9a877 752 * @brief Initializes the CRYP peripheral in AES GCM encryption mode then
ganlikun 0:13413ea9a877 753 * encrypt pPlainData. The cypher data are available in pCypherData.
ganlikun 0:13413ea9a877 754 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 755 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 756 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 757 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 758 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 759 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 760 * @retval HAL status
ganlikun 0:13413ea9a877 761 */
ganlikun 0:13413ea9a877 762 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout)
ganlikun 0:13413ea9a877 763 {
ganlikun 0:13413ea9a877 764 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 765
ganlikun 0:13413ea9a877 766 /* Process Locked */
ganlikun 0:13413ea9a877 767 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 768
ganlikun 0:13413ea9a877 769 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 770 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 771
ganlikun 0:13413ea9a877 772 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 773 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 774 {
ganlikun 0:13413ea9a877 775 /* Set the key */
ganlikun 0:13413ea9a877 776 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 777
ganlikun 0:13413ea9a877 778 /* Set the CRYP peripheral in AES GCM mode */
ganlikun 0:13413ea9a877 779 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
ganlikun 0:13413ea9a877 780
ganlikun 0:13413ea9a877 781 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 782 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
ganlikun 0:13413ea9a877 783
ganlikun 0:13413ea9a877 784 /* Flush FIFO */
ganlikun 0:13413ea9a877 785 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 786
ganlikun 0:13413ea9a877 787 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 788 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 789
ganlikun 0:13413ea9a877 790 /* Get tick */
ganlikun 0:13413ea9a877 791 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 792
ganlikun 0:13413ea9a877 793 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 794 {
ganlikun 0:13413ea9a877 795 /* Check for the Timeout */
ganlikun 0:13413ea9a877 796 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 797 {
ganlikun 0:13413ea9a877 798 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 799 {
ganlikun 0:13413ea9a877 800 /* Change state */
ganlikun 0:13413ea9a877 801 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 802
ganlikun 0:13413ea9a877 803 /* Process Unlocked */
ganlikun 0:13413ea9a877 804 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 805
ganlikun 0:13413ea9a877 806 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 807 }
ganlikun 0:13413ea9a877 808 }
ganlikun 0:13413ea9a877 809 }
ganlikun 0:13413ea9a877 810
ganlikun 0:13413ea9a877 811 /* Set the header phase */
ganlikun 0:13413ea9a877 812 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 813 {
ganlikun 0:13413ea9a877 814 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 815 }
ganlikun 0:13413ea9a877 816
ganlikun 0:13413ea9a877 817 /* Disable the CRYP peripheral */
ganlikun 0:13413ea9a877 818 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 819
ganlikun 0:13413ea9a877 820 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 821 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 822
ganlikun 0:13413ea9a877 823 /* Flush FIFO */
ganlikun 0:13413ea9a877 824 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 825
ganlikun 0:13413ea9a877 826 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 827 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 828
ganlikun 0:13413ea9a877 829 /* Set the phase */
ganlikun 0:13413ea9a877 830 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 831 }
ganlikun 0:13413ea9a877 832
ganlikun 0:13413ea9a877 833 /* Write Plain Data and Get Cypher Data */
ganlikun 0:13413ea9a877 834 if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 835 {
ganlikun 0:13413ea9a877 836 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 837 }
ganlikun 0:13413ea9a877 838
ganlikun 0:13413ea9a877 839 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 840 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 841
ganlikun 0:13413ea9a877 842 /* Process Unlocked */
ganlikun 0:13413ea9a877 843 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 844
ganlikun 0:13413ea9a877 845 /* Return function status */
ganlikun 0:13413ea9a877 846 return HAL_OK;
ganlikun 0:13413ea9a877 847 }
ganlikun 0:13413ea9a877 848
ganlikun 0:13413ea9a877 849 /**
ganlikun 0:13413ea9a877 850 * @brief Initializes the CRYP peripheral in AES GCM decryption mode then
ganlikun 0:13413ea9a877 851 * decrypted pCypherData. The cypher data are available in pPlainData.
ganlikun 0:13413ea9a877 852 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 853 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 854 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 855 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 856 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 857 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 858 * @retval HAL status
ganlikun 0:13413ea9a877 859 */
ganlikun 0:13413ea9a877 860 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
ganlikun 0:13413ea9a877 861 {
ganlikun 0:13413ea9a877 862 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 863
ganlikun 0:13413ea9a877 864 /* Process Locked */
ganlikun 0:13413ea9a877 865 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 866
ganlikun 0:13413ea9a877 867 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 868 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 869
ganlikun 0:13413ea9a877 870 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 871 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 872 {
ganlikun 0:13413ea9a877 873 /* Set the key */
ganlikun 0:13413ea9a877 874 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 875
ganlikun 0:13413ea9a877 876 /* Set the CRYP peripheral in AES GCM decryption mode */
ganlikun 0:13413ea9a877 877 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
ganlikun 0:13413ea9a877 878
ganlikun 0:13413ea9a877 879 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 880 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
ganlikun 0:13413ea9a877 881
ganlikun 0:13413ea9a877 882 /* Flush FIFO */
ganlikun 0:13413ea9a877 883 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 884
ganlikun 0:13413ea9a877 885 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 886 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 887
ganlikun 0:13413ea9a877 888 /* Get tick */
ganlikun 0:13413ea9a877 889 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 890
ganlikun 0:13413ea9a877 891 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 892 {
ganlikun 0:13413ea9a877 893 /* Check for the Timeout */
ganlikun 0:13413ea9a877 894 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 895 {
ganlikun 0:13413ea9a877 896 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 897 {
ganlikun 0:13413ea9a877 898 /* Change state */
ganlikun 0:13413ea9a877 899 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 900
ganlikun 0:13413ea9a877 901 /* Process Unlocked */
ganlikun 0:13413ea9a877 902 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 903
ganlikun 0:13413ea9a877 904 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 905 }
ganlikun 0:13413ea9a877 906 }
ganlikun 0:13413ea9a877 907 }
ganlikun 0:13413ea9a877 908
ganlikun 0:13413ea9a877 909 /* Set the header phase */
ganlikun 0:13413ea9a877 910 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 911 {
ganlikun 0:13413ea9a877 912 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 913 }
ganlikun 0:13413ea9a877 914 /* Disable the CRYP peripheral */
ganlikun 0:13413ea9a877 915 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 916
ganlikun 0:13413ea9a877 917 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 918 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 919
ganlikun 0:13413ea9a877 920 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 921 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 922
ganlikun 0:13413ea9a877 923 /* Set the phase */
ganlikun 0:13413ea9a877 924 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 925 }
ganlikun 0:13413ea9a877 926
ganlikun 0:13413ea9a877 927 /* Write Plain Data and Get Cypher Data */
ganlikun 0:13413ea9a877 928 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 929 {
ganlikun 0:13413ea9a877 930 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 931 }
ganlikun 0:13413ea9a877 932
ganlikun 0:13413ea9a877 933 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 934 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 935
ganlikun 0:13413ea9a877 936 /* Process Unlocked */
ganlikun 0:13413ea9a877 937 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 938
ganlikun 0:13413ea9a877 939 /* Return function status */
ganlikun 0:13413ea9a877 940 return HAL_OK;
ganlikun 0:13413ea9a877 941 }
ganlikun 0:13413ea9a877 942
ganlikun 0:13413ea9a877 943 /**
ganlikun 0:13413ea9a877 944 * @brief Computes the authentication TAG.
ganlikun 0:13413ea9a877 945 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 946 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 947 * @param Size: Total length of the plain/cyphertext buffer
ganlikun 0:13413ea9a877 948 * @param AuthTag: Pointer to the authentication buffer
ganlikun 0:13413ea9a877 949 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 950 * @retval HAL status
ganlikun 0:13413ea9a877 951 */
ganlikun 0:13413ea9a877 952 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout)
ganlikun 0:13413ea9a877 953 {
ganlikun 0:13413ea9a877 954 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 955 uint64_t headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
ganlikun 0:13413ea9a877 956 uint64_t inputlength = Size * 8U; /* input length in bits */
ganlikun 0:13413ea9a877 957 uint32_t tagaddr = (uint32_t)AuthTag;
ganlikun 0:13413ea9a877 958
ganlikun 0:13413ea9a877 959 /* Process Locked */
ganlikun 0:13413ea9a877 960 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 961
ganlikun 0:13413ea9a877 962 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 963 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 964
ganlikun 0:13413ea9a877 965 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 966 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
ganlikun 0:13413ea9a877 967 {
ganlikun 0:13413ea9a877 968 /* Change the CRYP phase */
ganlikun 0:13413ea9a877 969 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
ganlikun 0:13413ea9a877 970
ganlikun 0:13413ea9a877 971 /* Disable CRYP to start the final phase */
ganlikun 0:13413ea9a877 972 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 973
ganlikun 0:13413ea9a877 974 /* Select final phase */
ganlikun 0:13413ea9a877 975 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
ganlikun 0:13413ea9a877 976
ganlikun 0:13413ea9a877 977 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 978 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 979
ganlikun 0:13413ea9a877 980 /* Write the number of bits in header (64 bits) followed by the number of bits
ganlikun 0:13413ea9a877 981 in the payload */
ganlikun 0:13413ea9a877 982 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
ganlikun 0:13413ea9a877 983 {
ganlikun 0:13413ea9a877 984 hcryp->Instance->DR = __RBIT(headerlength >> 32U);
ganlikun 0:13413ea9a877 985 hcryp->Instance->DR = __RBIT(headerlength);
ganlikun 0:13413ea9a877 986 hcryp->Instance->DR = __RBIT(inputlength >> 32U);
ganlikun 0:13413ea9a877 987 hcryp->Instance->DR = __RBIT(inputlength);
ganlikun 0:13413ea9a877 988 }
ganlikun 0:13413ea9a877 989 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
ganlikun 0:13413ea9a877 990 {
ganlikun 0:13413ea9a877 991 hcryp->Instance->DR = __REV(headerlength >> 32U);
ganlikun 0:13413ea9a877 992 hcryp->Instance->DR = __REV(headerlength);
ganlikun 0:13413ea9a877 993 hcryp->Instance->DR = __REV(inputlength >> 32U);
ganlikun 0:13413ea9a877 994 hcryp->Instance->DR = __REV(inputlength);
ganlikun 0:13413ea9a877 995 }
ganlikun 0:13413ea9a877 996 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
ganlikun 0:13413ea9a877 997 {
ganlikun 0:13413ea9a877 998 hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32U), 16U);
ganlikun 0:13413ea9a877 999 hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16U);
ganlikun 0:13413ea9a877 1000 hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32U), 16U);
ganlikun 0:13413ea9a877 1001 hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16U);
ganlikun 0:13413ea9a877 1002 }
ganlikun 0:13413ea9a877 1003 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
ganlikun 0:13413ea9a877 1004 {
ganlikun 0:13413ea9a877 1005 hcryp->Instance->DR = (uint32_t)(headerlength >> 32U);
ganlikun 0:13413ea9a877 1006 hcryp->Instance->DR = (uint32_t)(headerlength);
ganlikun 0:13413ea9a877 1007 hcryp->Instance->DR = (uint32_t)(inputlength >> 32U);
ganlikun 0:13413ea9a877 1008 hcryp->Instance->DR = (uint32_t)(inputlength);
ganlikun 0:13413ea9a877 1009 }
ganlikun 0:13413ea9a877 1010 /* Get tick */
ganlikun 0:13413ea9a877 1011 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1012
ganlikun 0:13413ea9a877 1013 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
ganlikun 0:13413ea9a877 1014 {
ganlikun 0:13413ea9a877 1015 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1016 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 1017 {
ganlikun 0:13413ea9a877 1018 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 1019 {
ganlikun 0:13413ea9a877 1020 /* Change state */
ganlikun 0:13413ea9a877 1021 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1022
ganlikun 0:13413ea9a877 1023 /* Process Unlocked */
ganlikun 0:13413ea9a877 1024 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1025
ganlikun 0:13413ea9a877 1026 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1027 }
ganlikun 0:13413ea9a877 1028 }
ganlikun 0:13413ea9a877 1029 }
ganlikun 0:13413ea9a877 1030
ganlikun 0:13413ea9a877 1031 /* Read the Auth TAG in the IN FIFO */
ganlikun 0:13413ea9a877 1032 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1033 tagaddr+=4U;
ganlikun 0:13413ea9a877 1034 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1035 tagaddr+=4U;
ganlikun 0:13413ea9a877 1036 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1037 tagaddr+=4U;
ganlikun 0:13413ea9a877 1038 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1039 }
ganlikun 0:13413ea9a877 1040
ganlikun 0:13413ea9a877 1041 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1042 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1043
ganlikun 0:13413ea9a877 1044 /* Process Unlocked */
ganlikun 0:13413ea9a877 1045 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1046
ganlikun 0:13413ea9a877 1047 /* Return function status */
ganlikun 0:13413ea9a877 1048 return HAL_OK;
ganlikun 0:13413ea9a877 1049 }
ganlikun 0:13413ea9a877 1050
ganlikun 0:13413ea9a877 1051 /**
ganlikun 0:13413ea9a877 1052 * @brief Computes the authentication TAG for AES CCM mode.
ganlikun 0:13413ea9a877 1053 * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt()
ganlikun 0:13413ea9a877 1054 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1055 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 1056 * @param AuthTag: Pointer to the authentication buffer
ganlikun 0:13413ea9a877 1057 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 1058 * @retval HAL status
ganlikun 0:13413ea9a877 1059 */
ganlikun 0:13413ea9a877 1060 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout)
ganlikun 0:13413ea9a877 1061 {
ganlikun 0:13413ea9a877 1062 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 1063 uint32_t tagaddr = (uint32_t)AuthTag;
ganlikun 0:13413ea9a877 1064 uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 1065 uint32_t temptag[4U] = {0U}; /* Temporary TAG (MAC) */
ganlikun 0:13413ea9a877 1066 uint32_t loopcounter;
ganlikun 0:13413ea9a877 1067
ganlikun 0:13413ea9a877 1068 /* Process Locked */
ganlikun 0:13413ea9a877 1069 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 1070
ganlikun 0:13413ea9a877 1071 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1072 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 1073
ganlikun 0:13413ea9a877 1074 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 1075 if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS)
ganlikun 0:13413ea9a877 1076 {
ganlikun 0:13413ea9a877 1077 /* Change the CRYP phase */
ganlikun 0:13413ea9a877 1078 hcryp->Phase = HAL_CRYP_PHASE_FINAL;
ganlikun 0:13413ea9a877 1079
ganlikun 0:13413ea9a877 1080 /* Disable CRYP to start the final phase */
ganlikun 0:13413ea9a877 1081 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 1082
ganlikun 0:13413ea9a877 1083 /* Select final phase */
ganlikun 0:13413ea9a877 1084 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL);
ganlikun 0:13413ea9a877 1085
ganlikun 0:13413ea9a877 1086 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1087 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1088
ganlikun 0:13413ea9a877 1089 /* Write the counter block in the IN FIFO */
ganlikun 0:13413ea9a877 1090 hcryp->Instance->DR = *(uint32_t*)ctraddr;
ganlikun 0:13413ea9a877 1091 ctraddr+=4U;
ganlikun 0:13413ea9a877 1092 hcryp->Instance->DR = *(uint32_t*)ctraddr;
ganlikun 0:13413ea9a877 1093 ctraddr+=4U;
ganlikun 0:13413ea9a877 1094 hcryp->Instance->DR = *(uint32_t*)ctraddr;
ganlikun 0:13413ea9a877 1095 ctraddr+=4U;
ganlikun 0:13413ea9a877 1096 hcryp->Instance->DR = *(uint32_t*)ctraddr;
ganlikun 0:13413ea9a877 1097
ganlikun 0:13413ea9a877 1098 /* Get tick */
ganlikun 0:13413ea9a877 1099 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1100
ganlikun 0:13413ea9a877 1101 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
ganlikun 0:13413ea9a877 1102 {
ganlikun 0:13413ea9a877 1103 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1104 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 1105 {
ganlikun 0:13413ea9a877 1106 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 1107 {
ganlikun 0:13413ea9a877 1108 /* Change state */
ganlikun 0:13413ea9a877 1109 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1110
ganlikun 0:13413ea9a877 1111 /* Process Unlocked */
ganlikun 0:13413ea9a877 1112 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1113
ganlikun 0:13413ea9a877 1114 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1115 }
ganlikun 0:13413ea9a877 1116 }
ganlikun 0:13413ea9a877 1117 }
ganlikun 0:13413ea9a877 1118
ganlikun 0:13413ea9a877 1119 /* Read the Auth TAG in the IN FIFO */
ganlikun 0:13413ea9a877 1120 temptag[0U] = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1121 temptag[1U] = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1122 temptag[2U] = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1123 temptag[3U] = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1124 }
ganlikun 0:13413ea9a877 1125
ganlikun 0:13413ea9a877 1126 /* Copy temporary authentication TAG in user TAG buffer */
ganlikun 0:13413ea9a877 1127 for(loopcounter = 0U; loopcounter < hcryp->Init.TagSize ; loopcounter++)
ganlikun 0:13413ea9a877 1128 {
ganlikun 0:13413ea9a877 1129 /* Set the authentication TAG buffer */
ganlikun 0:13413ea9a877 1130 *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter);
ganlikun 0:13413ea9a877 1131 }
ganlikun 0:13413ea9a877 1132
ganlikun 0:13413ea9a877 1133 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1134 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1135
ganlikun 0:13413ea9a877 1136 /* Process Unlocked */
ganlikun 0:13413ea9a877 1137 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1138
ganlikun 0:13413ea9a877 1139 /* Return function status */
ganlikun 0:13413ea9a877 1140 return HAL_OK;
ganlikun 0:13413ea9a877 1141 }
ganlikun 0:13413ea9a877 1142
ganlikun 0:13413ea9a877 1143 /**
ganlikun 0:13413ea9a877 1144 * @brief Initializes the CRYP peripheral in AES CCM decryption mode then
ganlikun 0:13413ea9a877 1145 * decrypted pCypherData. The cypher data are available in pPlainData.
ganlikun 0:13413ea9a877 1146 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1147 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 1148 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 1149 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 1150 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 1151 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 1152 * @retval HAL status
ganlikun 0:13413ea9a877 1153 */
ganlikun 0:13413ea9a877 1154 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout)
ganlikun 0:13413ea9a877 1155 {
ganlikun 0:13413ea9a877 1156 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 1157 uint32_t headersize = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 1158 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 1159 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 1160 uint32_t bufferidx = 0U;
ganlikun 0:13413ea9a877 1161 uint8_t blockb0[16U] = {0};/* Block B0 */
ganlikun 0:13413ea9a877 1162 uint8_t ctr[16U] = {0}; /* Counter */
ganlikun 0:13413ea9a877 1163 uint32_t b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 1164
ganlikun 0:13413ea9a877 1165 /* Process Locked */
ganlikun 0:13413ea9a877 1166 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 1167
ganlikun 0:13413ea9a877 1168 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1169 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 1170
ganlikun 0:13413ea9a877 1171 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 1172 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 1173 {
ganlikun 0:13413ea9a877 1174 /************************ Formatting the header block *********************/
ganlikun 0:13413ea9a877 1175 if(headersize != 0U)
ganlikun 0:13413ea9a877 1176 {
ganlikun 0:13413ea9a877 1177 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
ganlikun 0:13413ea9a877 1178 if(headersize < 65280U)
ganlikun 0:13413ea9a877 1179 {
ganlikun 0:13413ea9a877 1180 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
ganlikun 0:13413ea9a877 1181 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
ganlikun 0:13413ea9a877 1182 headersize += 2U;
ganlikun 0:13413ea9a877 1183 }
ganlikun 0:13413ea9a877 1184 else
ganlikun 0:13413ea9a877 1185 {
ganlikun 0:13413ea9a877 1186 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
ganlikun 0:13413ea9a877 1187 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
ganlikun 0:13413ea9a877 1188 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
ganlikun 0:13413ea9a877 1189 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
ganlikun 0:13413ea9a877 1190 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
ganlikun 0:13413ea9a877 1191 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
ganlikun 0:13413ea9a877 1192 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
ganlikun 0:13413ea9a877 1193 headersize += 6U;
ganlikun 0:13413ea9a877 1194 }
ganlikun 0:13413ea9a877 1195 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
ganlikun 0:13413ea9a877 1196 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
ganlikun 0:13413ea9a877 1197 {
ganlikun 0:13413ea9a877 1198 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
ganlikun 0:13413ea9a877 1199 }
ganlikun 0:13413ea9a877 1200 /* Check if the header size is modulo 16 */
ganlikun 0:13413ea9a877 1201 if ((headersize % 16U) != 0U)
ganlikun 0:13413ea9a877 1202 {
ganlikun 0:13413ea9a877 1203 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
ganlikun 0:13413ea9a877 1204 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
ganlikun 0:13413ea9a877 1205 {
ganlikun 0:13413ea9a877 1206 hcryp->Init.pScratch[loopcounter] = 0U;
ganlikun 0:13413ea9a877 1207 }
ganlikun 0:13413ea9a877 1208 /* Set the header size to modulo 16 */
ganlikun 0:13413ea9a877 1209 headersize = ((headersize/16U) + 1U) * 16U;
ganlikun 0:13413ea9a877 1210 }
ganlikun 0:13413ea9a877 1211 /* Set the pointer headeraddr to hcryp->Init.pScratch */
ganlikun 0:13413ea9a877 1212 headeraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 1213 }
ganlikun 0:13413ea9a877 1214 /*********************** Formatting the block B0 **************************/
ganlikun 0:13413ea9a877 1215 if(headersize != 0U)
ganlikun 0:13413ea9a877 1216 {
ganlikun 0:13413ea9a877 1217 blockb0[0U] = 0x40U;
ganlikun 0:13413ea9a877 1218 }
ganlikun 0:13413ea9a877 1219 /* Flags byte */
ganlikun 0:13413ea9a877 1220 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
ganlikun 0:13413ea9a877 1221 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2U))) >> 1U) & (uint8_t)0x07U) << 3U);
ganlikun 0:13413ea9a877 1222 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15U) - hcryp->Init.IVSize) - (uint8_t)1U) & (uint8_t)0x07U);
ganlikun 0:13413ea9a877 1223
ganlikun 0:13413ea9a877 1224 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
ganlikun 0:13413ea9a877 1225 {
ganlikun 0:13413ea9a877 1226 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
ganlikun 0:13413ea9a877 1227 }
ganlikun 0:13413ea9a877 1228 for ( ; loopcounter < 13U; loopcounter++)
ganlikun 0:13413ea9a877 1229 {
ganlikun 0:13413ea9a877 1230 blockb0[loopcounter+1U] = 0U;
ganlikun 0:13413ea9a877 1231 }
ganlikun 0:13413ea9a877 1232
ganlikun 0:13413ea9a877 1233 blockb0[14U] = (Size >> 8U);
ganlikun 0:13413ea9a877 1234 blockb0[15U] = (Size & 0xFFU);
ganlikun 0:13413ea9a877 1235
ganlikun 0:13413ea9a877 1236 /************************* Formatting the initial counter *****************/
ganlikun 0:13413ea9a877 1237 /* Byte 0:
ganlikun 0:13413ea9a877 1238 Bits 7 and 6 are reserved and shall be set to 0
ganlikun 0:13413ea9a877 1239 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
ganlikun 0:13413ea9a877 1240 blocks are distinct from B0
ganlikun 0:13413ea9a877 1241 Bits 0, 1, and 2 contain the same encoding of q as in B0
ganlikun 0:13413ea9a877 1242 */
ganlikun 0:13413ea9a877 1243 ctr[0U] = blockb0[0U] & 0x07U;
ganlikun 0:13413ea9a877 1244 /* byte 1 to NonceSize is the IV (Nonce) */
ganlikun 0:13413ea9a877 1245 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
ganlikun 0:13413ea9a877 1246 {
ganlikun 0:13413ea9a877 1247 ctr[loopcounter] = blockb0[loopcounter];
ganlikun 0:13413ea9a877 1248 }
ganlikun 0:13413ea9a877 1249 /* Set the LSB to 1 */
ganlikun 0:13413ea9a877 1250 ctr[15U] |= 0x01U;
ganlikun 0:13413ea9a877 1251
ganlikun 0:13413ea9a877 1252 /* Set the key */
ganlikun 0:13413ea9a877 1253 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 1254
ganlikun 0:13413ea9a877 1255 /* Set the CRYP peripheral in AES CCM mode */
ganlikun 0:13413ea9a877 1256 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
ganlikun 0:13413ea9a877 1257
ganlikun 0:13413ea9a877 1258 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 1259 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
ganlikun 0:13413ea9a877 1260
ganlikun 0:13413ea9a877 1261 /* Select init phase */
ganlikun 0:13413ea9a877 1262 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
ganlikun 0:13413ea9a877 1263
ganlikun 0:13413ea9a877 1264 b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 1265 /* Write the blockb0 block in the IN FIFO */
ganlikun 0:13413ea9a877 1266 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1267 b0addr+=4U;
ganlikun 0:13413ea9a877 1268 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1269 b0addr+=4U;
ganlikun 0:13413ea9a877 1270 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1271 b0addr+=4U;
ganlikun 0:13413ea9a877 1272 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1273
ganlikun 0:13413ea9a877 1274 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1275 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1276
ganlikun 0:13413ea9a877 1277 /* Get tick */
ganlikun 0:13413ea9a877 1278 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1279
ganlikun 0:13413ea9a877 1280 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 1281 {
ganlikun 0:13413ea9a877 1282 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1283 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 1284 {
ganlikun 0:13413ea9a877 1285 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 1286 {
ganlikun 0:13413ea9a877 1287 /* Change state */
ganlikun 0:13413ea9a877 1288 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1289
ganlikun 0:13413ea9a877 1290 /* Process Unlocked */
ganlikun 0:13413ea9a877 1291 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1292
ganlikun 0:13413ea9a877 1293 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1294 }
ganlikun 0:13413ea9a877 1295 }
ganlikun 0:13413ea9a877 1296 }
ganlikun 0:13413ea9a877 1297 /***************************** Header phase *******************************/
ganlikun 0:13413ea9a877 1298 if(headersize != 0U)
ganlikun 0:13413ea9a877 1299 {
ganlikun 0:13413ea9a877 1300 /* Select header phase */
ganlikun 0:13413ea9a877 1301 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 1302
ganlikun 0:13413ea9a877 1303 /* Enable Crypto processor */
ganlikun 0:13413ea9a877 1304 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1305
ganlikun 0:13413ea9a877 1306 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
ganlikun 0:13413ea9a877 1307 {
ganlikun 0:13413ea9a877 1308 /* Get tick */
ganlikun 0:13413ea9a877 1309 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1310
ganlikun 0:13413ea9a877 1311 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 1312 {
ganlikun 0:13413ea9a877 1313 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1314 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 1315 {
ganlikun 0:13413ea9a877 1316 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 1317 {
ganlikun 0:13413ea9a877 1318 /* Change state */
ganlikun 0:13413ea9a877 1319 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1320
ganlikun 0:13413ea9a877 1321 /* Process Unlocked */
ganlikun 0:13413ea9a877 1322 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1323
ganlikun 0:13413ea9a877 1324 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1325 }
ganlikun 0:13413ea9a877 1326 }
ganlikun 0:13413ea9a877 1327 }
ganlikun 0:13413ea9a877 1328 /* Write the header block in the IN FIFO */
ganlikun 0:13413ea9a877 1329 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1330 headeraddr+=4U;
ganlikun 0:13413ea9a877 1331 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1332 headeraddr+=4U;
ganlikun 0:13413ea9a877 1333 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1334 headeraddr+=4U;
ganlikun 0:13413ea9a877 1335 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1336 headeraddr+=4U;
ganlikun 0:13413ea9a877 1337 }
ganlikun 0:13413ea9a877 1338
ganlikun 0:13413ea9a877 1339 /* Get tick */
ganlikun 0:13413ea9a877 1340 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1341
ganlikun 0:13413ea9a877 1342 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 1343 {
ganlikun 0:13413ea9a877 1344 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1345 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 1346 {
ganlikun 0:13413ea9a877 1347 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
ganlikun 0:13413ea9a877 1348 {
ganlikun 0:13413ea9a877 1349 /* Change state */
ganlikun 0:13413ea9a877 1350 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1351
ganlikun 0:13413ea9a877 1352 /* Process Unlocked */
ganlikun 0:13413ea9a877 1353 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1354
ganlikun 0:13413ea9a877 1355 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1356 }
ganlikun 0:13413ea9a877 1357 }
ganlikun 0:13413ea9a877 1358 }
ganlikun 0:13413ea9a877 1359 }
ganlikun 0:13413ea9a877 1360 /* Save formatted counter into the scratch buffer pScratch */
ganlikun 0:13413ea9a877 1361 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
ganlikun 0:13413ea9a877 1362 {
ganlikun 0:13413ea9a877 1363 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
ganlikun 0:13413ea9a877 1364 }
ganlikun 0:13413ea9a877 1365 /* Reset bit 0 */
ganlikun 0:13413ea9a877 1366 hcryp->Init.pScratch[15U] &= 0xFEU;
ganlikun 0:13413ea9a877 1367 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 1368 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 1369
ganlikun 0:13413ea9a877 1370 /* Flush FIFO */
ganlikun 0:13413ea9a877 1371 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 1372
ganlikun 0:13413ea9a877 1373 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1374 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1375
ganlikun 0:13413ea9a877 1376 /* Set the phase */
ganlikun 0:13413ea9a877 1377 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 1378 }
ganlikun 0:13413ea9a877 1379
ganlikun 0:13413ea9a877 1380 /* Write Plain Data and Get Cypher Data */
ganlikun 0:13413ea9a877 1381 if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 1382 {
ganlikun 0:13413ea9a877 1383 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1384 }
ganlikun 0:13413ea9a877 1385
ganlikun 0:13413ea9a877 1386 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1387 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1388
ganlikun 0:13413ea9a877 1389 /* Process Unlocked */
ganlikun 0:13413ea9a877 1390 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1391
ganlikun 0:13413ea9a877 1392 /* Return function status */
ganlikun 0:13413ea9a877 1393 return HAL_OK;
ganlikun 0:13413ea9a877 1394 }
ganlikun 0:13413ea9a877 1395
ganlikun 0:13413ea9a877 1396 /**
ganlikun 0:13413ea9a877 1397 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT.
ganlikun 0:13413ea9a877 1398 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1399 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 1400 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 1401 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 1402 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 1403 * @retval HAL status
ganlikun 0:13413ea9a877 1404 */
ganlikun 0:13413ea9a877 1405 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
ganlikun 0:13413ea9a877 1406 {
ganlikun 0:13413ea9a877 1407 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 1408 uint32_t inputaddr;
ganlikun 0:13413ea9a877 1409 uint32_t outputaddr;
ganlikun 0:13413ea9a877 1410
ganlikun 0:13413ea9a877 1411 if(hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 1412 {
ganlikun 0:13413ea9a877 1413 /* Process Locked */
ganlikun 0:13413ea9a877 1414 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 1415
ganlikun 0:13413ea9a877 1416 /* Get the buffer addresses and sizes */
ganlikun 0:13413ea9a877 1417 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 1418 hcryp->pCrypInBuffPtr = pPlainData;
ganlikun 0:13413ea9a877 1419 hcryp->pCrypOutBuffPtr = pCypherData;
ganlikun 0:13413ea9a877 1420 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 1421
ganlikun 0:13413ea9a877 1422 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1423 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 1424
ganlikun 0:13413ea9a877 1425 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 1426 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 1427 {
ganlikun 0:13413ea9a877 1428 /* Set the key */
ganlikun 0:13413ea9a877 1429 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 1430
ganlikun 0:13413ea9a877 1431 /* Set the CRYP peripheral in AES GCM mode */
ganlikun 0:13413ea9a877 1432 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
ganlikun 0:13413ea9a877 1433
ganlikun 0:13413ea9a877 1434 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 1435 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
ganlikun 0:13413ea9a877 1436
ganlikun 0:13413ea9a877 1437 /* Flush FIFO */
ganlikun 0:13413ea9a877 1438 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 1439
ganlikun 0:13413ea9a877 1440 /* Enable CRYP to start the init phase */
ganlikun 0:13413ea9a877 1441 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1442
ganlikun 0:13413ea9a877 1443 /* Get tick */
ganlikun 0:13413ea9a877 1444 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1445
ganlikun 0:13413ea9a877 1446 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 1447 {
ganlikun 0:13413ea9a877 1448 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1449
ganlikun 0:13413ea9a877 1450 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 1451 {
ganlikun 0:13413ea9a877 1452 /* Change state */
ganlikun 0:13413ea9a877 1453 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1454
ganlikun 0:13413ea9a877 1455 /* Process Unlocked */
ganlikun 0:13413ea9a877 1456 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1457
ganlikun 0:13413ea9a877 1458 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1459
ganlikun 0:13413ea9a877 1460 }
ganlikun 0:13413ea9a877 1461 }
ganlikun 0:13413ea9a877 1462
ganlikun 0:13413ea9a877 1463 /* Set the header phase */
ganlikun 0:13413ea9a877 1464 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
ganlikun 0:13413ea9a877 1465 {
ganlikun 0:13413ea9a877 1466 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1467 }
ganlikun 0:13413ea9a877 1468 /* Disable the CRYP peripheral */
ganlikun 0:13413ea9a877 1469 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 1470
ganlikun 0:13413ea9a877 1471 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 1472 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 1473
ganlikun 0:13413ea9a877 1474 /* Flush FIFO */
ganlikun 0:13413ea9a877 1475 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 1476
ganlikun 0:13413ea9a877 1477 /* Set the phase */
ganlikun 0:13413ea9a877 1478 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 1479 }
ganlikun 0:13413ea9a877 1480
ganlikun 0:13413ea9a877 1481 if(Size != 0U)
ganlikun 0:13413ea9a877 1482 {
ganlikun 0:13413ea9a877 1483 /* Enable Interrupts */
ganlikun 0:13413ea9a877 1484 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 1485 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1486 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1487 }
ganlikun 0:13413ea9a877 1488 else
ganlikun 0:13413ea9a877 1489 {
ganlikun 0:13413ea9a877 1490 /* Process Locked */
ganlikun 0:13413ea9a877 1491 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1492 /* Change the CRYP state and phase */
ganlikun 0:13413ea9a877 1493 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1494 }
ganlikun 0:13413ea9a877 1495 /* Return function status */
ganlikun 0:13413ea9a877 1496 return HAL_OK;
ganlikun 0:13413ea9a877 1497 }
ganlikun 0:13413ea9a877 1498 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
ganlikun 0:13413ea9a877 1499 {
ganlikun 0:13413ea9a877 1500 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 1501 /* Write the Input block in the IN FIFO */
ganlikun 0:13413ea9a877 1502 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1503 inputaddr+=4U;
ganlikun 0:13413ea9a877 1504 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1505 inputaddr+=4U;
ganlikun 0:13413ea9a877 1506 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1507 inputaddr+=4U;
ganlikun 0:13413ea9a877 1508 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1509 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 1510 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 1511 if(hcryp->CrypInCount == 0U)
ganlikun 0:13413ea9a877 1512 {
ganlikun 0:13413ea9a877 1513 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
ganlikun 0:13413ea9a877 1514 /* Call the Input data transfer complete callback */
ganlikun 0:13413ea9a877 1515 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 1516 }
ganlikun 0:13413ea9a877 1517 }
ganlikun 0:13413ea9a877 1518 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
ganlikun 0:13413ea9a877 1519 {
ganlikun 0:13413ea9a877 1520 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 1521 /* Read the Output block from the Output FIFO */
ganlikun 0:13413ea9a877 1522 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1523 outputaddr+=4U;
ganlikun 0:13413ea9a877 1524 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1525 outputaddr+=4U;
ganlikun 0:13413ea9a877 1526 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1527 outputaddr+=4U;
ganlikun 0:13413ea9a877 1528 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1529 hcryp->pCrypOutBuffPtr += 16U;
ganlikun 0:13413ea9a877 1530 hcryp->CrypOutCount -= 16U;
ganlikun 0:13413ea9a877 1531 if(hcryp->CrypOutCount == 0U)
ganlikun 0:13413ea9a877 1532 {
ganlikun 0:13413ea9a877 1533 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 1534 /* Process Unlocked */
ganlikun 0:13413ea9a877 1535 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1536 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1537 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1538 /* Call Input transfer complete callback */
ganlikun 0:13413ea9a877 1539 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 1540 }
ganlikun 0:13413ea9a877 1541 }
ganlikun 0:13413ea9a877 1542
ganlikun 0:13413ea9a877 1543 /* Return function status */
ganlikun 0:13413ea9a877 1544 return HAL_OK;
ganlikun 0:13413ea9a877 1545 }
ganlikun 0:13413ea9a877 1546
ganlikun 0:13413ea9a877 1547 /**
ganlikun 0:13413ea9a877 1548 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
ganlikun 0:13413ea9a877 1549 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1550 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 1551 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 1552 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 1553 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 1554 * @retval HAL status
ganlikun 0:13413ea9a877 1555 */
ganlikun 0:13413ea9a877 1556 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
ganlikun 0:13413ea9a877 1557 {
ganlikun 0:13413ea9a877 1558 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 1559 uint32_t inputaddr;
ganlikun 0:13413ea9a877 1560 uint32_t outputaddr;
ganlikun 0:13413ea9a877 1561
ganlikun 0:13413ea9a877 1562 uint32_t headersize = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 1563 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 1564 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 1565 uint32_t bufferidx = 0U;
ganlikun 0:13413ea9a877 1566 uint8_t blockb0[16U] = {0};/* Block B0 */
ganlikun 0:13413ea9a877 1567 uint8_t ctr[16U] = {0}; /* Counter */
ganlikun 0:13413ea9a877 1568 uint32_t b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 1569
ganlikun 0:13413ea9a877 1570 if(hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 1571 {
ganlikun 0:13413ea9a877 1572 /* Process Locked */
ganlikun 0:13413ea9a877 1573 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 1574
ganlikun 0:13413ea9a877 1575 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 1576 hcryp->pCrypInBuffPtr = pPlainData;
ganlikun 0:13413ea9a877 1577 hcryp->pCrypOutBuffPtr = pCypherData;
ganlikun 0:13413ea9a877 1578 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 1579
ganlikun 0:13413ea9a877 1580 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1581 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 1582
ganlikun 0:13413ea9a877 1583 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 1584 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 1585 {
ganlikun 0:13413ea9a877 1586 /************************ Formatting the header block *******************/
ganlikun 0:13413ea9a877 1587 if(headersize != 0U)
ganlikun 0:13413ea9a877 1588 {
ganlikun 0:13413ea9a877 1589 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
ganlikun 0:13413ea9a877 1590 if(headersize < 65280U)
ganlikun 0:13413ea9a877 1591 {
ganlikun 0:13413ea9a877 1592 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
ganlikun 0:13413ea9a877 1593 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
ganlikun 0:13413ea9a877 1594 headersize += 2U;
ganlikun 0:13413ea9a877 1595 }
ganlikun 0:13413ea9a877 1596 else
ganlikun 0:13413ea9a877 1597 {
ganlikun 0:13413ea9a877 1598 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
ganlikun 0:13413ea9a877 1599 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
ganlikun 0:13413ea9a877 1600 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
ganlikun 0:13413ea9a877 1601 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
ganlikun 0:13413ea9a877 1602 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
ganlikun 0:13413ea9a877 1603 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
ganlikun 0:13413ea9a877 1604 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
ganlikun 0:13413ea9a877 1605 headersize += 6U;
ganlikun 0:13413ea9a877 1606 }
ganlikun 0:13413ea9a877 1607 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
ganlikun 0:13413ea9a877 1608 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
ganlikun 0:13413ea9a877 1609 {
ganlikun 0:13413ea9a877 1610 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
ganlikun 0:13413ea9a877 1611 }
ganlikun 0:13413ea9a877 1612 /* Check if the header size is modulo 16 */
ganlikun 0:13413ea9a877 1613 if ((headersize % 16U) != 0U)
ganlikun 0:13413ea9a877 1614 {
ganlikun 0:13413ea9a877 1615 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
ganlikun 0:13413ea9a877 1616 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
ganlikun 0:13413ea9a877 1617 {
ganlikun 0:13413ea9a877 1618 hcryp->Init.pScratch[loopcounter] = 0U;
ganlikun 0:13413ea9a877 1619 }
ganlikun 0:13413ea9a877 1620 /* Set the header size to modulo 16 */
ganlikun 0:13413ea9a877 1621 headersize = ((headersize/16U) + 1U) * 16U;
ganlikun 0:13413ea9a877 1622 }
ganlikun 0:13413ea9a877 1623 /* Set the pointer headeraddr to hcryp->Init.pScratch */
ganlikun 0:13413ea9a877 1624 headeraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 1625 }
ganlikun 0:13413ea9a877 1626 /*********************** Formatting the block B0 ************************/
ganlikun 0:13413ea9a877 1627 if(headersize != 0U)
ganlikun 0:13413ea9a877 1628 {
ganlikun 0:13413ea9a877 1629 blockb0[0U] = 0x40U;
ganlikun 0:13413ea9a877 1630 }
ganlikun 0:13413ea9a877 1631 /* Flags byte */
ganlikun 0:13413ea9a877 1632 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
ganlikun 0:13413ea9a877 1633 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
ganlikun 0:13413ea9a877 1634 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
ganlikun 0:13413ea9a877 1635
ganlikun 0:13413ea9a877 1636 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
ganlikun 0:13413ea9a877 1637 {
ganlikun 0:13413ea9a877 1638 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
ganlikun 0:13413ea9a877 1639 }
ganlikun 0:13413ea9a877 1640 for ( ; loopcounter < 13U; loopcounter++)
ganlikun 0:13413ea9a877 1641 {
ganlikun 0:13413ea9a877 1642 blockb0[loopcounter+1U] = 0U;
ganlikun 0:13413ea9a877 1643 }
ganlikun 0:13413ea9a877 1644
ganlikun 0:13413ea9a877 1645 blockb0[14U] = (Size >> 8U);
ganlikun 0:13413ea9a877 1646 blockb0[15U] = (Size & 0xFFU);
ganlikun 0:13413ea9a877 1647
ganlikun 0:13413ea9a877 1648 /************************* Formatting the initial counter ***************/
ganlikun 0:13413ea9a877 1649 /* Byte 0:
ganlikun 0:13413ea9a877 1650 Bits 7 and 6 are reserved and shall be set to 0
ganlikun 0:13413ea9a877 1651 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
ganlikun 0:13413ea9a877 1652 blocks are distinct from B0
ganlikun 0:13413ea9a877 1653 Bits 0, 1, and 2 contain the same encoding of q as in B0
ganlikun 0:13413ea9a877 1654 */
ganlikun 0:13413ea9a877 1655 ctr[0U] = blockb0[0U] & 0x07U;
ganlikun 0:13413ea9a877 1656 /* byte 1 to NonceSize is the IV (Nonce) */
ganlikun 0:13413ea9a877 1657 for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
ganlikun 0:13413ea9a877 1658 {
ganlikun 0:13413ea9a877 1659 ctr[loopcounter] = blockb0[loopcounter];
ganlikun 0:13413ea9a877 1660 }
ganlikun 0:13413ea9a877 1661 /* Set the LSB to 1 */
ganlikun 0:13413ea9a877 1662 ctr[15U] |= 0x01U;
ganlikun 0:13413ea9a877 1663
ganlikun 0:13413ea9a877 1664 /* Set the key */
ganlikun 0:13413ea9a877 1665 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 1666
ganlikun 0:13413ea9a877 1667 /* Set the CRYP peripheral in AES CCM mode */
ganlikun 0:13413ea9a877 1668 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
ganlikun 0:13413ea9a877 1669
ganlikun 0:13413ea9a877 1670 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 1671 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
ganlikun 0:13413ea9a877 1672
ganlikun 0:13413ea9a877 1673 /* Select init phase */
ganlikun 0:13413ea9a877 1674 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
ganlikun 0:13413ea9a877 1675
ganlikun 0:13413ea9a877 1676 b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 1677 /* Write the blockb0 block in the IN FIFO */
ganlikun 0:13413ea9a877 1678 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1679 b0addr+=4U;
ganlikun 0:13413ea9a877 1680 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1681 b0addr+=4U;
ganlikun 0:13413ea9a877 1682 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1683 b0addr+=4U;
ganlikun 0:13413ea9a877 1684 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 1685
ganlikun 0:13413ea9a877 1686 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1687 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1688
ganlikun 0:13413ea9a877 1689 /* Get tick */
ganlikun 0:13413ea9a877 1690 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1691
ganlikun 0:13413ea9a877 1692 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 1693 {
ganlikun 0:13413ea9a877 1694 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1695 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 1696 {
ganlikun 0:13413ea9a877 1697 /* Change state */
ganlikun 0:13413ea9a877 1698 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1699
ganlikun 0:13413ea9a877 1700 /* Process Unlocked */
ganlikun 0:13413ea9a877 1701 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1702
ganlikun 0:13413ea9a877 1703 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1704 }
ganlikun 0:13413ea9a877 1705 }
ganlikun 0:13413ea9a877 1706 /***************************** Header phase *****************************/
ganlikun 0:13413ea9a877 1707 if(headersize != 0U)
ganlikun 0:13413ea9a877 1708 {
ganlikun 0:13413ea9a877 1709 /* Select header phase */
ganlikun 0:13413ea9a877 1710 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 1711
ganlikun 0:13413ea9a877 1712 /* Enable Crypto processor */
ganlikun 0:13413ea9a877 1713 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1714
ganlikun 0:13413ea9a877 1715 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
ganlikun 0:13413ea9a877 1716 {
ganlikun 0:13413ea9a877 1717 /* Get tick */
ganlikun 0:13413ea9a877 1718 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1719
ganlikun 0:13413ea9a877 1720 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 1721 {
ganlikun 0:13413ea9a877 1722 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1723 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 1724 {
ganlikun 0:13413ea9a877 1725 /* Change state */
ganlikun 0:13413ea9a877 1726 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1727
ganlikun 0:13413ea9a877 1728 /* Process Unlocked */
ganlikun 0:13413ea9a877 1729 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1730
ganlikun 0:13413ea9a877 1731 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1732 }
ganlikun 0:13413ea9a877 1733 }
ganlikun 0:13413ea9a877 1734 /* Write the header block in the IN FIFO */
ganlikun 0:13413ea9a877 1735 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1736 headeraddr+=4U;
ganlikun 0:13413ea9a877 1737 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1738 headeraddr+=4U;
ganlikun 0:13413ea9a877 1739 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1740 headeraddr+=4U;
ganlikun 0:13413ea9a877 1741 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 1742 headeraddr+=4U;
ganlikun 0:13413ea9a877 1743 }
ganlikun 0:13413ea9a877 1744
ganlikun 0:13413ea9a877 1745 /* Get tick */
ganlikun 0:13413ea9a877 1746 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1747
ganlikun 0:13413ea9a877 1748 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 1749 {
ganlikun 0:13413ea9a877 1750 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1751 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 1752 {
ganlikun 0:13413ea9a877 1753 /* Change state */
ganlikun 0:13413ea9a877 1754 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1755
ganlikun 0:13413ea9a877 1756 /* Process Unlocked */
ganlikun 0:13413ea9a877 1757 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1758
ganlikun 0:13413ea9a877 1759 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1760 }
ganlikun 0:13413ea9a877 1761 }
ganlikun 0:13413ea9a877 1762 }
ganlikun 0:13413ea9a877 1763 /* Save formatted counter into the scratch buffer pScratch */
ganlikun 0:13413ea9a877 1764 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
ganlikun 0:13413ea9a877 1765 {
ganlikun 0:13413ea9a877 1766 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
ganlikun 0:13413ea9a877 1767 }
ganlikun 0:13413ea9a877 1768 /* Reset bit 0 */
ganlikun 0:13413ea9a877 1769 hcryp->Init.pScratch[15U] &= 0xFEU;
ganlikun 0:13413ea9a877 1770
ganlikun 0:13413ea9a877 1771 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 1772 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 1773
ganlikun 0:13413ea9a877 1774 /* Flush FIFO */
ganlikun 0:13413ea9a877 1775 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 1776
ganlikun 0:13413ea9a877 1777 /* Set the phase */
ganlikun 0:13413ea9a877 1778 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 1779 }
ganlikun 0:13413ea9a877 1780
ganlikun 0:13413ea9a877 1781 if(Size != 0U)
ganlikun 0:13413ea9a877 1782 {
ganlikun 0:13413ea9a877 1783 /* Enable Interrupts */
ganlikun 0:13413ea9a877 1784 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 1785 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1786 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1787 }
ganlikun 0:13413ea9a877 1788 else
ganlikun 0:13413ea9a877 1789 {
ganlikun 0:13413ea9a877 1790 /* Change the CRYP state and phase */
ganlikun 0:13413ea9a877 1791 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1792 }
ganlikun 0:13413ea9a877 1793
ganlikun 0:13413ea9a877 1794 /* Return function status */
ganlikun 0:13413ea9a877 1795 return HAL_OK;
ganlikun 0:13413ea9a877 1796 }
ganlikun 0:13413ea9a877 1797 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
ganlikun 0:13413ea9a877 1798 {
ganlikun 0:13413ea9a877 1799 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 1800 /* Write the Input block in the IN FIFO */
ganlikun 0:13413ea9a877 1801 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1802 inputaddr+=4U;
ganlikun 0:13413ea9a877 1803 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1804 inputaddr+=4U;
ganlikun 0:13413ea9a877 1805 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1806 inputaddr+=4U;
ganlikun 0:13413ea9a877 1807 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1808 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 1809 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 1810 if(hcryp->CrypInCount == 0U)
ganlikun 0:13413ea9a877 1811 {
ganlikun 0:13413ea9a877 1812 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
ganlikun 0:13413ea9a877 1813 /* Call Input transfer complete callback */
ganlikun 0:13413ea9a877 1814 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 1815 }
ganlikun 0:13413ea9a877 1816 }
ganlikun 0:13413ea9a877 1817 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
ganlikun 0:13413ea9a877 1818 {
ganlikun 0:13413ea9a877 1819 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 1820 /* Read the Output block from the Output FIFO */
ganlikun 0:13413ea9a877 1821 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1822 outputaddr+=4U;
ganlikun 0:13413ea9a877 1823 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1824 outputaddr+=4U;
ganlikun 0:13413ea9a877 1825 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1826 outputaddr+=4U;
ganlikun 0:13413ea9a877 1827 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1828 hcryp->pCrypOutBuffPtr += 16U;
ganlikun 0:13413ea9a877 1829 hcryp->CrypOutCount -= 16U;
ganlikun 0:13413ea9a877 1830 if(hcryp->CrypOutCount == 0U)
ganlikun 0:13413ea9a877 1831 {
ganlikun 0:13413ea9a877 1832 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 1833 /* Process Unlocked */
ganlikun 0:13413ea9a877 1834 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1835 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1836 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1837 /* Call Input transfer complete callback */
ganlikun 0:13413ea9a877 1838 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 1839 }
ganlikun 0:13413ea9a877 1840 }
ganlikun 0:13413ea9a877 1841
ganlikun 0:13413ea9a877 1842 /* Return function status */
ganlikun 0:13413ea9a877 1843 return HAL_OK;
ganlikun 0:13413ea9a877 1844 }
ganlikun 0:13413ea9a877 1845
ganlikun 0:13413ea9a877 1846 /**
ganlikun 0:13413ea9a877 1847 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT.
ganlikun 0:13413ea9a877 1848 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1849 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 1850 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 1851 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 1852 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 1853 * @retval HAL status
ganlikun 0:13413ea9a877 1854 */
ganlikun 0:13413ea9a877 1855 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
ganlikun 0:13413ea9a877 1856 {
ganlikun 0:13413ea9a877 1857 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 1858 uint32_t inputaddr;
ganlikun 0:13413ea9a877 1859 uint32_t outputaddr;
ganlikun 0:13413ea9a877 1860
ganlikun 0:13413ea9a877 1861 if(hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 1862 {
ganlikun 0:13413ea9a877 1863 /* Process Locked */
ganlikun 0:13413ea9a877 1864 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 1865
ganlikun 0:13413ea9a877 1866 /* Get the buffer addresses and sizes */
ganlikun 0:13413ea9a877 1867 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 1868 hcryp->pCrypInBuffPtr = pCypherData;
ganlikun 0:13413ea9a877 1869 hcryp->pCrypOutBuffPtr = pPlainData;
ganlikun 0:13413ea9a877 1870 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 1871
ganlikun 0:13413ea9a877 1872 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1873 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 1874
ganlikun 0:13413ea9a877 1875 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 1876 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 1877 {
ganlikun 0:13413ea9a877 1878 /* Set the key */
ganlikun 0:13413ea9a877 1879 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 1880
ganlikun 0:13413ea9a877 1881 /* Set the CRYP peripheral in AES GCM decryption mode */
ganlikun 0:13413ea9a877 1882 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
ganlikun 0:13413ea9a877 1883
ganlikun 0:13413ea9a877 1884 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 1885 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
ganlikun 0:13413ea9a877 1886
ganlikun 0:13413ea9a877 1887 /* Flush FIFO */
ganlikun 0:13413ea9a877 1888 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 1889
ganlikun 0:13413ea9a877 1890 /* Enable CRYP to start the init phase */
ganlikun 0:13413ea9a877 1891 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1892
ganlikun 0:13413ea9a877 1893 /* Get tick */
ganlikun 0:13413ea9a877 1894 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 1895
ganlikun 0:13413ea9a877 1896 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 1897 {
ganlikun 0:13413ea9a877 1898 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1899 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 1900 {
ganlikun 0:13413ea9a877 1901 /* Change state */
ganlikun 0:13413ea9a877 1902 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 1903
ganlikun 0:13413ea9a877 1904 /* Process Unlocked */
ganlikun 0:13413ea9a877 1905 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1906
ganlikun 0:13413ea9a877 1907 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1908 }
ganlikun 0:13413ea9a877 1909 }
ganlikun 0:13413ea9a877 1910
ganlikun 0:13413ea9a877 1911 /* Set the header phase */
ganlikun 0:13413ea9a877 1912 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
ganlikun 0:13413ea9a877 1913 {
ganlikun 0:13413ea9a877 1914 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1915 }
ganlikun 0:13413ea9a877 1916 /* Disable the CRYP peripheral */
ganlikun 0:13413ea9a877 1917 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 1918
ganlikun 0:13413ea9a877 1919 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 1920 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 1921
ganlikun 0:13413ea9a877 1922 /* Set the phase */
ganlikun 0:13413ea9a877 1923 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 1924 }
ganlikun 0:13413ea9a877 1925
ganlikun 0:13413ea9a877 1926 if(Size != 0U)
ganlikun 0:13413ea9a877 1927 {
ganlikun 0:13413ea9a877 1928 /* Enable Interrupts */
ganlikun 0:13413ea9a877 1929 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 1930 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 1931 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 1932 }
ganlikun 0:13413ea9a877 1933 else
ganlikun 0:13413ea9a877 1934 {
ganlikun 0:13413ea9a877 1935 /* Process Locked */
ganlikun 0:13413ea9a877 1936 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1937 /* Change the CRYP state and phase */
ganlikun 0:13413ea9a877 1938 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1939 }
ganlikun 0:13413ea9a877 1940
ganlikun 0:13413ea9a877 1941 /* Return function status */
ganlikun 0:13413ea9a877 1942 return HAL_OK;
ganlikun 0:13413ea9a877 1943 }
ganlikun 0:13413ea9a877 1944 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
ganlikun 0:13413ea9a877 1945 {
ganlikun 0:13413ea9a877 1946 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 1947 /* Write the Input block in the IN FIFO */
ganlikun 0:13413ea9a877 1948 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1949 inputaddr+=4U;
ganlikun 0:13413ea9a877 1950 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1951 inputaddr+=4U;
ganlikun 0:13413ea9a877 1952 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1953 inputaddr+=4U;
ganlikun 0:13413ea9a877 1954 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 1955 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 1956 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 1957 if(hcryp->CrypInCount == 0U)
ganlikun 0:13413ea9a877 1958 {
ganlikun 0:13413ea9a877 1959 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
ganlikun 0:13413ea9a877 1960 /* Call the Input data transfer complete callback */
ganlikun 0:13413ea9a877 1961 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 1962 }
ganlikun 0:13413ea9a877 1963 }
ganlikun 0:13413ea9a877 1964 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
ganlikun 0:13413ea9a877 1965 {
ganlikun 0:13413ea9a877 1966 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 1967 /* Read the Output block from the Output FIFO */
ganlikun 0:13413ea9a877 1968 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1969 outputaddr+=4U;
ganlikun 0:13413ea9a877 1970 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1971 outputaddr+=4U;
ganlikun 0:13413ea9a877 1972 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1973 outputaddr+=4U;
ganlikun 0:13413ea9a877 1974 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 1975 hcryp->pCrypOutBuffPtr += 16U;
ganlikun 0:13413ea9a877 1976 hcryp->CrypOutCount -= 16U;
ganlikun 0:13413ea9a877 1977 if(hcryp->CrypOutCount == 0U)
ganlikun 0:13413ea9a877 1978 {
ganlikun 0:13413ea9a877 1979 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 1980 /* Process Unlocked */
ganlikun 0:13413ea9a877 1981 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 1982 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 1983 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 1984 /* Call Input transfer complete callback */
ganlikun 0:13413ea9a877 1985 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 1986 }
ganlikun 0:13413ea9a877 1987 }
ganlikun 0:13413ea9a877 1988
ganlikun 0:13413ea9a877 1989 /* Return function status */
ganlikun 0:13413ea9a877 1990 return HAL_OK;
ganlikun 0:13413ea9a877 1991 }
ganlikun 0:13413ea9a877 1992
ganlikun 0:13413ea9a877 1993 /**
ganlikun 0:13413ea9a877 1994 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt
ganlikun 0:13413ea9a877 1995 * then decrypted pCypherData. The cypher data are available in pPlainData.
ganlikun 0:13413ea9a877 1996 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1997 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 1998 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 1999 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 2000 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 2001 * @retval HAL status
ganlikun 0:13413ea9a877 2002 */
ganlikun 0:13413ea9a877 2003 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
ganlikun 0:13413ea9a877 2004 {
ganlikun 0:13413ea9a877 2005 uint32_t inputaddr;
ganlikun 0:13413ea9a877 2006 uint32_t outputaddr;
ganlikun 0:13413ea9a877 2007 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 2008 uint32_t headersize = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 2009 uint32_t headeraddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 2010 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 2011 uint32_t bufferidx = 0U;
ganlikun 0:13413ea9a877 2012 uint8_t blockb0[16U] = {0};/* Block B0 */
ganlikun 0:13413ea9a877 2013 uint8_t ctr[16U] = {0}; /* Counter */
ganlikun 0:13413ea9a877 2014 uint32_t b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 2015
ganlikun 0:13413ea9a877 2016 if(hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 2017 {
ganlikun 0:13413ea9a877 2018 /* Process Locked */
ganlikun 0:13413ea9a877 2019 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 2020
ganlikun 0:13413ea9a877 2021 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 2022 hcryp->pCrypInBuffPtr = pCypherData;
ganlikun 0:13413ea9a877 2023 hcryp->pCrypOutBuffPtr = pPlainData;
ganlikun 0:13413ea9a877 2024 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 2025
ganlikun 0:13413ea9a877 2026 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 2027 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 2028
ganlikun 0:13413ea9a877 2029 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 2030 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 2031 {
ganlikun 0:13413ea9a877 2032 /************************ Formatting the header block *******************/
ganlikun 0:13413ea9a877 2033 if(headersize != 0U)
ganlikun 0:13413ea9a877 2034 {
ganlikun 0:13413ea9a877 2035 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
ganlikun 0:13413ea9a877 2036 if(headersize < 65280U)
ganlikun 0:13413ea9a877 2037 {
ganlikun 0:13413ea9a877 2038 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
ganlikun 0:13413ea9a877 2039 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
ganlikun 0:13413ea9a877 2040 headersize += 2U;
ganlikun 0:13413ea9a877 2041 }
ganlikun 0:13413ea9a877 2042 else
ganlikun 0:13413ea9a877 2043 {
ganlikun 0:13413ea9a877 2044 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
ganlikun 0:13413ea9a877 2045 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
ganlikun 0:13413ea9a877 2046 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
ganlikun 0:13413ea9a877 2047 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
ganlikun 0:13413ea9a877 2048 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
ganlikun 0:13413ea9a877 2049 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
ganlikun 0:13413ea9a877 2050 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
ganlikun 0:13413ea9a877 2051 headersize += 6U;
ganlikun 0:13413ea9a877 2052 }
ganlikun 0:13413ea9a877 2053 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
ganlikun 0:13413ea9a877 2054 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
ganlikun 0:13413ea9a877 2055 {
ganlikun 0:13413ea9a877 2056 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
ganlikun 0:13413ea9a877 2057 }
ganlikun 0:13413ea9a877 2058 /* Check if the header size is modulo 16 */
ganlikun 0:13413ea9a877 2059 if ((headersize % 16U) != 0U)
ganlikun 0:13413ea9a877 2060 {
ganlikun 0:13413ea9a877 2061 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
ganlikun 0:13413ea9a877 2062 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
ganlikun 0:13413ea9a877 2063 {
ganlikun 0:13413ea9a877 2064 hcryp->Init.pScratch[loopcounter] = 0U;
ganlikun 0:13413ea9a877 2065 }
ganlikun 0:13413ea9a877 2066 /* Set the header size to modulo 16 */
ganlikun 0:13413ea9a877 2067 headersize = ((headersize/16U) + 1U) * 16U;
ganlikun 0:13413ea9a877 2068 }
ganlikun 0:13413ea9a877 2069 /* Set the pointer headeraddr to hcryp->Init.pScratch */
ganlikun 0:13413ea9a877 2070 headeraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 2071 }
ganlikun 0:13413ea9a877 2072 /*********************** Formatting the block B0 ************************/
ganlikun 0:13413ea9a877 2073 if(headersize != 0U)
ganlikun 0:13413ea9a877 2074 {
ganlikun 0:13413ea9a877 2075 blockb0[0U] = 0x40U;
ganlikun 0:13413ea9a877 2076 }
ganlikun 0:13413ea9a877 2077 /* Flags byte */
ganlikun 0:13413ea9a877 2078 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
ganlikun 0:13413ea9a877 2079 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1U) & (uint8_t)0x07) << 3U);
ganlikun 0:13413ea9a877 2080 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
ganlikun 0:13413ea9a877 2081
ganlikun 0:13413ea9a877 2082 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
ganlikun 0:13413ea9a877 2083 {
ganlikun 0:13413ea9a877 2084 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
ganlikun 0:13413ea9a877 2085 }
ganlikun 0:13413ea9a877 2086 for ( ; loopcounter < 13U; loopcounter++)
ganlikun 0:13413ea9a877 2087 {
ganlikun 0:13413ea9a877 2088 blockb0[loopcounter+1U] = 0U;
ganlikun 0:13413ea9a877 2089 }
ganlikun 0:13413ea9a877 2090
ganlikun 0:13413ea9a877 2091 blockb0[14U] = (Size >> 8U);
ganlikun 0:13413ea9a877 2092 blockb0[15U] = (Size & 0xFFU);
ganlikun 0:13413ea9a877 2093
ganlikun 0:13413ea9a877 2094 /************************* Formatting the initial counter ***************/
ganlikun 0:13413ea9a877 2095 /* Byte 0:
ganlikun 0:13413ea9a877 2096 Bits 7 and 6 are reserved and shall be set to 0
ganlikun 0:13413ea9a877 2097 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
ganlikun 0:13413ea9a877 2098 blocks are distinct from B0
ganlikun 0:13413ea9a877 2099 Bits 0, 1, and 2 contain the same encoding of q as in B0
ganlikun 0:13413ea9a877 2100 */
ganlikun 0:13413ea9a877 2101 ctr[0U] = blockb0[0U] & 0x07U;
ganlikun 0:13413ea9a877 2102 /* byte 1 to NonceSize is the IV (Nonce) */
ganlikun 0:13413ea9a877 2103 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
ganlikun 0:13413ea9a877 2104 {
ganlikun 0:13413ea9a877 2105 ctr[loopcounter] = blockb0[loopcounter];
ganlikun 0:13413ea9a877 2106 }
ganlikun 0:13413ea9a877 2107 /* Set the LSB to 1 */
ganlikun 0:13413ea9a877 2108 ctr[15U] |= 0x01U;
ganlikun 0:13413ea9a877 2109
ganlikun 0:13413ea9a877 2110 /* Set the key */
ganlikun 0:13413ea9a877 2111 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 2112
ganlikun 0:13413ea9a877 2113 /* Set the CRYP peripheral in AES CCM mode */
ganlikun 0:13413ea9a877 2114 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
ganlikun 0:13413ea9a877 2115
ganlikun 0:13413ea9a877 2116 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 2117 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
ganlikun 0:13413ea9a877 2118
ganlikun 0:13413ea9a877 2119 /* Select init phase */
ganlikun 0:13413ea9a877 2120 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
ganlikun 0:13413ea9a877 2121
ganlikun 0:13413ea9a877 2122 b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 2123 /* Write the blockb0 block in the IN FIFO */
ganlikun 0:13413ea9a877 2124 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2125 b0addr+=4U;
ganlikun 0:13413ea9a877 2126 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2127 b0addr+=4U;
ganlikun 0:13413ea9a877 2128 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2129 b0addr+=4U;
ganlikun 0:13413ea9a877 2130 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2131
ganlikun 0:13413ea9a877 2132 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 2133 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2134
ganlikun 0:13413ea9a877 2135 /* Get tick */
ganlikun 0:13413ea9a877 2136 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2137
ganlikun 0:13413ea9a877 2138 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 2139 {
ganlikun 0:13413ea9a877 2140 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2141 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2142 {
ganlikun 0:13413ea9a877 2143 /* Change state */
ganlikun 0:13413ea9a877 2144 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2145
ganlikun 0:13413ea9a877 2146 /* Process Unlocked */
ganlikun 0:13413ea9a877 2147 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2148
ganlikun 0:13413ea9a877 2149 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2150 }
ganlikun 0:13413ea9a877 2151 }
ganlikun 0:13413ea9a877 2152 /***************************** Header phase *****************************/
ganlikun 0:13413ea9a877 2153 if(headersize != 0U)
ganlikun 0:13413ea9a877 2154 {
ganlikun 0:13413ea9a877 2155 /* Select header phase */
ganlikun 0:13413ea9a877 2156 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 2157
ganlikun 0:13413ea9a877 2158 /* Enable Crypto processor */
ganlikun 0:13413ea9a877 2159 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2160
ganlikun 0:13413ea9a877 2161 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
ganlikun 0:13413ea9a877 2162 {
ganlikun 0:13413ea9a877 2163 /* Get tick */
ganlikun 0:13413ea9a877 2164 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2165
ganlikun 0:13413ea9a877 2166 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 2167 {
ganlikun 0:13413ea9a877 2168 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2169 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2170 {
ganlikun 0:13413ea9a877 2171 /* Change state */
ganlikun 0:13413ea9a877 2172 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2173
ganlikun 0:13413ea9a877 2174 /* Process Unlocked */
ganlikun 0:13413ea9a877 2175 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2176
ganlikun 0:13413ea9a877 2177 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2178 }
ganlikun 0:13413ea9a877 2179 }
ganlikun 0:13413ea9a877 2180 /* Write the header block in the IN FIFO */
ganlikun 0:13413ea9a877 2181 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2182 headeraddr+=4U;
ganlikun 0:13413ea9a877 2183 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2184 headeraddr+=4U;
ganlikun 0:13413ea9a877 2185 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2186 headeraddr+=4U;
ganlikun 0:13413ea9a877 2187 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2188 headeraddr+=4U;
ganlikun 0:13413ea9a877 2189 }
ganlikun 0:13413ea9a877 2190
ganlikun 0:13413ea9a877 2191 /* Get tick */
ganlikun 0:13413ea9a877 2192 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2193
ganlikun 0:13413ea9a877 2194 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 2195 {
ganlikun 0:13413ea9a877 2196 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2197 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2198 {
ganlikun 0:13413ea9a877 2199 /* Change state */
ganlikun 0:13413ea9a877 2200 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2201
ganlikun 0:13413ea9a877 2202 /* Process Unlocked */
ganlikun 0:13413ea9a877 2203 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2204
ganlikun 0:13413ea9a877 2205 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2206 }
ganlikun 0:13413ea9a877 2207 }
ganlikun 0:13413ea9a877 2208 }
ganlikun 0:13413ea9a877 2209 /* Save formatted counter into the scratch buffer pScratch */
ganlikun 0:13413ea9a877 2210 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
ganlikun 0:13413ea9a877 2211 {
ganlikun 0:13413ea9a877 2212 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
ganlikun 0:13413ea9a877 2213 }
ganlikun 0:13413ea9a877 2214 /* Reset bit 0 */
ganlikun 0:13413ea9a877 2215 hcryp->Init.pScratch[15U] &= 0xFEU;
ganlikun 0:13413ea9a877 2216 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 2217 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 2218
ganlikun 0:13413ea9a877 2219 /* Flush FIFO */
ganlikun 0:13413ea9a877 2220 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 2221
ganlikun 0:13413ea9a877 2222 /* Set the phase */
ganlikun 0:13413ea9a877 2223 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 2224 }
ganlikun 0:13413ea9a877 2225
ganlikun 0:13413ea9a877 2226 /* Enable Interrupts */
ganlikun 0:13413ea9a877 2227 __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 2228
ganlikun 0:13413ea9a877 2229 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 2230 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2231
ganlikun 0:13413ea9a877 2232 /* Return function status */
ganlikun 0:13413ea9a877 2233 return HAL_OK;
ganlikun 0:13413ea9a877 2234 }
ganlikun 0:13413ea9a877 2235 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI))
ganlikun 0:13413ea9a877 2236 {
ganlikun 0:13413ea9a877 2237 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 2238 /* Write the Input block in the IN FIFO */
ganlikun 0:13413ea9a877 2239 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 2240 inputaddr+=4U;
ganlikun 0:13413ea9a877 2241 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 2242 inputaddr+=4U;
ganlikun 0:13413ea9a877 2243 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 2244 inputaddr+=4U;
ganlikun 0:13413ea9a877 2245 hcryp->Instance->DR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 2246 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 2247 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 2248 if(hcryp->CrypInCount == 0U)
ganlikun 0:13413ea9a877 2249 {
ganlikun 0:13413ea9a877 2250 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
ganlikun 0:13413ea9a877 2251 /* Call the Input data transfer complete callback */
ganlikun 0:13413ea9a877 2252 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 2253 }
ganlikun 0:13413ea9a877 2254 }
ganlikun 0:13413ea9a877 2255 else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI))
ganlikun 0:13413ea9a877 2256 {
ganlikun 0:13413ea9a877 2257 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 2258 /* Read the Output block from the Output FIFO */
ganlikun 0:13413ea9a877 2259 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 2260 outputaddr+=4U;
ganlikun 0:13413ea9a877 2261 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 2262 outputaddr+=4U;
ganlikun 0:13413ea9a877 2263 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 2264 outputaddr+=4U;
ganlikun 0:13413ea9a877 2265 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT;
ganlikun 0:13413ea9a877 2266 hcryp->pCrypOutBuffPtr += 16U;
ganlikun 0:13413ea9a877 2267 hcryp->CrypOutCount -= 16U;
ganlikun 0:13413ea9a877 2268 if(hcryp->CrypOutCount == 0U)
ganlikun 0:13413ea9a877 2269 {
ganlikun 0:13413ea9a877 2270 __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
ganlikun 0:13413ea9a877 2271 /* Process Unlocked */
ganlikun 0:13413ea9a877 2272 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2273 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 2274 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 2275 /* Call Input transfer complete callback */
ganlikun 0:13413ea9a877 2276 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 2277 }
ganlikun 0:13413ea9a877 2278 }
ganlikun 0:13413ea9a877 2279
ganlikun 0:13413ea9a877 2280 /* Return function status */
ganlikun 0:13413ea9a877 2281 return HAL_OK;
ganlikun 0:13413ea9a877 2282 }
ganlikun 0:13413ea9a877 2283
ganlikun 0:13413ea9a877 2284 /**
ganlikun 0:13413ea9a877 2285 * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA.
ganlikun 0:13413ea9a877 2286 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2287 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 2288 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 2289 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 2290 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 2291 * @retval HAL status
ganlikun 0:13413ea9a877 2292 */
ganlikun 0:13413ea9a877 2293 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
ganlikun 0:13413ea9a877 2294 {
ganlikun 0:13413ea9a877 2295 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 2296 uint32_t inputaddr;
ganlikun 0:13413ea9a877 2297 uint32_t outputaddr;
ganlikun 0:13413ea9a877 2298
ganlikun 0:13413ea9a877 2299 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
ganlikun 0:13413ea9a877 2300 {
ganlikun 0:13413ea9a877 2301 /* Process Locked */
ganlikun 0:13413ea9a877 2302 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 2303
ganlikun 0:13413ea9a877 2304 inputaddr = (uint32_t)pPlainData;
ganlikun 0:13413ea9a877 2305 outputaddr = (uint32_t)pCypherData;
ganlikun 0:13413ea9a877 2306
ganlikun 0:13413ea9a877 2307 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 2308 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 2309
ganlikun 0:13413ea9a877 2310 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 2311 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 2312 {
ganlikun 0:13413ea9a877 2313 /* Set the key */
ganlikun 0:13413ea9a877 2314 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 2315
ganlikun 0:13413ea9a877 2316 /* Set the CRYP peripheral in AES GCM mode */
ganlikun 0:13413ea9a877 2317 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT);
ganlikun 0:13413ea9a877 2318
ganlikun 0:13413ea9a877 2319 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 2320 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
ganlikun 0:13413ea9a877 2321
ganlikun 0:13413ea9a877 2322 /* Flush FIFO */
ganlikun 0:13413ea9a877 2323 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 2324
ganlikun 0:13413ea9a877 2325 /* Enable CRYP to start the init phase */
ganlikun 0:13413ea9a877 2326 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2327
ganlikun 0:13413ea9a877 2328 /* Get tick */
ganlikun 0:13413ea9a877 2329 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2330
ganlikun 0:13413ea9a877 2331 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 2332 {
ganlikun 0:13413ea9a877 2333 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2334 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2335 {
ganlikun 0:13413ea9a877 2336 /* Change state */
ganlikun 0:13413ea9a877 2337 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2338
ganlikun 0:13413ea9a877 2339 /* Process Unlocked */
ganlikun 0:13413ea9a877 2340 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2341
ganlikun 0:13413ea9a877 2342 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2343 }
ganlikun 0:13413ea9a877 2344 }
ganlikun 0:13413ea9a877 2345 /* Flush FIFO */
ganlikun 0:13413ea9a877 2346 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 2347
ganlikun 0:13413ea9a877 2348 /* Set the header phase */
ganlikun 0:13413ea9a877 2349 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
ganlikun 0:13413ea9a877 2350 {
ganlikun 0:13413ea9a877 2351 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2352 }
ganlikun 0:13413ea9a877 2353 /* Disable the CRYP peripheral */
ganlikun 0:13413ea9a877 2354 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 2355
ganlikun 0:13413ea9a877 2356 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 2357 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 2358
ganlikun 0:13413ea9a877 2359 /* Flush FIFO */
ganlikun 0:13413ea9a877 2360 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 2361
ganlikun 0:13413ea9a877 2362 /* Set the phase */
ganlikun 0:13413ea9a877 2363 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 2364 }
ganlikun 0:13413ea9a877 2365
ganlikun 0:13413ea9a877 2366 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 2367 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
ganlikun 0:13413ea9a877 2368
ganlikun 0:13413ea9a877 2369 /* Unlock process */
ganlikun 0:13413ea9a877 2370 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2371
ganlikun 0:13413ea9a877 2372 /* Return function status */
ganlikun 0:13413ea9a877 2373 return HAL_OK;
ganlikun 0:13413ea9a877 2374 }
ganlikun 0:13413ea9a877 2375 else
ganlikun 0:13413ea9a877 2376 {
ganlikun 0:13413ea9a877 2377 return HAL_ERROR;
ganlikun 0:13413ea9a877 2378 }
ganlikun 0:13413ea9a877 2379 }
ganlikun 0:13413ea9a877 2380
ganlikun 0:13413ea9a877 2381 /**
ganlikun 0:13413ea9a877 2382 * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt.
ganlikun 0:13413ea9a877 2383 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2384 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 2385 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 2386 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 2387 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 2388 * @retval HAL status
ganlikun 0:13413ea9a877 2389 */
ganlikun 0:13413ea9a877 2390 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData)
ganlikun 0:13413ea9a877 2391 {
ganlikun 0:13413ea9a877 2392 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 2393 uint32_t inputaddr;
ganlikun 0:13413ea9a877 2394 uint32_t outputaddr;
ganlikun 0:13413ea9a877 2395 uint32_t headersize;
ganlikun 0:13413ea9a877 2396 uint32_t headeraddr;
ganlikun 0:13413ea9a877 2397 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 2398 uint32_t bufferidx = 0U;
ganlikun 0:13413ea9a877 2399 uint8_t blockb0[16U] = {0};/* Block B0 */
ganlikun 0:13413ea9a877 2400 uint8_t ctr[16U] = {0}; /* Counter */
ganlikun 0:13413ea9a877 2401 uint32_t b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 2402
ganlikun 0:13413ea9a877 2403 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
ganlikun 0:13413ea9a877 2404 {
ganlikun 0:13413ea9a877 2405 /* Process Locked */
ganlikun 0:13413ea9a877 2406 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 2407
ganlikun 0:13413ea9a877 2408 inputaddr = (uint32_t)pPlainData;
ganlikun 0:13413ea9a877 2409 outputaddr = (uint32_t)pCypherData;
ganlikun 0:13413ea9a877 2410
ganlikun 0:13413ea9a877 2411 headersize = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 2412 headeraddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 2413
ganlikun 0:13413ea9a877 2414 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 2415 hcryp->pCrypInBuffPtr = pPlainData;
ganlikun 0:13413ea9a877 2416 hcryp->pCrypOutBuffPtr = pCypherData;
ganlikun 0:13413ea9a877 2417 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 2418
ganlikun 0:13413ea9a877 2419 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 2420 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 2421
ganlikun 0:13413ea9a877 2422 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 2423 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 2424 {
ganlikun 0:13413ea9a877 2425 /************************ Formatting the header block *******************/
ganlikun 0:13413ea9a877 2426 if(headersize != 0U)
ganlikun 0:13413ea9a877 2427 {
ganlikun 0:13413ea9a877 2428 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
ganlikun 0:13413ea9a877 2429 if(headersize < 65280U)
ganlikun 0:13413ea9a877 2430 {
ganlikun 0:13413ea9a877 2431 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
ganlikun 0:13413ea9a877 2432 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
ganlikun 0:13413ea9a877 2433 headersize += 2U;
ganlikun 0:13413ea9a877 2434 }
ganlikun 0:13413ea9a877 2435 else
ganlikun 0:13413ea9a877 2436 {
ganlikun 0:13413ea9a877 2437 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
ganlikun 0:13413ea9a877 2438 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
ganlikun 0:13413ea9a877 2439 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
ganlikun 0:13413ea9a877 2440 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
ganlikun 0:13413ea9a877 2441 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
ganlikun 0:13413ea9a877 2442 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
ganlikun 0:13413ea9a877 2443 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
ganlikun 0:13413ea9a877 2444 headersize += 6U;
ganlikun 0:13413ea9a877 2445 }
ganlikun 0:13413ea9a877 2446 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
ganlikun 0:13413ea9a877 2447 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
ganlikun 0:13413ea9a877 2448 {
ganlikun 0:13413ea9a877 2449 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
ganlikun 0:13413ea9a877 2450 }
ganlikun 0:13413ea9a877 2451 /* Check if the header size is modulo 16 */
ganlikun 0:13413ea9a877 2452 if ((headersize % 16U) != 0U)
ganlikun 0:13413ea9a877 2453 {
ganlikun 0:13413ea9a877 2454 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
ganlikun 0:13413ea9a877 2455 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
ganlikun 0:13413ea9a877 2456 {
ganlikun 0:13413ea9a877 2457 hcryp->Init.pScratch[loopcounter] = 0U;
ganlikun 0:13413ea9a877 2458 }
ganlikun 0:13413ea9a877 2459 /* Set the header size to modulo 16 */
ganlikun 0:13413ea9a877 2460 headersize = ((headersize/16U) + 1U) * 16U;
ganlikun 0:13413ea9a877 2461 }
ganlikun 0:13413ea9a877 2462 /* Set the pointer headeraddr to hcryp->Init.pScratch */
ganlikun 0:13413ea9a877 2463 headeraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 2464 }
ganlikun 0:13413ea9a877 2465 /*********************** Formatting the block B0 ************************/
ganlikun 0:13413ea9a877 2466 if(headersize != 0U)
ganlikun 0:13413ea9a877 2467 {
ganlikun 0:13413ea9a877 2468 blockb0[0U] = 0x40U;
ganlikun 0:13413ea9a877 2469 }
ganlikun 0:13413ea9a877 2470 /* Flags byte */
ganlikun 0:13413ea9a877 2471 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
ganlikun 0:13413ea9a877 2472 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3);
ganlikun 0:13413ea9a877 2473 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
ganlikun 0:13413ea9a877 2474
ganlikun 0:13413ea9a877 2475 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
ganlikun 0:13413ea9a877 2476 {
ganlikun 0:13413ea9a877 2477 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
ganlikun 0:13413ea9a877 2478 }
ganlikun 0:13413ea9a877 2479 for ( ; loopcounter < 13U; loopcounter++)
ganlikun 0:13413ea9a877 2480 {
ganlikun 0:13413ea9a877 2481 blockb0[loopcounter+1U] = 0U;
ganlikun 0:13413ea9a877 2482 }
ganlikun 0:13413ea9a877 2483
ganlikun 0:13413ea9a877 2484 blockb0[14U] = (Size >> 8U);
ganlikun 0:13413ea9a877 2485 blockb0[15U] = (Size & 0xFFU);
ganlikun 0:13413ea9a877 2486
ganlikun 0:13413ea9a877 2487 /************************* Formatting the initial counter ***************/
ganlikun 0:13413ea9a877 2488 /* Byte 0:
ganlikun 0:13413ea9a877 2489 Bits 7 and 6 are reserved and shall be set to 0
ganlikun 0:13413ea9a877 2490 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
ganlikun 0:13413ea9a877 2491 blocks are distinct from B0
ganlikun 0:13413ea9a877 2492 Bits 0, 1, and 2 contain the same encoding of q as in B0
ganlikun 0:13413ea9a877 2493 */
ganlikun 0:13413ea9a877 2494 ctr[0U] = blockb0[0U] & 0x07U;
ganlikun 0:13413ea9a877 2495 /* byte 1 to NonceSize is the IV (Nonce) */
ganlikun 0:13413ea9a877 2496 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
ganlikun 0:13413ea9a877 2497 {
ganlikun 0:13413ea9a877 2498 ctr[loopcounter] = blockb0[loopcounter];
ganlikun 0:13413ea9a877 2499 }
ganlikun 0:13413ea9a877 2500 /* Set the LSB to 1 */
ganlikun 0:13413ea9a877 2501 ctr[15U] |= 0x01U;
ganlikun 0:13413ea9a877 2502
ganlikun 0:13413ea9a877 2503 /* Set the key */
ganlikun 0:13413ea9a877 2504 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 2505
ganlikun 0:13413ea9a877 2506 /* Set the CRYP peripheral in AES CCM mode */
ganlikun 0:13413ea9a877 2507 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT);
ganlikun 0:13413ea9a877 2508
ganlikun 0:13413ea9a877 2509 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 2510 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
ganlikun 0:13413ea9a877 2511
ganlikun 0:13413ea9a877 2512 /* Select init phase */
ganlikun 0:13413ea9a877 2513 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
ganlikun 0:13413ea9a877 2514
ganlikun 0:13413ea9a877 2515 b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 2516 /* Write the blockb0 block in the IN FIFO */
ganlikun 0:13413ea9a877 2517 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2518 b0addr+=4U;
ganlikun 0:13413ea9a877 2519 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2520 b0addr+=4U;
ganlikun 0:13413ea9a877 2521 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2522 b0addr+=4U;
ganlikun 0:13413ea9a877 2523 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2524
ganlikun 0:13413ea9a877 2525 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 2526 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2527
ganlikun 0:13413ea9a877 2528 /* Get tick */
ganlikun 0:13413ea9a877 2529 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2530
ganlikun 0:13413ea9a877 2531 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 2532 {
ganlikun 0:13413ea9a877 2533 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2534 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2535 {
ganlikun 0:13413ea9a877 2536 /* Change state */
ganlikun 0:13413ea9a877 2537 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2538
ganlikun 0:13413ea9a877 2539 /* Process Unlocked */
ganlikun 0:13413ea9a877 2540 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2541
ganlikun 0:13413ea9a877 2542 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2543 }
ganlikun 0:13413ea9a877 2544 }
ganlikun 0:13413ea9a877 2545 /***************************** Header phase *****************************/
ganlikun 0:13413ea9a877 2546 if(headersize != 0U)
ganlikun 0:13413ea9a877 2547 {
ganlikun 0:13413ea9a877 2548 /* Select header phase */
ganlikun 0:13413ea9a877 2549 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 2550
ganlikun 0:13413ea9a877 2551 /* Enable Crypto processor */
ganlikun 0:13413ea9a877 2552 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2553
ganlikun 0:13413ea9a877 2554 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
ganlikun 0:13413ea9a877 2555 {
ganlikun 0:13413ea9a877 2556 /* Get tick */
ganlikun 0:13413ea9a877 2557 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2558
ganlikun 0:13413ea9a877 2559 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 2560 {
ganlikun 0:13413ea9a877 2561 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2562 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2563 {
ganlikun 0:13413ea9a877 2564 /* Change state */
ganlikun 0:13413ea9a877 2565 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2566
ganlikun 0:13413ea9a877 2567 /* Process Unlocked */
ganlikun 0:13413ea9a877 2568 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2569
ganlikun 0:13413ea9a877 2570 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2571 }
ganlikun 0:13413ea9a877 2572 }
ganlikun 0:13413ea9a877 2573 /* Write the header block in the IN FIFO */
ganlikun 0:13413ea9a877 2574 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2575 headeraddr+=4U;
ganlikun 0:13413ea9a877 2576 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2577 headeraddr+=4U;
ganlikun 0:13413ea9a877 2578 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2579 headeraddr+=4U;
ganlikun 0:13413ea9a877 2580 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2581 headeraddr+=4U;
ganlikun 0:13413ea9a877 2582 }
ganlikun 0:13413ea9a877 2583
ganlikun 0:13413ea9a877 2584 /* Get tick */
ganlikun 0:13413ea9a877 2585 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2586
ganlikun 0:13413ea9a877 2587 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 2588 {
ganlikun 0:13413ea9a877 2589 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2590 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2591 {
ganlikun 0:13413ea9a877 2592 /* Change state */
ganlikun 0:13413ea9a877 2593 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2594
ganlikun 0:13413ea9a877 2595 /* Process Unlocked */
ganlikun 0:13413ea9a877 2596 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2597
ganlikun 0:13413ea9a877 2598 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2599 }
ganlikun 0:13413ea9a877 2600 }
ganlikun 0:13413ea9a877 2601 }
ganlikun 0:13413ea9a877 2602 /* Save formatted counter into the scratch buffer pScratch */
ganlikun 0:13413ea9a877 2603 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
ganlikun 0:13413ea9a877 2604 {
ganlikun 0:13413ea9a877 2605 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
ganlikun 0:13413ea9a877 2606 }
ganlikun 0:13413ea9a877 2607 /* Reset bit 0 */
ganlikun 0:13413ea9a877 2608 hcryp->Init.pScratch[15U] &= 0xFEU;
ganlikun 0:13413ea9a877 2609
ganlikun 0:13413ea9a877 2610 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 2611 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 2612
ganlikun 0:13413ea9a877 2613 /* Flush FIFO */
ganlikun 0:13413ea9a877 2614 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 2615
ganlikun 0:13413ea9a877 2616 /* Set the phase */
ganlikun 0:13413ea9a877 2617 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 2618 }
ganlikun 0:13413ea9a877 2619
ganlikun 0:13413ea9a877 2620 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 2621 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
ganlikun 0:13413ea9a877 2622
ganlikun 0:13413ea9a877 2623 /* Unlock process */
ganlikun 0:13413ea9a877 2624 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2625
ganlikun 0:13413ea9a877 2626 /* Return function status */
ganlikun 0:13413ea9a877 2627 return HAL_OK;
ganlikun 0:13413ea9a877 2628 }
ganlikun 0:13413ea9a877 2629 else
ganlikun 0:13413ea9a877 2630 {
ganlikun 0:13413ea9a877 2631 return HAL_ERROR;
ganlikun 0:13413ea9a877 2632 }
ganlikun 0:13413ea9a877 2633 }
ganlikun 0:13413ea9a877 2634
ganlikun 0:13413ea9a877 2635 /**
ganlikun 0:13413ea9a877 2636 * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA.
ganlikun 0:13413ea9a877 2637 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2638 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 2639 * @param pCypherData: Pointer to the cyphertext buffer.
ganlikun 0:13413ea9a877 2640 * @param Size: Length of the cyphertext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 2641 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 2642 * @retval HAL status
ganlikun 0:13413ea9a877 2643 */
ganlikun 0:13413ea9a877 2644 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
ganlikun 0:13413ea9a877 2645 {
ganlikun 0:13413ea9a877 2646 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 2647 uint32_t inputaddr;
ganlikun 0:13413ea9a877 2648 uint32_t outputaddr;
ganlikun 0:13413ea9a877 2649
ganlikun 0:13413ea9a877 2650 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
ganlikun 0:13413ea9a877 2651 {
ganlikun 0:13413ea9a877 2652 /* Process Locked */
ganlikun 0:13413ea9a877 2653 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 2654
ganlikun 0:13413ea9a877 2655 inputaddr = (uint32_t)pCypherData;
ganlikun 0:13413ea9a877 2656 outputaddr = (uint32_t)pPlainData;
ganlikun 0:13413ea9a877 2657
ganlikun 0:13413ea9a877 2658 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 2659 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 2660
ganlikun 0:13413ea9a877 2661 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 2662 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 2663 {
ganlikun 0:13413ea9a877 2664 /* Set the key */
ganlikun 0:13413ea9a877 2665 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 2666
ganlikun 0:13413ea9a877 2667 /* Set the CRYP peripheral in AES GCM decryption mode */
ganlikun 0:13413ea9a877 2668 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT);
ganlikun 0:13413ea9a877 2669
ganlikun 0:13413ea9a877 2670 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 2671 CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect);
ganlikun 0:13413ea9a877 2672
ganlikun 0:13413ea9a877 2673 /* Enable CRYP to start the init phase */
ganlikun 0:13413ea9a877 2674 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2675
ganlikun 0:13413ea9a877 2676 /* Get tick */
ganlikun 0:13413ea9a877 2677 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2678
ganlikun 0:13413ea9a877 2679 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 2680 {
ganlikun 0:13413ea9a877 2681 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2682 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2683 {
ganlikun 0:13413ea9a877 2684 /* Change state */
ganlikun 0:13413ea9a877 2685 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2686
ganlikun 0:13413ea9a877 2687 /* Process Unlocked */
ganlikun 0:13413ea9a877 2688 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2689
ganlikun 0:13413ea9a877 2690 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2691 }
ganlikun 0:13413ea9a877 2692 }
ganlikun 0:13413ea9a877 2693
ganlikun 0:13413ea9a877 2694 /* Set the header phase */
ganlikun 0:13413ea9a877 2695 if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1U) != HAL_OK)
ganlikun 0:13413ea9a877 2696 {
ganlikun 0:13413ea9a877 2697 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2698 }
ganlikun 0:13413ea9a877 2699 /* Disable the CRYP peripheral */
ganlikun 0:13413ea9a877 2700 __HAL_CRYP_DISABLE(hcryp);
ganlikun 0:13413ea9a877 2701
ganlikun 0:13413ea9a877 2702 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 2703 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 2704
ganlikun 0:13413ea9a877 2705 /* Set the phase */
ganlikun 0:13413ea9a877 2706 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 2707 }
ganlikun 0:13413ea9a877 2708
ganlikun 0:13413ea9a877 2709 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 2710 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
ganlikun 0:13413ea9a877 2711
ganlikun 0:13413ea9a877 2712 /* Unlock process */
ganlikun 0:13413ea9a877 2713 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2714
ganlikun 0:13413ea9a877 2715 /* Return function status */
ganlikun 0:13413ea9a877 2716 return HAL_OK;
ganlikun 0:13413ea9a877 2717 }
ganlikun 0:13413ea9a877 2718 else
ganlikun 0:13413ea9a877 2719 {
ganlikun 0:13413ea9a877 2720 return HAL_ERROR;
ganlikun 0:13413ea9a877 2721 }
ganlikun 0:13413ea9a877 2722 }
ganlikun 0:13413ea9a877 2723
ganlikun 0:13413ea9a877 2724 /**
ganlikun 0:13413ea9a877 2725 * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA
ganlikun 0:13413ea9a877 2726 * then decrypted pCypherData. The cypher data are available in pPlainData.
ganlikun 0:13413ea9a877 2727 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2728 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 2729 * @param pCypherData: Pointer to the cyphertext buffer
ganlikun 0:13413ea9a877 2730 * @param Size: Length of the plaintext buffer, must be a multiple of 16
ganlikun 0:13413ea9a877 2731 * @param pPlainData: Pointer to the plaintext buffer
ganlikun 0:13413ea9a877 2732 * @retval HAL status
ganlikun 0:13413ea9a877 2733 */
ganlikun 0:13413ea9a877 2734 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData)
ganlikun 0:13413ea9a877 2735 {
ganlikun 0:13413ea9a877 2736 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 2737 uint32_t inputaddr;
ganlikun 0:13413ea9a877 2738 uint32_t outputaddr;
ganlikun 0:13413ea9a877 2739 uint32_t headersize;
ganlikun 0:13413ea9a877 2740 uint32_t headeraddr;
ganlikun 0:13413ea9a877 2741 uint32_t loopcounter = 0U;
ganlikun 0:13413ea9a877 2742 uint32_t bufferidx = 0U;
ganlikun 0:13413ea9a877 2743 uint8_t blockb0[16U] = {0};/* Block B0 */
ganlikun 0:13413ea9a877 2744 uint8_t ctr[16U] = {0}; /* Counter */
ganlikun 0:13413ea9a877 2745 uint32_t b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 2746
ganlikun 0:13413ea9a877 2747 if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS))
ganlikun 0:13413ea9a877 2748 {
ganlikun 0:13413ea9a877 2749 /* Process Locked */
ganlikun 0:13413ea9a877 2750 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 2751
ganlikun 0:13413ea9a877 2752 inputaddr = (uint32_t)pCypherData;
ganlikun 0:13413ea9a877 2753 outputaddr = (uint32_t)pPlainData;
ganlikun 0:13413ea9a877 2754
ganlikun 0:13413ea9a877 2755 headersize = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 2756 headeraddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 2757
ganlikun 0:13413ea9a877 2758 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 2759 hcryp->pCrypInBuffPtr = pCypherData;
ganlikun 0:13413ea9a877 2760 hcryp->pCrypOutBuffPtr = pPlainData;
ganlikun 0:13413ea9a877 2761 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 2762
ganlikun 0:13413ea9a877 2763 /* Change the CRYP peripheral state */
ganlikun 0:13413ea9a877 2764 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 2765
ganlikun 0:13413ea9a877 2766 /* Check if initialization phase has already been performed */
ganlikun 0:13413ea9a877 2767 if(hcryp->Phase == HAL_CRYP_PHASE_READY)
ganlikun 0:13413ea9a877 2768 {
ganlikun 0:13413ea9a877 2769 /************************ Formatting the header block *******************/
ganlikun 0:13413ea9a877 2770 if(headersize != 0U)
ganlikun 0:13413ea9a877 2771 {
ganlikun 0:13413ea9a877 2772 /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
ganlikun 0:13413ea9a877 2773 if(headersize < 65280U)
ganlikun 0:13413ea9a877 2774 {
ganlikun 0:13413ea9a877 2775 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF);
ganlikun 0:13413ea9a877 2776 hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF);
ganlikun 0:13413ea9a877 2777 headersize += 2U;
ganlikun 0:13413ea9a877 2778 }
ganlikun 0:13413ea9a877 2779 else
ganlikun 0:13413ea9a877 2780 {
ganlikun 0:13413ea9a877 2781 /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */
ganlikun 0:13413ea9a877 2782 hcryp->Init.pScratch[bufferidx++] = 0xFFU;
ganlikun 0:13413ea9a877 2783 hcryp->Init.pScratch[bufferidx++] = 0xFEU;
ganlikun 0:13413ea9a877 2784 hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000U;
ganlikun 0:13413ea9a877 2785 hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000U;
ganlikun 0:13413ea9a877 2786 hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00U;
ganlikun 0:13413ea9a877 2787 hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ffU;
ganlikun 0:13413ea9a877 2788 headersize += 6U;
ganlikun 0:13413ea9a877 2789 }
ganlikun 0:13413ea9a877 2790 /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */
ganlikun 0:13413ea9a877 2791 for(loopcounter = 0U; loopcounter < headersize; loopcounter++)
ganlikun 0:13413ea9a877 2792 {
ganlikun 0:13413ea9a877 2793 hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter];
ganlikun 0:13413ea9a877 2794 }
ganlikun 0:13413ea9a877 2795 /* Check if the header size is modulo 16 */
ganlikun 0:13413ea9a877 2796 if ((headersize % 16U) != 0U)
ganlikun 0:13413ea9a877 2797 {
ganlikun 0:13413ea9a877 2798 /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */
ganlikun 0:13413ea9a877 2799 for(loopcounter = headersize; loopcounter <= ((headersize/16U) + 1U) * 16U; loopcounter++)
ganlikun 0:13413ea9a877 2800 {
ganlikun 0:13413ea9a877 2801 hcryp->Init.pScratch[loopcounter] = 0U;
ganlikun 0:13413ea9a877 2802 }
ganlikun 0:13413ea9a877 2803 /* Set the header size to modulo 16 */
ganlikun 0:13413ea9a877 2804 headersize = ((headersize/16U) + 1U) * 16U;
ganlikun 0:13413ea9a877 2805 }
ganlikun 0:13413ea9a877 2806 /* Set the pointer headeraddr to hcryp->Init.pScratch */
ganlikun 0:13413ea9a877 2807 headeraddr = (uint32_t)hcryp->Init.pScratch;
ganlikun 0:13413ea9a877 2808 }
ganlikun 0:13413ea9a877 2809 /*********************** Formatting the block B0 ************************/
ganlikun 0:13413ea9a877 2810 if(headersize != 0U)
ganlikun 0:13413ea9a877 2811 {
ganlikun 0:13413ea9a877 2812 blockb0[0U] = 0x40U;
ganlikun 0:13413ea9a877 2813 }
ganlikun 0:13413ea9a877 2814 /* Flags byte */
ganlikun 0:13413ea9a877 2815 /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07U) */
ganlikun 0:13413ea9a877 2816 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07) << 3);
ganlikun 0:13413ea9a877 2817 blockb0[0U] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07);
ganlikun 0:13413ea9a877 2818
ganlikun 0:13413ea9a877 2819 for (loopcounter = 0U; loopcounter < hcryp->Init.IVSize; loopcounter++)
ganlikun 0:13413ea9a877 2820 {
ganlikun 0:13413ea9a877 2821 blockb0[loopcounter+1U] = hcryp->Init.pInitVect[loopcounter];
ganlikun 0:13413ea9a877 2822 }
ganlikun 0:13413ea9a877 2823 for ( ; loopcounter < 13U; loopcounter++)
ganlikun 0:13413ea9a877 2824 {
ganlikun 0:13413ea9a877 2825 blockb0[loopcounter+1U] = 0U;
ganlikun 0:13413ea9a877 2826 }
ganlikun 0:13413ea9a877 2827
ganlikun 0:13413ea9a877 2828 blockb0[14U] = (Size >> 8U);
ganlikun 0:13413ea9a877 2829 blockb0[15U] = (Size & 0xFFU);
ganlikun 0:13413ea9a877 2830
ganlikun 0:13413ea9a877 2831 /************************* Formatting the initial counter ***************/
ganlikun 0:13413ea9a877 2832 /* Byte 0:
ganlikun 0:13413ea9a877 2833 Bits 7 and 6 are reserved and shall be set to 0
ganlikun 0:13413ea9a877 2834 Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter
ganlikun 0:13413ea9a877 2835 blocks are distinct from B0
ganlikun 0:13413ea9a877 2836 Bits 0, 1, and 2 contain the same encoding of q as in B0
ganlikun 0:13413ea9a877 2837 */
ganlikun 0:13413ea9a877 2838 ctr[0U] = blockb0[0U] & 0x07U;
ganlikun 0:13413ea9a877 2839 /* byte 1 to NonceSize is the IV (Nonce) */
ganlikun 0:13413ea9a877 2840 for(loopcounter = 1U; loopcounter < hcryp->Init.IVSize + 1U; loopcounter++)
ganlikun 0:13413ea9a877 2841 {
ganlikun 0:13413ea9a877 2842 ctr[loopcounter] = blockb0[loopcounter];
ganlikun 0:13413ea9a877 2843 }
ganlikun 0:13413ea9a877 2844 /* Set the LSB to 1 */
ganlikun 0:13413ea9a877 2845 ctr[15U] |= 0x01U;
ganlikun 0:13413ea9a877 2846
ganlikun 0:13413ea9a877 2847 /* Set the key */
ganlikun 0:13413ea9a877 2848 CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize);
ganlikun 0:13413ea9a877 2849
ganlikun 0:13413ea9a877 2850 /* Set the CRYP peripheral in AES CCM mode */
ganlikun 0:13413ea9a877 2851 __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT);
ganlikun 0:13413ea9a877 2852
ganlikun 0:13413ea9a877 2853 /* Set the Initialization Vector */
ganlikun 0:13413ea9a877 2854 CRYPEx_GCMCCM_SetInitVector(hcryp, ctr);
ganlikun 0:13413ea9a877 2855
ganlikun 0:13413ea9a877 2856 /* Select init phase */
ganlikun 0:13413ea9a877 2857 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
ganlikun 0:13413ea9a877 2858
ganlikun 0:13413ea9a877 2859 b0addr = (uint32_t)blockb0;
ganlikun 0:13413ea9a877 2860 /* Write the blockb0 block in the IN FIFO */
ganlikun 0:13413ea9a877 2861 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2862 b0addr+=4U;
ganlikun 0:13413ea9a877 2863 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2864 b0addr+=4U;
ganlikun 0:13413ea9a877 2865 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2866 b0addr+=4U;
ganlikun 0:13413ea9a877 2867 hcryp->Instance->DR = *(uint32_t*)(b0addr);
ganlikun 0:13413ea9a877 2868
ganlikun 0:13413ea9a877 2869 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 2870 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2871
ganlikun 0:13413ea9a877 2872 /* Get tick */
ganlikun 0:13413ea9a877 2873 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2874
ganlikun 0:13413ea9a877 2875 while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
ganlikun 0:13413ea9a877 2876 {
ganlikun 0:13413ea9a877 2877 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2878
ganlikun 0:13413ea9a877 2879 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2880 {
ganlikun 0:13413ea9a877 2881 /* Change state */
ganlikun 0:13413ea9a877 2882 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2883
ganlikun 0:13413ea9a877 2884 /* Process Unlocked */
ganlikun 0:13413ea9a877 2885 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2886
ganlikun 0:13413ea9a877 2887 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2888
ganlikun 0:13413ea9a877 2889 }
ganlikun 0:13413ea9a877 2890 }
ganlikun 0:13413ea9a877 2891 /***************************** Header phase *****************************/
ganlikun 0:13413ea9a877 2892 if(headersize != 0U)
ganlikun 0:13413ea9a877 2893 {
ganlikun 0:13413ea9a877 2894 /* Select header phase */
ganlikun 0:13413ea9a877 2895 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
ganlikun 0:13413ea9a877 2896
ganlikun 0:13413ea9a877 2897 /* Enable Crypto processor */
ganlikun 0:13413ea9a877 2898 __HAL_CRYP_ENABLE(hcryp);
ganlikun 0:13413ea9a877 2899
ganlikun 0:13413ea9a877 2900 for(loopcounter = 0U; (loopcounter < headersize); loopcounter+=16U)
ganlikun 0:13413ea9a877 2901 {
ganlikun 0:13413ea9a877 2902 /* Get tick */
ganlikun 0:13413ea9a877 2903 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2904
ganlikun 0:13413ea9a877 2905 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM))
ganlikun 0:13413ea9a877 2906 {
ganlikun 0:13413ea9a877 2907 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2908 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2909 {
ganlikun 0:13413ea9a877 2910 /* Change state */
ganlikun 0:13413ea9a877 2911 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2912
ganlikun 0:13413ea9a877 2913 /* Process Unlocked */
ganlikun 0:13413ea9a877 2914 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2915
ganlikun 0:13413ea9a877 2916 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2917 }
ganlikun 0:13413ea9a877 2918 }
ganlikun 0:13413ea9a877 2919 /* Write the header block in the IN FIFO */
ganlikun 0:13413ea9a877 2920 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2921 headeraddr+=4U;
ganlikun 0:13413ea9a877 2922 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2923 headeraddr+=4U;
ganlikun 0:13413ea9a877 2924 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2925 headeraddr+=4U;
ganlikun 0:13413ea9a877 2926 hcryp->Instance->DR = *(uint32_t*)(headeraddr);
ganlikun 0:13413ea9a877 2927 headeraddr+=4U;
ganlikun 0:13413ea9a877 2928 }
ganlikun 0:13413ea9a877 2929
ganlikun 0:13413ea9a877 2930 /* Get tick */
ganlikun 0:13413ea9a877 2931 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 2932
ganlikun 0:13413ea9a877 2933 while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY)
ganlikun 0:13413ea9a877 2934 {
ganlikun 0:13413ea9a877 2935 /* Check for the Timeout */
ganlikun 0:13413ea9a877 2936 if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE)
ganlikun 0:13413ea9a877 2937 {
ganlikun 0:13413ea9a877 2938 /* Change state */
ganlikun 0:13413ea9a877 2939 hcryp->State = HAL_CRYP_STATE_TIMEOUT;
ganlikun 0:13413ea9a877 2940
ganlikun 0:13413ea9a877 2941 /* Process Unlocked */
ganlikun 0:13413ea9a877 2942 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2943
ganlikun 0:13413ea9a877 2944 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 2945 }
ganlikun 0:13413ea9a877 2946 }
ganlikun 0:13413ea9a877 2947 }
ganlikun 0:13413ea9a877 2948 /* Save formatted counter into the scratch buffer pScratch */
ganlikun 0:13413ea9a877 2949 for(loopcounter = 0U; (loopcounter < 16U); loopcounter++)
ganlikun 0:13413ea9a877 2950 {
ganlikun 0:13413ea9a877 2951 hcryp->Init.pScratch[loopcounter] = ctr[loopcounter];
ganlikun 0:13413ea9a877 2952 }
ganlikun 0:13413ea9a877 2953 /* Reset bit 0 */
ganlikun 0:13413ea9a877 2954 hcryp->Init.pScratch[15U] &= 0xFEU;
ganlikun 0:13413ea9a877 2955 /* Select payload phase once the header phase is performed */
ganlikun 0:13413ea9a877 2956 __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
ganlikun 0:13413ea9a877 2957
ganlikun 0:13413ea9a877 2958 /* Flush FIFO */
ganlikun 0:13413ea9a877 2959 __HAL_CRYP_FIFO_FLUSH(hcryp);
ganlikun 0:13413ea9a877 2960
ganlikun 0:13413ea9a877 2961 /* Set the phase */
ganlikun 0:13413ea9a877 2962 hcryp->Phase = HAL_CRYP_PHASE_PROCESS;
ganlikun 0:13413ea9a877 2963 }
ganlikun 0:13413ea9a877 2964 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 2965 CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
ganlikun 0:13413ea9a877 2966
ganlikun 0:13413ea9a877 2967 /* Unlock process */
ganlikun 0:13413ea9a877 2968 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 2969
ganlikun 0:13413ea9a877 2970 /* Return function status */
ganlikun 0:13413ea9a877 2971 return HAL_OK;
ganlikun 0:13413ea9a877 2972 }
ganlikun 0:13413ea9a877 2973 else
ganlikun 0:13413ea9a877 2974 {
ganlikun 0:13413ea9a877 2975 return HAL_ERROR;
ganlikun 0:13413ea9a877 2976 }
ganlikun 0:13413ea9a877 2977 }
ganlikun 0:13413ea9a877 2978
ganlikun 0:13413ea9a877 2979 /**
ganlikun 0:13413ea9a877 2980 * @}
ganlikun 0:13413ea9a877 2981 */
ganlikun 0:13413ea9a877 2982
ganlikun 0:13413ea9a877 2983 /** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management
ganlikun 0:13413ea9a877 2984 * @brief CRYPEx IRQ handler.
ganlikun 0:13413ea9a877 2985 *
ganlikun 0:13413ea9a877 2986 @verbatim
ganlikun 0:13413ea9a877 2987 ==============================================================================
ganlikun 0:13413ea9a877 2988 ##### CRYPEx IRQ handler management #####
ganlikun 0:13413ea9a877 2989 ==============================================================================
ganlikun 0:13413ea9a877 2990 [..] This section provides CRYPEx IRQ handler function.
ganlikun 0:13413ea9a877 2991
ganlikun 0:13413ea9a877 2992 @endverbatim
ganlikun 0:13413ea9a877 2993 * @{
ganlikun 0:13413ea9a877 2994 */
ganlikun 0:13413ea9a877 2995
ganlikun 0:13413ea9a877 2996 /**
ganlikun 0:13413ea9a877 2997 * @brief This function handles CRYPEx interrupt request.
ganlikun 0:13413ea9a877 2998 * @param hcryp: pointer to a CRYPEx_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2999 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3000 * @retval None
ganlikun 0:13413ea9a877 3001 */
ganlikun 0:13413ea9a877 3002
ganlikun 0:13413ea9a877 3003 void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp)
ganlikun 0:13413ea9a877 3004 {
ganlikun 0:13413ea9a877 3005 switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION)
ganlikun 0:13413ea9a877 3006 {
ganlikun 0:13413ea9a877 3007 case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT:
ganlikun 0:13413ea9a877 3008 HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0U, NULL);
ganlikun 0:13413ea9a877 3009 break;
ganlikun 0:13413ea9a877 3010
ganlikun 0:13413ea9a877 3011 case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT:
ganlikun 0:13413ea9a877 3012 HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0U, NULL);
ganlikun 0:13413ea9a877 3013 break;
ganlikun 0:13413ea9a877 3014
ganlikun 0:13413ea9a877 3015 case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT:
ganlikun 0:13413ea9a877 3016 HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0U, NULL);
ganlikun 0:13413ea9a877 3017 break;
ganlikun 0:13413ea9a877 3018
ganlikun 0:13413ea9a877 3019 case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT:
ganlikun 0:13413ea9a877 3020 HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0U, NULL);
ganlikun 0:13413ea9a877 3021 break;
ganlikun 0:13413ea9a877 3022
ganlikun 0:13413ea9a877 3023 default:
ganlikun 0:13413ea9a877 3024 break;
ganlikun 0:13413ea9a877 3025 }
ganlikun 0:13413ea9a877 3026 }
ganlikun 0:13413ea9a877 3027
ganlikun 0:13413ea9a877 3028 /**
ganlikun 0:13413ea9a877 3029 * @}
ganlikun 0:13413ea9a877 3030 */
ganlikun 0:13413ea9a877 3031
ganlikun 0:13413ea9a877 3032 /**
ganlikun 0:13413ea9a877 3033 * @}
ganlikun 0:13413ea9a877 3034 */
ganlikun 0:13413ea9a877 3035 #endif /* CRYP */
ganlikun 0:13413ea9a877 3036
ganlikun 0:13413ea9a877 3037 #if defined (AES)
ganlikun 0:13413ea9a877 3038
ganlikun 0:13413ea9a877 3039 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
ganlikun 0:13413ea9a877 3040 * @{
ganlikun 0:13413ea9a877 3041 */
ganlikun 0:13413ea9a877 3042 #define CRYP_CCF_TIMEOUTVALUE 22000U /*!< CCF flag raising time-out value */
ganlikun 0:13413ea9a877 3043 #define CRYP_BUSY_TIMEOUTVALUE 22000U /*!< BUSY flag reset time-out value */
ganlikun 0:13413ea9a877 3044
ganlikun 0:13413ea9a877 3045 #define CRYP_POLLING_OFF 0x0U /*!< No polling when padding */
ganlikun 0:13413ea9a877 3046 #define CRYP_POLLING_ON 0x1U /*!< Polling when padding */
ganlikun 0:13413ea9a877 3047 /**
ganlikun 0:13413ea9a877 3048 * @}
ganlikun 0:13413ea9a877 3049 */
ganlikun 0:13413ea9a877 3050
ganlikun 0:13413ea9a877 3051 /* Private macro -------------------------------------------------------------*/
ganlikun 0:13413ea9a877 3052 /* Private variables ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 3053 /* Private function prototypes -----------------------------------------------*/
ganlikun 0:13413ea9a877 3054 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
ganlikun 0:13413ea9a877 3055 * @{
ganlikun 0:13413ea9a877 3056 */
ganlikun 0:13413ea9a877 3057 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
ganlikun 0:13413ea9a877 3058 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
ganlikun 0:13413ea9a877 3059 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
ganlikun 0:13413ea9a877 3060 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
ganlikun 0:13413ea9a877 3061 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 3062 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 3063 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 3064 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
ganlikun 0:13413ea9a877 3065 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
ganlikun 0:13413ea9a877 3066 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 3067 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 3068 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 3069 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
ganlikun 0:13413ea9a877 3070 /**
ganlikun 0:13413ea9a877 3071 * @}
ganlikun 0:13413ea9a877 3072 */
ganlikun 0:13413ea9a877 3073
ganlikun 0:13413ea9a877 3074 /* Exported functions ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 3075
ganlikun 0:13413ea9a877 3076 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
ganlikun 0:13413ea9a877 3077 * @{
ganlikun 0:13413ea9a877 3078 */
ganlikun 0:13413ea9a877 3079
ganlikun 0:13413ea9a877 3080
ganlikun 0:13413ea9a877 3081 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
ganlikun 0:13413ea9a877 3082 * @brief Extended callback functions.
ganlikun 0:13413ea9a877 3083 *
ganlikun 0:13413ea9a877 3084 @verbatim
ganlikun 0:13413ea9a877 3085 ===============================================================================
ganlikun 0:13413ea9a877 3086 ##### Extended callback functions #####
ganlikun 0:13413ea9a877 3087 ===============================================================================
ganlikun 0:13413ea9a877 3088 [..] This section provides callback function:
ganlikun 0:13413ea9a877 3089 (+) Computation completed.
ganlikun 0:13413ea9a877 3090
ganlikun 0:13413ea9a877 3091 @endverbatim
ganlikun 0:13413ea9a877 3092 * @{
ganlikun 0:13413ea9a877 3093 */
ganlikun 0:13413ea9a877 3094
ganlikun 0:13413ea9a877 3095
ganlikun 0:13413ea9a877 3096 /**
ganlikun 0:13413ea9a877 3097 * @brief Computation completed callbacks.
ganlikun 0:13413ea9a877 3098 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 3099 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3100 * @retval None
ganlikun 0:13413ea9a877 3101 */
ganlikun 0:13413ea9a877 3102 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
ganlikun 0:13413ea9a877 3103 {
ganlikun 0:13413ea9a877 3104 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 3105 UNUSED(hcryp);
ganlikun 0:13413ea9a877 3106
ganlikun 0:13413ea9a877 3107 /* NOTE : This function should not be modified; when the callback is needed,
ganlikun 0:13413ea9a877 3108 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
ganlikun 0:13413ea9a877 3109 */
ganlikun 0:13413ea9a877 3110 }
ganlikun 0:13413ea9a877 3111
ganlikun 0:13413ea9a877 3112 /**
ganlikun 0:13413ea9a877 3113 * @}
ganlikun 0:13413ea9a877 3114 */
ganlikun 0:13413ea9a877 3115
ganlikun 0:13413ea9a877 3116 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
ganlikun 0:13413ea9a877 3117 * @brief Extended processing functions.
ganlikun 0:13413ea9a877 3118 *
ganlikun 0:13413ea9a877 3119 @verbatim
ganlikun 0:13413ea9a877 3120 ==============================================================================
ganlikun 0:13413ea9a877 3121 ##### AES extended processing functions #####
ganlikun 0:13413ea9a877 3122 ==============================================================================
ganlikun 0:13413ea9a877 3123 [..] This section provides functions allowing to:
ganlikun 0:13413ea9a877 3124 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
ganlikun 0:13413ea9a877 3125 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
ganlikun 0:13413ea9a877 3126 based on the processing type. Three processing types are available:
ganlikun 0:13413ea9a877 3127 (++) Polling mode
ganlikun 0:13413ea9a877 3128 (++) Interrupt mode
ganlikun 0:13413ea9a877 3129 (++) DMA mode
ganlikun 0:13413ea9a877 3130 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
ganlikun 0:13413ea9a877 3131 algorithm in different chaining modes.
ganlikun 0:13413ea9a877 3132 Functions are generic (handles GCM, GMAC, CMAC and CCM when applicable) and process only one phase
ganlikun 0:13413ea9a877 3133 so that steps can be skipped if so required. Functions are only differentiated based on the processing type.
ganlikun 0:13413ea9a877 3134 Three processing types are available:
ganlikun 0:13413ea9a877 3135 (++) Polling mode
ganlikun 0:13413ea9a877 3136 (++) Interrupt mode
ganlikun 0:13413ea9a877 3137 (++) DMA mode
ganlikun 0:13413ea9a877 3138
ganlikun 0:13413ea9a877 3139 @endverbatim
ganlikun 0:13413ea9a877 3140 * @{
ganlikun 0:13413ea9a877 3141 */
ganlikun 0:13413ea9a877 3142
ganlikun 0:13413ea9a877 3143 /**
ganlikun 0:13413ea9a877 3144 * @brief Carry out in polling mode the ciphering or deciphering operation according to
ganlikun 0:13413ea9a877 3145 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
ganlikun 0:13413ea9a877 3146 * chaining modes ECB, CBC and CTR are managed by this function in polling mode.
ganlikun 0:13413ea9a877 3147 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 3148 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3149 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
ganlikun 0:13413ea9a877 3150 * or key derivation+decryption.
ganlikun 0:13413ea9a877 3151 * Parameter is meaningless in case of key derivation.
ganlikun 0:13413ea9a877 3152 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
ganlikun 0:13413ea9a877 3153 * Parameter is meaningless in case of key derivation.
ganlikun 0:13413ea9a877 3154 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
ganlikun 0:13413ea9a877 3155 * decryption/key derivation+decryption, or pointer to the derivative keys in
ganlikun 0:13413ea9a877 3156 * case of key derivation only.
ganlikun 0:13413ea9a877 3157 * @param Timeout: Specify Timeout value
ganlikun 0:13413ea9a877 3158 * @retval HAL status
ganlikun 0:13413ea9a877 3159 */
ganlikun 0:13413ea9a877 3160 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
ganlikun 0:13413ea9a877 3161 {
ganlikun 0:13413ea9a877 3162
ganlikun 0:13413ea9a877 3163 if (hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 3164 {
ganlikun 0:13413ea9a877 3165 /* Check parameters setting */
ganlikun 0:13413ea9a877 3166 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
ganlikun 0:13413ea9a877 3167 {
ganlikun 0:13413ea9a877 3168 if (pOutputData == NULL)
ganlikun 0:13413ea9a877 3169 {
ganlikun 0:13413ea9a877 3170 return HAL_ERROR;
ganlikun 0:13413ea9a877 3171 }
ganlikun 0:13413ea9a877 3172 }
ganlikun 0:13413ea9a877 3173 else
ganlikun 0:13413ea9a877 3174 {
ganlikun 0:13413ea9a877 3175 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 3176 {
ganlikun 0:13413ea9a877 3177 return HAL_ERROR;
ganlikun 0:13413ea9a877 3178 }
ganlikun 0:13413ea9a877 3179 }
ganlikun 0:13413ea9a877 3180
ganlikun 0:13413ea9a877 3181 /* Process Locked */
ganlikun 0:13413ea9a877 3182 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 3183
ganlikun 0:13413ea9a877 3184 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3185 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 3186
ganlikun 0:13413ea9a877 3187 /* Call CRYP_ReadKey() API if the operating mode is set to
ganlikun 0:13413ea9a877 3188 key derivation, CRYP_ProcessData() otherwise */
ganlikun 0:13413ea9a877 3189 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
ganlikun 0:13413ea9a877 3190 {
ganlikun 0:13413ea9a877 3191 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3192 {
ganlikun 0:13413ea9a877 3193 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3194 }
ganlikun 0:13413ea9a877 3195 }
ganlikun 0:13413ea9a877 3196 else
ganlikun 0:13413ea9a877 3197 {
ganlikun 0:13413ea9a877 3198 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3199 {
ganlikun 0:13413ea9a877 3200 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3201 }
ganlikun 0:13413ea9a877 3202 }
ganlikun 0:13413ea9a877 3203
ganlikun 0:13413ea9a877 3204 /* If the state has not been set to SUSPENDED, set it to
ganlikun 0:13413ea9a877 3205 READY, otherwise keep it as it is */
ganlikun 0:13413ea9a877 3206 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
ganlikun 0:13413ea9a877 3207 {
ganlikun 0:13413ea9a877 3208 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3209 }
ganlikun 0:13413ea9a877 3210
ganlikun 0:13413ea9a877 3211 /* Process Unlocked */
ganlikun 0:13413ea9a877 3212 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3213
ganlikun 0:13413ea9a877 3214 return HAL_OK;
ganlikun 0:13413ea9a877 3215 }
ganlikun 0:13413ea9a877 3216 else
ganlikun 0:13413ea9a877 3217 {
ganlikun 0:13413ea9a877 3218 return HAL_BUSY;
ganlikun 0:13413ea9a877 3219 }
ganlikun 0:13413ea9a877 3220 }
ganlikun 0:13413ea9a877 3221
ganlikun 0:13413ea9a877 3222 /**
ganlikun 0:13413ea9a877 3223 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to
ganlikun 0:13413ea9a877 3224 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
ganlikun 0:13413ea9a877 3225 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
ganlikun 0:13413ea9a877 3226 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 3227 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3228 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
ganlikun 0:13413ea9a877 3229 * or key derivation+decryption.
ganlikun 0:13413ea9a877 3230 * Parameter is meaningless in case of key derivation.
ganlikun 0:13413ea9a877 3231 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
ganlikun 0:13413ea9a877 3232 * Parameter is meaningless in case of key derivation.
ganlikun 0:13413ea9a877 3233 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
ganlikun 0:13413ea9a877 3234 * decryption/key derivation+decryption, or pointer to the derivative keys in
ganlikun 0:13413ea9a877 3235 * case of key derivation only.
ganlikun 0:13413ea9a877 3236 * @retval HAL status
ganlikun 0:13413ea9a877 3237 */
ganlikun 0:13413ea9a877 3238 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
ganlikun 0:13413ea9a877 3239 {
ganlikun 0:13413ea9a877 3240 uint32_t inputaddr = 0U;
ganlikun 0:13413ea9a877 3241
ganlikun 0:13413ea9a877 3242 if(hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 3243 {
ganlikun 0:13413ea9a877 3244 /* Check parameters setting */
ganlikun 0:13413ea9a877 3245 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
ganlikun 0:13413ea9a877 3246 {
ganlikun 0:13413ea9a877 3247 if (pOutputData == NULL)
ganlikun 0:13413ea9a877 3248 {
ganlikun 0:13413ea9a877 3249 return HAL_ERROR;
ganlikun 0:13413ea9a877 3250 }
ganlikun 0:13413ea9a877 3251 }
ganlikun 0:13413ea9a877 3252 else
ganlikun 0:13413ea9a877 3253 {
ganlikun 0:13413ea9a877 3254 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 3255 {
ganlikun 0:13413ea9a877 3256 return HAL_ERROR;
ganlikun 0:13413ea9a877 3257 }
ganlikun 0:13413ea9a877 3258 }
ganlikun 0:13413ea9a877 3259 /* Process Locked */
ganlikun 0:13413ea9a877 3260 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 3261
ganlikun 0:13413ea9a877 3262 /* If operating mode is not limited to key derivation only,
ganlikun 0:13413ea9a877 3263 get the buffers addresses and sizes */
ganlikun 0:13413ea9a877 3264 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
ganlikun 0:13413ea9a877 3265 {
ganlikun 0:13413ea9a877 3266
ganlikun 0:13413ea9a877 3267 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 3268 hcryp->pCrypInBuffPtr = pInputData;
ganlikun 0:13413ea9a877 3269 hcryp->pCrypOutBuffPtr = pOutputData;
ganlikun 0:13413ea9a877 3270 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 3271 }
ganlikun 0:13413ea9a877 3272
ganlikun 0:13413ea9a877 3273 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3274 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 3275
ganlikun 0:13413ea9a877 3276 /* Process Unlocked */
ganlikun 0:13413ea9a877 3277 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3278
ganlikun 0:13413ea9a877 3279 /* Enable Computation Complete Flag and Error Interrupts */
ganlikun 0:13413ea9a877 3280 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 3281
ganlikun 0:13413ea9a877 3282 /* If operating mode is key derivation only, the input data have
ganlikun 0:13413ea9a877 3283 already been entered during the initialization process. For
ganlikun 0:13413ea9a877 3284 the other operating modes, they are fed to the CRYP hardware
ganlikun 0:13413ea9a877 3285 block at this point. */
ganlikun 0:13413ea9a877 3286 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
ganlikun 0:13413ea9a877 3287 {
ganlikun 0:13413ea9a877 3288 /* Initiate the processing under interrupt in entering
ganlikun 0:13413ea9a877 3289 the first input data */
ganlikun 0:13413ea9a877 3290 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 3291 /* Increment/decrement instance pointer/counter */
ganlikun 0:13413ea9a877 3292 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 3293 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 3294 /* Write the first input block in the Data Input register */
ganlikun 0:13413ea9a877 3295 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3296 inputaddr+=4U;
ganlikun 0:13413ea9a877 3297 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3298 inputaddr+=4U;
ganlikun 0:13413ea9a877 3299 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3300 inputaddr+=4U;
ganlikun 0:13413ea9a877 3301 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3302 }
ganlikun 0:13413ea9a877 3303
ganlikun 0:13413ea9a877 3304 /* Return function status */
ganlikun 0:13413ea9a877 3305 return HAL_OK;
ganlikun 0:13413ea9a877 3306 }
ganlikun 0:13413ea9a877 3307 else
ganlikun 0:13413ea9a877 3308 {
ganlikun 0:13413ea9a877 3309 return HAL_BUSY;
ganlikun 0:13413ea9a877 3310 }
ganlikun 0:13413ea9a877 3311 }
ganlikun 0:13413ea9a877 3312
ganlikun 0:13413ea9a877 3313 /**
ganlikun 0:13413ea9a877 3314 * @brief Carry out in DMA mode the ciphering or deciphering operation according to
ganlikun 0:13413ea9a877 3315 * hcryp->Init structure fields.
ganlikun 0:13413ea9a877 3316 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 3317 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3318 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
ganlikun 0:13413ea9a877 3319 * or key derivation+decryption.
ganlikun 0:13413ea9a877 3320 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
ganlikun 0:13413ea9a877 3321 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
ganlikun 0:13413ea9a877 3322 * decryption/key derivation+decryption.
ganlikun 0:13413ea9a877 3323 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
ganlikun 0:13413ea9a877 3324 * @note Supported operating modes are encryption, decryption and key derivation with decryption.
ganlikun 0:13413ea9a877 3325 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
ganlikun 0:13413ea9a877 3326 * registers must be done by software.
ganlikun 0:13413ea9a877 3327 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
ganlikun 0:13413ea9a877 3328 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
ganlikun 0:13413ea9a877 3329 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
ganlikun 0:13413ea9a877 3330 * @retval HAL status
ganlikun 0:13413ea9a877 3331 */
ganlikun 0:13413ea9a877 3332 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
ganlikun 0:13413ea9a877 3333 {
ganlikun 0:13413ea9a877 3334 uint32_t inputaddr = 0U;
ganlikun 0:13413ea9a877 3335 uint32_t outputaddr = 0U;
ganlikun 0:13413ea9a877 3336
ganlikun 0:13413ea9a877 3337 if (hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 3338 {
ganlikun 0:13413ea9a877 3339 /* Check parameters setting */
ganlikun 0:13413ea9a877 3340 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
ganlikun 0:13413ea9a877 3341 {
ganlikun 0:13413ea9a877 3342 /* no DMA channel is provided for key derivation operating mode,
ganlikun 0:13413ea9a877 3343 access to AES_KEYRx registers must be done by software */
ganlikun 0:13413ea9a877 3344 return HAL_ERROR;
ganlikun 0:13413ea9a877 3345 }
ganlikun 0:13413ea9a877 3346 else
ganlikun 0:13413ea9a877 3347 {
ganlikun 0:13413ea9a877 3348 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 3349 {
ganlikun 0:13413ea9a877 3350 return HAL_ERROR;
ganlikun 0:13413ea9a877 3351 }
ganlikun 0:13413ea9a877 3352 }
ganlikun 0:13413ea9a877 3353
ganlikun 0:13413ea9a877 3354 /* Process Locked */
ganlikun 0:13413ea9a877 3355 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 3356
ganlikun 0:13413ea9a877 3357 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 3358 outputaddr = (uint32_t)pOutputData;
ganlikun 0:13413ea9a877 3359
ganlikun 0:13413ea9a877 3360 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3361 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 3362
ganlikun 0:13413ea9a877 3363 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 3364 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
ganlikun 0:13413ea9a877 3365
ganlikun 0:13413ea9a877 3366 /* Process Unlocked */
ganlikun 0:13413ea9a877 3367 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3368
ganlikun 0:13413ea9a877 3369 /* Return function status */
ganlikun 0:13413ea9a877 3370 return HAL_OK;
ganlikun 0:13413ea9a877 3371 }
ganlikun 0:13413ea9a877 3372 else
ganlikun 0:13413ea9a877 3373 {
ganlikun 0:13413ea9a877 3374 return HAL_BUSY;
ganlikun 0:13413ea9a877 3375 }
ganlikun 0:13413ea9a877 3376 }
ganlikun 0:13413ea9a877 3377
ganlikun 0:13413ea9a877 3378 /**
ganlikun 0:13413ea9a877 3379 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
ganlikun 0:13413ea9a877 3380 * operation according to hcryp->Init structure fields.
ganlikun 0:13413ea9a877 3381 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 3382 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3383 * @param pInputData:
ganlikun 0:13413ea9a877 3384 * - pointer to payload data in GCM payload phase,
ganlikun 0:13413ea9a877 3385 * - pointer to B0 block in CMAC header phase,
ganlikun 0:13413ea9a877 3386 * - pointer to C block in CMAC final phase.
ganlikun 0:13413ea9a877 3387 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases.
ganlikun 0:13413ea9a877 3388 * @param Size:
ganlikun 0:13413ea9a877 3389 * - length of the input payload data buffer in bytes,
ganlikun 0:13413ea9a877 3390 * - length of B0 block (in bytes) in CMAC header phase,
ganlikun 0:13413ea9a877 3391 * - length of C block (in bytes) in CMAC final phase.
ganlikun 0:13413ea9a877 3392 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
ganlikun 0:13413ea9a877 3393 * @param pOutputData:
ganlikun 0:13413ea9a877 3394 * - pointer to plain or cipher text in GCM payload phase,
ganlikun 0:13413ea9a877 3395 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
ganlikun 0:13413ea9a877 3396 * - Parameter is meaningless in case of GCM/GMAC init and header phases
ganlikun 0:13413ea9a877 3397 * and in case of CMAC header phase.
ganlikun 0:13413ea9a877 3398 * @param Timeout: Specify Timeout value
ganlikun 0:13413ea9a877 3399 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC, CMAC and CCM when the latter is applicable.
ganlikun 0:13413ea9a877 3400 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
ganlikun 0:13413ea9a877 3401 * can be skipped by the user if so required.
ganlikun 0:13413ea9a877 3402 * @retval HAL status
ganlikun 0:13413ea9a877 3403 */
ganlikun 0:13413ea9a877 3404 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
ganlikun 0:13413ea9a877 3405 {
ganlikun 0:13413ea9a877 3406 uint32_t index = 0U;
ganlikun 0:13413ea9a877 3407 uint32_t inputaddr = 0U;
ganlikun 0:13413ea9a877 3408 uint32_t outputaddr = 0U;
ganlikun 0:13413ea9a877 3409 uint32_t tagaddr = 0U;
ganlikun 0:13413ea9a877 3410 uint64_t headerlength = 0U;
ganlikun 0:13413ea9a877 3411 uint64_t inputlength = 0U;
ganlikun 0:13413ea9a877 3412 uint64_t payloadlength = 0U;
ganlikun 0:13413ea9a877 3413 uint32_t difflength = 0U;
ganlikun 0:13413ea9a877 3414 uint32_t addhoc_process = 0U;
ganlikun 0:13413ea9a877 3415
ganlikun 0:13413ea9a877 3416 if (hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 3417 {
ganlikun 0:13413ea9a877 3418 /* input/output parameters check */
ganlikun 0:13413ea9a877 3419 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 3420 {
ganlikun 0:13413ea9a877 3421 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
ganlikun 0:13413ea9a877 3422 {
ganlikun 0:13413ea9a877 3423 return HAL_ERROR;
ganlikun 0:13413ea9a877 3424 }
ganlikun 0:13413ea9a877 3425 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3426 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 3427 #else
ganlikun 0:13413ea9a877 3428 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 3429 #endif
ganlikun 0:13413ea9a877 3430 {
ganlikun 0:13413ea9a877 3431 /* In case of CMAC (or CCM) header phase resumption, we can have pInputData = NULL and Size = 0 */
ganlikun 0:13413ea9a877 3432 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
ganlikun 0:13413ea9a877 3433 {
ganlikun 0:13413ea9a877 3434 return HAL_ERROR;
ganlikun 0:13413ea9a877 3435 }
ganlikun 0:13413ea9a877 3436 }
ganlikun 0:13413ea9a877 3437 }
ganlikun 0:13413ea9a877 3438 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 3439 {
ganlikun 0:13413ea9a877 3440 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 3441 {
ganlikun 0:13413ea9a877 3442 return HAL_ERROR;
ganlikun 0:13413ea9a877 3443 }
ganlikun 0:13413ea9a877 3444 }
ganlikun 0:13413ea9a877 3445 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 3446 {
ganlikun 0:13413ea9a877 3447 if (pOutputData == NULL)
ganlikun 0:13413ea9a877 3448 {
ganlikun 0:13413ea9a877 3449 return HAL_ERROR;
ganlikun 0:13413ea9a877 3450 }
ganlikun 0:13413ea9a877 3451 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3452 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
ganlikun 0:13413ea9a877 3453 #else
ganlikun 0:13413ea9a877 3454 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
ganlikun 0:13413ea9a877 3455 #endif
ganlikun 0:13413ea9a877 3456 {
ganlikun 0:13413ea9a877 3457 return HAL_ERROR;
ganlikun 0:13413ea9a877 3458 }
ganlikun 0:13413ea9a877 3459 }
ganlikun 0:13413ea9a877 3460
ganlikun 0:13413ea9a877 3461 /* Process Locked */
ganlikun 0:13413ea9a877 3462 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 3463
ganlikun 0:13413ea9a877 3464 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3465 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 3466
ganlikun 0:13413ea9a877 3467 /*==============================================*/
ganlikun 0:13413ea9a877 3468 /* GCM/GMAC (or CCM when applicable) init phase */
ganlikun 0:13413ea9a877 3469 /*==============================================*/
ganlikun 0:13413ea9a877 3470 /* In case of init phase, the input data (Key and Initialization Vector) have
ganlikun 0:13413ea9a877 3471 already been entered during the initialization process. Therefore, the
ganlikun 0:13413ea9a877 3472 API just waits for the CCF flag to be set. */
ganlikun 0:13413ea9a877 3473 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
ganlikun 0:13413ea9a877 3474 {
ganlikun 0:13413ea9a877 3475 /* just wait for hash computation */
ganlikun 0:13413ea9a877 3476 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3477 {
ganlikun 0:13413ea9a877 3478 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3479 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3480 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3481 }
ganlikun 0:13413ea9a877 3482
ganlikun 0:13413ea9a877 3483 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 3484 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 3485 /* Mark that the initialization phase is over */
ganlikun 0:13413ea9a877 3486 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
ganlikun 0:13413ea9a877 3487 }
ganlikun 0:13413ea9a877 3488 /*=====================================*/
ganlikun 0:13413ea9a877 3489 /* GCM/GMAC or (CCM/)CMAC header phase */
ganlikun 0:13413ea9a877 3490 /*=====================================*/
ganlikun 0:13413ea9a877 3491 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 3492 {
ganlikun 0:13413ea9a877 3493 /* Set header phase; for GCM or GMAC, set data-byte at this point */
ganlikun 0:13413ea9a877 3494 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 3495 {
ganlikun 0:13413ea9a877 3496 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
ganlikun 0:13413ea9a877 3497 }
ganlikun 0:13413ea9a877 3498 else
ganlikun 0:13413ea9a877 3499 {
ganlikun 0:13413ea9a877 3500 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
ganlikun 0:13413ea9a877 3501 }
ganlikun 0:13413ea9a877 3502
ganlikun 0:13413ea9a877 3503 /* Enable the Peripheral */
ganlikun 0:13413ea9a877 3504 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 3505
ganlikun 0:13413ea9a877 3506 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3507 /* in case of CMAC, enter B0 block in header phase, before the header itself. */
ganlikun 0:13413ea9a877 3508 /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
ganlikun 0:13413ea9a877 3509 skip these steps and go directly to header buffer feeding to the HW */
ganlikun 0:13413ea9a877 3510 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0U))
ganlikun 0:13413ea9a877 3511 {
ganlikun 0:13413ea9a877 3512 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 3513
ganlikun 0:13413ea9a877 3514 for(index=0U; (index < Size); index += 16U)
ganlikun 0:13413ea9a877 3515 {
ganlikun 0:13413ea9a877 3516 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 3517 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3518 inputaddr+=4U;
ganlikun 0:13413ea9a877 3519 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3520 inputaddr+=4U;
ganlikun 0:13413ea9a877 3521 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3522 inputaddr+=4U;
ganlikun 0:13413ea9a877 3523 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3524 inputaddr+=4U;
ganlikun 0:13413ea9a877 3525
ganlikun 0:13413ea9a877 3526 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3527 {
ganlikun 0:13413ea9a877 3528 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3529 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3530 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3531 }
ganlikun 0:13413ea9a877 3532 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 3533 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 3534
ganlikun 0:13413ea9a877 3535 /* If the suspension flag has been raised and if the processing is not about
ganlikun 0:13413ea9a877 3536 to end, suspend processing */
ganlikun 0:13413ea9a877 3537 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Size))
ganlikun 0:13413ea9a877 3538 {
ganlikun 0:13413ea9a877 3539 /* reset SuspendRequest */
ganlikun 0:13413ea9a877 3540 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
ganlikun 0:13413ea9a877 3541 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3542 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
ganlikun 0:13413ea9a877 3543 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 3544 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
ganlikun 0:13413ea9a877 3545
ganlikun 0:13413ea9a877 3546 /* Save current reading and writing locations of Input and Output buffers */
ganlikun 0:13413ea9a877 3547 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 3548 /* Save the total number of bytes (B blocks + header) that remain to be
ganlikun 0:13413ea9a877 3549 processed at this point */
ganlikun 0:13413ea9a877 3550 hcryp->CrypInCount = hcryp->Init.HeaderSize + Size - (index+16U);
ganlikun 0:13413ea9a877 3551
ganlikun 0:13413ea9a877 3552 /* Process Unlocked */
ganlikun 0:13413ea9a877 3553 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3554
ganlikun 0:13413ea9a877 3555 return HAL_OK;
ganlikun 0:13413ea9a877 3556 }
ganlikun 0:13413ea9a877 3557 } /* for(index=0; (index < Size); index += 16) */
ganlikun 0:13413ea9a877 3558 }
ganlikun 0:13413ea9a877 3559 #endif /* !defined(AES_CR_NPBLB) */
ganlikun 0:13413ea9a877 3560
ganlikun 0:13413ea9a877 3561 /* Enter header */
ganlikun 0:13413ea9a877 3562 inputaddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 3563 /* Local variable headerlength is a number of bytes multiple of 128 bits,
ganlikun 0:13413ea9a877 3564 remaining header data (if any) are handled after this loop */
ganlikun 0:13413ea9a877 3565 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
ganlikun 0:13413ea9a877 3566 if ((hcryp->Init.HeaderSize % 16U) != 0U)
ganlikun 0:13413ea9a877 3567 {
ganlikun 0:13413ea9a877 3568 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
ganlikun 0:13413ea9a877 3569 }
ganlikun 0:13413ea9a877 3570 for(index=0U; index < headerlength; index += 16U)
ganlikun 0:13413ea9a877 3571 {
ganlikun 0:13413ea9a877 3572 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 3573 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3574 inputaddr+=4U;
ganlikun 0:13413ea9a877 3575 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3576 inputaddr+=4U;
ganlikun 0:13413ea9a877 3577 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3578 inputaddr+=4U;
ganlikun 0:13413ea9a877 3579 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3580 inputaddr+=4U;
ganlikun 0:13413ea9a877 3581
ganlikun 0:13413ea9a877 3582 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3583 {
ganlikun 0:13413ea9a877 3584 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3585 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3586 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3587 }
ganlikun 0:13413ea9a877 3588 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 3589 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 3590
ganlikun 0:13413ea9a877 3591 /* If the suspension flag has been raised and if the processing is not about
ganlikun 0:13413ea9a877 3592 to end, suspend processing */
ganlikun 0:13413ea9a877 3593 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < headerlength))
ganlikun 0:13413ea9a877 3594 {
ganlikun 0:13413ea9a877 3595 /* reset SuspendRequest */
ganlikun 0:13413ea9a877 3596 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
ganlikun 0:13413ea9a877 3597 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3598 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
ganlikun 0:13413ea9a877 3599 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 3600 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
ganlikun 0:13413ea9a877 3601
ganlikun 0:13413ea9a877 3602 /* Save current reading and writing locations of Input and Output buffers */
ganlikun 0:13413ea9a877 3603 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 3604 /* Save the total number of bytes that remain to be processed at this point */
ganlikun 0:13413ea9a877 3605 hcryp->CrypInCount = hcryp->Init.HeaderSize - (index+16U);
ganlikun 0:13413ea9a877 3606
ganlikun 0:13413ea9a877 3607 /* Process Unlocked */
ganlikun 0:13413ea9a877 3608 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3609
ganlikun 0:13413ea9a877 3610 return HAL_OK;
ganlikun 0:13413ea9a877 3611 }
ganlikun 0:13413ea9a877 3612 }
ganlikun 0:13413ea9a877 3613
ganlikun 0:13413ea9a877 3614 /* Case header length is not a multiple of 16 bytes */
ganlikun 0:13413ea9a877 3615 if (difflength != 0U)
ganlikun 0:13413ea9a877 3616 {
ganlikun 0:13413ea9a877 3617 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 3618 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
ganlikun 0:13413ea9a877 3619 }
ganlikun 0:13413ea9a877 3620
ganlikun 0:13413ea9a877 3621 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 3622 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
ganlikun 0:13413ea9a877 3623 }
ganlikun 0:13413ea9a877 3624 /*============================================*/
ganlikun 0:13413ea9a877 3625 /* GCM (or CCM when applicable) payload phase */
ganlikun 0:13413ea9a877 3626 /*============================================*/
ganlikun 0:13413ea9a877 3627 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 3628 {
ganlikun 0:13413ea9a877 3629
ganlikun 0:13413ea9a877 3630 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
ganlikun 0:13413ea9a877 3631
ganlikun 0:13413ea9a877 3632 /* if the header phase has been bypassed, AES must be enabled again */
ganlikun 0:13413ea9a877 3633 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
ganlikun 0:13413ea9a877 3634 {
ganlikun 0:13413ea9a877 3635 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 3636 }
ganlikun 0:13413ea9a877 3637
ganlikun 0:13413ea9a877 3638 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 3639 outputaddr = (uint32_t)pOutputData;
ganlikun 0:13413ea9a877 3640
ganlikun 0:13413ea9a877 3641 /* Enter payload */
ganlikun 0:13413ea9a877 3642 /* Specific handling to manage payload last block size less than 128 bits */
ganlikun 0:13413ea9a877 3643 if ((Size % 16U) != 0U)
ganlikun 0:13413ea9a877 3644 {
ganlikun 0:13413ea9a877 3645 payloadlength = (Size/16U) * 16U;
ganlikun 0:13413ea9a877 3646 difflength = (uint32_t) (Size - payloadlength);
ganlikun 0:13413ea9a877 3647 addhoc_process = 1U;
ganlikun 0:13413ea9a877 3648 }
ganlikun 0:13413ea9a877 3649 else
ganlikun 0:13413ea9a877 3650 {
ganlikun 0:13413ea9a877 3651 payloadlength = Size;
ganlikun 0:13413ea9a877 3652 addhoc_process = 0U;
ganlikun 0:13413ea9a877 3653 }
ganlikun 0:13413ea9a877 3654
ganlikun 0:13413ea9a877 3655 /* Feed payload */
ganlikun 0:13413ea9a877 3656 for(index=0U; index < payloadlength; index += 16U)
ganlikun 0:13413ea9a877 3657 {
ganlikun 0:13413ea9a877 3658 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 3659 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3660 inputaddr+=4U;
ganlikun 0:13413ea9a877 3661 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3662 inputaddr+=4U;
ganlikun 0:13413ea9a877 3663 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3664 inputaddr+=4U;
ganlikun 0:13413ea9a877 3665 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3666 inputaddr+=4U;
ganlikun 0:13413ea9a877 3667
ganlikun 0:13413ea9a877 3668 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3669 {
ganlikun 0:13413ea9a877 3670 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3671 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3672 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3673 }
ganlikun 0:13413ea9a877 3674
ganlikun 0:13413ea9a877 3675 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 3676 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 3677
ganlikun 0:13413ea9a877 3678 /* Retrieve output data: read the output block
ganlikun 0:13413ea9a877 3679 from the Data Output Register */
ganlikun 0:13413ea9a877 3680 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3681 outputaddr+=4U;
ganlikun 0:13413ea9a877 3682 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3683 outputaddr+=4U;
ganlikun 0:13413ea9a877 3684 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3685 outputaddr+=4U;
ganlikun 0:13413ea9a877 3686 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3687 outputaddr+=4U;
ganlikun 0:13413ea9a877 3688
ganlikun 0:13413ea9a877 3689 /* If the suspension flag has been raised and if the processing is not about
ganlikun 0:13413ea9a877 3690 to end, suspend processing */
ganlikun 0:13413ea9a877 3691 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < payloadlength))
ganlikun 0:13413ea9a877 3692 {
ganlikun 0:13413ea9a877 3693 /* no flag waiting under IRQ handling */
ganlikun 0:13413ea9a877 3694 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
ganlikun 0:13413ea9a877 3695 {
ganlikun 0:13413ea9a877 3696 /* Ensure that Busy flag is reset */
ganlikun 0:13413ea9a877 3697 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 3698 {
ganlikun 0:13413ea9a877 3699 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3700 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3701 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3702 }
ganlikun 0:13413ea9a877 3703 }
ganlikun 0:13413ea9a877 3704 /* reset SuspendRequest */
ganlikun 0:13413ea9a877 3705 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
ganlikun 0:13413ea9a877 3706 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3707 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
ganlikun 0:13413ea9a877 3708 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 3709 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
ganlikun 0:13413ea9a877 3710
ganlikun 0:13413ea9a877 3711 /* Save current reading and writing locations of Input and Output buffers */
ganlikun 0:13413ea9a877 3712 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
ganlikun 0:13413ea9a877 3713 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 3714 /* Save the number of bytes that remain to be processed at this point */
ganlikun 0:13413ea9a877 3715 hcryp->CrypInCount = Size - (index+16U);
ganlikun 0:13413ea9a877 3716
ganlikun 0:13413ea9a877 3717 /* Process Unlocked */
ganlikun 0:13413ea9a877 3718 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3719
ganlikun 0:13413ea9a877 3720 return HAL_OK;
ganlikun 0:13413ea9a877 3721 }
ganlikun 0:13413ea9a877 3722
ganlikun 0:13413ea9a877 3723 }
ganlikun 0:13413ea9a877 3724
ganlikun 0:13413ea9a877 3725 /* Additional processing to manage GCM(/CCM) encryption and decryption cases when
ganlikun 0:13413ea9a877 3726 payload last block size less than 128 bits */
ganlikun 0:13413ea9a877 3727 if (addhoc_process == 1U)
ganlikun 0:13413ea9a877 3728 {
ganlikun 0:13413ea9a877 3729 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 3730 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
ganlikun 0:13413ea9a877 3731 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
ganlikun 0:13413ea9a877 3732 } /* (addhoc_process == 1) */
ganlikun 0:13413ea9a877 3733
ganlikun 0:13413ea9a877 3734 /* Mark that the payload phase is over */
ganlikun 0:13413ea9a877 3735 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
ganlikun 0:13413ea9a877 3736 }
ganlikun 0:13413ea9a877 3737 /*====================================*/
ganlikun 0:13413ea9a877 3738 /* GCM/GMAC or (CCM/)CMAC final phase */
ganlikun 0:13413ea9a877 3739 /*====================================*/
ganlikun 0:13413ea9a877 3740 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 3741 {
ganlikun 0:13413ea9a877 3742 tagaddr = (uint32_t)pOutputData;
ganlikun 0:13413ea9a877 3743
ganlikun 0:13413ea9a877 3744 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3745 /* By default, clear NPBLB field */
ganlikun 0:13413ea9a877 3746 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
ganlikun 0:13413ea9a877 3747 #endif
ganlikun 0:13413ea9a877 3748
ganlikun 0:13413ea9a877 3749 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
ganlikun 0:13413ea9a877 3750
ganlikun 0:13413ea9a877 3751 /* if the header and payload phases have been bypassed, AES must be enabled again */
ganlikun 0:13413ea9a877 3752 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
ganlikun 0:13413ea9a877 3753 {
ganlikun 0:13413ea9a877 3754 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 3755 }
ganlikun 0:13413ea9a877 3756
ganlikun 0:13413ea9a877 3757 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 3758 {
ganlikun 0:13413ea9a877 3759 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
ganlikun 0:13413ea9a877 3760 inputlength = Size * 8U; /* input length in bits */
ganlikun 0:13413ea9a877 3761
ganlikun 0:13413ea9a877 3762
ganlikun 0:13413ea9a877 3763 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
ganlikun 0:13413ea9a877 3764 {
ganlikun 0:13413ea9a877 3765 hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
ganlikun 0:13413ea9a877 3766 hcryp->Instance->DINR = __RBIT(headerlength);
ganlikun 0:13413ea9a877 3767 hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
ganlikun 0:13413ea9a877 3768 hcryp->Instance->DINR = __RBIT(inputlength);
ganlikun 0:13413ea9a877 3769 }
ganlikun 0:13413ea9a877 3770 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
ganlikun 0:13413ea9a877 3771 {
ganlikun 0:13413ea9a877 3772 hcryp->Instance->DINR = __REV((headerlength)>>32U);
ganlikun 0:13413ea9a877 3773 hcryp->Instance->DINR = __REV(headerlength);
ganlikun 0:13413ea9a877 3774 hcryp->Instance->DINR = __REV((inputlength)>>32U);
ganlikun 0:13413ea9a877 3775 hcryp->Instance->DINR = __REV(inputlength);
ganlikun 0:13413ea9a877 3776 }
ganlikun 0:13413ea9a877 3777 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
ganlikun 0:13413ea9a877 3778 {
ganlikun 0:13413ea9a877 3779 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
ganlikun 0:13413ea9a877 3780 hcryp->Instance->DINR = __ROR(headerlength, 16U);
ganlikun 0:13413ea9a877 3781 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
ganlikun 0:13413ea9a877 3782 hcryp->Instance->DINR = __ROR(inputlength, 16U);
ganlikun 0:13413ea9a877 3783 }
ganlikun 0:13413ea9a877 3784 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
ganlikun 0:13413ea9a877 3785 {
ganlikun 0:13413ea9a877 3786 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
ganlikun 0:13413ea9a877 3787 hcryp->Instance->DINR = (uint32_t)(headerlength);
ganlikun 0:13413ea9a877 3788 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
ganlikun 0:13413ea9a877 3789 hcryp->Instance->DINR = (uint32_t)(inputlength);
ganlikun 0:13413ea9a877 3790 }
ganlikun 0:13413ea9a877 3791 }
ganlikun 0:13413ea9a877 3792 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3793 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 3794 {
ganlikun 0:13413ea9a877 3795 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 3796 /* Enter the last block made of a 128-bit value formatted
ganlikun 0:13413ea9a877 3797 from the original B0 packet. */
ganlikun 0:13413ea9a877 3798 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3799 inputaddr+=4U;
ganlikun 0:13413ea9a877 3800 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3801 inputaddr+=4U;
ganlikun 0:13413ea9a877 3802 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3803 inputaddr+=4U;
ganlikun 0:13413ea9a877 3804 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 3805 }
ganlikun 0:13413ea9a877 3806 #endif
ganlikun 0:13413ea9a877 3807
ganlikun 0:13413ea9a877 3808
ganlikun 0:13413ea9a877 3809 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 3810 {
ganlikun 0:13413ea9a877 3811 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3812 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3813 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 3814 }
ganlikun 0:13413ea9a877 3815
ganlikun 0:13413ea9a877 3816 /* Read the Auth TAG in the Data Out register */
ganlikun 0:13413ea9a877 3817 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3818 tagaddr+=4U;
ganlikun 0:13413ea9a877 3819 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3820 tagaddr+=4U;
ganlikun 0:13413ea9a877 3821 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3822 tagaddr+=4U;
ganlikun 0:13413ea9a877 3823 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 3824
ganlikun 0:13413ea9a877 3825
ganlikun 0:13413ea9a877 3826 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 3827 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 3828 /* Mark that the final phase is over */
ganlikun 0:13413ea9a877 3829 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
ganlikun 0:13413ea9a877 3830 /* Disable the Peripheral */
ganlikun 0:13413ea9a877 3831 __HAL_CRYP_DISABLE();
ganlikun 0:13413ea9a877 3832 }
ganlikun 0:13413ea9a877 3833 /*=================================================*/
ganlikun 0:13413ea9a877 3834 /* case incorrect hcryp->Init.GCMCMACPhase setting */
ganlikun 0:13413ea9a877 3835 /*=================================================*/
ganlikun 0:13413ea9a877 3836 else
ganlikun 0:13413ea9a877 3837 {
ganlikun 0:13413ea9a877 3838 hcryp->State = HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 3839 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3840 return HAL_ERROR;
ganlikun 0:13413ea9a877 3841 }
ganlikun 0:13413ea9a877 3842
ganlikun 0:13413ea9a877 3843 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3844 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 3845
ganlikun 0:13413ea9a877 3846 /* Process Unlocked */
ganlikun 0:13413ea9a877 3847 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3848
ganlikun 0:13413ea9a877 3849 return HAL_OK;
ganlikun 0:13413ea9a877 3850 }
ganlikun 0:13413ea9a877 3851 else
ganlikun 0:13413ea9a877 3852 {
ganlikun 0:13413ea9a877 3853 return HAL_BUSY;
ganlikun 0:13413ea9a877 3854 }
ganlikun 0:13413ea9a877 3855 }
ganlikun 0:13413ea9a877 3856
ganlikun 0:13413ea9a877 3857
ganlikun 0:13413ea9a877 3858
ganlikun 0:13413ea9a877 3859
ganlikun 0:13413ea9a877 3860 /**
ganlikun 0:13413ea9a877 3861 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
ganlikun 0:13413ea9a877 3862 * operation according to hcryp->Init structure fields.
ganlikun 0:13413ea9a877 3863 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 3864 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 3865 * @param pInputData:
ganlikun 0:13413ea9a877 3866 * - pointer to payload data in GCM payload phase,
ganlikun 0:13413ea9a877 3867 * - pointer to B0 block in CMAC header phase,
ganlikun 0:13413ea9a877 3868 * - pointer to C block in CMAC final phase.
ganlikun 0:13413ea9a877 3869 * Parameter is meaningless in case of GCM/GMAC init, header and final phases.
ganlikun 0:13413ea9a877 3870 * @param Size:
ganlikun 0:13413ea9a877 3871 * - length of the input payload data buffer in bytes,
ganlikun 0:13413ea9a877 3872 * - length of B0 block (in bytes) in CMAC header phase,
ganlikun 0:13413ea9a877 3873 * - length of C block (in bytes) in CMAC final phase.
ganlikun 0:13413ea9a877 3874 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
ganlikun 0:13413ea9a877 3875 * @param pOutputData:
ganlikun 0:13413ea9a877 3876 * - pointer to plain or cipher text in GCM payload phase,
ganlikun 0:13413ea9a877 3877 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
ganlikun 0:13413ea9a877 3878 * - Parameter is meaningless in case of GCM/GMAC init and header phases
ganlikun 0:13413ea9a877 3879 * and in case of CMAC header phase.
ganlikun 0:13413ea9a877 3880 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
ganlikun 0:13413ea9a877 3881 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
ganlikun 0:13413ea9a877 3882 * can be skipped by the user if so required.
ganlikun 0:13413ea9a877 3883 * @retval HAL status
ganlikun 0:13413ea9a877 3884 */
ganlikun 0:13413ea9a877 3885 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
ganlikun 0:13413ea9a877 3886 {
ganlikun 0:13413ea9a877 3887
ganlikun 0:13413ea9a877 3888 uint32_t inputaddr = 0U;
ganlikun 0:13413ea9a877 3889 uint64_t headerlength = 0U;
ganlikun 0:13413ea9a877 3890 uint64_t inputlength = 0U;
ganlikun 0:13413ea9a877 3891 uint32_t index = 0U;
ganlikun 0:13413ea9a877 3892 uint32_t addhoc_process = 0U;
ganlikun 0:13413ea9a877 3893 uint32_t difflength = 0U;
ganlikun 0:13413ea9a877 3894 uint32_t difflengthmod4 = 0U;
ganlikun 0:13413ea9a877 3895 uint32_t mask[3U] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
ganlikun 0:13413ea9a877 3896
ganlikun 0:13413ea9a877 3897
ganlikun 0:13413ea9a877 3898 if (hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 3899 {
ganlikun 0:13413ea9a877 3900 /* input/output parameters check */
ganlikun 0:13413ea9a877 3901 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 3902 {
ganlikun 0:13413ea9a877 3903 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
ganlikun 0:13413ea9a877 3904 {
ganlikun 0:13413ea9a877 3905 return HAL_ERROR;
ganlikun 0:13413ea9a877 3906 }
ganlikun 0:13413ea9a877 3907 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3908 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 3909 #else
ganlikun 0:13413ea9a877 3910 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 3911 #endif
ganlikun 0:13413ea9a877 3912 {
ganlikun 0:13413ea9a877 3913 /* In case of CMAC header phase resumption, we can have pInputData = NULL and Size = 0 */
ganlikun 0:13413ea9a877 3914 if (((pInputData != NULL) && (Size == 0U)) || ((pInputData == NULL) && (Size != 0U)))
ganlikun 0:13413ea9a877 3915 {
ganlikun 0:13413ea9a877 3916 return HAL_ERROR;
ganlikun 0:13413ea9a877 3917 }
ganlikun 0:13413ea9a877 3918 }
ganlikun 0:13413ea9a877 3919 }
ganlikun 0:13413ea9a877 3920 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 3921 {
ganlikun 0:13413ea9a877 3922 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 3923 {
ganlikun 0:13413ea9a877 3924 return HAL_ERROR;
ganlikun 0:13413ea9a877 3925 }
ganlikun 0:13413ea9a877 3926 }
ganlikun 0:13413ea9a877 3927 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 3928 {
ganlikun 0:13413ea9a877 3929 if (pOutputData == NULL)
ganlikun 0:13413ea9a877 3930 {
ganlikun 0:13413ea9a877 3931 return HAL_ERROR;
ganlikun 0:13413ea9a877 3932 }
ganlikun 0:13413ea9a877 3933 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3934 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
ganlikun 0:13413ea9a877 3935 #else
ganlikun 0:13413ea9a877 3936 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
ganlikun 0:13413ea9a877 3937 #endif
ganlikun 0:13413ea9a877 3938 {
ganlikun 0:13413ea9a877 3939 return HAL_ERROR;
ganlikun 0:13413ea9a877 3940 }
ganlikun 0:13413ea9a877 3941 }
ganlikun 0:13413ea9a877 3942
ganlikun 0:13413ea9a877 3943 /* Process Locked */
ganlikun 0:13413ea9a877 3944 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 3945
ganlikun 0:13413ea9a877 3946 /* Change the CRYP state */
ganlikun 0:13413ea9a877 3947 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 3948
ganlikun 0:13413ea9a877 3949 /* Process Unlocked */
ganlikun 0:13413ea9a877 3950 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 3951
ganlikun 0:13413ea9a877 3952 /* Enable Computation Complete Flag and Error Interrupts */
ganlikun 0:13413ea9a877 3953 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 3954
ganlikun 0:13413ea9a877 3955 /*==============================================*/
ganlikun 0:13413ea9a877 3956 /* GCM/GMAC (or CCM when applicable) init phase */
ganlikun 0:13413ea9a877 3957 /*==============================================*/
ganlikun 0:13413ea9a877 3958 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
ganlikun 0:13413ea9a877 3959 {
ganlikun 0:13413ea9a877 3960 /* In case of init phase, the input data (Key and Initialization Vector) have
ganlikun 0:13413ea9a877 3961 already been entered during the initialization process. Therefore, the
ganlikun 0:13413ea9a877 3962 software just waits for the CCF interrupt to be raised and which will
ganlikun 0:13413ea9a877 3963 be handled by CRYP_AES_Auth_IT() API. */
ganlikun 0:13413ea9a877 3964 }
ganlikun 0:13413ea9a877 3965 /*=====================================*/
ganlikun 0:13413ea9a877 3966 /* GCM/GMAC or (CCM/)CMAC header phase */
ganlikun 0:13413ea9a877 3967 /*=====================================*/
ganlikun 0:13413ea9a877 3968 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 3969 {
ganlikun 0:13413ea9a877 3970
ganlikun 0:13413ea9a877 3971 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 3972 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 3973 #else
ganlikun 0:13413ea9a877 3974 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 3975 #endif
ganlikun 0:13413ea9a877 3976 {
ganlikun 0:13413ea9a877 3977 /* In case of CMAC, B blocks are first entered, before the header.
ganlikun 0:13413ea9a877 3978 Therefore, B blocks and the header are entered back-to-back
ganlikun 0:13413ea9a877 3979 as if it was only one single block.
ganlikun 0:13413ea9a877 3980 However, in case of resumption after suspension, if all the
ganlikun 0:13413ea9a877 3981 B blocks have been entered (in that case, Size = 0), only the
ganlikun 0:13413ea9a877 3982 remainder of the non-processed header bytes are entered. */
ganlikun 0:13413ea9a877 3983 if (Size != 0U)
ganlikun 0:13413ea9a877 3984 {
ganlikun 0:13413ea9a877 3985 hcryp->CrypInCount = Size + hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 3986 hcryp->pCrypInBuffPtr = pInputData;
ganlikun 0:13413ea9a877 3987 }
ganlikun 0:13413ea9a877 3988 else
ganlikun 0:13413ea9a877 3989 {
ganlikun 0:13413ea9a877 3990 hcryp->CrypInCount = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 3991 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
ganlikun 0:13413ea9a877 3992 }
ganlikun 0:13413ea9a877 3993 }
ganlikun 0:13413ea9a877 3994 else
ganlikun 0:13413ea9a877 3995 {
ganlikun 0:13413ea9a877 3996 /* Get the header addresses and sizes */
ganlikun 0:13413ea9a877 3997 hcryp->CrypInCount = hcryp->Init.HeaderSize;
ganlikun 0:13413ea9a877 3998 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
ganlikun 0:13413ea9a877 3999 }
ganlikun 0:13413ea9a877 4000
ganlikun 0:13413ea9a877 4001 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 4002
ganlikun 0:13413ea9a877 4003 /* Set header phase; for GCM or GMAC, set data-byte at this point */
ganlikun 0:13413ea9a877 4004 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 4005 {
ganlikun 0:13413ea9a877 4006 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_HEADER_PHASE|hcryp->Init.DataType);
ganlikun 0:13413ea9a877 4007 }
ganlikun 0:13413ea9a877 4008 else
ganlikun 0:13413ea9a877 4009 {
ganlikun 0:13413ea9a877 4010 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_HEADER_PHASE);
ganlikun 0:13413ea9a877 4011 }
ganlikun 0:13413ea9a877 4012
ganlikun 0:13413ea9a877 4013 /* Enable the Peripheral */
ganlikun 0:13413ea9a877 4014 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 4015
ganlikun 0:13413ea9a877 4016 /* Increment/decrement instance pointer/counter */
ganlikun 0:13413ea9a877 4017 if (hcryp->CrypInCount == 0U)
ganlikun 0:13413ea9a877 4018 {
ganlikun 0:13413ea9a877 4019 /* Case of no header */
ganlikun 0:13413ea9a877 4020 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4021 return HAL_OK;
ganlikun 0:13413ea9a877 4022 }
ganlikun 0:13413ea9a877 4023 else if (hcryp->CrypInCount < 16U)
ganlikun 0:13413ea9a877 4024 {
ganlikun 0:13413ea9a877 4025 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 4026 addhoc_process = 1U;
ganlikun 0:13413ea9a877 4027 difflength = (uint32_t) (hcryp->Init.HeaderSize);
ganlikun 0:13413ea9a877 4028 difflengthmod4 = difflength%4U;
ganlikun 0:13413ea9a877 4029 }
ganlikun 0:13413ea9a877 4030 else
ganlikun 0:13413ea9a877 4031 {
ganlikun 0:13413ea9a877 4032 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 4033 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 4034 }
ganlikun 0:13413ea9a877 4035
ganlikun 0:13413ea9a877 4036 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4037 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 4038 #else
ganlikun 0:13413ea9a877 4039 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 4040 #endif
ganlikun 0:13413ea9a877 4041 {
ganlikun 0:13413ea9a877 4042 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
ganlikun 0:13413ea9a877 4043 {
ganlikun 0:13413ea9a877 4044 /* All B blocks will have been entered after the next
ganlikun 0:13413ea9a877 4045 four DINR writing, so point at header buffer for
ganlikun 0:13413ea9a877 4046 the next iteration */
ganlikun 0:13413ea9a877 4047 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
ganlikun 0:13413ea9a877 4048 }
ganlikun 0:13413ea9a877 4049 }
ganlikun 0:13413ea9a877 4050
ganlikun 0:13413ea9a877 4051 /* Enter header first block to initiate the process
ganlikun 0:13413ea9a877 4052 in the Data Input register */
ganlikun 0:13413ea9a877 4053 if (addhoc_process == 0U)
ganlikun 0:13413ea9a877 4054 {
ganlikun 0:13413ea9a877 4055 /* Header has size equal or larger than 128 bits */
ganlikun 0:13413ea9a877 4056 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4057 inputaddr+=4U;
ganlikun 0:13413ea9a877 4058 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4059 inputaddr+=4U;
ganlikun 0:13413ea9a877 4060 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4061 inputaddr+=4U;
ganlikun 0:13413ea9a877 4062 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4063 }
ganlikun 0:13413ea9a877 4064 else
ganlikun 0:13413ea9a877 4065 {
ganlikun 0:13413ea9a877 4066 /* Header has size less than 128 bits */
ganlikun 0:13413ea9a877 4067 /* Enter complete words when possible */
ganlikun 0:13413ea9a877 4068 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 4069 {
ganlikun 0:13413ea9a877 4070 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 4071 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4072 inputaddr+=4U;
ganlikun 0:13413ea9a877 4073 }
ganlikun 0:13413ea9a877 4074 /* Enter incomplete word padded with zeroes if applicable
ganlikun 0:13413ea9a877 4075 (case of header length not a multiple of 32-bits) */
ganlikun 0:13413ea9a877 4076 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 4077 {
ganlikun 0:13413ea9a877 4078 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
ganlikun 0:13413ea9a877 4079 }
ganlikun 0:13413ea9a877 4080 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
ganlikun 0:13413ea9a877 4081 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 4082 {
ganlikun 0:13413ea9a877 4083 hcryp->Instance->DINR = 0U;
ganlikun 0:13413ea9a877 4084 }
ganlikun 0:13413ea9a877 4085
ganlikun 0:13413ea9a877 4086 }
ganlikun 0:13413ea9a877 4087 }
ganlikun 0:13413ea9a877 4088 /*============================================*/
ganlikun 0:13413ea9a877 4089 /* GCM (or CCM when applicable) payload phase */
ganlikun 0:13413ea9a877 4090 /*============================================*/
ganlikun 0:13413ea9a877 4091 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 4092 {
ganlikun 0:13413ea9a877 4093 /* Get the buffer addresses and sizes */
ganlikun 0:13413ea9a877 4094 hcryp->CrypInCount = Size;
ganlikun 0:13413ea9a877 4095 hcryp->pCrypInBuffPtr = pInputData;
ganlikun 0:13413ea9a877 4096 hcryp->pCrypOutBuffPtr = pOutputData;
ganlikun 0:13413ea9a877 4097 hcryp->CrypOutCount = Size;
ganlikun 0:13413ea9a877 4098
ganlikun 0:13413ea9a877 4099 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 4100
ganlikun 0:13413ea9a877 4101 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE);
ganlikun 0:13413ea9a877 4102
ganlikun 0:13413ea9a877 4103 /* if the header phase has been bypassed, AES must be enabled again */
ganlikun 0:13413ea9a877 4104 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
ganlikun 0:13413ea9a877 4105 {
ganlikun 0:13413ea9a877 4106 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 4107 }
ganlikun 0:13413ea9a877 4108
ganlikun 0:13413ea9a877 4109 /* Specific handling to manage payload size less than 128 bits */
ganlikun 0:13413ea9a877 4110 if (Size < 16U)
ganlikun 0:13413ea9a877 4111 {
ganlikun 0:13413ea9a877 4112 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4113 /* In case of GCM encryption or CCM decryption, specify the number of padding
ganlikun 0:13413ea9a877 4114 bytes in last block of payload */
ganlikun 0:13413ea9a877 4115 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 4116 {
ganlikun 0:13413ea9a877 4117 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 4118 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))
ganlikun 0:13413ea9a877 4119 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 4120 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
ganlikun 0:13413ea9a877 4121 {
ganlikun 0:13413ea9a877 4122 /* Set NPBLB field in writing the number of padding bytes
ganlikun 0:13413ea9a877 4123 for the last block of payload */
ganlikun 0:13413ea9a877 4124 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
ganlikun 0:13413ea9a877 4125 }
ganlikun 0:13413ea9a877 4126 }
ganlikun 0:13413ea9a877 4127 #else
ganlikun 0:13413ea9a877 4128 /* Software workaround applied to GCM encryption only */
ganlikun 0:13413ea9a877 4129 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
ganlikun 0:13413ea9a877 4130 {
ganlikun 0:13413ea9a877 4131 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
ganlikun 0:13413ea9a877 4132 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
ganlikun 0:13413ea9a877 4133 }
ganlikun 0:13413ea9a877 4134 #endif
ganlikun 0:13413ea9a877 4135
ganlikun 0:13413ea9a877 4136 /* Set hcryp->CrypInCount to 0 (no more data to enter) */
ganlikun 0:13413ea9a877 4137 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 4138
ganlikun 0:13413ea9a877 4139 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes,
ganlikun 0:13413ea9a877 4140 to have a complete block of 128 bits */
ganlikun 0:13413ea9a877 4141 difflength = (uint32_t) (Size);
ganlikun 0:13413ea9a877 4142 difflengthmod4 = difflength%4U;
ganlikun 0:13413ea9a877 4143 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
ganlikun 0:13413ea9a877 4144 to have a complete block of 128 bits */
ganlikun 0:13413ea9a877 4145 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 4146 {
ganlikun 0:13413ea9a877 4147 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 4148 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4149 inputaddr+=4U;
ganlikun 0:13413ea9a877 4150 }
ganlikun 0:13413ea9a877 4151 /* If required, manage input data size not multiple of 32 bits */
ganlikun 0:13413ea9a877 4152 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 4153 {
ganlikun 0:13413ea9a877 4154 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
ganlikun 0:13413ea9a877 4155 }
ganlikun 0:13413ea9a877 4156 /* Wrap-up in padding with zero-words if applicable */
ganlikun 0:13413ea9a877 4157 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 4158 {
ganlikun 0:13413ea9a877 4159 hcryp->Instance->DINR = 0U;
ganlikun 0:13413ea9a877 4160 }
ganlikun 0:13413ea9a877 4161 }
ganlikun 0:13413ea9a877 4162 else
ganlikun 0:13413ea9a877 4163 {
ganlikun 0:13413ea9a877 4164 /* Increment/decrement instance pointer/counter */
ganlikun 0:13413ea9a877 4165 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 4166 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 4167
ganlikun 0:13413ea9a877 4168 /* Enter payload first block to initiate the process
ganlikun 0:13413ea9a877 4169 in the Data Input register */
ganlikun 0:13413ea9a877 4170 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4171 inputaddr+=4U;
ganlikun 0:13413ea9a877 4172 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4173 inputaddr+=4U;
ganlikun 0:13413ea9a877 4174 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4175 inputaddr+=4U;
ganlikun 0:13413ea9a877 4176 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4177 }
ganlikun 0:13413ea9a877 4178 }
ganlikun 0:13413ea9a877 4179 /*====================================*/
ganlikun 0:13413ea9a877 4180 /* GCM/GMAC or (CCM/)CMAC final phase */
ganlikun 0:13413ea9a877 4181 /*====================================*/
ganlikun 0:13413ea9a877 4182 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 4183 {
ganlikun 0:13413ea9a877 4184 hcryp->pCrypOutBuffPtr = pOutputData;
ganlikun 0:13413ea9a877 4185
ganlikun 0:13413ea9a877 4186 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4187 /* By default, clear NPBLB field */
ganlikun 0:13413ea9a877 4188 CLEAR_BIT(hcryp->Instance->CR, AES_CR_NPBLB);
ganlikun 0:13413ea9a877 4189 #endif
ganlikun 0:13413ea9a877 4190
ganlikun 0:13413ea9a877 4191 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
ganlikun 0:13413ea9a877 4192
ganlikun 0:13413ea9a877 4193 /* if the header and payload phases have been bypassed, AES must be enabled again */
ganlikun 0:13413ea9a877 4194 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
ganlikun 0:13413ea9a877 4195 {
ganlikun 0:13413ea9a877 4196 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 4197 }
ganlikun 0:13413ea9a877 4198
ganlikun 0:13413ea9a877 4199 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 4200 {
ganlikun 0:13413ea9a877 4201 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
ganlikun 0:13413ea9a877 4202 inputlength = Size * 8U; /* Input length in bits */
ganlikun 0:13413ea9a877 4203 /* Write the number of bits in the header on 64 bits followed by the number
ganlikun 0:13413ea9a877 4204 of bits in the payload on 64 bits as well */
ganlikun 0:13413ea9a877 4205 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
ganlikun 0:13413ea9a877 4206 {
ganlikun 0:13413ea9a877 4207 hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
ganlikun 0:13413ea9a877 4208 hcryp->Instance->DINR = __RBIT(headerlength);
ganlikun 0:13413ea9a877 4209 hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
ganlikun 0:13413ea9a877 4210 hcryp->Instance->DINR = __RBIT(inputlength);
ganlikun 0:13413ea9a877 4211 }
ganlikun 0:13413ea9a877 4212 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
ganlikun 0:13413ea9a877 4213 {
ganlikun 0:13413ea9a877 4214 hcryp->Instance->DINR = __REV((headerlength)>>32U);
ganlikun 0:13413ea9a877 4215 hcryp->Instance->DINR = __REV(headerlength);
ganlikun 0:13413ea9a877 4216 hcryp->Instance->DINR = __REV((inputlength)>>32U);
ganlikun 0:13413ea9a877 4217 hcryp->Instance->DINR = __REV(inputlength);
ganlikun 0:13413ea9a877 4218 }
ganlikun 0:13413ea9a877 4219 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
ganlikun 0:13413ea9a877 4220 {
ganlikun 0:13413ea9a877 4221 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
ganlikun 0:13413ea9a877 4222 hcryp->Instance->DINR = __ROR(headerlength, 16U);
ganlikun 0:13413ea9a877 4223 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
ganlikun 0:13413ea9a877 4224 hcryp->Instance->DINR = __ROR(inputlength, 16U);
ganlikun 0:13413ea9a877 4225 }
ganlikun 0:13413ea9a877 4226 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
ganlikun 0:13413ea9a877 4227 {
ganlikun 0:13413ea9a877 4228 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
ganlikun 0:13413ea9a877 4229 hcryp->Instance->DINR = (uint32_t)(headerlength);
ganlikun 0:13413ea9a877 4230 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
ganlikun 0:13413ea9a877 4231 hcryp->Instance->DINR = (uint32_t)(inputlength);
ganlikun 0:13413ea9a877 4232 }
ganlikun 0:13413ea9a877 4233 }
ganlikun 0:13413ea9a877 4234 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4235 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 4236 {
ganlikun 0:13413ea9a877 4237 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 4238 /* Enter the last block made of a 128-bit value formatted
ganlikun 0:13413ea9a877 4239 from the original B0 packet. */
ganlikun 0:13413ea9a877 4240 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4241 inputaddr+=4U;
ganlikun 0:13413ea9a877 4242 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4243 inputaddr+=4U;
ganlikun 0:13413ea9a877 4244 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4245 inputaddr+=4U;
ganlikun 0:13413ea9a877 4246 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4247 inputaddr+=4U;
ganlikun 0:13413ea9a877 4248 }
ganlikun 0:13413ea9a877 4249 #endif
ganlikun 0:13413ea9a877 4250 }
ganlikun 0:13413ea9a877 4251 /*=================================================*/
ganlikun 0:13413ea9a877 4252 /* case incorrect hcryp->Init.GCMCMACPhase setting */
ganlikun 0:13413ea9a877 4253 /*=================================================*/
ganlikun 0:13413ea9a877 4254 else
ganlikun 0:13413ea9a877 4255 {
ganlikun 0:13413ea9a877 4256 hcryp->State = HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 4257 return HAL_ERROR;
ganlikun 0:13413ea9a877 4258 }
ganlikun 0:13413ea9a877 4259
ganlikun 0:13413ea9a877 4260 return HAL_OK;
ganlikun 0:13413ea9a877 4261 }
ganlikun 0:13413ea9a877 4262 else
ganlikun 0:13413ea9a877 4263 {
ganlikun 0:13413ea9a877 4264 return HAL_BUSY;
ganlikun 0:13413ea9a877 4265 }
ganlikun 0:13413ea9a877 4266 }
ganlikun 0:13413ea9a877 4267
ganlikun 0:13413ea9a877 4268
ganlikun 0:13413ea9a877 4269
ganlikun 0:13413ea9a877 4270
ganlikun 0:13413ea9a877 4271 /**
ganlikun 0:13413ea9a877 4272 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
ganlikun 0:13413ea9a877 4273 * operation according to hcryp->Init structure fields.
ganlikun 0:13413ea9a877 4274 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4275 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 4276 * @param pInputData:
ganlikun 0:13413ea9a877 4277 * - pointer to payload data in GCM payload phase,
ganlikun 0:13413ea9a877 4278 * - pointer to B0 block in CMAC header phase,
ganlikun 0:13413ea9a877 4279 * - pointer to C block in CMAC final phase.
ganlikun 0:13413ea9a877 4280 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases.
ganlikun 0:13413ea9a877 4281 * @param Size:
ganlikun 0:13413ea9a877 4282 * - length of the input payload data buffer in bytes,
ganlikun 0:13413ea9a877 4283 * - length of B block (in bytes) in CMAC header phase,
ganlikun 0:13413ea9a877 4284 * - length of C block (in bytes) in CMAC final phase.
ganlikun 0:13413ea9a877 4285 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
ganlikun 0:13413ea9a877 4286 * @param pOutputData:
ganlikun 0:13413ea9a877 4287 * - pointer to plain or cipher text in GCM payload phase,
ganlikun 0:13413ea9a877 4288 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
ganlikun 0:13413ea9a877 4289 * - Parameter is meaningless in case of GCM/GMAC init and header phases
ganlikun 0:13413ea9a877 4290 * and in case of CMAC header phase.
ganlikun 0:13413ea9a877 4291 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
ganlikun 0:13413ea9a877 4292 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
ganlikun 0:13413ea9a877 4293 * can be skipped by the user if so required.
ganlikun 0:13413ea9a877 4294 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
ganlikun 0:13413ea9a877 4295 * @retval HAL status
ganlikun 0:13413ea9a877 4296 */
ganlikun 0:13413ea9a877 4297 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
ganlikun 0:13413ea9a877 4298 {
ganlikun 0:13413ea9a877 4299 uint32_t inputaddr = 0U;
ganlikun 0:13413ea9a877 4300 uint32_t outputaddr = 0U;
ganlikun 0:13413ea9a877 4301 uint32_t tagaddr = 0U;
ganlikun 0:13413ea9a877 4302 uint64_t headerlength = 0U;
ganlikun 0:13413ea9a877 4303 uint64_t inputlength = 0U;
ganlikun 0:13413ea9a877 4304 uint64_t payloadlength = 0U;
ganlikun 0:13413ea9a877 4305
ganlikun 0:13413ea9a877 4306
ganlikun 0:13413ea9a877 4307 if (hcryp->State == HAL_CRYP_STATE_READY)
ganlikun 0:13413ea9a877 4308 {
ganlikun 0:13413ea9a877 4309 /* input/output parameters check */
ganlikun 0:13413ea9a877 4310 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 4311 {
ganlikun 0:13413ea9a877 4312 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0U))
ganlikun 0:13413ea9a877 4313 {
ganlikun 0:13413ea9a877 4314 return HAL_ERROR;
ganlikun 0:13413ea9a877 4315 }
ganlikun 0:13413ea9a877 4316 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4317 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 4318 #else
ganlikun 0:13413ea9a877 4319 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 4320 #endif
ganlikun 0:13413ea9a877 4321 {
ganlikun 0:13413ea9a877 4322 if ((pInputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 4323 {
ganlikun 0:13413ea9a877 4324 return HAL_ERROR;
ganlikun 0:13413ea9a877 4325 }
ganlikun 0:13413ea9a877 4326 }
ganlikun 0:13413ea9a877 4327 }
ganlikun 0:13413ea9a877 4328 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 4329 {
ganlikun 0:13413ea9a877 4330 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0U))
ganlikun 0:13413ea9a877 4331 {
ganlikun 0:13413ea9a877 4332 return HAL_ERROR;
ganlikun 0:13413ea9a877 4333 }
ganlikun 0:13413ea9a877 4334 }
ganlikun 0:13413ea9a877 4335 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 4336 {
ganlikun 0:13413ea9a877 4337 if (pOutputData == NULL)
ganlikun 0:13413ea9a877 4338 {
ganlikun 0:13413ea9a877 4339 return HAL_ERROR;
ganlikun 0:13413ea9a877 4340 }
ganlikun 0:13413ea9a877 4341 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4342 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC) && (pInputData == NULL))
ganlikun 0:13413ea9a877 4343 #else
ganlikun 0:13413ea9a877 4344 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
ganlikun 0:13413ea9a877 4345 #endif
ganlikun 0:13413ea9a877 4346 {
ganlikun 0:13413ea9a877 4347 return HAL_ERROR;
ganlikun 0:13413ea9a877 4348 }
ganlikun 0:13413ea9a877 4349 }
ganlikun 0:13413ea9a877 4350
ganlikun 0:13413ea9a877 4351 /* Process Locked */
ganlikun 0:13413ea9a877 4352 __HAL_LOCK(hcryp);
ganlikun 0:13413ea9a877 4353
ganlikun 0:13413ea9a877 4354 /* Change the CRYP state */
ganlikun 0:13413ea9a877 4355 hcryp->State = HAL_CRYP_STATE_BUSY;
ganlikun 0:13413ea9a877 4356
ganlikun 0:13413ea9a877 4357 /*==============================================*/
ganlikun 0:13413ea9a877 4358 /* GCM/GMAC (or CCM when applicable) init phase */
ganlikun 0:13413ea9a877 4359 /*==============================================*/
ganlikun 0:13413ea9a877 4360 /* In case of init phase, the input data (Key and Initialization Vector) have
ganlikun 0:13413ea9a877 4361 already been entered during the initialization process. No DMA transfer is
ganlikun 0:13413ea9a877 4362 required at that point therefore, the software just waits for the CCF flag
ganlikun 0:13413ea9a877 4363 to be raised. */
ganlikun 0:13413ea9a877 4364 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
ganlikun 0:13413ea9a877 4365 {
ganlikun 0:13413ea9a877 4366 /* just wait for hash computation */
ganlikun 0:13413ea9a877 4367 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 4368 {
ganlikun 0:13413ea9a877 4369 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4370 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4371 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 4372 }
ganlikun 0:13413ea9a877 4373
ganlikun 0:13413ea9a877 4374 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 4375 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 4376 /* Mark that the initialization phase is over */
ganlikun 0:13413ea9a877 4377 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
ganlikun 0:13413ea9a877 4378 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4379 }
ganlikun 0:13413ea9a877 4380 /*===============================*/
ganlikun 0:13413ea9a877 4381 /* GCM/GMAC or CMAC header phase */
ganlikun 0:13413ea9a877 4382 /*===============================*/
ganlikun 0:13413ea9a877 4383 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
ganlikun 0:13413ea9a877 4384 {
ganlikun 0:13413ea9a877 4385 /* Set header phase; for GCM or GMAC, set data-byte at this point */
ganlikun 0:13413ea9a877 4386 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 4387 {
ganlikun 0:13413ea9a877 4388 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType);
ganlikun 0:13413ea9a877 4389 }
ganlikun 0:13413ea9a877 4390 else
ganlikun 0:13413ea9a877 4391 {
ganlikun 0:13413ea9a877 4392 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE);
ganlikun 0:13413ea9a877 4393 }
ganlikun 0:13413ea9a877 4394
ganlikun 0:13413ea9a877 4395 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4396 /* enter first B0 block in polling mode (no DMA transfer for B0) */
ganlikun 0:13413ea9a877 4397 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 4398 {
ganlikun 0:13413ea9a877 4399 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 4400 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 4401
ganlikun 0:13413ea9a877 4402 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 4403 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4404 inputaddr+=4U;
ganlikun 0:13413ea9a877 4405 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4406 inputaddr+=4U;
ganlikun 0:13413ea9a877 4407 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4408 inputaddr+=4U;
ganlikun 0:13413ea9a877 4409 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4410
ganlikun 0:13413ea9a877 4411 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 4412 {
ganlikun 0:13413ea9a877 4413 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4414 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4415 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 4416 }
ganlikun 0:13413ea9a877 4417 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 4418 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 4419 }
ganlikun 0:13413ea9a877 4420 #endif
ganlikun 0:13413ea9a877 4421
ganlikun 0:13413ea9a877 4422 /* No header case */
ganlikun 0:13413ea9a877 4423 if (hcryp->Init.Header == NULL)
ganlikun 0:13413ea9a877 4424 {
ganlikun 0:13413ea9a877 4425 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4426 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 4427 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
ganlikun 0:13413ea9a877 4428 /* Process Unlocked */
ganlikun 0:13413ea9a877 4429 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4430
ganlikun 0:13413ea9a877 4431 return HAL_OK;
ganlikun 0:13413ea9a877 4432 }
ganlikun 0:13413ea9a877 4433
ganlikun 0:13413ea9a877 4434 inputaddr = (uint32_t)hcryp->Init.Header;
ganlikun 0:13413ea9a877 4435 if ((hcryp->Init.HeaderSize % 16U) != 0U)
ganlikun 0:13413ea9a877 4436 {
ganlikun 0:13413ea9a877 4437
ganlikun 0:13413ea9a877 4438 if (hcryp->Init.HeaderSize < 16U)
ganlikun 0:13413ea9a877 4439 {
ganlikun 0:13413ea9a877 4440 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
ganlikun 0:13413ea9a877 4441
ganlikun 0:13413ea9a877 4442 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4443 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 4444 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
ganlikun 0:13413ea9a877 4445
ganlikun 0:13413ea9a877 4446 /* CCF flag indicating header phase AES processing completion
ganlikun 0:13413ea9a877 4447 will be checked at the start of the next phase:
ganlikun 0:13413ea9a877 4448 - payload phase (GCM / CCM when applicable)
ganlikun 0:13413ea9a877 4449 - final phase (GMAC or CMAC). */
ganlikun 0:13413ea9a877 4450 }
ganlikun 0:13413ea9a877 4451 else
ganlikun 0:13413ea9a877 4452 {
ganlikun 0:13413ea9a877 4453 /* Local variable headerlength is a number of bytes multiple of 128 bits,
ganlikun 0:13413ea9a877 4454 remaining header data (if any) are handled after this loop */
ganlikun 0:13413ea9a877 4455 headerlength = (((hcryp->Init.HeaderSize)/16U)*16U) ;
ganlikun 0:13413ea9a877 4456 /* Store the ending transfer point */
ganlikun 0:13413ea9a877 4457 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
ganlikun 0:13413ea9a877 4458 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
ganlikun 0:13413ea9a877 4459
ganlikun 0:13413ea9a877 4460 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 4461 /* (incomplete DMA transfer, will be wrapped up after completion of
ganlikun 0:13413ea9a877 4462 the first one (initiated here) with data padding */
ganlikun 0:13413ea9a877 4463 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, headerlength, 0U);
ganlikun 0:13413ea9a877 4464 }
ganlikun 0:13413ea9a877 4465 }
ganlikun 0:13413ea9a877 4466 else
ganlikun 0:13413ea9a877 4467 {
ganlikun 0:13413ea9a877 4468 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 4469 /* Set the input address and start DMA transfer */
ganlikun 0:13413ea9a877 4470 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, hcryp->Init.HeaderSize, 0U);
ganlikun 0:13413ea9a877 4471 }
ganlikun 0:13413ea9a877 4472
ganlikun 0:13413ea9a877 4473 }
ganlikun 0:13413ea9a877 4474 /*============================================*/
ganlikun 0:13413ea9a877 4475 /* GCM (or CCM when applicable) payload phase */
ganlikun 0:13413ea9a877 4476 /*============================================*/
ganlikun 0:13413ea9a877 4477 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 4478 {
ganlikun 0:13413ea9a877 4479 /* Coming from header phase, wait for CCF flag to be raised
ganlikun 0:13413ea9a877 4480 if header present and fed to the IP in the previous phase */
ganlikun 0:13413ea9a877 4481 if (hcryp->Init.Header != NULL)
ganlikun 0:13413ea9a877 4482 {
ganlikun 0:13413ea9a877 4483 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 4484 {
ganlikun 0:13413ea9a877 4485 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4486 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4487 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 4488 }
ganlikun 0:13413ea9a877 4489 }
ganlikun 0:13413ea9a877 4490 else
ganlikun 0:13413ea9a877 4491 {
ganlikun 0:13413ea9a877 4492 /* Enable the Peripheral since wasn't in header phase (no header case) */
ganlikun 0:13413ea9a877 4493 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 4494 }
ganlikun 0:13413ea9a877 4495 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 4496 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 4497
ganlikun 0:13413ea9a877 4498 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PAYLOAD_PHASE);
ganlikun 0:13413ea9a877 4499
ganlikun 0:13413ea9a877 4500 /* Specific handling to manage payload size less than 128 bits */
ganlikun 0:13413ea9a877 4501 if ((Size % 16U) != 0U)
ganlikun 0:13413ea9a877 4502 {
ganlikun 0:13413ea9a877 4503 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 4504 outputaddr = (uint32_t)pOutputData;
ganlikun 0:13413ea9a877 4505 if (Size < 16U)
ganlikun 0:13413ea9a877 4506 {
ganlikun 0:13413ea9a877 4507 /* Block is now entered in polling mode, no actual gain in resorting to DMA */
ganlikun 0:13413ea9a877 4508 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 4509 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
ganlikun 0:13413ea9a877 4510
ganlikun 0:13413ea9a877 4511 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
ganlikun 0:13413ea9a877 4512
ganlikun 0:13413ea9a877 4513 /* Change the CRYP state to ready */
ganlikun 0:13413ea9a877 4514 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4515 /* Mark that the payload phase is over */
ganlikun 0:13413ea9a877 4516 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
ganlikun 0:13413ea9a877 4517
ganlikun 0:13413ea9a877 4518 /* Call output data transfer complete callback */
ganlikun 0:13413ea9a877 4519 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 4520 }
ganlikun 0:13413ea9a877 4521 else
ganlikun 0:13413ea9a877 4522 {
ganlikun 0:13413ea9a877 4523 payloadlength = (Size/16U) * 16U;
ganlikun 0:13413ea9a877 4524
ganlikun 0:13413ea9a877 4525 /* Store the ending transfer points */
ganlikun 0:13413ea9a877 4526 hcryp->pCrypInBuffPtr = pInputData + payloadlength;
ganlikun 0:13413ea9a877 4527 hcryp->pCrypOutBuffPtr = pOutputData + payloadlength;
ganlikun 0:13413ea9a877 4528 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
ganlikun 0:13413ea9a877 4529
ganlikun 0:13413ea9a877 4530 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 4531 /* (incomplete DMA transfer, will be wrapped up with data padding
ganlikun 0:13413ea9a877 4532 after completion of the one initiated here) */
ganlikun 0:13413ea9a877 4533 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, payloadlength, outputaddr);
ganlikun 0:13413ea9a877 4534 }
ganlikun 0:13413ea9a877 4535 }
ganlikun 0:13413ea9a877 4536 else
ganlikun 0:13413ea9a877 4537 {
ganlikun 0:13413ea9a877 4538 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 4539 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 4540 outputaddr = (uint32_t)pOutputData;
ganlikun 0:13413ea9a877 4541
ganlikun 0:13413ea9a877 4542 /* Set the input and output addresses and start DMA transfer */
ganlikun 0:13413ea9a877 4543 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
ganlikun 0:13413ea9a877 4544 }
ganlikun 0:13413ea9a877 4545 }
ganlikun 0:13413ea9a877 4546 /*====================================*/
ganlikun 0:13413ea9a877 4547 /* GCM/GMAC or (CCM/)CMAC final phase */
ganlikun 0:13413ea9a877 4548 /*====================================*/
ganlikun 0:13413ea9a877 4549 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 4550 {
ganlikun 0:13413ea9a877 4551 /* If coming from header phase (GMAC or CMAC case),
ganlikun 0:13413ea9a877 4552 wait for CCF flag to be raised */
ganlikun 0:13413ea9a877 4553 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 4554 {
ganlikun 0:13413ea9a877 4555 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 4556 {
ganlikun 0:13413ea9a877 4557 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4558 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4559 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 4560 }
ganlikun 0:13413ea9a877 4561 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 4562 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 4563 }
ganlikun 0:13413ea9a877 4564
ganlikun 0:13413ea9a877 4565 tagaddr = (uint32_t)pOutputData;
ganlikun 0:13413ea9a877 4566
ganlikun 0:13413ea9a877 4567 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_FINAL_PHASE);
ganlikun 0:13413ea9a877 4568
ganlikun 0:13413ea9a877 4569 /* if the header and payload phases have been bypassed, AES must be enabled again */
ganlikun 0:13413ea9a877 4570 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
ganlikun 0:13413ea9a877 4571 {
ganlikun 0:13413ea9a877 4572 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 4573 }
ganlikun 0:13413ea9a877 4574
ganlikun 0:13413ea9a877 4575 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 4576 {
ganlikun 0:13413ea9a877 4577 headerlength = hcryp->Init.HeaderSize * 8U; /* Header length in bits */
ganlikun 0:13413ea9a877 4578 inputlength = Size * 8U; /* input length in bits */
ganlikun 0:13413ea9a877 4579 /* Write the number of bits in the header on 64 bits followed by the number
ganlikun 0:13413ea9a877 4580 of bits in the payload on 64 bits as well */
ganlikun 0:13413ea9a877 4581 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
ganlikun 0:13413ea9a877 4582 {
ganlikun 0:13413ea9a877 4583 hcryp->Instance->DINR = __RBIT((headerlength)>>32U);
ganlikun 0:13413ea9a877 4584 hcryp->Instance->DINR = __RBIT(headerlength);
ganlikun 0:13413ea9a877 4585 hcryp->Instance->DINR = __RBIT((inputlength)>>32U);
ganlikun 0:13413ea9a877 4586 hcryp->Instance->DINR = __RBIT(inputlength);
ganlikun 0:13413ea9a877 4587 }
ganlikun 0:13413ea9a877 4588 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
ganlikun 0:13413ea9a877 4589 {
ganlikun 0:13413ea9a877 4590 hcryp->Instance->DINR = __REV((headerlength)>>32U);
ganlikun 0:13413ea9a877 4591 hcryp->Instance->DINR = __REV(headerlength);
ganlikun 0:13413ea9a877 4592 hcryp->Instance->DINR = __REV((inputlength)>>32U);
ganlikun 0:13413ea9a877 4593 hcryp->Instance->DINR = __REV(inputlength);
ganlikun 0:13413ea9a877 4594 }
ganlikun 0:13413ea9a877 4595 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
ganlikun 0:13413ea9a877 4596 {
ganlikun 0:13413ea9a877 4597 hcryp->Instance->DINR = __ROR((headerlength)>>32U, 16U);
ganlikun 0:13413ea9a877 4598 hcryp->Instance->DINR = __ROR(headerlength, 16U);
ganlikun 0:13413ea9a877 4599 hcryp->Instance->DINR = __ROR((inputlength)>>32U, 16U);
ganlikun 0:13413ea9a877 4600 hcryp->Instance->DINR = __ROR(inputlength, 16U);
ganlikun 0:13413ea9a877 4601 }
ganlikun 0:13413ea9a877 4602 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
ganlikun 0:13413ea9a877 4603 {
ganlikun 0:13413ea9a877 4604 hcryp->Instance->DINR = (uint32_t)(headerlength>>32U);
ganlikun 0:13413ea9a877 4605 hcryp->Instance->DINR = (uint32_t)(headerlength);
ganlikun 0:13413ea9a877 4606 hcryp->Instance->DINR = (uint32_t)(inputlength>>32U);
ganlikun 0:13413ea9a877 4607 hcryp->Instance->DINR = (uint32_t)(inputlength);
ganlikun 0:13413ea9a877 4608 }
ganlikun 0:13413ea9a877 4609 }
ganlikun 0:13413ea9a877 4610 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 4611 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 4612 {
ganlikun 0:13413ea9a877 4613 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 4614
ganlikun 0:13413ea9a877 4615 inputaddr = (uint32_t)pInputData;
ganlikun 0:13413ea9a877 4616 /* Enter the last block made of a 128-bit value formatted
ganlikun 0:13413ea9a877 4617 from the original B0 packet. */
ganlikun 0:13413ea9a877 4618 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4619 inputaddr+=4U;
ganlikun 0:13413ea9a877 4620 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4621 inputaddr+=4U;
ganlikun 0:13413ea9a877 4622 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4623 inputaddr+=4U;
ganlikun 0:13413ea9a877 4624 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 4625 inputaddr+=4U;
ganlikun 0:13413ea9a877 4626 }
ganlikun 0:13413ea9a877 4627 #endif
ganlikun 0:13413ea9a877 4628
ganlikun 0:13413ea9a877 4629 /* No DMA transfer is required at that point therefore, the software
ganlikun 0:13413ea9a877 4630 just waits for the CCF flag to be raised. */
ganlikun 0:13413ea9a877 4631 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 4632 {
ganlikun 0:13413ea9a877 4633 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4634 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4635 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 4636 }
ganlikun 0:13413ea9a877 4637 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 4638 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 4639 /* Read the Auth TAG in the IN FIFO */
ganlikun 0:13413ea9a877 4640 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 4641 tagaddr+=4U;
ganlikun 0:13413ea9a877 4642 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 4643 tagaddr+=4U;
ganlikun 0:13413ea9a877 4644 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 4645 tagaddr+=4U;
ganlikun 0:13413ea9a877 4646 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 4647
ganlikun 0:13413ea9a877 4648 /* Mark that the final phase is over */
ganlikun 0:13413ea9a877 4649 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
ganlikun 0:13413ea9a877 4650 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4651 /* Disable the Peripheral */
ganlikun 0:13413ea9a877 4652 __HAL_CRYP_DISABLE();
ganlikun 0:13413ea9a877 4653 }
ganlikun 0:13413ea9a877 4654 /*=================================================*/
ganlikun 0:13413ea9a877 4655 /* case incorrect hcryp->Init.GCMCMACPhase setting */
ganlikun 0:13413ea9a877 4656 /*=================================================*/
ganlikun 0:13413ea9a877 4657 else
ganlikun 0:13413ea9a877 4658 {
ganlikun 0:13413ea9a877 4659 hcryp->State = HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 4660 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4661 return HAL_ERROR;
ganlikun 0:13413ea9a877 4662 }
ganlikun 0:13413ea9a877 4663
ganlikun 0:13413ea9a877 4664 /* Process Unlocked */
ganlikun 0:13413ea9a877 4665 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4666
ganlikun 0:13413ea9a877 4667 return HAL_OK;
ganlikun 0:13413ea9a877 4668 }
ganlikun 0:13413ea9a877 4669 else
ganlikun 0:13413ea9a877 4670 {
ganlikun 0:13413ea9a877 4671 return HAL_BUSY;
ganlikun 0:13413ea9a877 4672 }
ganlikun 0:13413ea9a877 4673 }
ganlikun 0:13413ea9a877 4674
ganlikun 0:13413ea9a877 4675 /**
ganlikun 0:13413ea9a877 4676 * @}
ganlikun 0:13413ea9a877 4677 */
ganlikun 0:13413ea9a877 4678
ganlikun 0:13413ea9a877 4679 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
ganlikun 0:13413ea9a877 4680 * @brief Extended processing functions.
ganlikun 0:13413ea9a877 4681 *
ganlikun 0:13413ea9a877 4682 @verbatim
ganlikun 0:13413ea9a877 4683 ==============================================================================
ganlikun 0:13413ea9a877 4684 ##### AES extended suspension and resumption functions #####
ganlikun 0:13413ea9a877 4685 ==============================================================================
ganlikun 0:13413ea9a877 4686 [..] This section provides functions allowing to:
ganlikun 0:13413ea9a877 4687 (+) save in memory the Initialization Vector, the Key registers, the Control register or
ganlikun 0:13413ea9a877 4688 the Suspend registers when a process is suspended by a higher priority message
ganlikun 0:13413ea9a877 4689 (+) write back in CRYP hardware block the saved values listed above when the suspended
ganlikun 0:13413ea9a877 4690 lower priority message processing is resumed.
ganlikun 0:13413ea9a877 4691
ganlikun 0:13413ea9a877 4692 @endverbatim
ganlikun 0:13413ea9a877 4693 * @{
ganlikun 0:13413ea9a877 4694 */
ganlikun 0:13413ea9a877 4695
ganlikun 0:13413ea9a877 4696
ganlikun 0:13413ea9a877 4697 /**
ganlikun 0:13413ea9a877 4698 * @brief In case of message processing suspension, read the Initialization Vector.
ganlikun 0:13413ea9a877 4699 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4700 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4701 * @param Output: Pointer to the buffer containing the saved Initialization Vector.
ganlikun 0:13413ea9a877 4702 * @note This value has to be stored for reuse by writing the AES_IVRx registers
ganlikun 0:13413ea9a877 4703 * as soon as the interrupted processing has to be resumed.
ganlikun 0:13413ea9a877 4704 * Applicable to all chaining modes.
ganlikun 0:13413ea9a877 4705 * @note AES must be disabled when reading or resetting the IV values.
ganlikun 0:13413ea9a877 4706 * @retval None
ganlikun 0:13413ea9a877 4707 */
ganlikun 0:13413ea9a877 4708 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
ganlikun 0:13413ea9a877 4709 {
ganlikun 0:13413ea9a877 4710 uint32_t outputaddr = (uint32_t)Output;
ganlikun 0:13413ea9a877 4711
ganlikun 0:13413ea9a877 4712 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
ganlikun 0:13413ea9a877 4713 outputaddr+=4U;
ganlikun 0:13413ea9a877 4714 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
ganlikun 0:13413ea9a877 4715 outputaddr+=4U;
ganlikun 0:13413ea9a877 4716 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
ganlikun 0:13413ea9a877 4717 outputaddr+=4U;
ganlikun 0:13413ea9a877 4718 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
ganlikun 0:13413ea9a877 4719 }
ganlikun 0:13413ea9a877 4720
ganlikun 0:13413ea9a877 4721 /**
ganlikun 0:13413ea9a877 4722 * @brief In case of message processing resumption, rewrite the Initialization
ganlikun 0:13413ea9a877 4723 * Vector in the AES_IVRx registers.
ganlikun 0:13413ea9a877 4724 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4725 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4726 * @param Input: Pointer to the buffer containing the saved Initialization Vector to
ganlikun 0:13413ea9a877 4727 * write back in the CRYP hardware block.
ganlikun 0:13413ea9a877 4728 * @note Applicable to all chaining modes.
ganlikun 0:13413ea9a877 4729 * @note AES must be disabled when reading or resetting the IV values.
ganlikun 0:13413ea9a877 4730 * @retval None
ganlikun 0:13413ea9a877 4731 */
ganlikun 0:13413ea9a877 4732 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
ganlikun 0:13413ea9a877 4733 {
ganlikun 0:13413ea9a877 4734 uint32_t ivaddr = (uint32_t)Input;
ganlikun 0:13413ea9a877 4735
ganlikun 0:13413ea9a877 4736 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4737 ivaddr+=4U;
ganlikun 0:13413ea9a877 4738 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4739 ivaddr+=4U;
ganlikun 0:13413ea9a877 4740 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4741 ivaddr+=4U;
ganlikun 0:13413ea9a877 4742 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4743 }
ganlikun 0:13413ea9a877 4744
ganlikun 0:13413ea9a877 4745
ganlikun 0:13413ea9a877 4746 /**
ganlikun 0:13413ea9a877 4747 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Suspend Registers.
ganlikun 0:13413ea9a877 4748 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4749 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4750 * @param Output: Pointer to the buffer containing the saved Suspend Registers.
ganlikun 0:13413ea9a877 4751 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
ganlikun 0:13413ea9a877 4752 * as soon as the interrupted processing has to be resumed.
ganlikun 0:13413ea9a877 4753 * @retval None
ganlikun 0:13413ea9a877 4754 */
ganlikun 0:13413ea9a877 4755 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
ganlikun 0:13413ea9a877 4756 {
ganlikun 0:13413ea9a877 4757 uint32_t outputaddr = (uint32_t)Output;
ganlikun 0:13413ea9a877 4758
ganlikun 0:13413ea9a877 4759 /* In case of GCM payload phase encryption, check that suspension can be carried out */
ganlikun 0:13413ea9a877 4760 if (READ_BIT(hcryp->Instance->CR, (AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_GCM_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
ganlikun 0:13413ea9a877 4761 {
ganlikun 0:13413ea9a877 4762 /* Ensure that Busy flag is reset */
ganlikun 0:13413ea9a877 4763 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 4764 {
ganlikun 0:13413ea9a877 4765 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
ganlikun 0:13413ea9a877 4766 hcryp->State = HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 4767
ganlikun 0:13413ea9a877 4768 /* Process Unlocked */
ganlikun 0:13413ea9a877 4769 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 4770
ganlikun 0:13413ea9a877 4771 HAL_CRYP_ErrorCallback(hcryp);
ganlikun 0:13413ea9a877 4772 return ;
ganlikun 0:13413ea9a877 4773 }
ganlikun 0:13413ea9a877 4774 }
ganlikun 0:13413ea9a877 4775
ganlikun 0:13413ea9a877 4776 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
ganlikun 0:13413ea9a877 4777 outputaddr+=4U;
ganlikun 0:13413ea9a877 4778 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
ganlikun 0:13413ea9a877 4779 outputaddr+=4U;
ganlikun 0:13413ea9a877 4780 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
ganlikun 0:13413ea9a877 4781 outputaddr+=4U;
ganlikun 0:13413ea9a877 4782 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
ganlikun 0:13413ea9a877 4783 outputaddr+=4U;
ganlikun 0:13413ea9a877 4784 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
ganlikun 0:13413ea9a877 4785 outputaddr+=4U;
ganlikun 0:13413ea9a877 4786 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
ganlikun 0:13413ea9a877 4787 outputaddr+=4U;
ganlikun 0:13413ea9a877 4788 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
ganlikun 0:13413ea9a877 4789 outputaddr+=4U;
ganlikun 0:13413ea9a877 4790 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
ganlikun 0:13413ea9a877 4791 }
ganlikun 0:13413ea9a877 4792
ganlikun 0:13413ea9a877 4793 /**
ganlikun 0:13413ea9a877 4794 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Suspend
ganlikun 0:13413ea9a877 4795 * Registers in the AES_SUSPxR registers.
ganlikun 0:13413ea9a877 4796 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4797 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4798 * @param Input: Pointer to the buffer containing the saved suspend registers to
ganlikun 0:13413ea9a877 4799 * write back in the CRYP hardware block.
ganlikun 0:13413ea9a877 4800 * @retval None
ganlikun 0:13413ea9a877 4801 */
ganlikun 0:13413ea9a877 4802 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
ganlikun 0:13413ea9a877 4803 {
ganlikun 0:13413ea9a877 4804 uint32_t ivaddr = (uint32_t)Input;
ganlikun 0:13413ea9a877 4805
ganlikun 0:13413ea9a877 4806 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4807 ivaddr+=4U;
ganlikun 0:13413ea9a877 4808 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4809 ivaddr+=4U;
ganlikun 0:13413ea9a877 4810 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4811 ivaddr+=4U;
ganlikun 0:13413ea9a877 4812 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4813 ivaddr+=4U;
ganlikun 0:13413ea9a877 4814 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4815 ivaddr+=4U;
ganlikun 0:13413ea9a877 4816 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4817 ivaddr+=4U;
ganlikun 0:13413ea9a877 4818 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4819 ivaddr+=4U;
ganlikun 0:13413ea9a877 4820 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
ganlikun 0:13413ea9a877 4821 }
ganlikun 0:13413ea9a877 4822
ganlikun 0:13413ea9a877 4823
ganlikun 0:13413ea9a877 4824 /**
ganlikun 0:13413ea9a877 4825 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Key Registers.
ganlikun 0:13413ea9a877 4826 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4827 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4828 * @param Output: Pointer to the buffer containing the saved Key Registers.
ganlikun 0:13413ea9a877 4829 * @param KeySize: Indicates the key size (128 or 256 bits).
ganlikun 0:13413ea9a877 4830 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
ganlikun 0:13413ea9a877 4831 * as soon as the interrupted processing has to be resumed.
ganlikun 0:13413ea9a877 4832 * @retval None
ganlikun 0:13413ea9a877 4833 */
ganlikun 0:13413ea9a877 4834 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
ganlikun 0:13413ea9a877 4835 {
ganlikun 0:13413ea9a877 4836 uint32_t keyaddr = (uint32_t)Output;
ganlikun 0:13413ea9a877 4837
ganlikun 0:13413ea9a877 4838 if (KeySize == CRYP_KEYSIZE_256B)
ganlikun 0:13413ea9a877 4839 {
ganlikun 0:13413ea9a877 4840 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
ganlikun 0:13413ea9a877 4841 keyaddr+=4U;
ganlikun 0:13413ea9a877 4842 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
ganlikun 0:13413ea9a877 4843 keyaddr+=4U;
ganlikun 0:13413ea9a877 4844 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
ganlikun 0:13413ea9a877 4845 keyaddr+=4U;
ganlikun 0:13413ea9a877 4846 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
ganlikun 0:13413ea9a877 4847 keyaddr+=4U;
ganlikun 0:13413ea9a877 4848 }
ganlikun 0:13413ea9a877 4849
ganlikun 0:13413ea9a877 4850 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
ganlikun 0:13413ea9a877 4851 keyaddr+=4U;
ganlikun 0:13413ea9a877 4852 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
ganlikun 0:13413ea9a877 4853 keyaddr+=4U;
ganlikun 0:13413ea9a877 4854 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
ganlikun 0:13413ea9a877 4855 keyaddr+=4U;
ganlikun 0:13413ea9a877 4856 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
ganlikun 0:13413ea9a877 4857 }
ganlikun 0:13413ea9a877 4858
ganlikun 0:13413ea9a877 4859 /**
ganlikun 0:13413ea9a877 4860 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Key
ganlikun 0:13413ea9a877 4861 * Registers in the AES_KEYRx registers.
ganlikun 0:13413ea9a877 4862 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4863 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4864 * @param Input: Pointer to the buffer containing the saved key registers to
ganlikun 0:13413ea9a877 4865 * write back in the CRYP hardware block.
ganlikun 0:13413ea9a877 4866 * @param KeySize: Indicates the key size (128 or 256 bits)
ganlikun 0:13413ea9a877 4867 * @retval None
ganlikun 0:13413ea9a877 4868 */
ganlikun 0:13413ea9a877 4869 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
ganlikun 0:13413ea9a877 4870 {
ganlikun 0:13413ea9a877 4871 uint32_t keyaddr = (uint32_t)Input;
ganlikun 0:13413ea9a877 4872
ganlikun 0:13413ea9a877 4873 if (KeySize == CRYP_KEYSIZE_256B)
ganlikun 0:13413ea9a877 4874 {
ganlikun 0:13413ea9a877 4875 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4876 keyaddr+=4U;
ganlikun 0:13413ea9a877 4877 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4878 keyaddr+=4U;
ganlikun 0:13413ea9a877 4879 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4880 keyaddr+=4U;
ganlikun 0:13413ea9a877 4881 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4882 keyaddr+=4U;
ganlikun 0:13413ea9a877 4883 }
ganlikun 0:13413ea9a877 4884
ganlikun 0:13413ea9a877 4885 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4886 keyaddr+=4U;
ganlikun 0:13413ea9a877 4887 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4888 keyaddr+=4U;
ganlikun 0:13413ea9a877 4889 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4890 keyaddr+=4U;
ganlikun 0:13413ea9a877 4891 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
ganlikun 0:13413ea9a877 4892 }
ganlikun 0:13413ea9a877 4893
ganlikun 0:13413ea9a877 4894
ganlikun 0:13413ea9a877 4895 /**
ganlikun 0:13413ea9a877 4896 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Control Register.
ganlikun 0:13413ea9a877 4897 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4898 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4899 * @param Output: Pointer to the buffer containing the saved Control Register.
ganlikun 0:13413ea9a877 4900 * @note This values has to be stored for reuse by writing back the AES_CR register
ganlikun 0:13413ea9a877 4901 * as soon as the interrupted processing has to be resumed.
ganlikun 0:13413ea9a877 4902 * @retval None
ganlikun 0:13413ea9a877 4903 */
ganlikun 0:13413ea9a877 4904 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
ganlikun 0:13413ea9a877 4905 {
ganlikun 0:13413ea9a877 4906 *(uint32_t*)(Output) = hcryp->Instance->CR;
ganlikun 0:13413ea9a877 4907 }
ganlikun 0:13413ea9a877 4908
ganlikun 0:13413ea9a877 4909 /**
ganlikun 0:13413ea9a877 4910 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Control
ganlikun 0:13413ea9a877 4911 * Registers in the AES_CR register.
ganlikun 0:13413ea9a877 4912 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4913 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4914 * @param Input: Pointer to the buffer containing the saved Control Register to
ganlikun 0:13413ea9a877 4915 * write back in the CRYP hardware block.
ganlikun 0:13413ea9a877 4916 * @retval None
ganlikun 0:13413ea9a877 4917 */
ganlikun 0:13413ea9a877 4918 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
ganlikun 0:13413ea9a877 4919 {
ganlikun 0:13413ea9a877 4920 hcryp->Instance->CR = *(uint32_t*)(Input);
ganlikun 0:13413ea9a877 4921 /* At the same time, set handle state back to READY to be able to resume the AES calculations
ganlikun 0:13413ea9a877 4922 without the processing APIs returning HAL_BUSY when called. */
ganlikun 0:13413ea9a877 4923 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4924 }
ganlikun 0:13413ea9a877 4925
ganlikun 0:13413ea9a877 4926 /**
ganlikun 0:13413ea9a877 4927 * @brief Request CRYP processing suspension when in polling or interruption mode.
ganlikun 0:13413ea9a877 4928 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 4929 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 4930 * @note Set the handle field SuspendRequest to the appropriate value so that
ganlikun 0:13413ea9a877 4931 * the on-going CRYP processing is suspended as soon as the required
ganlikun 0:13413ea9a877 4932 * conditions are met.
ganlikun 0:13413ea9a877 4933 * @note It is advised not to suspend the CRYP processing when the DMA controller
ganlikun 0:13413ea9a877 4934 * is managing the data transfer
ganlikun 0:13413ea9a877 4935 * @retval None
ganlikun 0:13413ea9a877 4936 */
ganlikun 0:13413ea9a877 4937 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
ganlikun 0:13413ea9a877 4938 {
ganlikun 0:13413ea9a877 4939 /* Set Handle Suspend Request field */
ganlikun 0:13413ea9a877 4940 hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
ganlikun 0:13413ea9a877 4941 }
ganlikun 0:13413ea9a877 4942
ganlikun 0:13413ea9a877 4943 /**
ganlikun 0:13413ea9a877 4944 * @}
ganlikun 0:13413ea9a877 4945 */
ganlikun 0:13413ea9a877 4946
ganlikun 0:13413ea9a877 4947 /**
ganlikun 0:13413ea9a877 4948 * @}
ganlikun 0:13413ea9a877 4949 */
ganlikun 0:13413ea9a877 4950
ganlikun 0:13413ea9a877 4951 /** @addtogroup CRYPEx_Private_Functions
ganlikun 0:13413ea9a877 4952 * @{
ganlikun 0:13413ea9a877 4953 */
ganlikun 0:13413ea9a877 4954
ganlikun 0:13413ea9a877 4955 /**
ganlikun 0:13413ea9a877 4956 * @brief DMA CRYP Input Data process complete callback
ganlikun 0:13413ea9a877 4957 * for GCM, GMAC or CMAC chainging modes.
ganlikun 0:13413ea9a877 4958 * @note Specific setting of hcryp fields are required only
ganlikun 0:13413ea9a877 4959 * in the case of header phase where no output data DMA
ganlikun 0:13413ea9a877 4960 * transfer is on-going (only input data transfer is enabled
ganlikun 0:13413ea9a877 4961 * in such a case).
ganlikun 0:13413ea9a877 4962 * @param hdma: DMA handle.
ganlikun 0:13413ea9a877 4963 * @retval None
ganlikun 0:13413ea9a877 4964 */
ganlikun 0:13413ea9a877 4965 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 4966 {
ganlikun 0:13413ea9a877 4967 uint32_t difflength = 0U;
ganlikun 0:13413ea9a877 4968
ganlikun 0:13413ea9a877 4969 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 4970
ganlikun 0:13413ea9a877 4971 /* Disable the DMA transfer for input request */
ganlikun 0:13413ea9a877 4972 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
ganlikun 0:13413ea9a877 4973
ganlikun 0:13413ea9a877 4974 if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 4975 {
ganlikun 0:13413ea9a877 4976
ganlikun 0:13413ea9a877 4977 if (hcryp->CrypInCount != 0U)
ganlikun 0:13413ea9a877 4978 {
ganlikun 0:13413ea9a877 4979 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
ganlikun 0:13413ea9a877 4980 difflength = hcryp->CrypInCount;
ganlikun 0:13413ea9a877 4981 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 4982
ganlikun 0:13413ea9a877 4983 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
ganlikun 0:13413ea9a877 4984 }
ganlikun 0:13413ea9a877 4985 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 4986 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 4987 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
ganlikun 0:13413ea9a877 4988 }
ganlikun 0:13413ea9a877 4989 /* CCF flag indicating header phase AES processing completion
ganlikun 0:13413ea9a877 4990 will be checked at the start of the next phase:
ganlikun 0:13413ea9a877 4991 - payload phase (GCM or CCM when applicable)
ganlikun 0:13413ea9a877 4992 - final phase (GMAC or CMAC).
ganlikun 0:13413ea9a877 4993 This allows to avoid the Wait on Flag within the IRQ handling. */
ganlikun 0:13413ea9a877 4994
ganlikun 0:13413ea9a877 4995 /* Call input data transfer complete callback */
ganlikun 0:13413ea9a877 4996 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 4997 }
ganlikun 0:13413ea9a877 4998
ganlikun 0:13413ea9a877 4999 /**
ganlikun 0:13413ea9a877 5000 * @brief DMA CRYP Output Data process complete callback
ganlikun 0:13413ea9a877 5001 * for GCM, GMAC or CMAC chainging modes.
ganlikun 0:13413ea9a877 5002 * @note This callback is called only in the payload phase.
ganlikun 0:13413ea9a877 5003 * @param hdma: DMA handle.
ganlikun 0:13413ea9a877 5004 * @retval None
ganlikun 0:13413ea9a877 5005 */
ganlikun 0:13413ea9a877 5006 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 5007 {
ganlikun 0:13413ea9a877 5008 uint32_t difflength = 0U;
ganlikun 0:13413ea9a877 5009 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 5010
ganlikun 0:13413ea9a877 5011 /* Disable the DMA transfer for output request */
ganlikun 0:13413ea9a877 5012 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
ganlikun 0:13413ea9a877 5013
ganlikun 0:13413ea9a877 5014 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5015 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5016
ganlikun 0:13413ea9a877 5017 /* Initiate additional transfer to wrap-up data feeding to the IP */
ganlikun 0:13413ea9a877 5018 if (hcryp->CrypInCount != 0U)
ganlikun 0:13413ea9a877 5019 {
ganlikun 0:13413ea9a877 5020 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
ganlikun 0:13413ea9a877 5021 difflength = hcryp->CrypInCount;
ganlikun 0:13413ea9a877 5022 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 5023
ganlikun 0:13413ea9a877 5024 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
ganlikun 0:13413ea9a877 5025 }
ganlikun 0:13413ea9a877 5026
ganlikun 0:13413ea9a877 5027 /* Change the CRYP state to ready */
ganlikun 0:13413ea9a877 5028 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5029 /* Mark that the payload phase is over */
ganlikun 0:13413ea9a877 5030 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
ganlikun 0:13413ea9a877 5031
ganlikun 0:13413ea9a877 5032 /* Call output data transfer complete callback */
ganlikun 0:13413ea9a877 5033 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5034 }
ganlikun 0:13413ea9a877 5035
ganlikun 0:13413ea9a877 5036 /**
ganlikun 0:13413ea9a877 5037 * @brief DMA CRYP communication error callback
ganlikun 0:13413ea9a877 5038 * for GCM, GMAC or CMAC chainging modes.
ganlikun 0:13413ea9a877 5039 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 5040 * @retval None
ganlikun 0:13413ea9a877 5041 */
ganlikun 0:13413ea9a877 5042 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 5043 {
ganlikun 0:13413ea9a877 5044 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 5045
ganlikun 0:13413ea9a877 5046 hcryp->State= HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 5047 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
ganlikun 0:13413ea9a877 5048 HAL_CRYP_ErrorCallback(hcryp);
ganlikun 0:13413ea9a877 5049 /* Clear Error Flag */
ganlikun 0:13413ea9a877 5050 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
ganlikun 0:13413ea9a877 5051 }
ganlikun 0:13413ea9a877 5052
ganlikun 0:13413ea9a877 5053 /**
ganlikun 0:13413ea9a877 5054 * @brief Handle CRYP block input/output data handling under interruption
ganlikun 0:13413ea9a877 5055 * for GCM, GMAC or CMAC chaining modes.
ganlikun 0:13413ea9a877 5056 * @note The function is called under interruption only, once
ganlikun 0:13413ea9a877 5057 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
ganlikun 0:13413ea9a877 5058 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5059 * the configuration information for CRYP module
ganlikun 0:13413ea9a877 5060 * @retval HAL status
ganlikun 0:13413ea9a877 5061 */
ganlikun 0:13413ea9a877 5062 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
ganlikun 0:13413ea9a877 5063 {
ganlikun 0:13413ea9a877 5064 uint32_t inputaddr = 0x0U;
ganlikun 0:13413ea9a877 5065 uint32_t outputaddr = 0x0U;
ganlikun 0:13413ea9a877 5066 uint32_t index = 0x0U;
ganlikun 0:13413ea9a877 5067 uint32_t addhoc_process = 0U;
ganlikun 0:13413ea9a877 5068 uint32_t difflength = 0U;
ganlikun 0:13413ea9a877 5069 uint32_t difflengthmod4 = 0U;
ganlikun 0:13413ea9a877 5070 uint32_t mask[3] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
ganlikun 0:13413ea9a877 5071 uint32_t intermediate_data[4U] = {0U};
ganlikun 0:13413ea9a877 5072
ganlikun 0:13413ea9a877 5073 if(hcryp->State == HAL_CRYP_STATE_BUSY)
ganlikun 0:13413ea9a877 5074 {
ganlikun 0:13413ea9a877 5075 /*===========================*/
ganlikun 0:13413ea9a877 5076 /* GCM/GMAC(/CCM) init phase */
ganlikun 0:13413ea9a877 5077 /*===========================*/
ganlikun 0:13413ea9a877 5078 if (hcryp->Init.GCMCMACPhase == CRYP_INIT_PHASE)
ganlikun 0:13413ea9a877 5079 {
ganlikun 0:13413ea9a877 5080 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5081 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5082 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5083 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5084 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5085 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5086
ganlikun 0:13413ea9a877 5087 /* Mark that the initialization phase is over */
ganlikun 0:13413ea9a877 5088 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
ganlikun 0:13413ea9a877 5089
ganlikun 0:13413ea9a877 5090 /* Process Unlocked */
ganlikun 0:13413ea9a877 5091 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5092 /* Call computation complete callback */
ganlikun 0:13413ea9a877 5093 HAL_CRYPEx_ComputationCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5094 return HAL_OK;
ganlikun 0:13413ea9a877 5095 }
ganlikun 0:13413ea9a877 5096 /*=====================================*/
ganlikun 0:13413ea9a877 5097 /* GCM/GMAC or (CCM/)CMAC header phase */
ganlikun 0:13413ea9a877 5098 /*=====================================*/
ganlikun 0:13413ea9a877 5099 else if (hcryp->Init.GCMCMACPhase == CRYP_HEADER_PHASE)
ganlikun 0:13413ea9a877 5100 {
ganlikun 0:13413ea9a877 5101 /* Check if all input header data have been entered */
ganlikun 0:13413ea9a877 5102 if (hcryp->CrypInCount == 0U)
ganlikun 0:13413ea9a877 5103 {
ganlikun 0:13413ea9a877 5104 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5105 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5106 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5107 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5108 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5109 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5110 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 5111 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
ganlikun 0:13413ea9a877 5112
ganlikun 0:13413ea9a877 5113 /* Process Unlocked */
ganlikun 0:13413ea9a877 5114 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5115
ganlikun 0:13413ea9a877 5116 /* Call computation complete callback */
ganlikun 0:13413ea9a877 5117 HAL_CRYPEx_ComputationCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5118
ganlikun 0:13413ea9a877 5119 return HAL_OK;
ganlikun 0:13413ea9a877 5120 }
ganlikun 0:13413ea9a877 5121 /* If suspension flag has been raised, suspend processing */
ganlikun 0:13413ea9a877 5122 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
ganlikun 0:13413ea9a877 5123 {
ganlikun 0:13413ea9a877 5124 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5125 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5126
ganlikun 0:13413ea9a877 5127 /* reset SuspendRequest */
ganlikun 0:13413ea9a877 5128 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
ganlikun 0:13413ea9a877 5129 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5130 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5131 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5132 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
ganlikun 0:13413ea9a877 5133 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 5134 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
ganlikun 0:13413ea9a877 5135
ganlikun 0:13413ea9a877 5136 /* Process Unlocked */
ganlikun 0:13413ea9a877 5137 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5138
ganlikun 0:13413ea9a877 5139 return HAL_OK;
ganlikun 0:13413ea9a877 5140 }
ganlikun 0:13413ea9a877 5141 else /* Carry on feeding input data to the CRYP hardware block */
ganlikun 0:13413ea9a877 5142 {
ganlikun 0:13413ea9a877 5143 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5144 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5145 /* Get the last Input data address */
ganlikun 0:13413ea9a877 5146 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 5147
ganlikun 0:13413ea9a877 5148 /* Increment/decrement instance pointer/counter */
ganlikun 0:13413ea9a877 5149 if (hcryp->CrypInCount < 16U)
ganlikun 0:13413ea9a877 5150 {
ganlikun 0:13413ea9a877 5151 difflength = hcryp->CrypInCount;
ganlikun 0:13413ea9a877 5152 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 5153 addhoc_process = 1U;
ganlikun 0:13413ea9a877 5154 difflengthmod4 = difflength%4U;
ganlikun 0:13413ea9a877 5155 }
ganlikun 0:13413ea9a877 5156 else
ganlikun 0:13413ea9a877 5157 {
ganlikun 0:13413ea9a877 5158 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 5159 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 5160 }
ganlikun 0:13413ea9a877 5161
ganlikun 0:13413ea9a877 5162 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5163 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 5164 #else
ganlikun 0:13413ea9a877 5165 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
ganlikun 0:13413ea9a877 5166 #endif
ganlikun 0:13413ea9a877 5167 {
ganlikun 0:13413ea9a877 5168 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
ganlikun 0:13413ea9a877 5169 {
ganlikun 0:13413ea9a877 5170 /* All B blocks will have been entered after the next
ganlikun 0:13413ea9a877 5171 four DINR writing, so point at header buffer for
ganlikun 0:13413ea9a877 5172 the next iteration */
ganlikun 0:13413ea9a877 5173 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
ganlikun 0:13413ea9a877 5174 }
ganlikun 0:13413ea9a877 5175 }
ganlikun 0:13413ea9a877 5176
ganlikun 0:13413ea9a877 5177 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 5178 if (addhoc_process == 0U)
ganlikun 0:13413ea9a877 5179 {
ganlikun 0:13413ea9a877 5180 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5181 inputaddr+=4U;
ganlikun 0:13413ea9a877 5182 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5183 inputaddr+=4U;
ganlikun 0:13413ea9a877 5184 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5185 inputaddr+=4U;
ganlikun 0:13413ea9a877 5186 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5187 }
ganlikun 0:13413ea9a877 5188 else
ganlikun 0:13413ea9a877 5189 {
ganlikun 0:13413ea9a877 5190 /* Header remainder has size less than 128 bits */
ganlikun 0:13413ea9a877 5191 /* Enter complete words when possible */
ganlikun 0:13413ea9a877 5192 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 5193 {
ganlikun 0:13413ea9a877 5194 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 5195 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5196 inputaddr+=4U;
ganlikun 0:13413ea9a877 5197 }
ganlikun 0:13413ea9a877 5198 /* Enter incomplete word padded with zeroes if applicable
ganlikun 0:13413ea9a877 5199 (case of header length not a multiple of 32-bits) */
ganlikun 0:13413ea9a877 5200 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 5201 {
ganlikun 0:13413ea9a877 5202 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
ganlikun 0:13413ea9a877 5203 }
ganlikun 0:13413ea9a877 5204 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
ganlikun 0:13413ea9a877 5205 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 5206 {
ganlikun 0:13413ea9a877 5207 hcryp->Instance->DINR = 0U;
ganlikun 0:13413ea9a877 5208 }
ganlikun 0:13413ea9a877 5209 }
ganlikun 0:13413ea9a877 5210
ganlikun 0:13413ea9a877 5211 return HAL_OK;
ganlikun 0:13413ea9a877 5212 }
ganlikun 0:13413ea9a877 5213 }
ganlikun 0:13413ea9a877 5214 /*=======================*/
ganlikun 0:13413ea9a877 5215 /* GCM/CCM payload phase */
ganlikun 0:13413ea9a877 5216 /*=======================*/
ganlikun 0:13413ea9a877 5217 else if (hcryp->Init.GCMCMACPhase == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 5218 {
ganlikun 0:13413ea9a877 5219 /* Get the last output data address */
ganlikun 0:13413ea9a877 5220 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 5221
ganlikun 0:13413ea9a877 5222 /* Specific handling to manage payload size less than 128 bits
ganlikun 0:13413ea9a877 5223 when GCM (or CCM when applicable) encryption or decryption is selected.
ganlikun 0:13413ea9a877 5224 Check here if the last block output data are read */
ganlikun 0:13413ea9a877 5225 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5226 if ((hcryp->CrypOutCount < 16U) && \
ganlikun 0:13413ea9a877 5227 (hcryp->CrypOutCount > 0U))
ganlikun 0:13413ea9a877 5228 #else
ganlikun 0:13413ea9a877 5229 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
ganlikun 0:13413ea9a877 5230 (hcryp->CrypOutCount < 16U) && \
ganlikun 0:13413ea9a877 5231 (hcryp->CrypOutCount > 0U))
ganlikun 0:13413ea9a877 5232 #endif
ganlikun 0:13413ea9a877 5233 {
ganlikun 0:13413ea9a877 5234 addhoc_process = 1U;
ganlikun 0:13413ea9a877 5235 difflength = hcryp->CrypOutCount;
ganlikun 0:13413ea9a877 5236 difflengthmod4 = difflength%4U;
ganlikun 0:13413ea9a877 5237 hcryp->CrypOutCount = 0U; /* mark that no more output data will be needed */
ganlikun 0:13413ea9a877 5238 /* Retrieve intermediate data */
ganlikun 0:13413ea9a877 5239 for(index=0U; index < 4U; index ++)
ganlikun 0:13413ea9a877 5240 {
ganlikun 0:13413ea9a877 5241 intermediate_data[index] = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5242 }
ganlikun 0:13413ea9a877 5243 /* Retrieve last words of cyphered data */
ganlikun 0:13413ea9a877 5244 /* First, retrieve complete output words */
ganlikun 0:13413ea9a877 5245 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 5246 {
ganlikun 0:13413ea9a877 5247 *(uint32_t*)(outputaddr) = intermediate_data[index];
ganlikun 0:13413ea9a877 5248 outputaddr+=4U;
ganlikun 0:13413ea9a877 5249 }
ganlikun 0:13413ea9a877 5250 /* Next, retrieve partial output word if applicable;
ganlikun 0:13413ea9a877 5251 at the same time, start masking intermediate data
ganlikun 0:13413ea9a877 5252 with a mask of zeros of same size than the padding
ganlikun 0:13413ea9a877 5253 applied to the last block of payload */
ganlikun 0:13413ea9a877 5254 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 5255 {
ganlikun 0:13413ea9a877 5256 intermediate_data[difflength/4U] &= mask[difflengthmod4-1U];
ganlikun 0:13413ea9a877 5257 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
ganlikun 0:13413ea9a877 5258 }
ganlikun 0:13413ea9a877 5259
ganlikun 0:13413ea9a877 5260 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5261 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
ganlikun 0:13413ea9a877 5262 {
ganlikun 0:13413ea9a877 5263 /* Change again CHMOD configuration to GCM mode */
ganlikun 0:13413ea9a877 5264 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);
ganlikun 0:13413ea9a877 5265
ganlikun 0:13413ea9a877 5266 /* Select FINAL phase */
ganlikun 0:13413ea9a877 5267 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
ganlikun 0:13413ea9a877 5268
ganlikun 0:13413ea9a877 5269 /* Before inserting the intermediate data, carry on masking operation
ganlikun 0:13413ea9a877 5270 with a mask of zeros of same size than the padding applied to the last block of payload */
ganlikun 0:13413ea9a877 5271 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 5272 {
ganlikun 0:13413ea9a877 5273 intermediate_data[(difflength+3U)/4U+index] = 0U;
ganlikun 0:13413ea9a877 5274 }
ganlikun 0:13413ea9a877 5275
ganlikun 0:13413ea9a877 5276 /* Insert intermediate data to trigger an additional DOUTR reading round */
ganlikun 0:13413ea9a877 5277 /* Clear Computation Complete Flag before entering new block */
ganlikun 0:13413ea9a877 5278 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5279 for(index=0U; index < 4U; index ++)
ganlikun 0:13413ea9a877 5280 {
ganlikun 0:13413ea9a877 5281 hcryp->Instance->DINR = intermediate_data[index];
ganlikun 0:13413ea9a877 5282 }
ganlikun 0:13413ea9a877 5283 }
ganlikun 0:13413ea9a877 5284 else
ganlikun 0:13413ea9a877 5285 #endif
ganlikun 0:13413ea9a877 5286 {
ganlikun 0:13413ea9a877 5287 /* Payload phase is now over */
ganlikun 0:13413ea9a877 5288 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5289 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5290 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5291 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5292 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5293 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5294 /* Mark that the payload phase is over */
ganlikun 0:13413ea9a877 5295 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
ganlikun 0:13413ea9a877 5296
ganlikun 0:13413ea9a877 5297 /* Process Unlocked */
ganlikun 0:13413ea9a877 5298 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5299
ganlikun 0:13413ea9a877 5300 /* Call computation complete callback */
ganlikun 0:13413ea9a877 5301 HAL_CRYPEx_ComputationCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5302 }
ganlikun 0:13413ea9a877 5303 return HAL_OK;
ganlikun 0:13413ea9a877 5304 }
ganlikun 0:13413ea9a877 5305 else
ganlikun 0:13413ea9a877 5306 {
ganlikun 0:13413ea9a877 5307 if (hcryp->CrypOutCount != 0U)
ganlikun 0:13413ea9a877 5308 {
ganlikun 0:13413ea9a877 5309 /* Usual case (different than GCM/CCM last block < 128 bits ciphering) */
ganlikun 0:13413ea9a877 5310 /* Retrieve the last block available from the CRYP hardware block:
ganlikun 0:13413ea9a877 5311 read the output block from the Data Output Register */
ganlikun 0:13413ea9a877 5312 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5313 outputaddr+=4U;
ganlikun 0:13413ea9a877 5314 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5315 outputaddr+=4U;
ganlikun 0:13413ea9a877 5316 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5317 outputaddr+=4U;
ganlikun 0:13413ea9a877 5318 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5319
ganlikun 0:13413ea9a877 5320 /* Increment/decrement instance pointer/counter */
ganlikun 0:13413ea9a877 5321 hcryp->pCrypOutBuffPtr += 16U;
ganlikun 0:13413ea9a877 5322 hcryp->CrypOutCount -= 16U;
ganlikun 0:13413ea9a877 5323 }
ganlikun 0:13413ea9a877 5324 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5325 else
ganlikun 0:13413ea9a877 5326 {
ganlikun 0:13413ea9a877 5327 /* Software work-around: additional DOUTR reading round to discard the data */
ganlikun 0:13413ea9a877 5328 for(index=0U; index < 4U; index ++)
ganlikun 0:13413ea9a877 5329 {
ganlikun 0:13413ea9a877 5330 intermediate_data[index] = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5331 }
ganlikun 0:13413ea9a877 5332 }
ganlikun 0:13413ea9a877 5333 #endif
ganlikun 0:13413ea9a877 5334 }
ganlikun 0:13413ea9a877 5335
ganlikun 0:13413ea9a877 5336 /* Check if all output text has been retrieved */
ganlikun 0:13413ea9a877 5337 if (hcryp->CrypOutCount == 0U)
ganlikun 0:13413ea9a877 5338 {
ganlikun 0:13413ea9a877 5339 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5340 /* Make sure that software-work around is not running before disabling
ganlikun 0:13413ea9a877 5341 the interruptions (indeed, if software work-around is running, the
ganlikun 0:13413ea9a877 5342 interruptions must not be disabled to allow the additional DOUTR
ganlikun 0:13413ea9a877 5343 reading round */
ganlikun 0:13413ea9a877 5344 if (addhoc_process == 0U)
ganlikun 0:13413ea9a877 5345 #endif
ganlikun 0:13413ea9a877 5346 {
ganlikun 0:13413ea9a877 5347 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5348 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5349 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5350 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5351 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5352 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5353 /* Mark that the payload phase is over */
ganlikun 0:13413ea9a877 5354 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
ganlikun 0:13413ea9a877 5355
ganlikun 0:13413ea9a877 5356 /* Process Unlocked */
ganlikun 0:13413ea9a877 5357 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5358
ganlikun 0:13413ea9a877 5359 /* Call computation complete callback */
ganlikun 0:13413ea9a877 5360 HAL_CRYPEx_ComputationCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5361 }
ganlikun 0:13413ea9a877 5362
ganlikun 0:13413ea9a877 5363 return HAL_OK;
ganlikun 0:13413ea9a877 5364 }
ganlikun 0:13413ea9a877 5365 /* If suspension flag has been raised, suspend processing */
ganlikun 0:13413ea9a877 5366 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
ganlikun 0:13413ea9a877 5367 {
ganlikun 0:13413ea9a877 5368 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5369 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5370
ganlikun 0:13413ea9a877 5371 /* reset SuspendRequest */
ganlikun 0:13413ea9a877 5372 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
ganlikun 0:13413ea9a877 5373 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5374 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5375 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5376 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
ganlikun 0:13413ea9a877 5377 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 5378 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
ganlikun 0:13413ea9a877 5379
ganlikun 0:13413ea9a877 5380 /* Process Unlocked */
ganlikun 0:13413ea9a877 5381 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5382
ganlikun 0:13413ea9a877 5383 return HAL_OK;
ganlikun 0:13413ea9a877 5384 }
ganlikun 0:13413ea9a877 5385 else /* Output data are still expected, carry on feeding the CRYP
ganlikun 0:13413ea9a877 5386 hardware block with input data */
ganlikun 0:13413ea9a877 5387 {
ganlikun 0:13413ea9a877 5388 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5389 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5390 /* Get the last Input data address */
ganlikun 0:13413ea9a877 5391 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 5392
ganlikun 0:13413ea9a877 5393 /* Usual input data feeding case */
ganlikun 0:13413ea9a877 5394 if (hcryp->CrypInCount < 16U)
ganlikun 0:13413ea9a877 5395 {
ganlikun 0:13413ea9a877 5396 difflength = (uint32_t) (hcryp->CrypInCount);
ganlikun 0:13413ea9a877 5397 difflengthmod4 = difflength%4U;
ganlikun 0:13413ea9a877 5398 hcryp->CrypInCount = 0U;
ganlikun 0:13413ea9a877 5399
ganlikun 0:13413ea9a877 5400 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5401 /* In case of GCM encryption or CCM decryption, specify the number of padding
ganlikun 0:13413ea9a877 5402 bytes in last block of payload */
ganlikun 0:13413ea9a877 5403 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 5404 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))
ganlikun 0:13413ea9a877 5405 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 5406 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
ganlikun 0:13413ea9a877 5407 {
ganlikun 0:13413ea9a877 5408 /* Set NPBLB field in writing the number of padding bytes
ganlikun 0:13413ea9a877 5409 for the last block of payload */
ganlikun 0:13413ea9a877 5410 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
ganlikun 0:13413ea9a877 5411 }
ganlikun 0:13413ea9a877 5412 #else
ganlikun 0:13413ea9a877 5413 /* Software workaround applied to GCM encryption only */
ganlikun 0:13413ea9a877 5414 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
ganlikun 0:13413ea9a877 5415 {
ganlikun 0:13413ea9a877 5416 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
ganlikun 0:13413ea9a877 5417 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
ganlikun 0:13413ea9a877 5418 }
ganlikun 0:13413ea9a877 5419 #endif
ganlikun 0:13413ea9a877 5420
ganlikun 0:13413ea9a877 5421 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
ganlikun 0:13413ea9a877 5422 to have a complete block of 128 bits */
ganlikun 0:13413ea9a877 5423 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 5424 {
ganlikun 0:13413ea9a877 5425 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 5426 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5427 inputaddr+=4U;
ganlikun 0:13413ea9a877 5428 }
ganlikun 0:13413ea9a877 5429 /* If required, manage input data size not multiple of 32 bits */
ganlikun 0:13413ea9a877 5430 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 5431 {
ganlikun 0:13413ea9a877 5432 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1U]);
ganlikun 0:13413ea9a877 5433 }
ganlikun 0:13413ea9a877 5434 /* Wrap-up in padding with zero-words if applicable */
ganlikun 0:13413ea9a877 5435 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 5436 {
ganlikun 0:13413ea9a877 5437 hcryp->Instance->DINR = 0U;
ganlikun 0:13413ea9a877 5438 }
ganlikun 0:13413ea9a877 5439 }
ganlikun 0:13413ea9a877 5440 else
ganlikun 0:13413ea9a877 5441 {
ganlikun 0:13413ea9a877 5442 hcryp->pCrypInBuffPtr += 16U;
ganlikun 0:13413ea9a877 5443 hcryp->CrypInCount -= 16U;
ganlikun 0:13413ea9a877 5444
ganlikun 0:13413ea9a877 5445 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 5446 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5447 inputaddr+=4U;
ganlikun 0:13413ea9a877 5448 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5449 inputaddr+=4U;
ganlikun 0:13413ea9a877 5450 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5451 inputaddr+=4U;
ganlikun 0:13413ea9a877 5452 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5453 }
ganlikun 0:13413ea9a877 5454
ganlikun 0:13413ea9a877 5455 return HAL_OK;
ganlikun 0:13413ea9a877 5456 }
ganlikun 0:13413ea9a877 5457 }
ganlikun 0:13413ea9a877 5458 /*====================================*/
ganlikun 0:13413ea9a877 5459 /* GCM/GMAC or (CCM/)CMAC final phase */
ganlikun 0:13413ea9a877 5460 /*====================================*/
ganlikun 0:13413ea9a877 5461 else if (hcryp->Init.GCMCMACPhase == CRYP_FINAL_PHASE)
ganlikun 0:13413ea9a877 5462 {
ganlikun 0:13413ea9a877 5463 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5464 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5465
ganlikun 0:13413ea9a877 5466 /* Get the last output data address */
ganlikun 0:13413ea9a877 5467 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 5468
ganlikun 0:13413ea9a877 5469 /* Retrieve the last expected data from the CRYP hardware block:
ganlikun 0:13413ea9a877 5470 read the output block from the Data Output Register */
ganlikun 0:13413ea9a877 5471 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5472 outputaddr+=4U;
ganlikun 0:13413ea9a877 5473 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5474 outputaddr+=4U;
ganlikun 0:13413ea9a877 5475 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5476 outputaddr+=4U;
ganlikun 0:13413ea9a877 5477 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5478
ganlikun 0:13413ea9a877 5479 /* Disable Computation Complete Flag and Errors Interrupts */
ganlikun 0:13413ea9a877 5480 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
ganlikun 0:13413ea9a877 5481 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5482 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5483 /* Mark that the header phase is over */
ganlikun 0:13413ea9a877 5484 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
ganlikun 0:13413ea9a877 5485
ganlikun 0:13413ea9a877 5486 /* Disable the Peripheral */
ganlikun 0:13413ea9a877 5487 __HAL_CRYP_DISABLE();
ganlikun 0:13413ea9a877 5488 /* Process Unlocked */
ganlikun 0:13413ea9a877 5489 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5490
ganlikun 0:13413ea9a877 5491 /* Call computation complete callback */
ganlikun 0:13413ea9a877 5492 HAL_CRYPEx_ComputationCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5493
ganlikun 0:13413ea9a877 5494 return HAL_OK;
ganlikun 0:13413ea9a877 5495 }
ganlikun 0:13413ea9a877 5496 else
ganlikun 0:13413ea9a877 5497 {
ganlikun 0:13413ea9a877 5498 /* Clear Computation Complete Flag */
ganlikun 0:13413ea9a877 5499 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5500 hcryp->State = HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 5501 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5502 return HAL_ERROR;
ganlikun 0:13413ea9a877 5503 }
ganlikun 0:13413ea9a877 5504 }
ganlikun 0:13413ea9a877 5505 else
ganlikun 0:13413ea9a877 5506 {
ganlikun 0:13413ea9a877 5507 return HAL_BUSY;
ganlikun 0:13413ea9a877 5508 }
ganlikun 0:13413ea9a877 5509 }
ganlikun 0:13413ea9a877 5510
ganlikun 0:13413ea9a877 5511 /**
ganlikun 0:13413ea9a877 5512 * @brief Set the DMA configuration and start the DMA transfer
ganlikun 0:13413ea9a877 5513 * for GCM, GMAC or CMAC chainging modes.
ganlikun 0:13413ea9a877 5514 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5515 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5516 * @param inputaddr: Address of the Input buffer.
ganlikun 0:13413ea9a877 5517 * @param Size: Size of the Input buffer un bytes, must be a multiple of 16.
ganlikun 0:13413ea9a877 5518 * @param outputaddr: Address of the Output buffer, null pointer when no output DMA stream
ganlikun 0:13413ea9a877 5519 * has to be configured.
ganlikun 0:13413ea9a877 5520 * @retval None
ganlikun 0:13413ea9a877 5521 */
ganlikun 0:13413ea9a877 5522 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
ganlikun 0:13413ea9a877 5523 {
ganlikun 0:13413ea9a877 5524
ganlikun 0:13413ea9a877 5525 /* Set the input CRYP DMA transfer complete callback */
ganlikun 0:13413ea9a877 5526 hcryp->hdmain->XferCpltCallback = CRYP_GCMCMAC_DMAInCplt;
ganlikun 0:13413ea9a877 5527 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 5528 hcryp->hdmain->XferErrorCallback = CRYP_GCMCMAC_DMAError;
ganlikun 0:13413ea9a877 5529
ganlikun 0:13413ea9a877 5530 if (outputaddr != 0U)
ganlikun 0:13413ea9a877 5531 {
ganlikun 0:13413ea9a877 5532 /* Set the output CRYP DMA transfer complete callback */
ganlikun 0:13413ea9a877 5533 hcryp->hdmaout->XferCpltCallback = CRYP_GCMCMAC_DMAOutCplt;
ganlikun 0:13413ea9a877 5534 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 5535 hcryp->hdmaout->XferErrorCallback = CRYP_GCMCMAC_DMAError;
ganlikun 0:13413ea9a877 5536 }
ganlikun 0:13413ea9a877 5537
ganlikun 0:13413ea9a877 5538 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 5539 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 5540
ganlikun 0:13413ea9a877 5541 /* Enable the DMA input stream */
ganlikun 0:13413ea9a877 5542 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U);
ganlikun 0:13413ea9a877 5543
ganlikun 0:13413ea9a877 5544 /* Enable the DMA input request */
ganlikun 0:13413ea9a877 5545 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
ganlikun 0:13413ea9a877 5546
ganlikun 0:13413ea9a877 5547
ganlikun 0:13413ea9a877 5548 if (outputaddr != 0U)
ganlikun 0:13413ea9a877 5549 {
ganlikun 0:13413ea9a877 5550 /* Enable the DMA output stream */
ganlikun 0:13413ea9a877 5551 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U);
ganlikun 0:13413ea9a877 5552
ganlikun 0:13413ea9a877 5553 /* Enable the DMA output request */
ganlikun 0:13413ea9a877 5554 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
ganlikun 0:13413ea9a877 5555 }
ganlikun 0:13413ea9a877 5556 }
ganlikun 0:13413ea9a877 5557
ganlikun 0:13413ea9a877 5558 /**
ganlikun 0:13413ea9a877 5559 * @brief Write/read input/output data in polling mode.
ganlikun 0:13413ea9a877 5560 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5561 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5562 * @param Input: Pointer to the Input buffer.
ganlikun 0:13413ea9a877 5563 * @param Ilength: Length of the Input buffer in bytes, must be a multiple of 16.
ganlikun 0:13413ea9a877 5564 * @param Output: Pointer to the returned buffer.
ganlikun 0:13413ea9a877 5565 * @param Timeout: Specify Timeout value.
ganlikun 0:13413ea9a877 5566 * @retval HAL status
ganlikun 0:13413ea9a877 5567 */
ganlikun 0:13413ea9a877 5568 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
ganlikun 0:13413ea9a877 5569 {
ganlikun 0:13413ea9a877 5570 uint32_t index = 0U;
ganlikun 0:13413ea9a877 5571 uint32_t inputaddr = (uint32_t)Input;
ganlikun 0:13413ea9a877 5572 uint32_t outputaddr = (uint32_t)Output;
ganlikun 0:13413ea9a877 5573
ganlikun 0:13413ea9a877 5574
ganlikun 0:13413ea9a877 5575 for(index=0U; (index < Ilength); index += 16U)
ganlikun 0:13413ea9a877 5576 {
ganlikun 0:13413ea9a877 5577 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 5578 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5579 inputaddr+=4U;
ganlikun 0:13413ea9a877 5580 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5581 inputaddr+=4U;
ganlikun 0:13413ea9a877 5582 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5583 inputaddr+=4U;
ganlikun 0:13413ea9a877 5584 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5585 inputaddr+=4U;
ganlikun 0:13413ea9a877 5586
ganlikun 0:13413ea9a877 5587 /* Wait for CCF flag to be raised */
ganlikun 0:13413ea9a877 5588 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 5589 {
ganlikun 0:13413ea9a877 5590 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5591 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5592 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 5593 }
ganlikun 0:13413ea9a877 5594
ganlikun 0:13413ea9a877 5595 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5596 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5597
ganlikun 0:13413ea9a877 5598 /* Read the Output block from the Data Output Register */
ganlikun 0:13413ea9a877 5599 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5600 outputaddr+=4U;
ganlikun 0:13413ea9a877 5601 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5602 outputaddr+=4U;
ganlikun 0:13413ea9a877 5603 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5604 outputaddr+=4U;
ganlikun 0:13413ea9a877 5605 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5606 outputaddr+=4U;
ganlikun 0:13413ea9a877 5607
ganlikun 0:13413ea9a877 5608 /* If the suspension flag has been raised and if the processing is not about
ganlikun 0:13413ea9a877 5609 to end, suspend processing */
ganlikun 0:13413ea9a877 5610 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16U) < Ilength))
ganlikun 0:13413ea9a877 5611 {
ganlikun 0:13413ea9a877 5612 /* Reset SuspendRequest */
ganlikun 0:13413ea9a877 5613 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
ganlikun 0:13413ea9a877 5614
ganlikun 0:13413ea9a877 5615 /* Save current reading and writing locations of Input and Output buffers */
ganlikun 0:13413ea9a877 5616 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
ganlikun 0:13413ea9a877 5617 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
ganlikun 0:13413ea9a877 5618 /* Save the number of bytes that remain to be processed at this point */
ganlikun 0:13413ea9a877 5619 hcryp->CrypInCount = Ilength - (index+16U);
ganlikun 0:13413ea9a877 5620
ganlikun 0:13413ea9a877 5621 /* Change the CRYP state */
ganlikun 0:13413ea9a877 5622 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
ganlikun 0:13413ea9a877 5623
ganlikun 0:13413ea9a877 5624 return HAL_OK;
ganlikun 0:13413ea9a877 5625 }
ganlikun 0:13413ea9a877 5626
ganlikun 0:13413ea9a877 5627 }
ganlikun 0:13413ea9a877 5628 /* Return function status */
ganlikun 0:13413ea9a877 5629 return HAL_OK;
ganlikun 0:13413ea9a877 5630
ganlikun 0:13413ea9a877 5631 }
ganlikun 0:13413ea9a877 5632
ganlikun 0:13413ea9a877 5633 /**
ganlikun 0:13413ea9a877 5634 * @brief Read derivative key in polling mode when CRYP hardware block is set
ganlikun 0:13413ea9a877 5635 * in key derivation operating mode (mode 2).
ganlikun 0:13413ea9a877 5636 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5637 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5638 * @param Output: Pointer to the returned buffer.
ganlikun 0:13413ea9a877 5639 * @param Timeout: Specify Timeout value.
ganlikun 0:13413ea9a877 5640 * @retval HAL status
ganlikun 0:13413ea9a877 5641 */
ganlikun 0:13413ea9a877 5642 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
ganlikun 0:13413ea9a877 5643 {
ganlikun 0:13413ea9a877 5644 uint32_t outputaddr = (uint32_t)Output;
ganlikun 0:13413ea9a877 5645
ganlikun 0:13413ea9a877 5646 /* Wait for CCF flag to be raised */
ganlikun 0:13413ea9a877 5647 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
ganlikun 0:13413ea9a877 5648 {
ganlikun 0:13413ea9a877 5649 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5650 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5651 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 5652 }
ganlikun 0:13413ea9a877 5653 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5654 __HAL_CRYP_CLEAR_FLAG( CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5655
ganlikun 0:13413ea9a877 5656 /* Read the derivative key from the AES_KEYRx registers */
ganlikun 0:13413ea9a877 5657 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
ganlikun 0:13413ea9a877 5658 {
ganlikun 0:13413ea9a877 5659 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
ganlikun 0:13413ea9a877 5660 outputaddr+=4U;
ganlikun 0:13413ea9a877 5661 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
ganlikun 0:13413ea9a877 5662 outputaddr+=4U;
ganlikun 0:13413ea9a877 5663 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
ganlikun 0:13413ea9a877 5664 outputaddr+=4U;
ganlikun 0:13413ea9a877 5665 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
ganlikun 0:13413ea9a877 5666 outputaddr+=4U;
ganlikun 0:13413ea9a877 5667 }
ganlikun 0:13413ea9a877 5668
ganlikun 0:13413ea9a877 5669 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
ganlikun 0:13413ea9a877 5670 outputaddr+=4U;
ganlikun 0:13413ea9a877 5671 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
ganlikun 0:13413ea9a877 5672 outputaddr+=4U;
ganlikun 0:13413ea9a877 5673 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
ganlikun 0:13413ea9a877 5674 outputaddr+=4U;
ganlikun 0:13413ea9a877 5675 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
ganlikun 0:13413ea9a877 5676
ganlikun 0:13413ea9a877 5677 /* Return function status */
ganlikun 0:13413ea9a877 5678 return HAL_OK;
ganlikun 0:13413ea9a877 5679 }
ganlikun 0:13413ea9a877 5680
ganlikun 0:13413ea9a877 5681 /**
ganlikun 0:13413ea9a877 5682 * @brief Set the DMA configuration and start the DMA transfer.
ganlikun 0:13413ea9a877 5683 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5684 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5685 * @param inputaddr: Address of the Input buffer.
ganlikun 0:13413ea9a877 5686 * @param Size: Size of the Input buffer in bytes, must be a multiple of 16.
ganlikun 0:13413ea9a877 5687 * @param outputaddr: Address of the Output buffer.
ganlikun 0:13413ea9a877 5688 * @retval None
ganlikun 0:13413ea9a877 5689 */
ganlikun 0:13413ea9a877 5690 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
ganlikun 0:13413ea9a877 5691 {
ganlikun 0:13413ea9a877 5692 /* Set the CRYP DMA transfer complete callback */
ganlikun 0:13413ea9a877 5693 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
ganlikun 0:13413ea9a877 5694 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 5695 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
ganlikun 0:13413ea9a877 5696
ganlikun 0:13413ea9a877 5697 /* Set the CRYP DMA transfer complete callback */
ganlikun 0:13413ea9a877 5698 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
ganlikun 0:13413ea9a877 5699 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 5700 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
ganlikun 0:13413ea9a877 5701
ganlikun 0:13413ea9a877 5702 /* Enable the DMA input stream */
ganlikun 0:13413ea9a877 5703 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4U);
ganlikun 0:13413ea9a877 5704
ganlikun 0:13413ea9a877 5705 /* Enable the DMA output stream */
ganlikun 0:13413ea9a877 5706 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4U);
ganlikun 0:13413ea9a877 5707
ganlikun 0:13413ea9a877 5708 /* Enable In and Out DMA requests */
ganlikun 0:13413ea9a877 5709 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
ganlikun 0:13413ea9a877 5710
ganlikun 0:13413ea9a877 5711 /* Enable the CRYP peripheral */
ganlikun 0:13413ea9a877 5712 __HAL_CRYP_ENABLE();
ganlikun 0:13413ea9a877 5713 }
ganlikun 0:13413ea9a877 5714
ganlikun 0:13413ea9a877 5715 /**
ganlikun 0:13413ea9a877 5716 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
ganlikun 0:13413ea9a877 5717 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5718 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5719 * @param Timeout: Timeout duration.
ganlikun 0:13413ea9a877 5720 * @retval HAL status
ganlikun 0:13413ea9a877 5721 */
ganlikun 0:13413ea9a877 5722 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
ganlikun 0:13413ea9a877 5723 {
ganlikun 0:13413ea9a877 5724 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 5725
ganlikun 0:13413ea9a877 5726 /* Get timeout */
ganlikun 0:13413ea9a877 5727 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 5728
ganlikun 0:13413ea9a877 5729 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
ganlikun 0:13413ea9a877 5730 {
ganlikun 0:13413ea9a877 5731 /* Check for the Timeout */
ganlikun 0:13413ea9a877 5732 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 5733 {
ganlikun 0:13413ea9a877 5734 if((HAL_GetTick() - tickstart ) > Timeout)
ganlikun 0:13413ea9a877 5735 {
ganlikun 0:13413ea9a877 5736 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 5737 }
ganlikun 0:13413ea9a877 5738 }
ganlikun 0:13413ea9a877 5739 }
ganlikun 0:13413ea9a877 5740 return HAL_OK;
ganlikun 0:13413ea9a877 5741 }
ganlikun 0:13413ea9a877 5742
ganlikun 0:13413ea9a877 5743 /**
ganlikun 0:13413ea9a877 5744 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
ganlikun 0:13413ea9a877 5745 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5746 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5747 * @param Timeout: Timeout duration.
ganlikun 0:13413ea9a877 5748 * @retval HAL status
ganlikun 0:13413ea9a877 5749 */
ganlikun 0:13413ea9a877 5750 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
ganlikun 0:13413ea9a877 5751 {
ganlikun 0:13413ea9a877 5752 uint32_t tickstart = 0U;
ganlikun 0:13413ea9a877 5753
ganlikun 0:13413ea9a877 5754 /* Get timeout */
ganlikun 0:13413ea9a877 5755 tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 5756
ganlikun 0:13413ea9a877 5757 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
ganlikun 0:13413ea9a877 5758 {
ganlikun 0:13413ea9a877 5759 /* Check for the Timeout */
ganlikun 0:13413ea9a877 5760 if(Timeout != HAL_MAX_DELAY)
ganlikun 0:13413ea9a877 5761 {
ganlikun 0:13413ea9a877 5762 if((HAL_GetTick() - tickstart ) > Timeout)
ganlikun 0:13413ea9a877 5763 {
ganlikun 0:13413ea9a877 5764 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 5765 }
ganlikun 0:13413ea9a877 5766 }
ganlikun 0:13413ea9a877 5767 }
ganlikun 0:13413ea9a877 5768 return HAL_OK;
ganlikun 0:13413ea9a877 5769 }
ganlikun 0:13413ea9a877 5770
ganlikun 0:13413ea9a877 5771 /**
ganlikun 0:13413ea9a877 5772 * @brief DMA CRYP Input Data process complete callback.
ganlikun 0:13413ea9a877 5773 * @param hdma: DMA handle.
ganlikun 0:13413ea9a877 5774 * @retval None
ganlikun 0:13413ea9a877 5775 */
ganlikun 0:13413ea9a877 5776 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 5777 {
ganlikun 0:13413ea9a877 5778 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 5779
ganlikun 0:13413ea9a877 5780 /* Disable the DMA transfer for input request */
ganlikun 0:13413ea9a877 5781 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
ganlikun 0:13413ea9a877 5782
ganlikun 0:13413ea9a877 5783 /* Call input data transfer complete callback */
ganlikun 0:13413ea9a877 5784 HAL_CRYP_InCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5785 }
ganlikun 0:13413ea9a877 5786
ganlikun 0:13413ea9a877 5787 /**
ganlikun 0:13413ea9a877 5788 * @brief DMA CRYP Output Data process complete callback.
ganlikun 0:13413ea9a877 5789 * @param hdma: DMA handle.
ganlikun 0:13413ea9a877 5790 * @retval None
ganlikun 0:13413ea9a877 5791 */
ganlikun 0:13413ea9a877 5792 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 5793 {
ganlikun 0:13413ea9a877 5794 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 5795
ganlikun 0:13413ea9a877 5796 /* Disable the DMA transfer for output request */
ganlikun 0:13413ea9a877 5797 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
ganlikun 0:13413ea9a877 5798
ganlikun 0:13413ea9a877 5799 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5800 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5801
ganlikun 0:13413ea9a877 5802 /* Disable CRYP */
ganlikun 0:13413ea9a877 5803 __HAL_CRYP_DISABLE();
ganlikun 0:13413ea9a877 5804
ganlikun 0:13413ea9a877 5805 /* Change the CRYP state to ready */
ganlikun 0:13413ea9a877 5806 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5807
ganlikun 0:13413ea9a877 5808 /* Call output data transfer complete callback */
ganlikun 0:13413ea9a877 5809 HAL_CRYP_OutCpltCallback(hcryp);
ganlikun 0:13413ea9a877 5810 }
ganlikun 0:13413ea9a877 5811
ganlikun 0:13413ea9a877 5812 /**
ganlikun 0:13413ea9a877 5813 * @brief DMA CRYP communication error callback.
ganlikun 0:13413ea9a877 5814 * @param hdma: DMA handle.
ganlikun 0:13413ea9a877 5815 * @retval None
ganlikun 0:13413ea9a877 5816 */
ganlikun 0:13413ea9a877 5817 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 5818 {
ganlikun 0:13413ea9a877 5819 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 5820
ganlikun 0:13413ea9a877 5821 hcryp->State= HAL_CRYP_STATE_ERROR;
ganlikun 0:13413ea9a877 5822 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
ganlikun 0:13413ea9a877 5823 HAL_CRYP_ErrorCallback(hcryp);
ganlikun 0:13413ea9a877 5824 /* Clear Error Flag */
ganlikun 0:13413ea9a877 5825 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
ganlikun 0:13413ea9a877 5826 }
ganlikun 0:13413ea9a877 5827
ganlikun 0:13413ea9a877 5828 /**
ganlikun 0:13413ea9a877 5829 * @brief Last header or payload block padding when size is not a multiple of 128 bits.
ganlikun 0:13413ea9a877 5830 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 5831 * the configuration information for CRYP module.
ganlikun 0:13413ea9a877 5832 * @param difflength: size remainder after having fed all complete 128-bit blocks.
ganlikun 0:13413ea9a877 5833 * @param polling: specifies whether or not polling on CCF must be done after having
ganlikun 0:13413ea9a877 5834 * entered a complete block.
ganlikun 0:13413ea9a877 5835 * @retval None
ganlikun 0:13413ea9a877 5836 */
ganlikun 0:13413ea9a877 5837 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
ganlikun 0:13413ea9a877 5838 {
ganlikun 0:13413ea9a877 5839 uint32_t index = 0U;
ganlikun 0:13413ea9a877 5840 uint32_t difflengthmod4 = difflength%4U;
ganlikun 0:13413ea9a877 5841 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
ganlikun 0:13413ea9a877 5842 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
ganlikun 0:13413ea9a877 5843 uint32_t mask[3U] = {0x0FFU, 0x0FFFFU, 0x0FFFFFFU};
ganlikun 0:13413ea9a877 5844 uint32_t intermediate_data[4U] = {0U};
ganlikun 0:13413ea9a877 5845
ganlikun 0:13413ea9a877 5846 #if defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5847 /* In case of GCM encryption or CCM decryption, specify the number of padding
ganlikun 0:13413ea9a877 5848 bytes in last block of payload */
ganlikun 0:13413ea9a877 5849 if (READ_BIT(hcryp->Instance->CR,AES_CR_GCMPH) == CRYP_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 5850 {
ganlikun 0:13413ea9a877 5851 if (((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_GCM_GMAC)
ganlikun 0:13413ea9a877 5852 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_ENCRYPT))
ganlikun 0:13413ea9a877 5853 || ((READ_BIT(hcryp->Instance->CR, AES_CR_CHMOD) == CRYP_CHAINMODE_AES_CCM_CMAC)
ganlikun 0:13413ea9a877 5854 && (READ_BIT(hcryp->Instance->CR, AES_CR_MODE) == CRYP_ALGOMODE_DECRYPT)))
ganlikun 0:13413ea9a877 5855 {
ganlikun 0:13413ea9a877 5856 /* Set NPBLB field in writing the number of padding bytes
ganlikun 0:13413ea9a877 5857 for the last block of payload */
ganlikun 0:13413ea9a877 5858 MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 16U - difflength);
ganlikun 0:13413ea9a877 5859 }
ganlikun 0:13413ea9a877 5860 }
ganlikun 0:13413ea9a877 5861 #else
ganlikun 0:13413ea9a877 5862 /* Software workaround applied to GCM encryption only */
ganlikun 0:13413ea9a877 5863 if ((hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) &&
ganlikun 0:13413ea9a877 5864 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
ganlikun 0:13413ea9a877 5865 {
ganlikun 0:13413ea9a877 5866 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
ganlikun 0:13413ea9a877 5867 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
ganlikun 0:13413ea9a877 5868 }
ganlikun 0:13413ea9a877 5869 #endif
ganlikun 0:13413ea9a877 5870
ganlikun 0:13413ea9a877 5871 /* Wrap-up entering header or payload data */
ganlikun 0:13413ea9a877 5872 /* Enter complete words when possible */
ganlikun 0:13413ea9a877 5873 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 5874 {
ganlikun 0:13413ea9a877 5875 /* Write the Input block in the Data Input register */
ganlikun 0:13413ea9a877 5876 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
ganlikun 0:13413ea9a877 5877 inputaddr+=4U;
ganlikun 0:13413ea9a877 5878 }
ganlikun 0:13413ea9a877 5879 /* Enter incomplete word padded with zeroes if applicable
ganlikun 0:13413ea9a877 5880 (case of header length not a multiple of 32-bits) */
ganlikun 0:13413ea9a877 5881 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 5882 {
ganlikun 0:13413ea9a877 5883 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
ganlikun 0:13413ea9a877 5884 }
ganlikun 0:13413ea9a877 5885 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
ganlikun 0:13413ea9a877 5886 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 5887 {
ganlikun 0:13413ea9a877 5888 hcryp->Instance->DINR = 0U;
ganlikun 0:13413ea9a877 5889 }
ganlikun 0:13413ea9a877 5890
ganlikun 0:13413ea9a877 5891 if (polling == CRYP_POLLING_ON)
ganlikun 0:13413ea9a877 5892 {
ganlikun 0:13413ea9a877 5893 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 5894 {
ganlikun 0:13413ea9a877 5895 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5896 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5897 HAL_CRYP_ErrorCallback(hcryp);
ganlikun 0:13413ea9a877 5898 }
ganlikun 0:13413ea9a877 5899
ganlikun 0:13413ea9a877 5900 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5901 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5902 }
ganlikun 0:13413ea9a877 5903
ganlikun 0:13413ea9a877 5904 /* if payload */
ganlikun 0:13413ea9a877 5905 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
ganlikun 0:13413ea9a877 5906 {
ganlikun 0:13413ea9a877 5907
ganlikun 0:13413ea9a877 5908 /* Retrieve intermediate data */
ganlikun 0:13413ea9a877 5909 for(index=0U; index < 4U; index ++)
ganlikun 0:13413ea9a877 5910 {
ganlikun 0:13413ea9a877 5911 intermediate_data[index] = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5912 }
ganlikun 0:13413ea9a877 5913 /* Retrieve last words of cyphered data */
ganlikun 0:13413ea9a877 5914 /* First, retrieve complete output words */
ganlikun 0:13413ea9a877 5915 for(index=0U; index < (difflength/4U); index ++)
ganlikun 0:13413ea9a877 5916 {
ganlikun 0:13413ea9a877 5917 *(uint32_t*)(outputaddr) = intermediate_data[index];
ganlikun 0:13413ea9a877 5918 outputaddr+=4U;
ganlikun 0:13413ea9a877 5919 }
ganlikun 0:13413ea9a877 5920 /* Next, retrieve partial output word if applicable;
ganlikun 0:13413ea9a877 5921 at the same time, start masking intermediate data
ganlikun 0:13413ea9a877 5922 with a mask of zeros of same size than the padding
ganlikun 0:13413ea9a877 5923 applied to the last block of payload */
ganlikun 0:13413ea9a877 5924 if (difflengthmod4 != 0U)
ganlikun 0:13413ea9a877 5925 {
ganlikun 0:13413ea9a877 5926 intermediate_data[difflength/4U] &= mask[difflengthmod4-1U];
ganlikun 0:13413ea9a877 5927 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4U];
ganlikun 0:13413ea9a877 5928 }
ganlikun 0:13413ea9a877 5929
ganlikun 0:13413ea9a877 5930 #if !defined(AES_CR_NPBLB)
ganlikun 0:13413ea9a877 5931 /* Software workaround applied to GCM encryption only,
ganlikun 0:13413ea9a877 5932 applicable for AES IP v2 version (where NPBLB is not defined) */
ganlikun 0:13413ea9a877 5933 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
ganlikun 0:13413ea9a877 5934 {
ganlikun 0:13413ea9a877 5935 /* Change again CHMOD configuration to GCM mode */
ganlikun 0:13413ea9a877 5936 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);
ganlikun 0:13413ea9a877 5937
ganlikun 0:13413ea9a877 5938 /* Select FINAL phase */
ganlikun 0:13413ea9a877 5939 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
ganlikun 0:13413ea9a877 5940
ganlikun 0:13413ea9a877 5941 /* Before inserting the intermediate data, carry on masking operation
ganlikun 0:13413ea9a877 5942 with a mask of zeros of same size than the padding applied to the last block of payload */
ganlikun 0:13413ea9a877 5943 for(index=0U; index < (4U - ((difflength+3U)/4U)); index ++)
ganlikun 0:13413ea9a877 5944 {
ganlikun 0:13413ea9a877 5945 intermediate_data[(difflength+3U)/4U+index] = 0U;
ganlikun 0:13413ea9a877 5946 }
ganlikun 0:13413ea9a877 5947 /* Insert intermediate data */
ganlikun 0:13413ea9a877 5948 for(index=0U; index < 4U; index ++)
ganlikun 0:13413ea9a877 5949 {
ganlikun 0:13413ea9a877 5950 hcryp->Instance->DINR = intermediate_data[index];
ganlikun 0:13413ea9a877 5951 }
ganlikun 0:13413ea9a877 5952
ganlikun 0:13413ea9a877 5953 /* Wait for completion, and read data on DOUT. This data is to discard. */
ganlikun 0:13413ea9a877 5954 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
ganlikun 0:13413ea9a877 5955 {
ganlikun 0:13413ea9a877 5956 hcryp->State = HAL_CRYP_STATE_READY;
ganlikun 0:13413ea9a877 5957 __HAL_UNLOCK(hcryp);
ganlikun 0:13413ea9a877 5958 HAL_CRYP_ErrorCallback(hcryp);
ganlikun 0:13413ea9a877 5959 }
ganlikun 0:13413ea9a877 5960
ganlikun 0:13413ea9a877 5961 /* Read data to discard */
ganlikun 0:13413ea9a877 5962 /* Clear CCF Flag */
ganlikun 0:13413ea9a877 5963 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
ganlikun 0:13413ea9a877 5964 for(index=0U; index < 4U; index ++)
ganlikun 0:13413ea9a877 5965 {
ganlikun 0:13413ea9a877 5966 intermediate_data[index] = hcryp->Instance->DOUTR;
ganlikun 0:13413ea9a877 5967 }
ganlikun 0:13413ea9a877 5968
ganlikun 0:13413ea9a877 5969 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
ganlikun 0:13413ea9a877 5970 #endif /* !defined(AES_CR_NPBLB) */
ganlikun 0:13413ea9a877 5971 } /* if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) */
ganlikun 0:13413ea9a877 5972
ganlikun 0:13413ea9a877 5973 }
ganlikun 0:13413ea9a877 5974
ganlikun 0:13413ea9a877 5975 /**
ganlikun 0:13413ea9a877 5976 * @}
ganlikun 0:13413ea9a877 5977 */
ganlikun 0:13413ea9a877 5978
ganlikun 0:13413ea9a877 5979 #endif /* AES */
ganlikun 0:13413ea9a877 5980
ganlikun 0:13413ea9a877 5981 #endif /* HAL_CRYP_MODULE_ENABLED */
ganlikun 0:13413ea9a877 5982 /**
ganlikun 0:13413ea9a877 5983 * @}
ganlikun 0:13413ea9a877 5984 */
ganlikun 0:13413ea9a877 5985
ganlikun 0:13413ea9a877 5986 /**
ganlikun 0:13413ea9a877 5987 * @}
ganlikun 0:13413ea9a877 5988 */
ganlikun 0:13413ea9a877 5989
ganlikun 0:13413ea9a877 5990 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
ganlikun 0:13413ea9a877 5991