TUKS MCU Introductory course / TUKS-COURSE-TIMER
Committer:
elmot
Date:
Fri Feb 24 21:13:56 2017 +0000
Revision:
1:d0dfbce63a89
Ready-to-copy

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elmot 1:d0dfbce63a89 1 /**
elmot 1:d0dfbce63a89 2 ******************************************************************************
elmot 1:d0dfbce63a89 3 * @file stm32l4xx_hal_cryp_ex.c
elmot 1:d0dfbce63a89 4 * @author MCD Application Team
elmot 1:d0dfbce63a89 5 * @version V1.5.1
elmot 1:d0dfbce63a89 6 * @date 31-May-2016
elmot 1:d0dfbce63a89 7 * @brief CRYPEx HAL module driver.
elmot 1:d0dfbce63a89 8 * This file provides firmware functions to manage the extended
elmot 1:d0dfbce63a89 9 * functionalities of the Cryptography (CRYP) peripheral.
elmot 1:d0dfbce63a89 10 *
elmot 1:d0dfbce63a89 11 ******************************************************************************
elmot 1:d0dfbce63a89 12 * @attention
elmot 1:d0dfbce63a89 13 *
elmot 1:d0dfbce63a89 14 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
elmot 1:d0dfbce63a89 15 *
elmot 1:d0dfbce63a89 16 * Redistribution and use in source and binary forms, with or without modification,
elmot 1:d0dfbce63a89 17 * are permitted provided that the following conditions are met:
elmot 1:d0dfbce63a89 18 * 1. Redistributions of source code must retain the above copyright notice,
elmot 1:d0dfbce63a89 19 * this list of conditions and the following disclaimer.
elmot 1:d0dfbce63a89 20 * 2. Redistributions in binary form must reproduce the above copyright notice,
elmot 1:d0dfbce63a89 21 * this list of conditions and the following disclaimer in the documentation
elmot 1:d0dfbce63a89 22 * and/or other materials provided with the distribution.
elmot 1:d0dfbce63a89 23 * 3. Neither the name of STMicroelectronics nor the names of its contributors
elmot 1:d0dfbce63a89 24 * may be used to endorse or promote products derived from this software
elmot 1:d0dfbce63a89 25 * without specific prior written permission.
elmot 1:d0dfbce63a89 26 *
elmot 1:d0dfbce63a89 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
elmot 1:d0dfbce63a89 28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
elmot 1:d0dfbce63a89 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
elmot 1:d0dfbce63a89 30 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
elmot 1:d0dfbce63a89 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
elmot 1:d0dfbce63a89 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
elmot 1:d0dfbce63a89 33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
elmot 1:d0dfbce63a89 34 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
elmot 1:d0dfbce63a89 35 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
elmot 1:d0dfbce63a89 36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
elmot 1:d0dfbce63a89 37 *
elmot 1:d0dfbce63a89 38 ******************************************************************************
elmot 1:d0dfbce63a89 39 */
elmot 1:d0dfbce63a89 40
elmot 1:d0dfbce63a89 41 /* Includes ------------------------------------------------------------------*/
elmot 1:d0dfbce63a89 42 #include "stm32l4xx_hal.h"
elmot 1:d0dfbce63a89 43
elmot 1:d0dfbce63a89 44 #ifdef HAL_CRYP_MODULE_ENABLED
elmot 1:d0dfbce63a89 45
elmot 1:d0dfbce63a89 46 #if defined (STM32L442xx) || defined (STM32L443xx) || defined(STM32L485xx) || defined(STM32L486xx)
elmot 1:d0dfbce63a89 47
elmot 1:d0dfbce63a89 48 /** @addtogroup STM32L4xx_HAL_Driver
elmot 1:d0dfbce63a89 49 * @{
elmot 1:d0dfbce63a89 50 */
elmot 1:d0dfbce63a89 51
elmot 1:d0dfbce63a89 52 /** @defgroup CRYPEx CRYPEx
elmot 1:d0dfbce63a89 53 * @brief CRYP Extended HAL module driver
elmot 1:d0dfbce63a89 54 * @{
elmot 1:d0dfbce63a89 55 */
elmot 1:d0dfbce63a89 56
elmot 1:d0dfbce63a89 57 /* Private typedef -----------------------------------------------------------*/
elmot 1:d0dfbce63a89 58 /* Private define ------------------------------------------------------------*/
elmot 1:d0dfbce63a89 59 /** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants
elmot 1:d0dfbce63a89 60 * @{
elmot 1:d0dfbce63a89 61 */
elmot 1:d0dfbce63a89 62 #define CRYP_CCF_TIMEOUTVALUE 22000 /*!< CCF flag raising time-out value */
elmot 1:d0dfbce63a89 63 #define CRYP_BUSY_TIMEOUTVALUE 22000 /*!< BUSY flag reset time-out value */
elmot 1:d0dfbce63a89 64
elmot 1:d0dfbce63a89 65 #define CRYP_POLLING_OFF 0x0 /*!< No polling when padding */
elmot 1:d0dfbce63a89 66 #define CRYP_POLLING_ON 0x1 /*!< Polling when padding */
elmot 1:d0dfbce63a89 67 /**
elmot 1:d0dfbce63a89 68 * @}
elmot 1:d0dfbce63a89 69 */
elmot 1:d0dfbce63a89 70
elmot 1:d0dfbce63a89 71 /* Private macro -------------------------------------------------------------*/
elmot 1:d0dfbce63a89 72 /* Private variables ---------------------------------------------------------*/
elmot 1:d0dfbce63a89 73 /* Private function prototypes -----------------------------------------------*/
elmot 1:d0dfbce63a89 74 /** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions
elmot 1:d0dfbce63a89 75 * @{
elmot 1:d0dfbce63a89 76 */
elmot 1:d0dfbce63a89 77 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout);
elmot 1:d0dfbce63a89 78 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout);
elmot 1:d0dfbce63a89 79 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
elmot 1:d0dfbce63a89 80 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
elmot 1:d0dfbce63a89 81 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma);
elmot 1:d0dfbce63a89 82 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma);
elmot 1:d0dfbce63a89 83 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma);
elmot 1:d0dfbce63a89 84 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
elmot 1:d0dfbce63a89 85 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
elmot 1:d0dfbce63a89 86 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
elmot 1:d0dfbce63a89 87 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
elmot 1:d0dfbce63a89 88 static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
elmot 1:d0dfbce63a89 89 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling);
elmot 1:d0dfbce63a89 90 /**
elmot 1:d0dfbce63a89 91 * @}
elmot 1:d0dfbce63a89 92 */
elmot 1:d0dfbce63a89 93
elmot 1:d0dfbce63a89 94 /* Exported functions ---------------------------------------------------------*/
elmot 1:d0dfbce63a89 95
elmot 1:d0dfbce63a89 96 /** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions
elmot 1:d0dfbce63a89 97 * @{
elmot 1:d0dfbce63a89 98 */
elmot 1:d0dfbce63a89 99
elmot 1:d0dfbce63a89 100
elmot 1:d0dfbce63a89 101 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended callback function
elmot 1:d0dfbce63a89 102 * @brief Extended callback functions.
elmot 1:d0dfbce63a89 103 *
elmot 1:d0dfbce63a89 104 @verbatim
elmot 1:d0dfbce63a89 105 ===============================================================================
elmot 1:d0dfbce63a89 106 ##### Extended callback functions #####
elmot 1:d0dfbce63a89 107 ===============================================================================
elmot 1:d0dfbce63a89 108 [..] This section provides callback function:
elmot 1:d0dfbce63a89 109 (+) Computation completed.
elmot 1:d0dfbce63a89 110
elmot 1:d0dfbce63a89 111 @endverbatim
elmot 1:d0dfbce63a89 112 * @{
elmot 1:d0dfbce63a89 113 */
elmot 1:d0dfbce63a89 114
elmot 1:d0dfbce63a89 115
elmot 1:d0dfbce63a89 116 /**
elmot 1:d0dfbce63a89 117 * @brief Computation completed callbacks.
elmot 1:d0dfbce63a89 118 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 119 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 120 * @retval None
elmot 1:d0dfbce63a89 121 */
elmot 1:d0dfbce63a89 122 __weak void HAL_CRYPEx_ComputationCpltCallback(CRYP_HandleTypeDef *hcryp)
elmot 1:d0dfbce63a89 123 {
elmot 1:d0dfbce63a89 124 /* Prevent unused argument(s) compilation warning */
elmot 1:d0dfbce63a89 125 UNUSED(hcryp);
elmot 1:d0dfbce63a89 126
elmot 1:d0dfbce63a89 127 /* NOTE : This function should not be modified; when the callback is needed,
elmot 1:d0dfbce63a89 128 the HAL_CRYPEx_ComputationCpltCallback can be implemented in the user file
elmot 1:d0dfbce63a89 129 */
elmot 1:d0dfbce63a89 130 }
elmot 1:d0dfbce63a89 131
elmot 1:d0dfbce63a89 132 /**
elmot 1:d0dfbce63a89 133 * @}
elmot 1:d0dfbce63a89 134 */
elmot 1:d0dfbce63a89 135
elmot 1:d0dfbce63a89 136 /** @defgroup CRYPEx_Exported_Functions_Group2 AES extended processing functions
elmot 1:d0dfbce63a89 137 * @brief Extended processing functions.
elmot 1:d0dfbce63a89 138 *
elmot 1:d0dfbce63a89 139 @verbatim
elmot 1:d0dfbce63a89 140 ==============================================================================
elmot 1:d0dfbce63a89 141 ##### AES extended processing functions #####
elmot 1:d0dfbce63a89 142 ==============================================================================
elmot 1:d0dfbce63a89 143 [..] This section provides functions allowing to:
elmot 1:d0dfbce63a89 144 (+) Encrypt plaintext or decrypt cipher text using AES algorithm in different chaining modes.
elmot 1:d0dfbce63a89 145 Functions are generic (handles ECB, CBC and CTR and all modes) and are only differentiated
elmot 1:d0dfbce63a89 146 based on the processing type. Three processing types are available:
elmot 1:d0dfbce63a89 147 (++) Polling mode
elmot 1:d0dfbce63a89 148 (++) Interrupt mode
elmot 1:d0dfbce63a89 149 (++) DMA mode
elmot 1:d0dfbce63a89 150 (+) Generate and authentication tag in addition to encrypt/decrypt a plain/cipher text using AES
elmot 1:d0dfbce63a89 151 algorithm in different chaining modes.
elmot 1:d0dfbce63a89 152 Functions are generic (handles GCM, GMAC and CMAC) and process only one phase so that steps
elmot 1:d0dfbce63a89 153 can be skipped if so required. Functions are only differentiated based on the processing type.
elmot 1:d0dfbce63a89 154 Three processing types are available:
elmot 1:d0dfbce63a89 155 (++) Polling mode
elmot 1:d0dfbce63a89 156 (++) Interrupt mode
elmot 1:d0dfbce63a89 157 (++) DMA mode
elmot 1:d0dfbce63a89 158
elmot 1:d0dfbce63a89 159 @endverbatim
elmot 1:d0dfbce63a89 160 * @{
elmot 1:d0dfbce63a89 161 */
elmot 1:d0dfbce63a89 162
elmot 1:d0dfbce63a89 163 /**
elmot 1:d0dfbce63a89 164 * @brief Carry out in polling mode the ciphering or deciphering operation according to
elmot 1:d0dfbce63a89 165 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
elmot 1:d0dfbce63a89 166 * chaining modes ECB, CBC and CTR are managed by this function in polling mode.
elmot 1:d0dfbce63a89 167 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 168 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 169 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
elmot 1:d0dfbce63a89 170 * or key derivation+decryption.
elmot 1:d0dfbce63a89 171 * Parameter is meaningless in case of key derivation.
elmot 1:d0dfbce63a89 172 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
elmot 1:d0dfbce63a89 173 * Parameter is meaningless in case of key derivation.
elmot 1:d0dfbce63a89 174 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
elmot 1:d0dfbce63a89 175 * decryption/key derivation+decryption, or pointer to the derivative keys in
elmot 1:d0dfbce63a89 176 * case of key derivation only.
elmot 1:d0dfbce63a89 177 * @param Timeout: Specify Timeout value
elmot 1:d0dfbce63a89 178 * @retval HAL status
elmot 1:d0dfbce63a89 179 */
elmot 1:d0dfbce63a89 180 HAL_StatusTypeDef HAL_CRYPEx_AES(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData, uint32_t Timeout)
elmot 1:d0dfbce63a89 181 {
elmot 1:d0dfbce63a89 182
elmot 1:d0dfbce63a89 183 if (hcryp->State == HAL_CRYP_STATE_READY)
elmot 1:d0dfbce63a89 184 {
elmot 1:d0dfbce63a89 185 /* Check parameters setting */
elmot 1:d0dfbce63a89 186 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
elmot 1:d0dfbce63a89 187 {
elmot 1:d0dfbce63a89 188 if (pOutputData == NULL)
elmot 1:d0dfbce63a89 189 {
elmot 1:d0dfbce63a89 190 return HAL_ERROR;
elmot 1:d0dfbce63a89 191 }
elmot 1:d0dfbce63a89 192 }
elmot 1:d0dfbce63a89 193 else
elmot 1:d0dfbce63a89 194 {
elmot 1:d0dfbce63a89 195 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 196 {
elmot 1:d0dfbce63a89 197 return HAL_ERROR;
elmot 1:d0dfbce63a89 198 }
elmot 1:d0dfbce63a89 199 }
elmot 1:d0dfbce63a89 200
elmot 1:d0dfbce63a89 201 /* Process Locked */
elmot 1:d0dfbce63a89 202 __HAL_LOCK(hcryp);
elmot 1:d0dfbce63a89 203
elmot 1:d0dfbce63a89 204 /* Change the CRYP state */
elmot 1:d0dfbce63a89 205 hcryp->State = HAL_CRYP_STATE_BUSY;
elmot 1:d0dfbce63a89 206
elmot 1:d0dfbce63a89 207 /* Call CRYP_ReadKey() API if the operating mode is set to
elmot 1:d0dfbce63a89 208 key derivation, CRYP_ProcessData() otherwise */
elmot 1:d0dfbce63a89 209 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
elmot 1:d0dfbce63a89 210 {
elmot 1:d0dfbce63a89 211 if(CRYP_ReadKey(hcryp, pOutputData, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 212 {
elmot 1:d0dfbce63a89 213 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 214 }
elmot 1:d0dfbce63a89 215 }
elmot 1:d0dfbce63a89 216 else
elmot 1:d0dfbce63a89 217 {
elmot 1:d0dfbce63a89 218 if(CRYP_ProcessData(hcryp, pInputData, Size, pOutputData, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 219 {
elmot 1:d0dfbce63a89 220 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 221 }
elmot 1:d0dfbce63a89 222 }
elmot 1:d0dfbce63a89 223
elmot 1:d0dfbce63a89 224 /* If the state has not been set to SUSPENDED, set it to
elmot 1:d0dfbce63a89 225 READY, otherwise keep it as it is */
elmot 1:d0dfbce63a89 226 if (hcryp->State != HAL_CRYP_STATE_SUSPENDED)
elmot 1:d0dfbce63a89 227 {
elmot 1:d0dfbce63a89 228 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 229 }
elmot 1:d0dfbce63a89 230
elmot 1:d0dfbce63a89 231 /* Process Unlocked */
elmot 1:d0dfbce63a89 232 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 233
elmot 1:d0dfbce63a89 234 return HAL_OK;
elmot 1:d0dfbce63a89 235 }
elmot 1:d0dfbce63a89 236 else
elmot 1:d0dfbce63a89 237 {
elmot 1:d0dfbce63a89 238 return HAL_BUSY;
elmot 1:d0dfbce63a89 239 }
elmot 1:d0dfbce63a89 240 }
elmot 1:d0dfbce63a89 241
elmot 1:d0dfbce63a89 242
elmot 1:d0dfbce63a89 243
elmot 1:d0dfbce63a89 244 /**
elmot 1:d0dfbce63a89 245 * @brief Carry out in interrupt mode the ciphering or deciphering operation according to
elmot 1:d0dfbce63a89 246 * hcryp->Init structure fields, all operating modes (encryption, key derivation and/or decryption) and
elmot 1:d0dfbce63a89 247 * chaining modes ECB, CBC and CTR are managed by this function in interrupt mode.
elmot 1:d0dfbce63a89 248 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 249 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 250 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
elmot 1:d0dfbce63a89 251 * or key derivation+decryption.
elmot 1:d0dfbce63a89 252 * Parameter is meaningless in case of key derivation.
elmot 1:d0dfbce63a89 253 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
elmot 1:d0dfbce63a89 254 * Parameter is meaningless in case of key derivation.
elmot 1:d0dfbce63a89 255 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
elmot 1:d0dfbce63a89 256 * decryption/key derivation+decryption, or pointer to the derivative keys in
elmot 1:d0dfbce63a89 257 * case of key derivation only.
elmot 1:d0dfbce63a89 258 * @retval HAL status
elmot 1:d0dfbce63a89 259 */
elmot 1:d0dfbce63a89 260 HAL_StatusTypeDef HAL_CRYPEx_AES_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
elmot 1:d0dfbce63a89 261 {
elmot 1:d0dfbce63a89 262 uint32_t inputaddr = 0;
elmot 1:d0dfbce63a89 263
elmot 1:d0dfbce63a89 264 if(hcryp->State == HAL_CRYP_STATE_READY)
elmot 1:d0dfbce63a89 265 {
elmot 1:d0dfbce63a89 266 /* Check parameters setting */
elmot 1:d0dfbce63a89 267 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
elmot 1:d0dfbce63a89 268 {
elmot 1:d0dfbce63a89 269 if (pOutputData == NULL)
elmot 1:d0dfbce63a89 270 {
elmot 1:d0dfbce63a89 271 return HAL_ERROR;
elmot 1:d0dfbce63a89 272 }
elmot 1:d0dfbce63a89 273 }
elmot 1:d0dfbce63a89 274 else
elmot 1:d0dfbce63a89 275 {
elmot 1:d0dfbce63a89 276 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 277 {
elmot 1:d0dfbce63a89 278 return HAL_ERROR;
elmot 1:d0dfbce63a89 279 }
elmot 1:d0dfbce63a89 280 }
elmot 1:d0dfbce63a89 281 /* Process Locked */
elmot 1:d0dfbce63a89 282 __HAL_LOCK(hcryp);
elmot 1:d0dfbce63a89 283
elmot 1:d0dfbce63a89 284 /* If operating mode is not limited to key derivation only,
elmot 1:d0dfbce63a89 285 get the buffers addresses and sizes */
elmot 1:d0dfbce63a89 286 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
elmot 1:d0dfbce63a89 287 {
elmot 1:d0dfbce63a89 288
elmot 1:d0dfbce63a89 289 hcryp->CrypInCount = Size;
elmot 1:d0dfbce63a89 290 hcryp->pCrypInBuffPtr = pInputData;
elmot 1:d0dfbce63a89 291 hcryp->pCrypOutBuffPtr = pOutputData;
elmot 1:d0dfbce63a89 292 hcryp->CrypOutCount = Size;
elmot 1:d0dfbce63a89 293 }
elmot 1:d0dfbce63a89 294
elmot 1:d0dfbce63a89 295 /* Change the CRYP state */
elmot 1:d0dfbce63a89 296 hcryp->State = HAL_CRYP_STATE_BUSY;
elmot 1:d0dfbce63a89 297
elmot 1:d0dfbce63a89 298 /* Process Unlocked */
elmot 1:d0dfbce63a89 299 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 300
elmot 1:d0dfbce63a89 301 /* Enable Computation Complete Flag and Error Interrupts */
elmot 1:d0dfbce63a89 302 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 303
elmot 1:d0dfbce63a89 304
elmot 1:d0dfbce63a89 305 /* If operating mode is key derivation only, the input data have
elmot 1:d0dfbce63a89 306 already been entered during the initialization process. For
elmot 1:d0dfbce63a89 307 the other operating modes, they are fed to the CRYP hardware
elmot 1:d0dfbce63a89 308 block at this point. */
elmot 1:d0dfbce63a89 309 if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
elmot 1:d0dfbce63a89 310 {
elmot 1:d0dfbce63a89 311 /* Initiate the processing under interrupt in entering
elmot 1:d0dfbce63a89 312 the first input data */
elmot 1:d0dfbce63a89 313 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
elmot 1:d0dfbce63a89 314 /* Increment/decrement instance pointer/counter */
elmot 1:d0dfbce63a89 315 hcryp->pCrypInBuffPtr += 16;
elmot 1:d0dfbce63a89 316 hcryp->CrypInCount -= 16;
elmot 1:d0dfbce63a89 317 /* Write the first input block in the Data Input register */
elmot 1:d0dfbce63a89 318 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 319 inputaddr+=4;
elmot 1:d0dfbce63a89 320 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 321 inputaddr+=4;
elmot 1:d0dfbce63a89 322 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 323 inputaddr+=4;
elmot 1:d0dfbce63a89 324 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 325 }
elmot 1:d0dfbce63a89 326
elmot 1:d0dfbce63a89 327 /* Return function status */
elmot 1:d0dfbce63a89 328 return HAL_OK;
elmot 1:d0dfbce63a89 329 }
elmot 1:d0dfbce63a89 330 else
elmot 1:d0dfbce63a89 331 {
elmot 1:d0dfbce63a89 332 return HAL_BUSY;
elmot 1:d0dfbce63a89 333 }
elmot 1:d0dfbce63a89 334 }
elmot 1:d0dfbce63a89 335
elmot 1:d0dfbce63a89 336
elmot 1:d0dfbce63a89 337
elmot 1:d0dfbce63a89 338
elmot 1:d0dfbce63a89 339
elmot 1:d0dfbce63a89 340 /**
elmot 1:d0dfbce63a89 341 * @brief Carry out in DMA mode the ciphering or deciphering operation according to
elmot 1:d0dfbce63a89 342 * hcryp->Init structure fields.
elmot 1:d0dfbce63a89 343 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 344 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 345 * @param pInputData: Pointer to the plain text in case of encryption or cipher text in case of decryption
elmot 1:d0dfbce63a89 346 * or key derivation+decryption.
elmot 1:d0dfbce63a89 347 * @param Size: Length of the input data buffer in bytes, must be a multiple of 16.
elmot 1:d0dfbce63a89 348 * @param pOutputData: Pointer to the cipher text in case of encryption or plain text in case of
elmot 1:d0dfbce63a89 349 * decryption/key derivation+decryption.
elmot 1:d0dfbce63a89 350 * @note Chaining modes ECB, CBC and CTR are managed by this function in DMA mode.
elmot 1:d0dfbce63a89 351 * @note Supported operating modes are encryption, decryption and key derivation with decryption.
elmot 1:d0dfbce63a89 352 * @note No DMA channel is provided for key derivation only and therefore, access to AES_KEYRx
elmot 1:d0dfbce63a89 353 * registers must be done by software.
elmot 1:d0dfbce63a89 354 * @note This API is not applicable to key derivation only; for such a mode, access to AES_KEYRx
elmot 1:d0dfbce63a89 355 * registers must be done by software thru HAL_CRYPEx_AES() or HAL_CRYPEx_AES_IT() APIs.
elmot 1:d0dfbce63a89 356 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
elmot 1:d0dfbce63a89 357 * @retval HAL status
elmot 1:d0dfbce63a89 358 */
elmot 1:d0dfbce63a89 359 HAL_StatusTypeDef HAL_CRYPEx_AES_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint16_t Size, uint8_t *pOutputData)
elmot 1:d0dfbce63a89 360 {
elmot 1:d0dfbce63a89 361 uint32_t inputaddr = 0;
elmot 1:d0dfbce63a89 362 uint32_t outputaddr = 0;
elmot 1:d0dfbce63a89 363
elmot 1:d0dfbce63a89 364 if (hcryp->State == HAL_CRYP_STATE_READY)
elmot 1:d0dfbce63a89 365 {
elmot 1:d0dfbce63a89 366 /* Check parameters setting */
elmot 1:d0dfbce63a89 367 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
elmot 1:d0dfbce63a89 368 {
elmot 1:d0dfbce63a89 369 /* no DMA channel is provided for key derivation operating mode,
elmot 1:d0dfbce63a89 370 access to AES_KEYRx registers must be done by software */
elmot 1:d0dfbce63a89 371 return HAL_ERROR;
elmot 1:d0dfbce63a89 372 }
elmot 1:d0dfbce63a89 373 else
elmot 1:d0dfbce63a89 374 {
elmot 1:d0dfbce63a89 375 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 376 {
elmot 1:d0dfbce63a89 377 return HAL_ERROR;
elmot 1:d0dfbce63a89 378 }
elmot 1:d0dfbce63a89 379 }
elmot 1:d0dfbce63a89 380
elmot 1:d0dfbce63a89 381
elmot 1:d0dfbce63a89 382 /* Process Locked */
elmot 1:d0dfbce63a89 383 __HAL_LOCK(hcryp);
elmot 1:d0dfbce63a89 384
elmot 1:d0dfbce63a89 385 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 386 outputaddr = (uint32_t)pOutputData;
elmot 1:d0dfbce63a89 387
elmot 1:d0dfbce63a89 388 /* Change the CRYP state */
elmot 1:d0dfbce63a89 389 hcryp->State = HAL_CRYP_STATE_BUSY;
elmot 1:d0dfbce63a89 390
elmot 1:d0dfbce63a89 391 /* Set the input and output addresses and start DMA transfer */
elmot 1:d0dfbce63a89 392 CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
elmot 1:d0dfbce63a89 393
elmot 1:d0dfbce63a89 394 /* Process Unlocked */
elmot 1:d0dfbce63a89 395 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 396
elmot 1:d0dfbce63a89 397 /* Return function status */
elmot 1:d0dfbce63a89 398 return HAL_OK;
elmot 1:d0dfbce63a89 399 }
elmot 1:d0dfbce63a89 400 else
elmot 1:d0dfbce63a89 401 {
elmot 1:d0dfbce63a89 402 return HAL_BUSY;
elmot 1:d0dfbce63a89 403 }
elmot 1:d0dfbce63a89 404 }
elmot 1:d0dfbce63a89 405
elmot 1:d0dfbce63a89 406
elmot 1:d0dfbce63a89 407
elmot 1:d0dfbce63a89 408
elmot 1:d0dfbce63a89 409
elmot 1:d0dfbce63a89 410
elmot 1:d0dfbce63a89 411 /**
elmot 1:d0dfbce63a89 412 * @brief Carry out in polling mode the authentication tag generation as well as the ciphering or deciphering
elmot 1:d0dfbce63a89 413 * operation according to hcryp->Init structure fields.
elmot 1:d0dfbce63a89 414 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 415 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 416 * @param pInputData:
elmot 1:d0dfbce63a89 417 * - pointer to payload data in GCM payload phase,
elmot 1:d0dfbce63a89 418 * - pointer to B0 block in CMAC header phase,
elmot 1:d0dfbce63a89 419 * - pointer to C block in CMAC final phase.
elmot 1:d0dfbce63a89 420 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases.
elmot 1:d0dfbce63a89 421 * @param Size:
elmot 1:d0dfbce63a89 422 * - length of the input payload data buffer in bytes,
elmot 1:d0dfbce63a89 423 * - length of B0 block (in bytes) in CMAC header phase,
elmot 1:d0dfbce63a89 424 * - length of C block (in bytes) in CMAC final phase.
elmot 1:d0dfbce63a89 425 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
elmot 1:d0dfbce63a89 426 * @param pOutputData:
elmot 1:d0dfbce63a89 427 * - pointer to plain or cipher text in GCM payload phase,
elmot 1:d0dfbce63a89 428 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
elmot 1:d0dfbce63a89 429 * - Parameter is meaningless in case of GCM/GMAC init and header phases
elmot 1:d0dfbce63a89 430 * and in case of CMAC header phase.
elmot 1:d0dfbce63a89 431 * @param Timeout: Specify Timeout value
elmot 1:d0dfbce63a89 432 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
elmot 1:d0dfbce63a89 433 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
elmot 1:d0dfbce63a89 434 * can be skipped by the user if so required.
elmot 1:d0dfbce63a89 435 * @retval HAL status
elmot 1:d0dfbce63a89 436 */
elmot 1:d0dfbce63a89 437 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData, uint32_t Timeout)
elmot 1:d0dfbce63a89 438 {
elmot 1:d0dfbce63a89 439 uint32_t index = 0;
elmot 1:d0dfbce63a89 440 uint32_t inputaddr = 0;
elmot 1:d0dfbce63a89 441 uint32_t outputaddr = 0;
elmot 1:d0dfbce63a89 442 uint32_t tagaddr = 0;
elmot 1:d0dfbce63a89 443 uint64_t headerlength = 0;
elmot 1:d0dfbce63a89 444 uint64_t inputlength = 0;
elmot 1:d0dfbce63a89 445 uint64_t payloadlength = 0;
elmot 1:d0dfbce63a89 446 uint32_t difflength = 0;
elmot 1:d0dfbce63a89 447 uint32_t addhoc_process = 0;
elmot 1:d0dfbce63a89 448
elmot 1:d0dfbce63a89 449 if (hcryp->State == HAL_CRYP_STATE_READY)
elmot 1:d0dfbce63a89 450 {
elmot 1:d0dfbce63a89 451 /* input/output parameters check */
elmot 1:d0dfbce63a89 452 if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 453 {
elmot 1:d0dfbce63a89 454 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0))
elmot 1:d0dfbce63a89 455 {
elmot 1:d0dfbce63a89 456 return HAL_ERROR;
elmot 1:d0dfbce63a89 457 }
elmot 1:d0dfbce63a89 458 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 459 {
elmot 1:d0dfbce63a89 460 /* In case of CMAC header phase resumption, we can have pInputData = NULL and Size = 0 */
elmot 1:d0dfbce63a89 461 if (((pInputData != NULL) && (Size == 0)) || ((pInputData == NULL) && (Size != 0)))
elmot 1:d0dfbce63a89 462 {
elmot 1:d0dfbce63a89 463 return HAL_ERROR;
elmot 1:d0dfbce63a89 464 }
elmot 1:d0dfbce63a89 465 }
elmot 1:d0dfbce63a89 466 }
elmot 1:d0dfbce63a89 467 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 468 {
elmot 1:d0dfbce63a89 469 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 470 {
elmot 1:d0dfbce63a89 471 return HAL_ERROR;
elmot 1:d0dfbce63a89 472 }
elmot 1:d0dfbce63a89 473 }
elmot 1:d0dfbce63a89 474 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 475 {
elmot 1:d0dfbce63a89 476 if (pOutputData == NULL)
elmot 1:d0dfbce63a89 477 {
elmot 1:d0dfbce63a89 478 return HAL_ERROR;
elmot 1:d0dfbce63a89 479 }
elmot 1:d0dfbce63a89 480 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
elmot 1:d0dfbce63a89 481 {
elmot 1:d0dfbce63a89 482 return HAL_ERROR;
elmot 1:d0dfbce63a89 483 }
elmot 1:d0dfbce63a89 484 }
elmot 1:d0dfbce63a89 485
elmot 1:d0dfbce63a89 486
elmot 1:d0dfbce63a89 487 /* Process Locked */
elmot 1:d0dfbce63a89 488 __HAL_LOCK(hcryp);
elmot 1:d0dfbce63a89 489
elmot 1:d0dfbce63a89 490 /* Change the CRYP state */
elmot 1:d0dfbce63a89 491 hcryp->State = HAL_CRYP_STATE_BUSY;
elmot 1:d0dfbce63a89 492
elmot 1:d0dfbce63a89 493 /*=====================*/
elmot 1:d0dfbce63a89 494 /* GCM/GMAC init phase */
elmot 1:d0dfbce63a89 495 /*=====================*/
elmot 1:d0dfbce63a89 496 /* In case of init phase, the input data (Key and Initialization Vector) have
elmot 1:d0dfbce63a89 497 already been entered during the initialization process. Therefore, the
elmot 1:d0dfbce63a89 498 API just waits for the CCF flag to be set. */
elmot 1:d0dfbce63a89 499 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_INIT_PHASE)
elmot 1:d0dfbce63a89 500 {
elmot 1:d0dfbce63a89 501 /* just wait for hash computation */
elmot 1:d0dfbce63a89 502 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 503 {
elmot 1:d0dfbce63a89 504 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 505 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 506 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 507 }
elmot 1:d0dfbce63a89 508
elmot 1:d0dfbce63a89 509 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 510 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 511 /* Mark that the initialization phase is over */
elmot 1:d0dfbce63a89 512 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
elmot 1:d0dfbce63a89 513 }
elmot 1:d0dfbce63a89 514 /*===============================*/
elmot 1:d0dfbce63a89 515 /* GCM/GMAC or CMAC header phase */
elmot 1:d0dfbce63a89 516 /*===============================*/
elmot 1:d0dfbce63a89 517 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 518 {
elmot 1:d0dfbce63a89 519 /* Set header phase; for GCM or GMAC, set data-byte at this point */
elmot 1:d0dfbce63a89 520 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
elmot 1:d0dfbce63a89 521 {
elmot 1:d0dfbce63a89 522 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType);
elmot 1:d0dfbce63a89 523 }
elmot 1:d0dfbce63a89 524 else
elmot 1:d0dfbce63a89 525 {
elmot 1:d0dfbce63a89 526 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE);
elmot 1:d0dfbce63a89 527 }
elmot 1:d0dfbce63a89 528
elmot 1:d0dfbce63a89 529 /* Enable the Peripheral */
elmot 1:d0dfbce63a89 530 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 531
elmot 1:d0dfbce63a89 532 /* in case of CMAC, enter B0 block in header phase, before the header itself. */
elmot 1:d0dfbce63a89 533 /* If Size = 0 (possible case of resumption after CMAC header phase suspension),
elmot 1:d0dfbce63a89 534 skip these steps and go directly to header buffer feeding to the HW */
elmot 1:d0dfbce63a89 535 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (Size != 0))
elmot 1:d0dfbce63a89 536 {
elmot 1:d0dfbce63a89 537 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 538
elmot 1:d0dfbce63a89 539 for(index=0; (index < Size); index += 16)
elmot 1:d0dfbce63a89 540 {
elmot 1:d0dfbce63a89 541 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 542 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 543 inputaddr+=4;
elmot 1:d0dfbce63a89 544 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 545 inputaddr+=4;
elmot 1:d0dfbce63a89 546 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 547 inputaddr+=4;
elmot 1:d0dfbce63a89 548 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 549 inputaddr+=4;
elmot 1:d0dfbce63a89 550
elmot 1:d0dfbce63a89 551 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 552 {
elmot 1:d0dfbce63a89 553 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 554 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 555 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 556 }
elmot 1:d0dfbce63a89 557 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 558 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 559
elmot 1:d0dfbce63a89 560 /* If the suspension flag has been raised and if the processing is not about
elmot 1:d0dfbce63a89 561 to end, suspend processing */
elmot 1:d0dfbce63a89 562 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16) < Size))
elmot 1:d0dfbce63a89 563 {
elmot 1:d0dfbce63a89 564 /* reset SuspendRequest */
elmot 1:d0dfbce63a89 565 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
elmot 1:d0dfbce63a89 566 /* Change the CRYP state */
elmot 1:d0dfbce63a89 567 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
elmot 1:d0dfbce63a89 568 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 569 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
elmot 1:d0dfbce63a89 570
elmot 1:d0dfbce63a89 571 /* Save current reading and writing locations of Input and Output buffers */
elmot 1:d0dfbce63a89 572 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 573 /* Save the total number of bytes (B blocks + header) that remain to be
elmot 1:d0dfbce63a89 574 processed at this point */
elmot 1:d0dfbce63a89 575 hcryp->CrypInCount = hcryp->Init.HeaderSize + Size - (index+16);
elmot 1:d0dfbce63a89 576
elmot 1:d0dfbce63a89 577 /* Process Unlocked */
elmot 1:d0dfbce63a89 578 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 579
elmot 1:d0dfbce63a89 580 return HAL_OK;
elmot 1:d0dfbce63a89 581 }
elmot 1:d0dfbce63a89 582 } /* for(index=0; (index < Size); index += 16) */
elmot 1:d0dfbce63a89 583 }
elmot 1:d0dfbce63a89 584
elmot 1:d0dfbce63a89 585 /* Enter header */
elmot 1:d0dfbce63a89 586 inputaddr = (uint32_t)hcryp->Init.Header;
elmot 1:d0dfbce63a89 587 /* Local variable headerlength is a number of bytes multiple of 128 bits,
elmot 1:d0dfbce63a89 588 remaining header data (if any) are handled after this loop */
elmot 1:d0dfbce63a89 589 headerlength = (((hcryp->Init.HeaderSize)/16)*16) ;
elmot 1:d0dfbce63a89 590 if ((hcryp->Init.HeaderSize % 16) != 0)
elmot 1:d0dfbce63a89 591 {
elmot 1:d0dfbce63a89 592 difflength = (uint32_t) (hcryp->Init.HeaderSize - headerlength);
elmot 1:d0dfbce63a89 593 }
elmot 1:d0dfbce63a89 594 for(index=0; index < headerlength; index += 16)
elmot 1:d0dfbce63a89 595 {
elmot 1:d0dfbce63a89 596 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 597 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 598 inputaddr+=4;
elmot 1:d0dfbce63a89 599 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 600 inputaddr+=4;
elmot 1:d0dfbce63a89 601 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 602 inputaddr+=4;
elmot 1:d0dfbce63a89 603 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 604 inputaddr+=4;
elmot 1:d0dfbce63a89 605
elmot 1:d0dfbce63a89 606 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 607 {
elmot 1:d0dfbce63a89 608 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 609 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 610 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 611 }
elmot 1:d0dfbce63a89 612 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 613 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 614
elmot 1:d0dfbce63a89 615 /* If the suspension flag has been raised and if the processing is not about
elmot 1:d0dfbce63a89 616 to end, suspend processing */
elmot 1:d0dfbce63a89 617 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16) < headerlength))
elmot 1:d0dfbce63a89 618 {
elmot 1:d0dfbce63a89 619 /* reset SuspendRequest */
elmot 1:d0dfbce63a89 620 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
elmot 1:d0dfbce63a89 621 /* Change the CRYP state */
elmot 1:d0dfbce63a89 622 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
elmot 1:d0dfbce63a89 623 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 624 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
elmot 1:d0dfbce63a89 625
elmot 1:d0dfbce63a89 626 /* Save current reading and writing locations of Input and Output buffers */
elmot 1:d0dfbce63a89 627 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 628 /* Save the total number of bytes that remain to be processed at this point */
elmot 1:d0dfbce63a89 629 hcryp->CrypInCount = hcryp->Init.HeaderSize - (index+16);
elmot 1:d0dfbce63a89 630
elmot 1:d0dfbce63a89 631 /* Process Unlocked */
elmot 1:d0dfbce63a89 632 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 633
elmot 1:d0dfbce63a89 634 return HAL_OK;
elmot 1:d0dfbce63a89 635 }
elmot 1:d0dfbce63a89 636 }
elmot 1:d0dfbce63a89 637
elmot 1:d0dfbce63a89 638 /* Case header length is not a multiple of 16 bytes */
elmot 1:d0dfbce63a89 639 if (difflength != 0)
elmot 1:d0dfbce63a89 640 {
elmot 1:d0dfbce63a89 641 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 642 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
elmot 1:d0dfbce63a89 643 }
elmot 1:d0dfbce63a89 644
elmot 1:d0dfbce63a89 645 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 646 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
elmot 1:d0dfbce63a89 647 }
elmot 1:d0dfbce63a89 648 /*========================*/
elmot 1:d0dfbce63a89 649 /* GCM/GMAC payload phase */
elmot 1:d0dfbce63a89 650 /*========================*/
elmot 1:d0dfbce63a89 651 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 652 {
elmot 1:d0dfbce63a89 653
elmot 1:d0dfbce63a89 654 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE);
elmot 1:d0dfbce63a89 655
elmot 1:d0dfbce63a89 656 /* if the header phase has been bypassed, AES must be enabled again */
elmot 1:d0dfbce63a89 657 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
elmot 1:d0dfbce63a89 658 {
elmot 1:d0dfbce63a89 659 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 660 }
elmot 1:d0dfbce63a89 661
elmot 1:d0dfbce63a89 662 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 663 outputaddr = (uint32_t)pOutputData;
elmot 1:d0dfbce63a89 664
elmot 1:d0dfbce63a89 665 /* Enter payload */
elmot 1:d0dfbce63a89 666 /* Specific handling to manage payload last block size less than 128 bits
elmot 1:d0dfbce63a89 667 when GCM encryption or decryption is selected */
elmot 1:d0dfbce63a89 668 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
elmot 1:d0dfbce63a89 669 ((Size % 16) != 0))
elmot 1:d0dfbce63a89 670 {
elmot 1:d0dfbce63a89 671 payloadlength = (Size/16) * 16;
elmot 1:d0dfbce63a89 672 difflength = (uint32_t) (Size - payloadlength);
elmot 1:d0dfbce63a89 673 addhoc_process = 1;
elmot 1:d0dfbce63a89 674 }
elmot 1:d0dfbce63a89 675 else
elmot 1:d0dfbce63a89 676 {
elmot 1:d0dfbce63a89 677 payloadlength = Size;
elmot 1:d0dfbce63a89 678 addhoc_process = 0;
elmot 1:d0dfbce63a89 679 }
elmot 1:d0dfbce63a89 680
elmot 1:d0dfbce63a89 681 /* Feed payload */
elmot 1:d0dfbce63a89 682 for(index=0; index < payloadlength; index += 16)
elmot 1:d0dfbce63a89 683 {
elmot 1:d0dfbce63a89 684 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 685 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 686 inputaddr+=4;
elmot 1:d0dfbce63a89 687 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 688 inputaddr+=4;
elmot 1:d0dfbce63a89 689 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 690 inputaddr+=4;
elmot 1:d0dfbce63a89 691 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 692 inputaddr+=4;
elmot 1:d0dfbce63a89 693
elmot 1:d0dfbce63a89 694 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 695 {
elmot 1:d0dfbce63a89 696 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 697 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 698 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 699 }
elmot 1:d0dfbce63a89 700
elmot 1:d0dfbce63a89 701 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 702 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 703
elmot 1:d0dfbce63a89 704 /* Retrieve output data: read the output block
elmot 1:d0dfbce63a89 705 from the Data Output Register */
elmot 1:d0dfbce63a89 706 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 707 outputaddr+=4;
elmot 1:d0dfbce63a89 708 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 709 outputaddr+=4;
elmot 1:d0dfbce63a89 710 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 711 outputaddr+=4;
elmot 1:d0dfbce63a89 712 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 713 outputaddr+=4;
elmot 1:d0dfbce63a89 714
elmot 1:d0dfbce63a89 715 /* If the suspension flag has been raised and if the processing is not about
elmot 1:d0dfbce63a89 716 to end, suspend processing */
elmot 1:d0dfbce63a89 717 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16) < payloadlength))
elmot 1:d0dfbce63a89 718 {
elmot 1:d0dfbce63a89 719 /* no flag waiting under IRQ handling */
elmot 1:d0dfbce63a89 720 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
elmot 1:d0dfbce63a89 721 {
elmot 1:d0dfbce63a89 722 /* Ensure that Busy flag is reset */
elmot 1:d0dfbce63a89 723 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 724 {
elmot 1:d0dfbce63a89 725 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 726 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 727 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 728 }
elmot 1:d0dfbce63a89 729 }
elmot 1:d0dfbce63a89 730 /* reset SuspendRequest */
elmot 1:d0dfbce63a89 731 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
elmot 1:d0dfbce63a89 732 /* Change the CRYP state */
elmot 1:d0dfbce63a89 733 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
elmot 1:d0dfbce63a89 734 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 735 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
elmot 1:d0dfbce63a89 736
elmot 1:d0dfbce63a89 737 /* Save current reading and writing locations of Input and Output buffers */
elmot 1:d0dfbce63a89 738 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
elmot 1:d0dfbce63a89 739 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 740 /* Save the number of bytes that remain to be processed at this point */
elmot 1:d0dfbce63a89 741 hcryp->CrypInCount = Size - (index+16);
elmot 1:d0dfbce63a89 742
elmot 1:d0dfbce63a89 743 /* Process Unlocked */
elmot 1:d0dfbce63a89 744 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 745
elmot 1:d0dfbce63a89 746 return HAL_OK;
elmot 1:d0dfbce63a89 747 }
elmot 1:d0dfbce63a89 748
elmot 1:d0dfbce63a89 749 }
elmot 1:d0dfbce63a89 750
elmot 1:d0dfbce63a89 751 /* Additional processing to manage GCM encryption and decryption cases when
elmot 1:d0dfbce63a89 752 payload last block size less than 128 bits */
elmot 1:d0dfbce63a89 753 if (addhoc_process == 1)
elmot 1:d0dfbce63a89 754 {
elmot 1:d0dfbce63a89 755
elmot 1:d0dfbce63a89 756 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 757 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
elmot 1:d0dfbce63a89 758 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
elmot 1:d0dfbce63a89 759
elmot 1:d0dfbce63a89 760 } /* (addhoc_process == 1) */
elmot 1:d0dfbce63a89 761
elmot 1:d0dfbce63a89 762 /* Mark that the payload phase is over */
elmot 1:d0dfbce63a89 763 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
elmot 1:d0dfbce63a89 764 }
elmot 1:d0dfbce63a89 765 /*==============================*/
elmot 1:d0dfbce63a89 766 /* GCM/GMAC or CMAC final phase */
elmot 1:d0dfbce63a89 767 /*==============================*/
elmot 1:d0dfbce63a89 768 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 769 {
elmot 1:d0dfbce63a89 770 tagaddr = (uint32_t)pOutputData;
elmot 1:d0dfbce63a89 771
elmot 1:d0dfbce63a89 772 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
elmot 1:d0dfbce63a89 773
elmot 1:d0dfbce63a89 774 /* if the header and payload phases have been bypassed, AES must be enabled again */
elmot 1:d0dfbce63a89 775 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
elmot 1:d0dfbce63a89 776 {
elmot 1:d0dfbce63a89 777 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 778 }
elmot 1:d0dfbce63a89 779
elmot 1:d0dfbce63a89 780 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
elmot 1:d0dfbce63a89 781 {
elmot 1:d0dfbce63a89 782 headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
elmot 1:d0dfbce63a89 783 inputlength = Size * 8; /* input length in bits */
elmot 1:d0dfbce63a89 784
elmot 1:d0dfbce63a89 785
elmot 1:d0dfbce63a89 786 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
elmot 1:d0dfbce63a89 787 {
elmot 1:d0dfbce63a89 788 hcryp->Instance->DINR = __RBIT((headerlength)>>32);
elmot 1:d0dfbce63a89 789 hcryp->Instance->DINR = __RBIT(headerlength);
elmot 1:d0dfbce63a89 790 hcryp->Instance->DINR = __RBIT((inputlength)>>32);
elmot 1:d0dfbce63a89 791 hcryp->Instance->DINR = __RBIT(inputlength);
elmot 1:d0dfbce63a89 792 }
elmot 1:d0dfbce63a89 793 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
elmot 1:d0dfbce63a89 794 {
elmot 1:d0dfbce63a89 795 hcryp->Instance->DINR = __REV((headerlength)>>32);
elmot 1:d0dfbce63a89 796 hcryp->Instance->DINR = __REV(headerlength);
elmot 1:d0dfbce63a89 797 hcryp->Instance->DINR = __REV((inputlength)>>32);
elmot 1:d0dfbce63a89 798 hcryp->Instance->DINR = __REV(inputlength);
elmot 1:d0dfbce63a89 799 }
elmot 1:d0dfbce63a89 800 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
elmot 1:d0dfbce63a89 801 {
elmot 1:d0dfbce63a89 802 hcryp->Instance->DINR = __ROR((headerlength)>>32, 16);
elmot 1:d0dfbce63a89 803 hcryp->Instance->DINR = __ROR(headerlength, 16);
elmot 1:d0dfbce63a89 804 hcryp->Instance->DINR = __ROR((inputlength)>>32, 16);
elmot 1:d0dfbce63a89 805 hcryp->Instance->DINR = __ROR(inputlength, 16);
elmot 1:d0dfbce63a89 806 }
elmot 1:d0dfbce63a89 807 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
elmot 1:d0dfbce63a89 808 {
elmot 1:d0dfbce63a89 809 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
elmot 1:d0dfbce63a89 810 hcryp->Instance->DINR = (uint32_t)(headerlength);
elmot 1:d0dfbce63a89 811 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
elmot 1:d0dfbce63a89 812 hcryp->Instance->DINR = (uint32_t)(inputlength);
elmot 1:d0dfbce63a89 813 }
elmot 1:d0dfbce63a89 814 }
elmot 1:d0dfbce63a89 815 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 816 {
elmot 1:d0dfbce63a89 817 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 818 /* Enter the last block made of a 128-bit value formatted
elmot 1:d0dfbce63a89 819 from the original B0 packet. */
elmot 1:d0dfbce63a89 820 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 821 inputaddr+=4;
elmot 1:d0dfbce63a89 822 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 823 inputaddr+=4;
elmot 1:d0dfbce63a89 824 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 825 inputaddr+=4;
elmot 1:d0dfbce63a89 826 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 827 }
elmot 1:d0dfbce63a89 828
elmot 1:d0dfbce63a89 829
elmot 1:d0dfbce63a89 830 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 831 {
elmot 1:d0dfbce63a89 832 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 833 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 834 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 835 }
elmot 1:d0dfbce63a89 836
elmot 1:d0dfbce63a89 837 /* Read the Auth TAG in the Data Out register */
elmot 1:d0dfbce63a89 838 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 839 tagaddr+=4;
elmot 1:d0dfbce63a89 840 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 841 tagaddr+=4;
elmot 1:d0dfbce63a89 842 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 843 tagaddr+=4;
elmot 1:d0dfbce63a89 844 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 845
elmot 1:d0dfbce63a89 846
elmot 1:d0dfbce63a89 847 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 848 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 849 /* Mark that the final phase is over */
elmot 1:d0dfbce63a89 850 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
elmot 1:d0dfbce63a89 851 /* Disable the Peripheral */
elmot 1:d0dfbce63a89 852 __HAL_CRYP_DISABLE();
elmot 1:d0dfbce63a89 853 }
elmot 1:d0dfbce63a89 854 /*=================================================*/
elmot 1:d0dfbce63a89 855 /* case incorrect hcryp->Init.GCMCMACPhase setting */
elmot 1:d0dfbce63a89 856 /*=================================================*/
elmot 1:d0dfbce63a89 857 else
elmot 1:d0dfbce63a89 858 {
elmot 1:d0dfbce63a89 859 hcryp->State = HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 860 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 861 return HAL_ERROR;
elmot 1:d0dfbce63a89 862 }
elmot 1:d0dfbce63a89 863
elmot 1:d0dfbce63a89 864 /* Change the CRYP state */
elmot 1:d0dfbce63a89 865 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 866
elmot 1:d0dfbce63a89 867 /* Process Unlocked */
elmot 1:d0dfbce63a89 868 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 869
elmot 1:d0dfbce63a89 870 return HAL_OK;
elmot 1:d0dfbce63a89 871 }
elmot 1:d0dfbce63a89 872 else
elmot 1:d0dfbce63a89 873 {
elmot 1:d0dfbce63a89 874 return HAL_BUSY;
elmot 1:d0dfbce63a89 875 }
elmot 1:d0dfbce63a89 876 }
elmot 1:d0dfbce63a89 877
elmot 1:d0dfbce63a89 878
elmot 1:d0dfbce63a89 879
elmot 1:d0dfbce63a89 880
elmot 1:d0dfbce63a89 881 /**
elmot 1:d0dfbce63a89 882 * @brief Carry out in interrupt mode the authentication tag generation as well as the ciphering or deciphering
elmot 1:d0dfbce63a89 883 * operation according to hcryp->Init structure fields.
elmot 1:d0dfbce63a89 884 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 885 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 886 * @param pInputData:
elmot 1:d0dfbce63a89 887 * - pointer to payload data in GCM payload phase,
elmot 1:d0dfbce63a89 888 * - pointer to B0 block in CMAC header phase,
elmot 1:d0dfbce63a89 889 * - pointer to C block in CMAC final phase.
elmot 1:d0dfbce63a89 890 * Parameter is meaningless in case of GCM/GMAC init, header and final phases.
elmot 1:d0dfbce63a89 891 * @param Size:
elmot 1:d0dfbce63a89 892 * - length of the input payload data buffer in bytes,
elmot 1:d0dfbce63a89 893 * - length of B0 block (in bytes) in CMAC header phase,
elmot 1:d0dfbce63a89 894 * - length of C block (in bytes) in CMAC final phase.
elmot 1:d0dfbce63a89 895 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
elmot 1:d0dfbce63a89 896 * @param pOutputData:
elmot 1:d0dfbce63a89 897 * - pointer to plain or cipher text in GCM payload phase,
elmot 1:d0dfbce63a89 898 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
elmot 1:d0dfbce63a89 899 * - Parameter is meaningless in case of GCM/GMAC init and header phases
elmot 1:d0dfbce63a89 900 * and in case of CMAC header phase.
elmot 1:d0dfbce63a89 901 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
elmot 1:d0dfbce63a89 902 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
elmot 1:d0dfbce63a89 903 * can be skipped by the user if so required.
elmot 1:d0dfbce63a89 904 * @retval HAL status
elmot 1:d0dfbce63a89 905 */
elmot 1:d0dfbce63a89 906 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
elmot 1:d0dfbce63a89 907 {
elmot 1:d0dfbce63a89 908
elmot 1:d0dfbce63a89 909 uint32_t inputaddr = 0;
elmot 1:d0dfbce63a89 910 uint64_t headerlength = 0;
elmot 1:d0dfbce63a89 911 uint64_t inputlength = 0;
elmot 1:d0dfbce63a89 912 uint32_t index = 0;
elmot 1:d0dfbce63a89 913 uint32_t addhoc_process = 0;
elmot 1:d0dfbce63a89 914 uint32_t difflength = 0;
elmot 1:d0dfbce63a89 915 uint32_t difflengthmod4 = 0;
elmot 1:d0dfbce63a89 916 uint32_t mask[3] = {0x0FF, 0x0FFFF, 0x0FFFFFF};
elmot 1:d0dfbce63a89 917
elmot 1:d0dfbce63a89 918
elmot 1:d0dfbce63a89 919 if (hcryp->State == HAL_CRYP_STATE_READY)
elmot 1:d0dfbce63a89 920 {
elmot 1:d0dfbce63a89 921 /* input/output parameters check */
elmot 1:d0dfbce63a89 922 if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 923 {
elmot 1:d0dfbce63a89 924 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0))
elmot 1:d0dfbce63a89 925 {
elmot 1:d0dfbce63a89 926 return HAL_ERROR;
elmot 1:d0dfbce63a89 927 }
elmot 1:d0dfbce63a89 928 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 929 {
elmot 1:d0dfbce63a89 930 /* In case of CMAC header phase resumption, we can have pInputData = NULL and Size = 0 */
elmot 1:d0dfbce63a89 931 if (((pInputData != NULL) && (Size == 0)) || ((pInputData == NULL) && (Size != 0)))
elmot 1:d0dfbce63a89 932 {
elmot 1:d0dfbce63a89 933 return HAL_ERROR;
elmot 1:d0dfbce63a89 934 }
elmot 1:d0dfbce63a89 935 }
elmot 1:d0dfbce63a89 936 }
elmot 1:d0dfbce63a89 937 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 938 {
elmot 1:d0dfbce63a89 939 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 940 {
elmot 1:d0dfbce63a89 941 return HAL_ERROR;
elmot 1:d0dfbce63a89 942 }
elmot 1:d0dfbce63a89 943 }
elmot 1:d0dfbce63a89 944 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 945 {
elmot 1:d0dfbce63a89 946 if (pOutputData == NULL)
elmot 1:d0dfbce63a89 947 {
elmot 1:d0dfbce63a89 948 return HAL_ERROR;
elmot 1:d0dfbce63a89 949 }
elmot 1:d0dfbce63a89 950 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
elmot 1:d0dfbce63a89 951 {
elmot 1:d0dfbce63a89 952 return HAL_ERROR;
elmot 1:d0dfbce63a89 953 }
elmot 1:d0dfbce63a89 954 }
elmot 1:d0dfbce63a89 955
elmot 1:d0dfbce63a89 956
elmot 1:d0dfbce63a89 957 /* Process Locked */
elmot 1:d0dfbce63a89 958 __HAL_LOCK(hcryp);
elmot 1:d0dfbce63a89 959
elmot 1:d0dfbce63a89 960 /* Change the CRYP state */
elmot 1:d0dfbce63a89 961 hcryp->State = HAL_CRYP_STATE_BUSY;
elmot 1:d0dfbce63a89 962
elmot 1:d0dfbce63a89 963 /* Process Unlocked */
elmot 1:d0dfbce63a89 964 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 965
elmot 1:d0dfbce63a89 966 /* Enable Computation Complete Flag and Error Interrupts */
elmot 1:d0dfbce63a89 967 __HAL_CRYP_ENABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 968
elmot 1:d0dfbce63a89 969
elmot 1:d0dfbce63a89 970
elmot 1:d0dfbce63a89 971 /*=====================*/
elmot 1:d0dfbce63a89 972 /* GCM/GMAC init phase */
elmot 1:d0dfbce63a89 973 /*=====================*/
elmot 1:d0dfbce63a89 974 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_INIT_PHASE)
elmot 1:d0dfbce63a89 975 {
elmot 1:d0dfbce63a89 976 /* In case of init phase, the input data (Key and Initialization Vector) have
elmot 1:d0dfbce63a89 977 already been entered during the initialization process. Therefore, the
elmot 1:d0dfbce63a89 978 software just waits for the CCF interrupt to be raised and which will
elmot 1:d0dfbce63a89 979 be handled by CRYP_AES_Auth_IT() API. */
elmot 1:d0dfbce63a89 980 }
elmot 1:d0dfbce63a89 981 /*===============================*/
elmot 1:d0dfbce63a89 982 /* GCM/GMAC or CMAC header phase */
elmot 1:d0dfbce63a89 983 /*===============================*/
elmot 1:d0dfbce63a89 984 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 985 {
elmot 1:d0dfbce63a89 986 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 987 {
elmot 1:d0dfbce63a89 988 /* In case of CMAC, B blocks are first entered, before the header.
elmot 1:d0dfbce63a89 989 Therefore, B blocks and the header are entered back-to-back
elmot 1:d0dfbce63a89 990 as if it was only one single block.
elmot 1:d0dfbce63a89 991 However, in case of resumption after suspension, if all the
elmot 1:d0dfbce63a89 992 B blocks have been entered (in that case, Size = 0), only the
elmot 1:d0dfbce63a89 993 remainder of the non-processed header bytes are entered. */
elmot 1:d0dfbce63a89 994 if (Size != 0)
elmot 1:d0dfbce63a89 995 {
elmot 1:d0dfbce63a89 996 hcryp->CrypInCount = Size + hcryp->Init.HeaderSize;
elmot 1:d0dfbce63a89 997 hcryp->pCrypInBuffPtr = pInputData;
elmot 1:d0dfbce63a89 998 }
elmot 1:d0dfbce63a89 999 else
elmot 1:d0dfbce63a89 1000 {
elmot 1:d0dfbce63a89 1001 hcryp->CrypInCount = hcryp->Init.HeaderSize;
elmot 1:d0dfbce63a89 1002 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
elmot 1:d0dfbce63a89 1003 }
elmot 1:d0dfbce63a89 1004 }
elmot 1:d0dfbce63a89 1005 else
elmot 1:d0dfbce63a89 1006 {
elmot 1:d0dfbce63a89 1007 /* Get the header addresses and sizes */
elmot 1:d0dfbce63a89 1008 hcryp->CrypInCount = hcryp->Init.HeaderSize;
elmot 1:d0dfbce63a89 1009 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
elmot 1:d0dfbce63a89 1010 }
elmot 1:d0dfbce63a89 1011
elmot 1:d0dfbce63a89 1012 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
elmot 1:d0dfbce63a89 1013
elmot 1:d0dfbce63a89 1014 /* Set header phase; for GCM or GMAC, set data-byte at this point */
elmot 1:d0dfbce63a89 1015 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
elmot 1:d0dfbce63a89 1016 {
elmot 1:d0dfbce63a89 1017 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType);
elmot 1:d0dfbce63a89 1018 }
elmot 1:d0dfbce63a89 1019 else
elmot 1:d0dfbce63a89 1020 {
elmot 1:d0dfbce63a89 1021 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE);
elmot 1:d0dfbce63a89 1022 }
elmot 1:d0dfbce63a89 1023
elmot 1:d0dfbce63a89 1024 /* Enable the Peripheral */
elmot 1:d0dfbce63a89 1025 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 1026
elmot 1:d0dfbce63a89 1027 /* Increment/decrement instance pointer/counter */
elmot 1:d0dfbce63a89 1028 if (hcryp->CrypInCount == 0)
elmot 1:d0dfbce63a89 1029 {
elmot 1:d0dfbce63a89 1030 /* Case of no header */
elmot 1:d0dfbce63a89 1031 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1032 return HAL_OK;
elmot 1:d0dfbce63a89 1033 }
elmot 1:d0dfbce63a89 1034 else if (hcryp->CrypInCount < 16)
elmot 1:d0dfbce63a89 1035 {
elmot 1:d0dfbce63a89 1036 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 1037 addhoc_process = 1;
elmot 1:d0dfbce63a89 1038 difflength = (uint32_t) (hcryp->Init.HeaderSize);
elmot 1:d0dfbce63a89 1039 difflengthmod4 = difflength%4;
elmot 1:d0dfbce63a89 1040 }
elmot 1:d0dfbce63a89 1041 else
elmot 1:d0dfbce63a89 1042 {
elmot 1:d0dfbce63a89 1043 hcryp->pCrypInBuffPtr += 16;
elmot 1:d0dfbce63a89 1044 hcryp->CrypInCount -= 16;
elmot 1:d0dfbce63a89 1045 }
elmot 1:d0dfbce63a89 1046
elmot 1:d0dfbce63a89 1047
elmot 1:d0dfbce63a89 1048 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 1049 {
elmot 1:d0dfbce63a89 1050 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
elmot 1:d0dfbce63a89 1051 {
elmot 1:d0dfbce63a89 1052 /* All B blocks will have been entered after the next
elmot 1:d0dfbce63a89 1053 four DINR writing, so point at header buffer for
elmot 1:d0dfbce63a89 1054 the next iteration */
elmot 1:d0dfbce63a89 1055 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
elmot 1:d0dfbce63a89 1056 }
elmot 1:d0dfbce63a89 1057 }
elmot 1:d0dfbce63a89 1058
elmot 1:d0dfbce63a89 1059 /* Enter header first block to initiate the process
elmot 1:d0dfbce63a89 1060 in the Data Input register */
elmot 1:d0dfbce63a89 1061 if (addhoc_process == 0)
elmot 1:d0dfbce63a89 1062 {
elmot 1:d0dfbce63a89 1063 /* Header has size equal or larger than 128 bits */
elmot 1:d0dfbce63a89 1064 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1065 inputaddr+=4;
elmot 1:d0dfbce63a89 1066 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1067 inputaddr+=4;
elmot 1:d0dfbce63a89 1068 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1069 inputaddr+=4;
elmot 1:d0dfbce63a89 1070 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1071 }
elmot 1:d0dfbce63a89 1072 else
elmot 1:d0dfbce63a89 1073 {
elmot 1:d0dfbce63a89 1074 /* Header has size less than 128 bits */
elmot 1:d0dfbce63a89 1075 /* Enter complete words when possible */
elmot 1:d0dfbce63a89 1076 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 1077 {
elmot 1:d0dfbce63a89 1078 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 1079 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1080 inputaddr+=4;
elmot 1:d0dfbce63a89 1081 }
elmot 1:d0dfbce63a89 1082 /* Enter incomplete word padded with zeroes if applicable
elmot 1:d0dfbce63a89 1083 (case of header length not a multiple of 32-bits) */
elmot 1:d0dfbce63a89 1084 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 1085 {
elmot 1:d0dfbce63a89 1086 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
elmot 1:d0dfbce63a89 1087 }
elmot 1:d0dfbce63a89 1088 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
elmot 1:d0dfbce63a89 1089 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 1090 {
elmot 1:d0dfbce63a89 1091 hcryp->Instance->DINR = 0;
elmot 1:d0dfbce63a89 1092 }
elmot 1:d0dfbce63a89 1093
elmot 1:d0dfbce63a89 1094 }
elmot 1:d0dfbce63a89 1095 }
elmot 1:d0dfbce63a89 1096 /*========================*/
elmot 1:d0dfbce63a89 1097 /* GCM/GMAC payload phase */
elmot 1:d0dfbce63a89 1098 /*========================*/
elmot 1:d0dfbce63a89 1099 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 1100 {
elmot 1:d0dfbce63a89 1101 /* Get the buffer addresses and sizes */
elmot 1:d0dfbce63a89 1102 hcryp->CrypInCount = Size;
elmot 1:d0dfbce63a89 1103 hcryp->pCrypInBuffPtr = pInputData;
elmot 1:d0dfbce63a89 1104 hcryp->pCrypOutBuffPtr = pOutputData;
elmot 1:d0dfbce63a89 1105 hcryp->CrypOutCount = Size;
elmot 1:d0dfbce63a89 1106
elmot 1:d0dfbce63a89 1107 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
elmot 1:d0dfbce63a89 1108
elmot 1:d0dfbce63a89 1109 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE);
elmot 1:d0dfbce63a89 1110
elmot 1:d0dfbce63a89 1111 /* if the header phase has been bypassed, AES must be enabled again */
elmot 1:d0dfbce63a89 1112 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
elmot 1:d0dfbce63a89 1113 {
elmot 1:d0dfbce63a89 1114 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 1115 }
elmot 1:d0dfbce63a89 1116
elmot 1:d0dfbce63a89 1117 /* Specific handling to manage payload size less than 128 bits
elmot 1:d0dfbce63a89 1118 when GCM encryption or decryption is selected */
elmot 1:d0dfbce63a89 1119 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
elmot 1:d0dfbce63a89 1120 (Size < 16))
elmot 1:d0dfbce63a89 1121 {
elmot 1:d0dfbce63a89 1122 /* Software workaround applied to GCM encryption only */
elmot 1:d0dfbce63a89 1123 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
elmot 1:d0dfbce63a89 1124 {
elmot 1:d0dfbce63a89 1125 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
elmot 1:d0dfbce63a89 1126 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
elmot 1:d0dfbce63a89 1127 }
elmot 1:d0dfbce63a89 1128
elmot 1:d0dfbce63a89 1129 /* Set hcryp->CrypInCount to 0 (no more data to enter) */
elmot 1:d0dfbce63a89 1130 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 1131
elmot 1:d0dfbce63a89 1132 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes,
elmot 1:d0dfbce63a89 1133 to have a complete block of 128 bits */
elmot 1:d0dfbce63a89 1134 difflength = (uint32_t) (Size);
elmot 1:d0dfbce63a89 1135 difflengthmod4 = difflength%4;
elmot 1:d0dfbce63a89 1136 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
elmot 1:d0dfbce63a89 1137 to have a complete block of 128 bits */
elmot 1:d0dfbce63a89 1138 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 1139 {
elmot 1:d0dfbce63a89 1140 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 1141 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1142 inputaddr+=4;
elmot 1:d0dfbce63a89 1143 }
elmot 1:d0dfbce63a89 1144 /* If required, manage input data size not multiple of 32 bits */
elmot 1:d0dfbce63a89 1145 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 1146 {
elmot 1:d0dfbce63a89 1147 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
elmot 1:d0dfbce63a89 1148 }
elmot 1:d0dfbce63a89 1149 /* Wrap-up in padding with zero-words if applicable */
elmot 1:d0dfbce63a89 1150 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 1151 {
elmot 1:d0dfbce63a89 1152 hcryp->Instance->DINR = 0;
elmot 1:d0dfbce63a89 1153 }
elmot 1:d0dfbce63a89 1154 }
elmot 1:d0dfbce63a89 1155 else
elmot 1:d0dfbce63a89 1156 {
elmot 1:d0dfbce63a89 1157 /* Increment/decrement instance pointer/counter */
elmot 1:d0dfbce63a89 1158 hcryp->pCrypInBuffPtr += 16;
elmot 1:d0dfbce63a89 1159 hcryp->CrypInCount -= 16;
elmot 1:d0dfbce63a89 1160
elmot 1:d0dfbce63a89 1161 /* Enter payload first block to initiate the process
elmot 1:d0dfbce63a89 1162 in the Data Input register */
elmot 1:d0dfbce63a89 1163 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1164 inputaddr+=4;
elmot 1:d0dfbce63a89 1165 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1166 inputaddr+=4;
elmot 1:d0dfbce63a89 1167 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1168 inputaddr+=4;
elmot 1:d0dfbce63a89 1169 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1170 }
elmot 1:d0dfbce63a89 1171 }
elmot 1:d0dfbce63a89 1172 /*==============================*/
elmot 1:d0dfbce63a89 1173 /* GCM/GMAC or CMAC final phase */
elmot 1:d0dfbce63a89 1174 /*==============================*/
elmot 1:d0dfbce63a89 1175 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 1176 {
elmot 1:d0dfbce63a89 1177 hcryp->pCrypOutBuffPtr = pOutputData;
elmot 1:d0dfbce63a89 1178
elmot 1:d0dfbce63a89 1179 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
elmot 1:d0dfbce63a89 1180
elmot 1:d0dfbce63a89 1181 /* if the header and payload phases have been bypassed, AES must be enabled again */
elmot 1:d0dfbce63a89 1182 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
elmot 1:d0dfbce63a89 1183 {
elmot 1:d0dfbce63a89 1184 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 1185 }
elmot 1:d0dfbce63a89 1186
elmot 1:d0dfbce63a89 1187 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
elmot 1:d0dfbce63a89 1188 {
elmot 1:d0dfbce63a89 1189 headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
elmot 1:d0dfbce63a89 1190 inputlength = Size * 8; /* input length in bits */
elmot 1:d0dfbce63a89 1191 /* Write the number of bits in the header on 64 bits followed by the number
elmot 1:d0dfbce63a89 1192 of bits in the payload on 64 bits as well */
elmot 1:d0dfbce63a89 1193 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
elmot 1:d0dfbce63a89 1194 {
elmot 1:d0dfbce63a89 1195 hcryp->Instance->DINR = __RBIT((headerlength)>>32);
elmot 1:d0dfbce63a89 1196 hcryp->Instance->DINR = __RBIT(headerlength);
elmot 1:d0dfbce63a89 1197 hcryp->Instance->DINR = __RBIT((inputlength)>>32);
elmot 1:d0dfbce63a89 1198 hcryp->Instance->DINR = __RBIT(inputlength);
elmot 1:d0dfbce63a89 1199 }
elmot 1:d0dfbce63a89 1200 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
elmot 1:d0dfbce63a89 1201 {
elmot 1:d0dfbce63a89 1202 hcryp->Instance->DINR = __REV((headerlength)>>32);
elmot 1:d0dfbce63a89 1203 hcryp->Instance->DINR = __REV(headerlength);
elmot 1:d0dfbce63a89 1204 hcryp->Instance->DINR = __REV((inputlength)>>32);
elmot 1:d0dfbce63a89 1205 hcryp->Instance->DINR = __REV(inputlength);
elmot 1:d0dfbce63a89 1206 }
elmot 1:d0dfbce63a89 1207 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
elmot 1:d0dfbce63a89 1208 {
elmot 1:d0dfbce63a89 1209 hcryp->Instance->DINR = __ROR((headerlength)>>32, 16);
elmot 1:d0dfbce63a89 1210 hcryp->Instance->DINR = __ROR(headerlength, 16);
elmot 1:d0dfbce63a89 1211 hcryp->Instance->DINR = __ROR((inputlength)>>32, 16);
elmot 1:d0dfbce63a89 1212 hcryp->Instance->DINR = __ROR(inputlength, 16);
elmot 1:d0dfbce63a89 1213 }
elmot 1:d0dfbce63a89 1214 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
elmot 1:d0dfbce63a89 1215 {
elmot 1:d0dfbce63a89 1216 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
elmot 1:d0dfbce63a89 1217 hcryp->Instance->DINR = (uint32_t)(headerlength);
elmot 1:d0dfbce63a89 1218 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
elmot 1:d0dfbce63a89 1219 hcryp->Instance->DINR = (uint32_t)(inputlength);
elmot 1:d0dfbce63a89 1220 }
elmot 1:d0dfbce63a89 1221 }
elmot 1:d0dfbce63a89 1222 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 1223 {
elmot 1:d0dfbce63a89 1224 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 1225 /* Enter the last block made of a 128-bit value formatted
elmot 1:d0dfbce63a89 1226 from the original B0 packet. */
elmot 1:d0dfbce63a89 1227 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1228 inputaddr+=4;
elmot 1:d0dfbce63a89 1229 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1230 inputaddr+=4;
elmot 1:d0dfbce63a89 1231 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1232 inputaddr+=4;
elmot 1:d0dfbce63a89 1233 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1234 inputaddr+=4;
elmot 1:d0dfbce63a89 1235 }
elmot 1:d0dfbce63a89 1236 }
elmot 1:d0dfbce63a89 1237 /*=================================================*/
elmot 1:d0dfbce63a89 1238 /* case incorrect hcryp->Init.GCMCMACPhase setting */
elmot 1:d0dfbce63a89 1239 /*=================================================*/
elmot 1:d0dfbce63a89 1240 else
elmot 1:d0dfbce63a89 1241 {
elmot 1:d0dfbce63a89 1242 hcryp->State = HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 1243 return HAL_ERROR;
elmot 1:d0dfbce63a89 1244 }
elmot 1:d0dfbce63a89 1245
elmot 1:d0dfbce63a89 1246 return HAL_OK;
elmot 1:d0dfbce63a89 1247 }
elmot 1:d0dfbce63a89 1248 else
elmot 1:d0dfbce63a89 1249 {
elmot 1:d0dfbce63a89 1250 return HAL_BUSY;
elmot 1:d0dfbce63a89 1251 }
elmot 1:d0dfbce63a89 1252 }
elmot 1:d0dfbce63a89 1253
elmot 1:d0dfbce63a89 1254
elmot 1:d0dfbce63a89 1255
elmot 1:d0dfbce63a89 1256
elmot 1:d0dfbce63a89 1257 /**
elmot 1:d0dfbce63a89 1258 * @brief Carry out in DMA mode the authentication tag generation as well as the ciphering or deciphering
elmot 1:d0dfbce63a89 1259 * operation according to hcryp->Init structure fields.
elmot 1:d0dfbce63a89 1260 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1261 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 1262 * @param pInputData:
elmot 1:d0dfbce63a89 1263 * - pointer to payload data in GCM payload phase,
elmot 1:d0dfbce63a89 1264 * - pointer to B0 block in CMAC header phase,
elmot 1:d0dfbce63a89 1265 * - pointer to C block in CMAC final phase.
elmot 1:d0dfbce63a89 1266 * - Parameter is meaningless in case of GCM/GMAC init, header and final phases.
elmot 1:d0dfbce63a89 1267 * @param Size:
elmot 1:d0dfbce63a89 1268 * - length of the input payload data buffer in bytes,
elmot 1:d0dfbce63a89 1269 * - length of B block (in bytes) in CMAC header phase,
elmot 1:d0dfbce63a89 1270 * - length of C block (in bytes) in CMAC final phase.
elmot 1:d0dfbce63a89 1271 * - Parameter is meaningless in case of GCM/GMAC init and header phases.
elmot 1:d0dfbce63a89 1272 * @param pOutputData:
elmot 1:d0dfbce63a89 1273 * - pointer to plain or cipher text in GCM payload phase,
elmot 1:d0dfbce63a89 1274 * - pointer to authentication tag in GCM/GMAC and CMAC final phases.
elmot 1:d0dfbce63a89 1275 * - Parameter is meaningless in case of GCM/GMAC init and header phases
elmot 1:d0dfbce63a89 1276 * and in case of CMAC header phase.
elmot 1:d0dfbce63a89 1277 * @note Supported operating modes are encryption and decryption, supported chaining modes are GCM, GMAC and CMAC.
elmot 1:d0dfbce63a89 1278 * @note Phases are singly processed according to hcryp->Init.GCMCMACPhase so that steps in these specific chaining modes
elmot 1:d0dfbce63a89 1279 * can be skipped by the user if so required.
elmot 1:d0dfbce63a89 1280 * @note pInputData and pOutputData buffers must be 32-bit aligned to ensure a correct DMA transfer to and from the IP.
elmot 1:d0dfbce63a89 1281 * @retval HAL status
elmot 1:d0dfbce63a89 1282 */
elmot 1:d0dfbce63a89 1283 HAL_StatusTypeDef HAL_CRYPEx_AES_Auth_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pInputData, uint64_t Size, uint8_t *pOutputData)
elmot 1:d0dfbce63a89 1284 {
elmot 1:d0dfbce63a89 1285 uint32_t inputaddr = 0;
elmot 1:d0dfbce63a89 1286 uint32_t outputaddr = 0;
elmot 1:d0dfbce63a89 1287 uint32_t tagaddr = 0;
elmot 1:d0dfbce63a89 1288 uint64_t headerlength = 0;
elmot 1:d0dfbce63a89 1289 uint64_t inputlength = 0;
elmot 1:d0dfbce63a89 1290 uint64_t payloadlength = 0;
elmot 1:d0dfbce63a89 1291
elmot 1:d0dfbce63a89 1292
elmot 1:d0dfbce63a89 1293 if (hcryp->State == HAL_CRYP_STATE_READY)
elmot 1:d0dfbce63a89 1294 {
elmot 1:d0dfbce63a89 1295 /* input/output parameters check */
elmot 1:d0dfbce63a89 1296 if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 1297 {
elmot 1:d0dfbce63a89 1298 if ((hcryp->Init.Header != NULL) && (hcryp->Init.HeaderSize == 0))
elmot 1:d0dfbce63a89 1299 {
elmot 1:d0dfbce63a89 1300 return HAL_ERROR;
elmot 1:d0dfbce63a89 1301 }
elmot 1:d0dfbce63a89 1302 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 1303 {
elmot 1:d0dfbce63a89 1304 if ((pInputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 1305 {
elmot 1:d0dfbce63a89 1306 return HAL_ERROR;
elmot 1:d0dfbce63a89 1307 }
elmot 1:d0dfbce63a89 1308 }
elmot 1:d0dfbce63a89 1309 }
elmot 1:d0dfbce63a89 1310 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 1311 {
elmot 1:d0dfbce63a89 1312 if ((pInputData == NULL) || (pOutputData == NULL) || (Size == 0))
elmot 1:d0dfbce63a89 1313 {
elmot 1:d0dfbce63a89 1314 return HAL_ERROR;
elmot 1:d0dfbce63a89 1315 }
elmot 1:d0dfbce63a89 1316 }
elmot 1:d0dfbce63a89 1317 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 1318 {
elmot 1:d0dfbce63a89 1319 if (pOutputData == NULL)
elmot 1:d0dfbce63a89 1320 {
elmot 1:d0dfbce63a89 1321 return HAL_ERROR;
elmot 1:d0dfbce63a89 1322 }
elmot 1:d0dfbce63a89 1323 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC) && (pInputData == NULL))
elmot 1:d0dfbce63a89 1324 {
elmot 1:d0dfbce63a89 1325 return HAL_ERROR;
elmot 1:d0dfbce63a89 1326 }
elmot 1:d0dfbce63a89 1327 }
elmot 1:d0dfbce63a89 1328
elmot 1:d0dfbce63a89 1329
elmot 1:d0dfbce63a89 1330 /* Process Locked */
elmot 1:d0dfbce63a89 1331 __HAL_LOCK(hcryp);
elmot 1:d0dfbce63a89 1332
elmot 1:d0dfbce63a89 1333 /* Change the CRYP state */
elmot 1:d0dfbce63a89 1334 hcryp->State = HAL_CRYP_STATE_BUSY;
elmot 1:d0dfbce63a89 1335
elmot 1:d0dfbce63a89 1336 /*=====================*/
elmot 1:d0dfbce63a89 1337 /* GCM/GMAC init phase */
elmot 1:d0dfbce63a89 1338 /*=====================*/
elmot 1:d0dfbce63a89 1339 /* In case of init phase, the input data (Key and Initialization Vector) have
elmot 1:d0dfbce63a89 1340 already been entered during the initialization process. No DMA transfer is
elmot 1:d0dfbce63a89 1341 required at that point therefore, the software just waits for the CCF flag
elmot 1:d0dfbce63a89 1342 to be raised. */
elmot 1:d0dfbce63a89 1343 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_INIT_PHASE)
elmot 1:d0dfbce63a89 1344 {
elmot 1:d0dfbce63a89 1345 /* just wait for hash computation */
elmot 1:d0dfbce63a89 1346 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 1347 {
elmot 1:d0dfbce63a89 1348 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1349 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1350 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 1351 }
elmot 1:d0dfbce63a89 1352
elmot 1:d0dfbce63a89 1353 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 1354 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1355 /* Mark that the initialization phase is over */
elmot 1:d0dfbce63a89 1356 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
elmot 1:d0dfbce63a89 1357 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1358 }
elmot 1:d0dfbce63a89 1359 /*===============================*/
elmot 1:d0dfbce63a89 1360 /* GCM/GMAC or CMAC header phase */
elmot 1:d0dfbce63a89 1361 /*===============================*/
elmot 1:d0dfbce63a89 1362 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 1363 {
elmot 1:d0dfbce63a89 1364 /* Set header phase; for GCM or GMAC, set data-byte at this point */
elmot 1:d0dfbce63a89 1365 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
elmot 1:d0dfbce63a89 1366 {
elmot 1:d0dfbce63a89 1367 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH|AES_CR_DATATYPE, CRYP_GCMCMAC_HEADER_PHASE|hcryp->Init.DataType);
elmot 1:d0dfbce63a89 1368 }
elmot 1:d0dfbce63a89 1369 else
elmot 1:d0dfbce63a89 1370 {
elmot 1:d0dfbce63a89 1371 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_HEADER_PHASE);
elmot 1:d0dfbce63a89 1372 }
elmot 1:d0dfbce63a89 1373
elmot 1:d0dfbce63a89 1374 /* enter first B0 block in polling mode (no DMA transfer for B0) */
elmot 1:d0dfbce63a89 1375 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 1376 {
elmot 1:d0dfbce63a89 1377 /* Enable the CRYP peripheral */
elmot 1:d0dfbce63a89 1378 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 1379
elmot 1:d0dfbce63a89 1380 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 1381 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1382 inputaddr+=4;
elmot 1:d0dfbce63a89 1383 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1384 inputaddr+=4;
elmot 1:d0dfbce63a89 1385 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1386 inputaddr+=4;
elmot 1:d0dfbce63a89 1387 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1388
elmot 1:d0dfbce63a89 1389 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 1390 {
elmot 1:d0dfbce63a89 1391 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1392 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1393 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 1394 }
elmot 1:d0dfbce63a89 1395 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 1396 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1397 }
elmot 1:d0dfbce63a89 1398
elmot 1:d0dfbce63a89 1399 /* No header case */
elmot 1:d0dfbce63a89 1400 if (hcryp->Init.Header == NULL)
elmot 1:d0dfbce63a89 1401 {
elmot 1:d0dfbce63a89 1402 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1403 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 1404 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
elmot 1:d0dfbce63a89 1405 /* Process Unlocked */
elmot 1:d0dfbce63a89 1406 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1407
elmot 1:d0dfbce63a89 1408 return HAL_OK;
elmot 1:d0dfbce63a89 1409 }
elmot 1:d0dfbce63a89 1410
elmot 1:d0dfbce63a89 1411 inputaddr = (uint32_t)hcryp->Init.Header;
elmot 1:d0dfbce63a89 1412 if ((hcryp->Init.HeaderSize % 16) != 0)
elmot 1:d0dfbce63a89 1413 {
elmot 1:d0dfbce63a89 1414
elmot 1:d0dfbce63a89 1415 if (hcryp->Init.HeaderSize < 16)
elmot 1:d0dfbce63a89 1416 {
elmot 1:d0dfbce63a89 1417 /*difflength = (uint32_t) (hcryp->Init.HeaderSize);*/
elmot 1:d0dfbce63a89 1418
elmot 1:d0dfbce63a89 1419 CRYP_Padding(hcryp, (uint32_t) (hcryp->Init.HeaderSize), CRYP_POLLING_OFF);
elmot 1:d0dfbce63a89 1420
elmot 1:d0dfbce63a89 1421 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1422 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 1423 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
elmot 1:d0dfbce63a89 1424
elmot 1:d0dfbce63a89 1425 /* CCF flag indicating header phase AES processing completion
elmot 1:d0dfbce63a89 1426 will be checked at the start of the next phase:
elmot 1:d0dfbce63a89 1427 - payload phase (GCM)
elmot 1:d0dfbce63a89 1428 - final phase (GMAC or CMAC). */
elmot 1:d0dfbce63a89 1429 }
elmot 1:d0dfbce63a89 1430 else
elmot 1:d0dfbce63a89 1431 {
elmot 1:d0dfbce63a89 1432 /* Local variable headerlength is a number of bytes multiple of 128 bits,
elmot 1:d0dfbce63a89 1433 remaining header data (if any) are handled after this loop */
elmot 1:d0dfbce63a89 1434 headerlength = (((hcryp->Init.HeaderSize)/16)*16) ;
elmot 1:d0dfbce63a89 1435 /* Store the ending transfer point */
elmot 1:d0dfbce63a89 1436 hcryp->pCrypInBuffPtr = hcryp->Init.Header + headerlength;
elmot 1:d0dfbce63a89 1437 hcryp->CrypInCount = (uint32_t)(hcryp->Init.HeaderSize - headerlength); /* remainder */
elmot 1:d0dfbce63a89 1438
elmot 1:d0dfbce63a89 1439 /* Set the input and output addresses and start DMA transfer */
elmot 1:d0dfbce63a89 1440 /* (incomplete DMA transfer, will be wrapped up after completion of
elmot 1:d0dfbce63a89 1441 the first one (initiated here) with data padding */
elmot 1:d0dfbce63a89 1442 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, headerlength, 0);
elmot 1:d0dfbce63a89 1443 }
elmot 1:d0dfbce63a89 1444 }
elmot 1:d0dfbce63a89 1445 else
elmot 1:d0dfbce63a89 1446 {
elmot 1:d0dfbce63a89 1447 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 1448 /* Set the input address and start DMA transfer */
elmot 1:d0dfbce63a89 1449 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, hcryp->Init.HeaderSize, 0);
elmot 1:d0dfbce63a89 1450 }
elmot 1:d0dfbce63a89 1451
elmot 1:d0dfbce63a89 1452
elmot 1:d0dfbce63a89 1453 }
elmot 1:d0dfbce63a89 1454 /*========================*/
elmot 1:d0dfbce63a89 1455 /* GCM/GMAC payload phase */
elmot 1:d0dfbce63a89 1456 /*========================*/
elmot 1:d0dfbce63a89 1457 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 1458 {
elmot 1:d0dfbce63a89 1459 /* Coming from header phase, wait for CCF flag to be raised
elmot 1:d0dfbce63a89 1460 if header present and fed to the IP in the previous phase */
elmot 1:d0dfbce63a89 1461 if (hcryp->Init.Header != NULL)
elmot 1:d0dfbce63a89 1462 {
elmot 1:d0dfbce63a89 1463 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 1464 {
elmot 1:d0dfbce63a89 1465 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1466 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1467 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 1468 }
elmot 1:d0dfbce63a89 1469 }
elmot 1:d0dfbce63a89 1470 else
elmot 1:d0dfbce63a89 1471 {
elmot 1:d0dfbce63a89 1472 /* Enable the Peripheral since wasn't in header phase (no header case) */
elmot 1:d0dfbce63a89 1473 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 1474 }
elmot 1:d0dfbce63a89 1475 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 1476 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1477
elmot 1:d0dfbce63a89 1478 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCM_PAYLOAD_PHASE);
elmot 1:d0dfbce63a89 1479
elmot 1:d0dfbce63a89 1480 /* Specific handling to manage payload size less than 128 bits
elmot 1:d0dfbce63a89 1481 when GCM encryption or decryption is selected */
elmot 1:d0dfbce63a89 1482 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
elmot 1:d0dfbce63a89 1483 ((Size % 16) != 0))
elmot 1:d0dfbce63a89 1484 {
elmot 1:d0dfbce63a89 1485 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 1486 outputaddr = (uint32_t)pOutputData;
elmot 1:d0dfbce63a89 1487 if (Size < 16)
elmot 1:d0dfbce63a89 1488 {
elmot 1:d0dfbce63a89 1489 /* Block is now entered in polling mode, no actual gain in resorting to DMA */
elmot 1:d0dfbce63a89 1490 /*difflength = (uint32_t)Size;*/
elmot 1:d0dfbce63a89 1491 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 1492 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
elmot 1:d0dfbce63a89 1493
elmot 1:d0dfbce63a89 1494 CRYP_Padding(hcryp, (uint32_t)Size, CRYP_POLLING_ON);
elmot 1:d0dfbce63a89 1495
elmot 1:d0dfbce63a89 1496 /* Change the CRYP state to ready */
elmot 1:d0dfbce63a89 1497 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1498 /* Mark that the payload phase is over */
elmot 1:d0dfbce63a89 1499 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
elmot 1:d0dfbce63a89 1500
elmot 1:d0dfbce63a89 1501 /* Call output data transfer complete callback */
elmot 1:d0dfbce63a89 1502 HAL_CRYP_OutCpltCallback(hcryp);
elmot 1:d0dfbce63a89 1503 }
elmot 1:d0dfbce63a89 1504 else
elmot 1:d0dfbce63a89 1505 {
elmot 1:d0dfbce63a89 1506 payloadlength = (Size/16) * 16;
elmot 1:d0dfbce63a89 1507
elmot 1:d0dfbce63a89 1508 /* Store the ending transfer points */
elmot 1:d0dfbce63a89 1509 hcryp->pCrypInBuffPtr = pInputData + payloadlength;
elmot 1:d0dfbce63a89 1510 hcryp->pCrypOutBuffPtr = pOutputData + payloadlength;
elmot 1:d0dfbce63a89 1511 hcryp->CrypInCount = (uint32_t)(Size - payloadlength); /* remainder */
elmot 1:d0dfbce63a89 1512
elmot 1:d0dfbce63a89 1513 /* Set the input and output addresses and start DMA transfer */
elmot 1:d0dfbce63a89 1514 /* (incomplete DMA transfer, will be wrapped up with data padding
elmot 1:d0dfbce63a89 1515 after completion of the one initiated here) */
elmot 1:d0dfbce63a89 1516 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, payloadlength, outputaddr);
elmot 1:d0dfbce63a89 1517 }
elmot 1:d0dfbce63a89 1518 }
elmot 1:d0dfbce63a89 1519 else
elmot 1:d0dfbce63a89 1520 {
elmot 1:d0dfbce63a89 1521 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 1522 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 1523 outputaddr = (uint32_t)pOutputData;
elmot 1:d0dfbce63a89 1524
elmot 1:d0dfbce63a89 1525 /* Set the input and output addresses and start DMA transfer */
elmot 1:d0dfbce63a89 1526 CRYP_GCMCMAC_SetDMAConfig(hcryp, inputaddr, Size, outputaddr);
elmot 1:d0dfbce63a89 1527 }
elmot 1:d0dfbce63a89 1528 }
elmot 1:d0dfbce63a89 1529 /*==============================*/
elmot 1:d0dfbce63a89 1530 /* GCM/GMAC or CMAC final phase */
elmot 1:d0dfbce63a89 1531 /*==============================*/
elmot 1:d0dfbce63a89 1532 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 1533 {
elmot 1:d0dfbce63a89 1534 /* If coming from header phase (GMAC or CMAC case),
elmot 1:d0dfbce63a89 1535 wait for CCF flag to be raised */
elmot 1:d0dfbce63a89 1536 if (READ_BIT(hcryp->Instance->CR, AES_CR_GCMPH) == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 1537 {
elmot 1:d0dfbce63a89 1538 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 1539 {
elmot 1:d0dfbce63a89 1540 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1541 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1542 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 1543 }
elmot 1:d0dfbce63a89 1544 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 1545 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1546 }
elmot 1:d0dfbce63a89 1547
elmot 1:d0dfbce63a89 1548 tagaddr = (uint32_t)pOutputData;
elmot 1:d0dfbce63a89 1549
elmot 1:d0dfbce63a89 1550 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
elmot 1:d0dfbce63a89 1551
elmot 1:d0dfbce63a89 1552 /* if the header and payload phases have been bypassed, AES must be enabled again */
elmot 1:d0dfbce63a89 1553 if (hcryp->Phase == HAL_CRYP_PHASE_INIT_OVER)
elmot 1:d0dfbce63a89 1554 {
elmot 1:d0dfbce63a89 1555 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 1556 }
elmot 1:d0dfbce63a89 1557
elmot 1:d0dfbce63a89 1558 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
elmot 1:d0dfbce63a89 1559 {
elmot 1:d0dfbce63a89 1560 headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */
elmot 1:d0dfbce63a89 1561 inputlength = Size * 8; /* input length in bits */
elmot 1:d0dfbce63a89 1562 /* Write the number of bits in the header on 64 bits followed by the number
elmot 1:d0dfbce63a89 1563 of bits in the payload on 64 bits as well */
elmot 1:d0dfbce63a89 1564 if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
elmot 1:d0dfbce63a89 1565 {
elmot 1:d0dfbce63a89 1566 hcryp->Instance->DINR = __RBIT((headerlength)>>32);
elmot 1:d0dfbce63a89 1567 hcryp->Instance->DINR = __RBIT(headerlength);
elmot 1:d0dfbce63a89 1568 hcryp->Instance->DINR = __RBIT((inputlength)>>32);
elmot 1:d0dfbce63a89 1569 hcryp->Instance->DINR = __RBIT(inputlength);
elmot 1:d0dfbce63a89 1570 }
elmot 1:d0dfbce63a89 1571 else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
elmot 1:d0dfbce63a89 1572 {
elmot 1:d0dfbce63a89 1573 hcryp->Instance->DINR = __REV((headerlength)>>32);
elmot 1:d0dfbce63a89 1574 hcryp->Instance->DINR = __REV(headerlength);
elmot 1:d0dfbce63a89 1575 hcryp->Instance->DINR = __REV((inputlength)>>32);
elmot 1:d0dfbce63a89 1576 hcryp->Instance->DINR = __REV(inputlength);
elmot 1:d0dfbce63a89 1577 }
elmot 1:d0dfbce63a89 1578 else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
elmot 1:d0dfbce63a89 1579 {
elmot 1:d0dfbce63a89 1580 hcryp->Instance->DINR = __ROR((headerlength)>>32, 16);
elmot 1:d0dfbce63a89 1581 hcryp->Instance->DINR = __ROR(headerlength, 16);
elmot 1:d0dfbce63a89 1582 hcryp->Instance->DINR = __ROR((inputlength)>>32, 16);
elmot 1:d0dfbce63a89 1583 hcryp->Instance->DINR = __ROR(inputlength, 16);
elmot 1:d0dfbce63a89 1584 }
elmot 1:d0dfbce63a89 1585 else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
elmot 1:d0dfbce63a89 1586 {
elmot 1:d0dfbce63a89 1587 hcryp->Instance->DINR = (uint32_t)(headerlength>>32);
elmot 1:d0dfbce63a89 1588 hcryp->Instance->DINR = (uint32_t)(headerlength);
elmot 1:d0dfbce63a89 1589 hcryp->Instance->DINR = (uint32_t)(inputlength>>32);
elmot 1:d0dfbce63a89 1590 hcryp->Instance->DINR = (uint32_t)(inputlength);
elmot 1:d0dfbce63a89 1591 }
elmot 1:d0dfbce63a89 1592 }
elmot 1:d0dfbce63a89 1593 else if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 1594 {
elmot 1:d0dfbce63a89 1595 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1596
elmot 1:d0dfbce63a89 1597 inputaddr = (uint32_t)pInputData;
elmot 1:d0dfbce63a89 1598 /* Enter the last block made of a 128-bit value formatted
elmot 1:d0dfbce63a89 1599 from the original B0 packet. */
elmot 1:d0dfbce63a89 1600 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1601 inputaddr+=4;
elmot 1:d0dfbce63a89 1602 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1603 inputaddr+=4;
elmot 1:d0dfbce63a89 1604 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1605 inputaddr+=4;
elmot 1:d0dfbce63a89 1606 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 1607 inputaddr+=4;
elmot 1:d0dfbce63a89 1608 }
elmot 1:d0dfbce63a89 1609
elmot 1:d0dfbce63a89 1610 /* No DMA transfer is required at that point therefore, the software
elmot 1:d0dfbce63a89 1611 just waits for the CCF flag to be raised. */
elmot 1:d0dfbce63a89 1612 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 1613 {
elmot 1:d0dfbce63a89 1614 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1615 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1616 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 1617 }
elmot 1:d0dfbce63a89 1618 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 1619 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1620 /* Read the Auth TAG in the IN FIFO */
elmot 1:d0dfbce63a89 1621 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 1622 tagaddr+=4;
elmot 1:d0dfbce63a89 1623 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 1624 tagaddr+=4;
elmot 1:d0dfbce63a89 1625 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 1626 tagaddr+=4;
elmot 1:d0dfbce63a89 1627 *(uint32_t*)(tagaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 1628
elmot 1:d0dfbce63a89 1629 /* Mark that the final phase is over */
elmot 1:d0dfbce63a89 1630 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
elmot 1:d0dfbce63a89 1631 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1632 /* Disable the Peripheral */
elmot 1:d0dfbce63a89 1633 __HAL_CRYP_DISABLE();
elmot 1:d0dfbce63a89 1634 }
elmot 1:d0dfbce63a89 1635 /*=================================================*/
elmot 1:d0dfbce63a89 1636 /* case incorrect hcryp->Init.GCMCMACPhase setting */
elmot 1:d0dfbce63a89 1637 /*=================================================*/
elmot 1:d0dfbce63a89 1638 else
elmot 1:d0dfbce63a89 1639 {
elmot 1:d0dfbce63a89 1640 hcryp->State = HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 1641 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1642 return HAL_ERROR;
elmot 1:d0dfbce63a89 1643 }
elmot 1:d0dfbce63a89 1644
elmot 1:d0dfbce63a89 1645 /* Process Unlocked */
elmot 1:d0dfbce63a89 1646 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1647
elmot 1:d0dfbce63a89 1648 return HAL_OK;
elmot 1:d0dfbce63a89 1649 }
elmot 1:d0dfbce63a89 1650 else
elmot 1:d0dfbce63a89 1651 {
elmot 1:d0dfbce63a89 1652 return HAL_BUSY;
elmot 1:d0dfbce63a89 1653 }
elmot 1:d0dfbce63a89 1654 }
elmot 1:d0dfbce63a89 1655
elmot 1:d0dfbce63a89 1656 /**
elmot 1:d0dfbce63a89 1657 * @}
elmot 1:d0dfbce63a89 1658 */
elmot 1:d0dfbce63a89 1659
elmot 1:d0dfbce63a89 1660 /** @defgroup CRYPEx_Exported_Functions_Group3 AES suspension/resumption functions
elmot 1:d0dfbce63a89 1661 * @brief Extended processing functions.
elmot 1:d0dfbce63a89 1662 *
elmot 1:d0dfbce63a89 1663 @verbatim
elmot 1:d0dfbce63a89 1664 ==============================================================================
elmot 1:d0dfbce63a89 1665 ##### AES extended suspension and resumption functions #####
elmot 1:d0dfbce63a89 1666 ==============================================================================
elmot 1:d0dfbce63a89 1667 [..] This section provides functions allowing to:
elmot 1:d0dfbce63a89 1668 (+) save in memory the Initialization Vector, the Key registers, the Control register or
elmot 1:d0dfbce63a89 1669 the Suspend registers when a process is suspended by a higher priority message
elmot 1:d0dfbce63a89 1670 (+) write back in CRYP hardware block the saved values listed above when the suspended
elmot 1:d0dfbce63a89 1671 lower priority message processing is resumed.
elmot 1:d0dfbce63a89 1672
elmot 1:d0dfbce63a89 1673 @endverbatim
elmot 1:d0dfbce63a89 1674 * @{
elmot 1:d0dfbce63a89 1675 */
elmot 1:d0dfbce63a89 1676
elmot 1:d0dfbce63a89 1677
elmot 1:d0dfbce63a89 1678 /**
elmot 1:d0dfbce63a89 1679 * @brief In case of message processing suspension, read the Initialization Vector.
elmot 1:d0dfbce63a89 1680 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1681 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1682 * @param Output: Pointer to the buffer containing the saved Initialization Vector.
elmot 1:d0dfbce63a89 1683 * @note This value has to be stored for reuse by writing the AES_IVRx registers
elmot 1:d0dfbce63a89 1684 * as soon as the interrupted processing has to be resumed.
elmot 1:d0dfbce63a89 1685 * Applicable to all chaining modes.
elmot 1:d0dfbce63a89 1686 * @note AES must be disabled when reading or resetting the IV values.
elmot 1:d0dfbce63a89 1687 * @retval None
elmot 1:d0dfbce63a89 1688 */
elmot 1:d0dfbce63a89 1689 void HAL_CRYPEx_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
elmot 1:d0dfbce63a89 1690 {
elmot 1:d0dfbce63a89 1691 uint32_t outputaddr = (uint32_t)Output;
elmot 1:d0dfbce63a89 1692
elmot 1:d0dfbce63a89 1693 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR3);
elmot 1:d0dfbce63a89 1694 outputaddr+=4;
elmot 1:d0dfbce63a89 1695 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR2);
elmot 1:d0dfbce63a89 1696 outputaddr+=4;
elmot 1:d0dfbce63a89 1697 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR1);
elmot 1:d0dfbce63a89 1698 outputaddr+=4;
elmot 1:d0dfbce63a89 1699 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->IVR0);
elmot 1:d0dfbce63a89 1700 }
elmot 1:d0dfbce63a89 1701
elmot 1:d0dfbce63a89 1702 /**
elmot 1:d0dfbce63a89 1703 * @brief In case of message processing resumption, rewrite the Initialization
elmot 1:d0dfbce63a89 1704 * Vector in the AES_IVRx registers.
elmot 1:d0dfbce63a89 1705 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1706 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1707 * @param Input: Pointer to the buffer containing the saved Initialization Vector to
elmot 1:d0dfbce63a89 1708 * write back in the CRYP hardware block.
elmot 1:d0dfbce63a89 1709 * @note Applicable to all chaining modes.
elmot 1:d0dfbce63a89 1710 * @note AES must be disabled when reading or resetting the IV values.
elmot 1:d0dfbce63a89 1711 * @retval None
elmot 1:d0dfbce63a89 1712 */
elmot 1:d0dfbce63a89 1713 void HAL_CRYPEx_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
elmot 1:d0dfbce63a89 1714 {
elmot 1:d0dfbce63a89 1715 uint32_t ivaddr = (uint32_t)Input;
elmot 1:d0dfbce63a89 1716
elmot 1:d0dfbce63a89 1717 hcryp->Instance->IVR3 = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1718 ivaddr+=4;
elmot 1:d0dfbce63a89 1719 hcryp->Instance->IVR2 = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1720 ivaddr+=4;
elmot 1:d0dfbce63a89 1721 hcryp->Instance->IVR1 = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1722 ivaddr+=4;
elmot 1:d0dfbce63a89 1723 hcryp->Instance->IVR0 = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1724 }
elmot 1:d0dfbce63a89 1725
elmot 1:d0dfbce63a89 1726
elmot 1:d0dfbce63a89 1727 /**
elmot 1:d0dfbce63a89 1728 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Suspend Registers.
elmot 1:d0dfbce63a89 1729 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1730 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1731 * @param Output: Pointer to the buffer containing the saved Suspend Registers.
elmot 1:d0dfbce63a89 1732 * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers
elmot 1:d0dfbce63a89 1733 * as soon as the interrupted processing has to be resumed.
elmot 1:d0dfbce63a89 1734 * @retval None
elmot 1:d0dfbce63a89 1735 */
elmot 1:d0dfbce63a89 1736 void HAL_CRYPEx_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
elmot 1:d0dfbce63a89 1737 {
elmot 1:d0dfbce63a89 1738 uint32_t outputaddr = (uint32_t)Output;
elmot 1:d0dfbce63a89 1739
elmot 1:d0dfbce63a89 1740 /* In case of GCM payload phase encryption, check that suspension can be carried out */
elmot 1:d0dfbce63a89 1741 if (READ_BIT(hcryp->Instance->CR, (AES_CR_GCMPH|AES_CR_MODE)) == (CRYP_GCM_PAYLOAD_PHASE|CRYP_ALGOMODE_ENCRYPT))
elmot 1:d0dfbce63a89 1742 {
elmot 1:d0dfbce63a89 1743 /* Ensure that Busy flag is reset */
elmot 1:d0dfbce63a89 1744 if(CRYP_WaitOnBusyFlagReset(hcryp, CRYP_BUSY_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 1745 {
elmot 1:d0dfbce63a89 1746 hcryp->ErrorCode |= HAL_CRYP_BUSY_ERROR;
elmot 1:d0dfbce63a89 1747 hcryp->State = HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 1748
elmot 1:d0dfbce63a89 1749 /* Process Unlocked */
elmot 1:d0dfbce63a89 1750 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 1751
elmot 1:d0dfbce63a89 1752 HAL_CRYP_ErrorCallback(hcryp);
elmot 1:d0dfbce63a89 1753 return ;
elmot 1:d0dfbce63a89 1754 }
elmot 1:d0dfbce63a89 1755 }
elmot 1:d0dfbce63a89 1756
elmot 1:d0dfbce63a89 1757 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP7R);
elmot 1:d0dfbce63a89 1758 outputaddr+=4;
elmot 1:d0dfbce63a89 1759 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP6R);
elmot 1:d0dfbce63a89 1760 outputaddr+=4;
elmot 1:d0dfbce63a89 1761 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP5R);
elmot 1:d0dfbce63a89 1762 outputaddr+=4;
elmot 1:d0dfbce63a89 1763 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP4R);
elmot 1:d0dfbce63a89 1764 outputaddr+=4;
elmot 1:d0dfbce63a89 1765 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP3R);
elmot 1:d0dfbce63a89 1766 outputaddr+=4;
elmot 1:d0dfbce63a89 1767 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP2R);
elmot 1:d0dfbce63a89 1768 outputaddr+=4;
elmot 1:d0dfbce63a89 1769 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP1R);
elmot 1:d0dfbce63a89 1770 outputaddr+=4;
elmot 1:d0dfbce63a89 1771 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->SUSP0R);
elmot 1:d0dfbce63a89 1772 }
elmot 1:d0dfbce63a89 1773
elmot 1:d0dfbce63a89 1774 /**
elmot 1:d0dfbce63a89 1775 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Suspend
elmot 1:d0dfbce63a89 1776 * Registers in the AES_SUSPxR registers.
elmot 1:d0dfbce63a89 1777 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1778 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1779 * @param Input: Pointer to the buffer containing the saved suspend registers to
elmot 1:d0dfbce63a89 1780 * write back in the CRYP hardware block.
elmot 1:d0dfbce63a89 1781 * @retval None
elmot 1:d0dfbce63a89 1782 */
elmot 1:d0dfbce63a89 1783 void HAL_CRYPEx_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
elmot 1:d0dfbce63a89 1784 {
elmot 1:d0dfbce63a89 1785 uint32_t ivaddr = (uint32_t)Input;
elmot 1:d0dfbce63a89 1786
elmot 1:d0dfbce63a89 1787 hcryp->Instance->SUSP7R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1788 ivaddr+=4;
elmot 1:d0dfbce63a89 1789 hcryp->Instance->SUSP6R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1790 ivaddr+=4;
elmot 1:d0dfbce63a89 1791 hcryp->Instance->SUSP5R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1792 ivaddr+=4;
elmot 1:d0dfbce63a89 1793 hcryp->Instance->SUSP4R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1794 ivaddr+=4;
elmot 1:d0dfbce63a89 1795 hcryp->Instance->SUSP3R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1796 ivaddr+=4;
elmot 1:d0dfbce63a89 1797 hcryp->Instance->SUSP2R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1798 ivaddr+=4;
elmot 1:d0dfbce63a89 1799 hcryp->Instance->SUSP1R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1800 ivaddr+=4;
elmot 1:d0dfbce63a89 1801 hcryp->Instance->SUSP0R = __REV(*(uint32_t*)(ivaddr));
elmot 1:d0dfbce63a89 1802 }
elmot 1:d0dfbce63a89 1803
elmot 1:d0dfbce63a89 1804
elmot 1:d0dfbce63a89 1805 /**
elmot 1:d0dfbce63a89 1806 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Key Registers.
elmot 1:d0dfbce63a89 1807 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1808 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1809 * @param Output: Pointer to the buffer containing the saved Key Registers.
elmot 1:d0dfbce63a89 1810 * @param KeySize: Indicates the key size (128 or 256 bits).
elmot 1:d0dfbce63a89 1811 * @note These values have to be stored for reuse by writing back the AES_KEYRx registers
elmot 1:d0dfbce63a89 1812 * as soon as the interrupted processing has to be resumed.
elmot 1:d0dfbce63a89 1813 * @retval None
elmot 1:d0dfbce63a89 1814 */
elmot 1:d0dfbce63a89 1815 void HAL_CRYPEx_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t KeySize)
elmot 1:d0dfbce63a89 1816 {
elmot 1:d0dfbce63a89 1817 uint32_t keyaddr = (uint32_t)Output;
elmot 1:d0dfbce63a89 1818
elmot 1:d0dfbce63a89 1819 if (KeySize == CRYP_KEYSIZE_256B)
elmot 1:d0dfbce63a89 1820 {
elmot 1:d0dfbce63a89 1821 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR7);
elmot 1:d0dfbce63a89 1822 keyaddr+=4;
elmot 1:d0dfbce63a89 1823 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR6);
elmot 1:d0dfbce63a89 1824 keyaddr+=4;
elmot 1:d0dfbce63a89 1825 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR5);
elmot 1:d0dfbce63a89 1826 keyaddr+=4;
elmot 1:d0dfbce63a89 1827 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR4);
elmot 1:d0dfbce63a89 1828 keyaddr+=4;
elmot 1:d0dfbce63a89 1829 }
elmot 1:d0dfbce63a89 1830
elmot 1:d0dfbce63a89 1831 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR3);
elmot 1:d0dfbce63a89 1832 keyaddr+=4;
elmot 1:d0dfbce63a89 1833 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR2);
elmot 1:d0dfbce63a89 1834 keyaddr+=4;
elmot 1:d0dfbce63a89 1835 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR1);
elmot 1:d0dfbce63a89 1836 keyaddr+=4;
elmot 1:d0dfbce63a89 1837 *(uint32_t*)(keyaddr) = __REV(hcryp->Instance->KEYR0);
elmot 1:d0dfbce63a89 1838 }
elmot 1:d0dfbce63a89 1839
elmot 1:d0dfbce63a89 1840 /**
elmot 1:d0dfbce63a89 1841 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Key
elmot 1:d0dfbce63a89 1842 * Registers in the AES_KEYRx registers.
elmot 1:d0dfbce63a89 1843 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1844 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1845 * @param Input: Pointer to the buffer containing the saved key registers to
elmot 1:d0dfbce63a89 1846 * write back in the CRYP hardware block.
elmot 1:d0dfbce63a89 1847 * @param KeySize: Indicates the key size (128 or 256 bits)
elmot 1:d0dfbce63a89 1848 * @retval None
elmot 1:d0dfbce63a89 1849 */
elmot 1:d0dfbce63a89 1850 void HAL_CRYPEx_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint32_t KeySize)
elmot 1:d0dfbce63a89 1851 {
elmot 1:d0dfbce63a89 1852 uint32_t keyaddr = (uint32_t)Input;
elmot 1:d0dfbce63a89 1853
elmot 1:d0dfbce63a89 1854 if (KeySize == CRYP_KEYSIZE_256B)
elmot 1:d0dfbce63a89 1855 {
elmot 1:d0dfbce63a89 1856 hcryp->Instance->KEYR7 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1857 keyaddr+=4;
elmot 1:d0dfbce63a89 1858 hcryp->Instance->KEYR6 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1859 keyaddr+=4;
elmot 1:d0dfbce63a89 1860 hcryp->Instance->KEYR5 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1861 keyaddr+=4;
elmot 1:d0dfbce63a89 1862 hcryp->Instance->KEYR4 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1863 keyaddr+=4;
elmot 1:d0dfbce63a89 1864 }
elmot 1:d0dfbce63a89 1865
elmot 1:d0dfbce63a89 1866 hcryp->Instance->KEYR3 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1867 keyaddr+=4;
elmot 1:d0dfbce63a89 1868 hcryp->Instance->KEYR2 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1869 keyaddr+=4;
elmot 1:d0dfbce63a89 1870 hcryp->Instance->KEYR1 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1871 keyaddr+=4;
elmot 1:d0dfbce63a89 1872 hcryp->Instance->KEYR0 = __REV(*(uint32_t*)(keyaddr));
elmot 1:d0dfbce63a89 1873 }
elmot 1:d0dfbce63a89 1874
elmot 1:d0dfbce63a89 1875
elmot 1:d0dfbce63a89 1876 /**
elmot 1:d0dfbce63a89 1877 * @brief In case of message GCM/GMAC or CMAC processing suspension, read the Control Register.
elmot 1:d0dfbce63a89 1878 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1879 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1880 * @param Output: Pointer to the buffer containing the saved Control Register.
elmot 1:d0dfbce63a89 1881 * @note This values has to be stored for reuse by writing back the AES_CR register
elmot 1:d0dfbce63a89 1882 * as soon as the interrupted processing has to be resumed.
elmot 1:d0dfbce63a89 1883 * @retval None
elmot 1:d0dfbce63a89 1884 */
elmot 1:d0dfbce63a89 1885 void HAL_CRYPEx_Read_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Output)
elmot 1:d0dfbce63a89 1886 {
elmot 1:d0dfbce63a89 1887 *(uint32_t*)(Output) = hcryp->Instance->CR;
elmot 1:d0dfbce63a89 1888 }
elmot 1:d0dfbce63a89 1889
elmot 1:d0dfbce63a89 1890 /**
elmot 1:d0dfbce63a89 1891 * @brief In case of message GCM/GMAC or CMAC processing resumption, rewrite the Control
elmot 1:d0dfbce63a89 1892 * Registers in the AES_CR register.
elmot 1:d0dfbce63a89 1893 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1894 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1895 * @param Input: Pointer to the buffer containing the saved Control Register to
elmot 1:d0dfbce63a89 1896 * write back in the CRYP hardware block.
elmot 1:d0dfbce63a89 1897 * @retval None
elmot 1:d0dfbce63a89 1898 */
elmot 1:d0dfbce63a89 1899 void HAL_CRYPEx_Write_ControlRegister(CRYP_HandleTypeDef *hcryp, uint8_t* Input)
elmot 1:d0dfbce63a89 1900 {
elmot 1:d0dfbce63a89 1901 hcryp->Instance->CR = *(uint32_t*)(Input);
elmot 1:d0dfbce63a89 1902 /* At the same time, set handle state back to READY to be able to resume the AES calculations
elmot 1:d0dfbce63a89 1903 without the processing APIs returning HAL_BUSY when called. */
elmot 1:d0dfbce63a89 1904 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1905 }
elmot 1:d0dfbce63a89 1906
elmot 1:d0dfbce63a89 1907 /**
elmot 1:d0dfbce63a89 1908 * @brief Request CRYP processing suspension when in polling or interruption mode.
elmot 1:d0dfbce63a89 1909 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 1910 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 1911 * @note Set the handle field SuspendRequest to the appropriate value so that
elmot 1:d0dfbce63a89 1912 * the on-going CRYP processing is suspended as soon as the required
elmot 1:d0dfbce63a89 1913 * conditions are met.
elmot 1:d0dfbce63a89 1914 * @note It is advised not to suspend the CRYP processing when the DMA controller
elmot 1:d0dfbce63a89 1915 * is managing the data transfer
elmot 1:d0dfbce63a89 1916 * @retval None
elmot 1:d0dfbce63a89 1917 */
elmot 1:d0dfbce63a89 1918 void HAL_CRYPEx_ProcessSuspend(CRYP_HandleTypeDef *hcryp)
elmot 1:d0dfbce63a89 1919 {
elmot 1:d0dfbce63a89 1920 /* Set Handle Suspend Request field */
elmot 1:d0dfbce63a89 1921 hcryp->SuspendRequest = HAL_CRYP_SUSPEND;
elmot 1:d0dfbce63a89 1922 }
elmot 1:d0dfbce63a89 1923
elmot 1:d0dfbce63a89 1924 /**
elmot 1:d0dfbce63a89 1925 * @}
elmot 1:d0dfbce63a89 1926 */
elmot 1:d0dfbce63a89 1927
elmot 1:d0dfbce63a89 1928 /**
elmot 1:d0dfbce63a89 1929 * @}
elmot 1:d0dfbce63a89 1930 */
elmot 1:d0dfbce63a89 1931
elmot 1:d0dfbce63a89 1932 /** @addtogroup CRYPEx_Private_Functions
elmot 1:d0dfbce63a89 1933 * @{
elmot 1:d0dfbce63a89 1934 */
elmot 1:d0dfbce63a89 1935
elmot 1:d0dfbce63a89 1936 /**
elmot 1:d0dfbce63a89 1937 * @brief DMA CRYP Input Data process complete callback
elmot 1:d0dfbce63a89 1938 * for GCM, GMAC or CMAC chainging modes.
elmot 1:d0dfbce63a89 1939 * @note Specific setting of hcryp fields are required only
elmot 1:d0dfbce63a89 1940 * in the case of header phase where no output data DMA
elmot 1:d0dfbce63a89 1941 * transfer is on-going (only input data transfer is enabled
elmot 1:d0dfbce63a89 1942 * in such a case).
elmot 1:d0dfbce63a89 1943 * @param hdma: DMA handle.
elmot 1:d0dfbce63a89 1944 * @retval None
elmot 1:d0dfbce63a89 1945 */
elmot 1:d0dfbce63a89 1946 static void CRYP_GCMCMAC_DMAInCplt(DMA_HandleTypeDef *hdma)
elmot 1:d0dfbce63a89 1947 {
elmot 1:d0dfbce63a89 1948 uint32_t difflength = 0;
elmot 1:d0dfbce63a89 1949
elmot 1:d0dfbce63a89 1950 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
elmot 1:d0dfbce63a89 1951
elmot 1:d0dfbce63a89 1952 /* Disable the DMA transfer for input request */
elmot 1:d0dfbce63a89 1953 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
elmot 1:d0dfbce63a89 1954
elmot 1:d0dfbce63a89 1955 if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 1956 {
elmot 1:d0dfbce63a89 1957
elmot 1:d0dfbce63a89 1958 if (hcryp->CrypInCount != 0)
elmot 1:d0dfbce63a89 1959 {
elmot 1:d0dfbce63a89 1960 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
elmot 1:d0dfbce63a89 1961 difflength = hcryp->CrypInCount;
elmot 1:d0dfbce63a89 1962 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 1963
elmot 1:d0dfbce63a89 1964 CRYP_Padding(hcryp, difflength, CRYP_POLLING_OFF);
elmot 1:d0dfbce63a89 1965 }
elmot 1:d0dfbce63a89 1966 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 1967 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 1968 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
elmot 1:d0dfbce63a89 1969 }
elmot 1:d0dfbce63a89 1970 /* CCF flag indicating header phase AES processing completion
elmot 1:d0dfbce63a89 1971 will be checked at the start of the next phase:
elmot 1:d0dfbce63a89 1972 - payload phase (GCM)
elmot 1:d0dfbce63a89 1973 - final phase (GMAC or CMAC).
elmot 1:d0dfbce63a89 1974 This allows to avoid the Wait on Flag within the IRQ handling. */
elmot 1:d0dfbce63a89 1975
elmot 1:d0dfbce63a89 1976 /* Call input data transfer complete callback */
elmot 1:d0dfbce63a89 1977 HAL_CRYP_InCpltCallback(hcryp);
elmot 1:d0dfbce63a89 1978 }
elmot 1:d0dfbce63a89 1979
elmot 1:d0dfbce63a89 1980 /**
elmot 1:d0dfbce63a89 1981 * @brief DMA CRYP Output Data process complete callback
elmot 1:d0dfbce63a89 1982 * for GCM, GMAC or CMAC chainging modes.
elmot 1:d0dfbce63a89 1983 * @note This callback is called only in the payload phase.
elmot 1:d0dfbce63a89 1984 * @param hdma: DMA handle.
elmot 1:d0dfbce63a89 1985 * @retval None
elmot 1:d0dfbce63a89 1986 */
elmot 1:d0dfbce63a89 1987 static void CRYP_GCMCMAC_DMAOutCplt(DMA_HandleTypeDef *hdma)
elmot 1:d0dfbce63a89 1988 {
elmot 1:d0dfbce63a89 1989 uint32_t difflength = 0;
elmot 1:d0dfbce63a89 1990 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
elmot 1:d0dfbce63a89 1991
elmot 1:d0dfbce63a89 1992 /* Disable the DMA transfer for output request */
elmot 1:d0dfbce63a89 1993 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
elmot 1:d0dfbce63a89 1994
elmot 1:d0dfbce63a89 1995 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 1996 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 1997
elmot 1:d0dfbce63a89 1998 /* Initiate additional transfer to wrap-up data feeding to the IP */
elmot 1:d0dfbce63a89 1999 if (hcryp->CrypInCount != 0)
elmot 1:d0dfbce63a89 2000 {
elmot 1:d0dfbce63a89 2001 /* Last block is now entered in polling mode, no actual gain in resorting to DMA */
elmot 1:d0dfbce63a89 2002 difflength = hcryp->CrypInCount;
elmot 1:d0dfbce63a89 2003 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 2004
elmot 1:d0dfbce63a89 2005 CRYP_Padding(hcryp, difflength, CRYP_POLLING_ON);
elmot 1:d0dfbce63a89 2006 }
elmot 1:d0dfbce63a89 2007
elmot 1:d0dfbce63a89 2008 /* Change the CRYP state to ready */
elmot 1:d0dfbce63a89 2009 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2010 /* Mark that the payload phase is over */
elmot 1:d0dfbce63a89 2011 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
elmot 1:d0dfbce63a89 2012
elmot 1:d0dfbce63a89 2013 /* Call output data transfer complete callback */
elmot 1:d0dfbce63a89 2014 HAL_CRYP_OutCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2015 }
elmot 1:d0dfbce63a89 2016
elmot 1:d0dfbce63a89 2017 /**
elmot 1:d0dfbce63a89 2018 * @brief DMA CRYP communication error callback
elmot 1:d0dfbce63a89 2019 * for GCM, GMAC or CMAC chainging modes.
elmot 1:d0dfbce63a89 2020 * @param hdma: DMA handle
elmot 1:d0dfbce63a89 2021 * @retval None
elmot 1:d0dfbce63a89 2022 */
elmot 1:d0dfbce63a89 2023 static void CRYP_GCMCMAC_DMAError(DMA_HandleTypeDef *hdma)
elmot 1:d0dfbce63a89 2024 {
elmot 1:d0dfbce63a89 2025 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
elmot 1:d0dfbce63a89 2026
elmot 1:d0dfbce63a89 2027 hcryp->State= HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 2028 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
elmot 1:d0dfbce63a89 2029 HAL_CRYP_ErrorCallback(hcryp);
elmot 1:d0dfbce63a89 2030 /* Clear Error Flag */
elmot 1:d0dfbce63a89 2031 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
elmot 1:d0dfbce63a89 2032 }
elmot 1:d0dfbce63a89 2033
elmot 1:d0dfbce63a89 2034
elmot 1:d0dfbce63a89 2035
elmot 1:d0dfbce63a89 2036 /**
elmot 1:d0dfbce63a89 2037 * @brief Handle CRYP block input/output data handling under interruption
elmot 1:d0dfbce63a89 2038 * for GCM, GMAC or CMAC chainging modes.
elmot 1:d0dfbce63a89 2039 * @note The function is called under interruption only, once
elmot 1:d0dfbce63a89 2040 * interruptions have been enabled by HAL_CRYPEx_AES_Auth_IT().
elmot 1:d0dfbce63a89 2041 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2042 * the configuration information for CRYP module
elmot 1:d0dfbce63a89 2043 * @retval HAL status
elmot 1:d0dfbce63a89 2044 */
elmot 1:d0dfbce63a89 2045 HAL_StatusTypeDef CRYP_AES_Auth_IT(CRYP_HandleTypeDef *hcryp)
elmot 1:d0dfbce63a89 2046 {
elmot 1:d0dfbce63a89 2047 uint32_t inputaddr = 0x0;
elmot 1:d0dfbce63a89 2048 uint32_t outputaddr = 0x0;
elmot 1:d0dfbce63a89 2049 uint32_t index = 0x0;
elmot 1:d0dfbce63a89 2050 uint32_t addhoc_process = 0;
elmot 1:d0dfbce63a89 2051 uint32_t difflength = 0;
elmot 1:d0dfbce63a89 2052 uint32_t difflengthmod4 = 0;
elmot 1:d0dfbce63a89 2053 uint32_t mask[3] = {0x0FF, 0x0FFFF, 0x0FFFFFF};
elmot 1:d0dfbce63a89 2054 uint32_t intermediate_data[4] = {0};
elmot 1:d0dfbce63a89 2055
elmot 1:d0dfbce63a89 2056 if(hcryp->State == HAL_CRYP_STATE_BUSY)
elmot 1:d0dfbce63a89 2057 {
elmot 1:d0dfbce63a89 2058 /*=====================*/
elmot 1:d0dfbce63a89 2059 /* GCM/GMAC init phase */
elmot 1:d0dfbce63a89 2060 /*=====================*/
elmot 1:d0dfbce63a89 2061 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_INIT_PHASE)
elmot 1:d0dfbce63a89 2062 {
elmot 1:d0dfbce63a89 2063 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2064 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2065 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2066 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2067 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2068 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2069
elmot 1:d0dfbce63a89 2070 /* Mark that the initialization phase is over */
elmot 1:d0dfbce63a89 2071 hcryp->Phase = HAL_CRYP_PHASE_INIT_OVER;
elmot 1:d0dfbce63a89 2072
elmot 1:d0dfbce63a89 2073 /* Process Unlocked */
elmot 1:d0dfbce63a89 2074 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2075 /* Call computation complete callback */
elmot 1:d0dfbce63a89 2076 HAL_CRYPEx_ComputationCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2077 return HAL_OK;
elmot 1:d0dfbce63a89 2078 }
elmot 1:d0dfbce63a89 2079 /*===============================*/
elmot 1:d0dfbce63a89 2080 /* GCM/GMAC or CMAC header phase */
elmot 1:d0dfbce63a89 2081 /*===============================*/
elmot 1:d0dfbce63a89 2082 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_HEADER_PHASE)
elmot 1:d0dfbce63a89 2083 {
elmot 1:d0dfbce63a89 2084 /* Check if all input header data have been entered */
elmot 1:d0dfbce63a89 2085 if (hcryp->CrypInCount == 0)
elmot 1:d0dfbce63a89 2086 {
elmot 1:d0dfbce63a89 2087 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2088 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2089 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2090 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2091 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2092 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2093 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 2094 hcryp->Phase = HAL_CRYP_PHASE_HEADER_OVER;
elmot 1:d0dfbce63a89 2095
elmot 1:d0dfbce63a89 2096 /* Process Unlocked */
elmot 1:d0dfbce63a89 2097 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2098
elmot 1:d0dfbce63a89 2099 /* Call computation complete callback */
elmot 1:d0dfbce63a89 2100 HAL_CRYPEx_ComputationCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2101
elmot 1:d0dfbce63a89 2102 return HAL_OK;
elmot 1:d0dfbce63a89 2103 }
elmot 1:d0dfbce63a89 2104 /* If suspension flag has been raised, suspend processing */
elmot 1:d0dfbce63a89 2105 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
elmot 1:d0dfbce63a89 2106 {
elmot 1:d0dfbce63a89 2107 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2108 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2109
elmot 1:d0dfbce63a89 2110 /* reset SuspendRequest */
elmot 1:d0dfbce63a89 2111 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
elmot 1:d0dfbce63a89 2112 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2113 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2114 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2115 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
elmot 1:d0dfbce63a89 2116 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 2117 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
elmot 1:d0dfbce63a89 2118
elmot 1:d0dfbce63a89 2119 /* Process Unlocked */
elmot 1:d0dfbce63a89 2120 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2121
elmot 1:d0dfbce63a89 2122 return HAL_OK;
elmot 1:d0dfbce63a89 2123 }
elmot 1:d0dfbce63a89 2124 else /* Carry on feeding input data to the CRYP hardware block */
elmot 1:d0dfbce63a89 2125 {
elmot 1:d0dfbce63a89 2126 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2127 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2128 /* Get the last Input data address */
elmot 1:d0dfbce63a89 2129 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
elmot 1:d0dfbce63a89 2130
elmot 1:d0dfbce63a89 2131 /* Increment/decrement instance pointer/counter */
elmot 1:d0dfbce63a89 2132 if (hcryp->CrypInCount < 16)
elmot 1:d0dfbce63a89 2133 {
elmot 1:d0dfbce63a89 2134 difflength = hcryp->CrypInCount;
elmot 1:d0dfbce63a89 2135 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 2136 addhoc_process = 1;
elmot 1:d0dfbce63a89 2137 difflengthmod4 = difflength%4;
elmot 1:d0dfbce63a89 2138 }
elmot 1:d0dfbce63a89 2139 else
elmot 1:d0dfbce63a89 2140 {
elmot 1:d0dfbce63a89 2141 hcryp->pCrypInBuffPtr += 16;
elmot 1:d0dfbce63a89 2142 hcryp->CrypInCount -= 16;
elmot 1:d0dfbce63a89 2143 }
elmot 1:d0dfbce63a89 2144
elmot 1:d0dfbce63a89 2145 if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)
elmot 1:d0dfbce63a89 2146 {
elmot 1:d0dfbce63a89 2147 if (hcryp->CrypInCount == hcryp->Init.HeaderSize)
elmot 1:d0dfbce63a89 2148 {
elmot 1:d0dfbce63a89 2149 /* All B blocks will have been entered after the next
elmot 1:d0dfbce63a89 2150 four DINR writing, so point at header buffer for
elmot 1:d0dfbce63a89 2151 the next iteration */
elmot 1:d0dfbce63a89 2152 hcryp->pCrypInBuffPtr = hcryp->Init.Header;
elmot 1:d0dfbce63a89 2153 }
elmot 1:d0dfbce63a89 2154 }
elmot 1:d0dfbce63a89 2155
elmot 1:d0dfbce63a89 2156 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 2157 if (addhoc_process == 0)
elmot 1:d0dfbce63a89 2158 {
elmot 1:d0dfbce63a89 2159 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2160 inputaddr+=4;
elmot 1:d0dfbce63a89 2161 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2162 inputaddr+=4;
elmot 1:d0dfbce63a89 2163 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2164 inputaddr+=4;
elmot 1:d0dfbce63a89 2165 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2166 }
elmot 1:d0dfbce63a89 2167 else
elmot 1:d0dfbce63a89 2168 {
elmot 1:d0dfbce63a89 2169 /* Header remainder has size less than 128 bits */
elmot 1:d0dfbce63a89 2170 /* Enter complete words when possible */
elmot 1:d0dfbce63a89 2171 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 2172 {
elmot 1:d0dfbce63a89 2173 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 2174 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2175 inputaddr+=4;
elmot 1:d0dfbce63a89 2176 }
elmot 1:d0dfbce63a89 2177 /* Enter incomplete word padded with zeroes if applicable
elmot 1:d0dfbce63a89 2178 (case of header length not a multiple of 32-bits) */
elmot 1:d0dfbce63a89 2179 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 2180 {
elmot 1:d0dfbce63a89 2181 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
elmot 1:d0dfbce63a89 2182 }
elmot 1:d0dfbce63a89 2183 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
elmot 1:d0dfbce63a89 2184 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 2185 {
elmot 1:d0dfbce63a89 2186 hcryp->Instance->DINR = 0;
elmot 1:d0dfbce63a89 2187 }
elmot 1:d0dfbce63a89 2188 }
elmot 1:d0dfbce63a89 2189
elmot 1:d0dfbce63a89 2190 return HAL_OK;
elmot 1:d0dfbce63a89 2191 }
elmot 1:d0dfbce63a89 2192 }
elmot 1:d0dfbce63a89 2193 /*========================*/
elmot 1:d0dfbce63a89 2194 /* GCM/GMAC payload phase */
elmot 1:d0dfbce63a89 2195 /*========================*/
elmot 1:d0dfbce63a89 2196 else if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 2197 {
elmot 1:d0dfbce63a89 2198 /* Get the last output data address */
elmot 1:d0dfbce63a89 2199 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
elmot 1:d0dfbce63a89 2200
elmot 1:d0dfbce63a89 2201 /* Specific handling to manage payload size less than 128 bits
elmot 1:d0dfbce63a89 2202 when GCM encryption or decryption is selected.
elmot 1:d0dfbce63a89 2203 Check here if the last block output data are read */
elmot 1:d0dfbce63a89 2204 if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC) && \
elmot 1:d0dfbce63a89 2205 (hcryp->CrypOutCount < 16) && \
elmot 1:d0dfbce63a89 2206 (hcryp->CrypOutCount > 0))
elmot 1:d0dfbce63a89 2207 {
elmot 1:d0dfbce63a89 2208 addhoc_process = 1;
elmot 1:d0dfbce63a89 2209 difflength = hcryp->CrypOutCount;
elmot 1:d0dfbce63a89 2210 difflengthmod4 = difflength%4;
elmot 1:d0dfbce63a89 2211 hcryp->CrypOutCount = 0; /* mark that no more output data will be needed */
elmot 1:d0dfbce63a89 2212 /* Retrieve intermediate data */
elmot 1:d0dfbce63a89 2213 for(index=0; index < 4; index ++)
elmot 1:d0dfbce63a89 2214 {
elmot 1:d0dfbce63a89 2215 intermediate_data[index] = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2216 }
elmot 1:d0dfbce63a89 2217 /* Retrieve last words of cyphered data */
elmot 1:d0dfbce63a89 2218 /* First, retrieve complete output words */
elmot 1:d0dfbce63a89 2219 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 2220 {
elmot 1:d0dfbce63a89 2221 *(uint32_t*)(outputaddr) = intermediate_data[index];
elmot 1:d0dfbce63a89 2222 outputaddr+=4;
elmot 1:d0dfbce63a89 2223 }
elmot 1:d0dfbce63a89 2224 /* Next, retrieve partial output word if applicable;
elmot 1:d0dfbce63a89 2225 at the same time, start masking intermediate data
elmot 1:d0dfbce63a89 2226 with a mask of zeros of same size than the padding
elmot 1:d0dfbce63a89 2227 applied to the last block of payload */
elmot 1:d0dfbce63a89 2228 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 2229 {
elmot 1:d0dfbce63a89 2230 intermediate_data[difflength/4] &= mask[difflengthmod4-1];
elmot 1:d0dfbce63a89 2231 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4];
elmot 1:d0dfbce63a89 2232 }
elmot 1:d0dfbce63a89 2233
elmot 1:d0dfbce63a89 2234 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
elmot 1:d0dfbce63a89 2235 {
elmot 1:d0dfbce63a89 2236 /* Change again CHMOD configuration to GCM mode */
elmot 1:d0dfbce63a89 2237 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);
elmot 1:d0dfbce63a89 2238
elmot 1:d0dfbce63a89 2239 /* Select FINAL phase */
elmot 1:d0dfbce63a89 2240 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
elmot 1:d0dfbce63a89 2241
elmot 1:d0dfbce63a89 2242 /* Before inserting the intermediate data, carry on masking operation
elmot 1:d0dfbce63a89 2243 with a mask of zeros of same size than the padding applied to the last block of payload */
elmot 1:d0dfbce63a89 2244 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 2245 {
elmot 1:d0dfbce63a89 2246 intermediate_data[(difflength+3)/4+index] = 0;
elmot 1:d0dfbce63a89 2247 }
elmot 1:d0dfbce63a89 2248
elmot 1:d0dfbce63a89 2249 /* Insert intermediate data to trigger an additional DOUTR reading round */
elmot 1:d0dfbce63a89 2250 /* Clear Computation Complete Flag before entering new block */
elmot 1:d0dfbce63a89 2251 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2252 for(index=0; index < 4; index ++)
elmot 1:d0dfbce63a89 2253 {
elmot 1:d0dfbce63a89 2254 hcryp->Instance->DINR = intermediate_data[index];
elmot 1:d0dfbce63a89 2255 }
elmot 1:d0dfbce63a89 2256 }
elmot 1:d0dfbce63a89 2257 else
elmot 1:d0dfbce63a89 2258 {
elmot 1:d0dfbce63a89 2259 /* Deciphering case: payload phase is now over */
elmot 1:d0dfbce63a89 2260 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2261 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2262 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2263 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2264 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2265 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2266 /* Mark that the payload phase is over */
elmot 1:d0dfbce63a89 2267 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
elmot 1:d0dfbce63a89 2268
elmot 1:d0dfbce63a89 2269 /* Process Unlocked */
elmot 1:d0dfbce63a89 2270 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2271
elmot 1:d0dfbce63a89 2272 /* Call computation complete callback */
elmot 1:d0dfbce63a89 2273 HAL_CRYPEx_ComputationCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2274 }
elmot 1:d0dfbce63a89 2275 return HAL_OK;
elmot 1:d0dfbce63a89 2276 }
elmot 1:d0dfbce63a89 2277 else
elmot 1:d0dfbce63a89 2278 {
elmot 1:d0dfbce63a89 2279 if (hcryp->CrypOutCount != 0)
elmot 1:d0dfbce63a89 2280 {
elmot 1:d0dfbce63a89 2281 /* Usual case (different than GCM last block < 128 bits ciphering) */
elmot 1:d0dfbce63a89 2282 /* Retrieve the last block available from the CRYP hardware block:
elmot 1:d0dfbce63a89 2283 read the output block from the Data Output Register */
elmot 1:d0dfbce63a89 2284 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2285 outputaddr+=4;
elmot 1:d0dfbce63a89 2286 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2287 outputaddr+=4;
elmot 1:d0dfbce63a89 2288 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2289 outputaddr+=4;
elmot 1:d0dfbce63a89 2290 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2291
elmot 1:d0dfbce63a89 2292 /* Increment/decrement instance pointer/counter */
elmot 1:d0dfbce63a89 2293 hcryp->pCrypOutBuffPtr += 16;
elmot 1:d0dfbce63a89 2294 hcryp->CrypOutCount -= 16;
elmot 1:d0dfbce63a89 2295 }
elmot 1:d0dfbce63a89 2296 else
elmot 1:d0dfbce63a89 2297 {
elmot 1:d0dfbce63a89 2298 /* Software work-around: additional DOUTR reading round to discard the data */
elmot 1:d0dfbce63a89 2299 for(index=0; index < 4; index ++)
elmot 1:d0dfbce63a89 2300 {
elmot 1:d0dfbce63a89 2301 intermediate_data[index] = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2302 }
elmot 1:d0dfbce63a89 2303
elmot 1:d0dfbce63a89 2304 }
elmot 1:d0dfbce63a89 2305 }
elmot 1:d0dfbce63a89 2306
elmot 1:d0dfbce63a89 2307 /* Check if all output text has been retrieved */
elmot 1:d0dfbce63a89 2308 if (hcryp->CrypOutCount == 0)
elmot 1:d0dfbce63a89 2309 {
elmot 1:d0dfbce63a89 2310 /* Make sure that software-work around is not running before disabling
elmot 1:d0dfbce63a89 2311 the interruptions (indeed, if software work-around is running, the
elmot 1:d0dfbce63a89 2312 interruptions must not be disabled to allow the additional DOUTR
elmot 1:d0dfbce63a89 2313 reading round */
elmot 1:d0dfbce63a89 2314 if (addhoc_process == 0)
elmot 1:d0dfbce63a89 2315 {
elmot 1:d0dfbce63a89 2316 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2317 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2318 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2319 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2320 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2321 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2322 /* Mark that the payload phase is over */
elmot 1:d0dfbce63a89 2323 hcryp->Phase = HAL_CRYP_PHASE_PAYLOAD_OVER;
elmot 1:d0dfbce63a89 2324
elmot 1:d0dfbce63a89 2325 /* Process Unlocked */
elmot 1:d0dfbce63a89 2326 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2327
elmot 1:d0dfbce63a89 2328 /* Call computation complete callback */
elmot 1:d0dfbce63a89 2329 HAL_CRYPEx_ComputationCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2330 }
elmot 1:d0dfbce63a89 2331
elmot 1:d0dfbce63a89 2332 return HAL_OK;
elmot 1:d0dfbce63a89 2333 }
elmot 1:d0dfbce63a89 2334 /* If suspension flag has been raised, suspend processing */
elmot 1:d0dfbce63a89 2335 else if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND)
elmot 1:d0dfbce63a89 2336 {
elmot 1:d0dfbce63a89 2337 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2338 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2339
elmot 1:d0dfbce63a89 2340 /* reset SuspendRequest */
elmot 1:d0dfbce63a89 2341 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
elmot 1:d0dfbce63a89 2342 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2343 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2344 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2345 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
elmot 1:d0dfbce63a89 2346 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 2347 hcryp->Phase = HAL_CRYP_PHASE_HEADER_SUSPENDED;
elmot 1:d0dfbce63a89 2348
elmot 1:d0dfbce63a89 2349 /* Process Unlocked */
elmot 1:d0dfbce63a89 2350 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2351
elmot 1:d0dfbce63a89 2352 return HAL_OK;
elmot 1:d0dfbce63a89 2353 }
elmot 1:d0dfbce63a89 2354 else /* Output data are still expected, carry on feeding the CRYP
elmot 1:d0dfbce63a89 2355 hardware block with input data */
elmot 1:d0dfbce63a89 2356 {
elmot 1:d0dfbce63a89 2357 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2358 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2359 /* Get the last Input data address */
elmot 1:d0dfbce63a89 2360 inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
elmot 1:d0dfbce63a89 2361
elmot 1:d0dfbce63a89 2362 /* Usual input data feeding case */
elmot 1:d0dfbce63a89 2363 if (hcryp->CrypInCount < 16)
elmot 1:d0dfbce63a89 2364 {
elmot 1:d0dfbce63a89 2365 difflength = (uint32_t) (hcryp->CrypInCount);
elmot 1:d0dfbce63a89 2366 difflengthmod4 = difflength%4;
elmot 1:d0dfbce63a89 2367 hcryp->CrypInCount = 0;
elmot 1:d0dfbce63a89 2368
elmot 1:d0dfbce63a89 2369 /* Software workaround applied to GCM encryption only */
elmot 1:d0dfbce63a89 2370 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
elmot 1:d0dfbce63a89 2371 {
elmot 1:d0dfbce63a89 2372 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
elmot 1:d0dfbce63a89 2373 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
elmot 1:d0dfbce63a89 2374 }
elmot 1:d0dfbce63a89 2375
elmot 1:d0dfbce63a89 2376 /* Insert the last block (which size is inferior to 128 bits) padded with zeroes
elmot 1:d0dfbce63a89 2377 to have a complete block of 128 bits */
elmot 1:d0dfbce63a89 2378 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 2379 {
elmot 1:d0dfbce63a89 2380 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 2381 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2382 inputaddr+=4;
elmot 1:d0dfbce63a89 2383 }
elmot 1:d0dfbce63a89 2384 /* If required, manage input data size not multiple of 32 bits */
elmot 1:d0dfbce63a89 2385 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 2386 {
elmot 1:d0dfbce63a89 2387 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
elmot 1:d0dfbce63a89 2388 }
elmot 1:d0dfbce63a89 2389 /* Wrap-up in padding with zero-words if applicable */
elmot 1:d0dfbce63a89 2390 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 2391 {
elmot 1:d0dfbce63a89 2392 hcryp->Instance->DINR = 0;
elmot 1:d0dfbce63a89 2393 }
elmot 1:d0dfbce63a89 2394
elmot 1:d0dfbce63a89 2395 }
elmot 1:d0dfbce63a89 2396 else
elmot 1:d0dfbce63a89 2397 {
elmot 1:d0dfbce63a89 2398 hcryp->pCrypInBuffPtr += 16;
elmot 1:d0dfbce63a89 2399 hcryp->CrypInCount -= 16;
elmot 1:d0dfbce63a89 2400
elmot 1:d0dfbce63a89 2401 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 2402 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2403 inputaddr+=4;
elmot 1:d0dfbce63a89 2404 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2405 inputaddr+=4;
elmot 1:d0dfbce63a89 2406 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2407 inputaddr+=4;
elmot 1:d0dfbce63a89 2408 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2409 }
elmot 1:d0dfbce63a89 2410
elmot 1:d0dfbce63a89 2411
elmot 1:d0dfbce63a89 2412 return HAL_OK;
elmot 1:d0dfbce63a89 2413 }
elmot 1:d0dfbce63a89 2414 }
elmot 1:d0dfbce63a89 2415 /*==============================*/
elmot 1:d0dfbce63a89 2416 /* GCM/GMAC or CMAC final phase */
elmot 1:d0dfbce63a89 2417 /*==============================*/
elmot 1:d0dfbce63a89 2418 else if (hcryp->Init.GCMCMACPhase == CRYP_GCMCMAC_FINAL_PHASE)
elmot 1:d0dfbce63a89 2419 {
elmot 1:d0dfbce63a89 2420 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2421 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2422
elmot 1:d0dfbce63a89 2423 /* Get the last output data address */
elmot 1:d0dfbce63a89 2424 outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
elmot 1:d0dfbce63a89 2425
elmot 1:d0dfbce63a89 2426 /* Retrieve the last expected data from the CRYP hardware block:
elmot 1:d0dfbce63a89 2427 read the output block from the Data Output Register */
elmot 1:d0dfbce63a89 2428 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2429 outputaddr+=4;
elmot 1:d0dfbce63a89 2430 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2431 outputaddr+=4;
elmot 1:d0dfbce63a89 2432 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2433 outputaddr+=4;
elmot 1:d0dfbce63a89 2434 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2435
elmot 1:d0dfbce63a89 2436 /* Disable Computation Complete Flag and Errors Interrupts */
elmot 1:d0dfbce63a89 2437 __HAL_CRYP_DISABLE_IT(CRYP_IT_CCFIE|CRYP_IT_ERRIE);
elmot 1:d0dfbce63a89 2438 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2439 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2440 /* Mark that the header phase is over */
elmot 1:d0dfbce63a89 2441 hcryp->Phase = HAL_CRYP_PHASE_FINAL_OVER;
elmot 1:d0dfbce63a89 2442
elmot 1:d0dfbce63a89 2443 /* Disable the Peripheral */
elmot 1:d0dfbce63a89 2444 __HAL_CRYP_DISABLE();
elmot 1:d0dfbce63a89 2445 /* Process Unlocked */
elmot 1:d0dfbce63a89 2446 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2447
elmot 1:d0dfbce63a89 2448 /* Call computation complete callback */
elmot 1:d0dfbce63a89 2449 HAL_CRYPEx_ComputationCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2450
elmot 1:d0dfbce63a89 2451 return HAL_OK;
elmot 1:d0dfbce63a89 2452 }
elmot 1:d0dfbce63a89 2453 else
elmot 1:d0dfbce63a89 2454 {
elmot 1:d0dfbce63a89 2455 /* Clear Computation Complete Flag */
elmot 1:d0dfbce63a89 2456 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2457 hcryp->State = HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 2458 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2459 return HAL_ERROR;
elmot 1:d0dfbce63a89 2460 }
elmot 1:d0dfbce63a89 2461 }
elmot 1:d0dfbce63a89 2462 else
elmot 1:d0dfbce63a89 2463 {
elmot 1:d0dfbce63a89 2464 return HAL_BUSY;
elmot 1:d0dfbce63a89 2465 }
elmot 1:d0dfbce63a89 2466 }
elmot 1:d0dfbce63a89 2467
elmot 1:d0dfbce63a89 2468
elmot 1:d0dfbce63a89 2469
elmot 1:d0dfbce63a89 2470 /**
elmot 1:d0dfbce63a89 2471 * @brief Set the DMA configuration and start the DMA transfer
elmot 1:d0dfbce63a89 2472 * for GCM, GMAC or CMAC chainging modes.
elmot 1:d0dfbce63a89 2473 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2474 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2475 * @param inputaddr: Address of the Input buffer.
elmot 1:d0dfbce63a89 2476 * @param Size: Size of the Input buffer un bytes, must be a multiple of 16.
elmot 1:d0dfbce63a89 2477 * @param outputaddr: Address of the Output buffer, null pointer when no output DMA stream
elmot 1:d0dfbce63a89 2478 * has to be configured.
elmot 1:d0dfbce63a89 2479 * @retval None
elmot 1:d0dfbce63a89 2480 */
elmot 1:d0dfbce63a89 2481 static void CRYP_GCMCMAC_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
elmot 1:d0dfbce63a89 2482 {
elmot 1:d0dfbce63a89 2483
elmot 1:d0dfbce63a89 2484 /* Set the input CRYP DMA transfer complete callback */
elmot 1:d0dfbce63a89 2485 hcryp->hdmain->XferCpltCallback = CRYP_GCMCMAC_DMAInCplt;
elmot 1:d0dfbce63a89 2486 /* Set the DMA error callback */
elmot 1:d0dfbce63a89 2487 hcryp->hdmain->XferErrorCallback = CRYP_GCMCMAC_DMAError;
elmot 1:d0dfbce63a89 2488
elmot 1:d0dfbce63a89 2489 if (outputaddr != 0)
elmot 1:d0dfbce63a89 2490 {
elmot 1:d0dfbce63a89 2491 /* Set the output CRYP DMA transfer complete callback */
elmot 1:d0dfbce63a89 2492 hcryp->hdmaout->XferCpltCallback = CRYP_GCMCMAC_DMAOutCplt;
elmot 1:d0dfbce63a89 2493 /* Set the DMA error callback */
elmot 1:d0dfbce63a89 2494 hcryp->hdmaout->XferErrorCallback = CRYP_GCMCMAC_DMAError;
elmot 1:d0dfbce63a89 2495 }
elmot 1:d0dfbce63a89 2496
elmot 1:d0dfbce63a89 2497 /* Enable the CRYP peripheral */
elmot 1:d0dfbce63a89 2498 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 2499
elmot 1:d0dfbce63a89 2500 /* Enable the DMA input stream */
elmot 1:d0dfbce63a89 2501 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4);
elmot 1:d0dfbce63a89 2502
elmot 1:d0dfbce63a89 2503 /* Enable the DMA input request */
elmot 1:d0dfbce63a89 2504 SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
elmot 1:d0dfbce63a89 2505
elmot 1:d0dfbce63a89 2506
elmot 1:d0dfbce63a89 2507 if (outputaddr != 0)
elmot 1:d0dfbce63a89 2508 {
elmot 1:d0dfbce63a89 2509 /* Enable the DMA output stream */
elmot 1:d0dfbce63a89 2510 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4);
elmot 1:d0dfbce63a89 2511
elmot 1:d0dfbce63a89 2512 /* Enable the DMA output request */
elmot 1:d0dfbce63a89 2513 SET_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
elmot 1:d0dfbce63a89 2514 }
elmot 1:d0dfbce63a89 2515 }
elmot 1:d0dfbce63a89 2516
elmot 1:d0dfbce63a89 2517
elmot 1:d0dfbce63a89 2518
elmot 1:d0dfbce63a89 2519 /**
elmot 1:d0dfbce63a89 2520 * @brief Write/read input/output data in polling mode.
elmot 1:d0dfbce63a89 2521 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2522 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2523 * @param Input: Pointer to the Input buffer.
elmot 1:d0dfbce63a89 2524 * @param Ilength: Length of the Input buffer in bytes, must be a multiple of 16.
elmot 1:d0dfbce63a89 2525 * @param Output: Pointer to the returned buffer.
elmot 1:d0dfbce63a89 2526 * @param Timeout: Specify Timeout value.
elmot 1:d0dfbce63a89 2527 * @retval HAL status
elmot 1:d0dfbce63a89 2528 */
elmot 1:d0dfbce63a89 2529 static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout)
elmot 1:d0dfbce63a89 2530 {
elmot 1:d0dfbce63a89 2531 uint32_t index = 0;
elmot 1:d0dfbce63a89 2532 uint32_t inputaddr = (uint32_t)Input;
elmot 1:d0dfbce63a89 2533 uint32_t outputaddr = (uint32_t)Output;
elmot 1:d0dfbce63a89 2534
elmot 1:d0dfbce63a89 2535
elmot 1:d0dfbce63a89 2536 for(index=0; (index < Ilength); index += 16)
elmot 1:d0dfbce63a89 2537 {
elmot 1:d0dfbce63a89 2538 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 2539 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2540 inputaddr+=4;
elmot 1:d0dfbce63a89 2541 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2542 inputaddr+=4;
elmot 1:d0dfbce63a89 2543 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2544 inputaddr+=4;
elmot 1:d0dfbce63a89 2545 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2546 inputaddr+=4;
elmot 1:d0dfbce63a89 2547
elmot 1:d0dfbce63a89 2548 /* Wait for CCF flag to be raised */
elmot 1:d0dfbce63a89 2549 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 2550 {
elmot 1:d0dfbce63a89 2551 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2552 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2553 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 2554 }
elmot 1:d0dfbce63a89 2555
elmot 1:d0dfbce63a89 2556 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2557 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2558
elmot 1:d0dfbce63a89 2559 /* Read the Output block from the Data Output Register */
elmot 1:d0dfbce63a89 2560 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2561 outputaddr+=4;
elmot 1:d0dfbce63a89 2562 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2563 outputaddr+=4;
elmot 1:d0dfbce63a89 2564 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2565 outputaddr+=4;
elmot 1:d0dfbce63a89 2566 *(uint32_t*)(outputaddr) = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2567 outputaddr+=4;
elmot 1:d0dfbce63a89 2568
elmot 1:d0dfbce63a89 2569 /* If the suspension flag has been raised and if the processing is not about
elmot 1:d0dfbce63a89 2570 to end, suspend processing */
elmot 1:d0dfbce63a89 2571 if ((hcryp->SuspendRequest == HAL_CRYP_SUSPEND) && ((index+16) < Ilength))
elmot 1:d0dfbce63a89 2572 {
elmot 1:d0dfbce63a89 2573 /* Reset SuspendRequest */
elmot 1:d0dfbce63a89 2574 hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
elmot 1:d0dfbce63a89 2575
elmot 1:d0dfbce63a89 2576 /* Save current reading and writing locations of Input and Output buffers */
elmot 1:d0dfbce63a89 2577 hcryp->pCrypOutBuffPtr = (uint8_t *)outputaddr;
elmot 1:d0dfbce63a89 2578 hcryp->pCrypInBuffPtr = (uint8_t *)inputaddr;
elmot 1:d0dfbce63a89 2579 /* Save the number of bytes that remain to be processed at this point */
elmot 1:d0dfbce63a89 2580 hcryp->CrypInCount = Ilength - (index+16);
elmot 1:d0dfbce63a89 2581
elmot 1:d0dfbce63a89 2582 /* Change the CRYP state */
elmot 1:d0dfbce63a89 2583 hcryp->State = HAL_CRYP_STATE_SUSPENDED;
elmot 1:d0dfbce63a89 2584
elmot 1:d0dfbce63a89 2585 return HAL_OK;
elmot 1:d0dfbce63a89 2586 }
elmot 1:d0dfbce63a89 2587
elmot 1:d0dfbce63a89 2588
elmot 1:d0dfbce63a89 2589 }
elmot 1:d0dfbce63a89 2590 /* Return function status */
elmot 1:d0dfbce63a89 2591 return HAL_OK;
elmot 1:d0dfbce63a89 2592
elmot 1:d0dfbce63a89 2593 }
elmot 1:d0dfbce63a89 2594
elmot 1:d0dfbce63a89 2595
elmot 1:d0dfbce63a89 2596
elmot 1:d0dfbce63a89 2597
elmot 1:d0dfbce63a89 2598
elmot 1:d0dfbce63a89 2599 /**
elmot 1:d0dfbce63a89 2600 * @brief Read derivative key in polling mode when CRYP hardware block is set
elmot 1:d0dfbce63a89 2601 * in key derivation operating mode (mode 2).
elmot 1:d0dfbce63a89 2602 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2603 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2604 * @param Output: Pointer to the returned buffer.
elmot 1:d0dfbce63a89 2605 * @param Timeout: Specify Timeout value.
elmot 1:d0dfbce63a89 2606 * @retval HAL status
elmot 1:d0dfbce63a89 2607 */
elmot 1:d0dfbce63a89 2608 static HAL_StatusTypeDef CRYP_ReadKey(CRYP_HandleTypeDef *hcryp, uint8_t* Output, uint32_t Timeout)
elmot 1:d0dfbce63a89 2609 {
elmot 1:d0dfbce63a89 2610 uint32_t outputaddr = (uint32_t)Output;
elmot 1:d0dfbce63a89 2611
elmot 1:d0dfbce63a89 2612 /* Wait for CCF flag to be raised */
elmot 1:d0dfbce63a89 2613 if(CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK)
elmot 1:d0dfbce63a89 2614 {
elmot 1:d0dfbce63a89 2615 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2616 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2617 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 2618 }
elmot 1:d0dfbce63a89 2619 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2620 __HAL_CRYP_CLEAR_FLAG( CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2621
elmot 1:d0dfbce63a89 2622 /* Read the derivative key from the AES_KEYRx registers */
elmot 1:d0dfbce63a89 2623 if (hcryp->Init.KeySize == CRYP_KEYSIZE_256B)
elmot 1:d0dfbce63a89 2624 {
elmot 1:d0dfbce63a89 2625 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR7);
elmot 1:d0dfbce63a89 2626 outputaddr+=4;
elmot 1:d0dfbce63a89 2627 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR6);
elmot 1:d0dfbce63a89 2628 outputaddr+=4;
elmot 1:d0dfbce63a89 2629 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR5);
elmot 1:d0dfbce63a89 2630 outputaddr+=4;
elmot 1:d0dfbce63a89 2631 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR4);
elmot 1:d0dfbce63a89 2632 outputaddr+=4;
elmot 1:d0dfbce63a89 2633 }
elmot 1:d0dfbce63a89 2634
elmot 1:d0dfbce63a89 2635 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR3);
elmot 1:d0dfbce63a89 2636 outputaddr+=4;
elmot 1:d0dfbce63a89 2637 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR2);
elmot 1:d0dfbce63a89 2638 outputaddr+=4;
elmot 1:d0dfbce63a89 2639 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR1);
elmot 1:d0dfbce63a89 2640 outputaddr+=4;
elmot 1:d0dfbce63a89 2641 *(uint32_t*)(outputaddr) = __REV(hcryp->Instance->KEYR0);
elmot 1:d0dfbce63a89 2642
elmot 1:d0dfbce63a89 2643
elmot 1:d0dfbce63a89 2644 /* Return function status */
elmot 1:d0dfbce63a89 2645 return HAL_OK;
elmot 1:d0dfbce63a89 2646 }
elmot 1:d0dfbce63a89 2647
elmot 1:d0dfbce63a89 2648 /**
elmot 1:d0dfbce63a89 2649 * @brief Set the DMA configuration and start the DMA transfer.
elmot 1:d0dfbce63a89 2650 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2651 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2652 * @param inputaddr: Address of the Input buffer.
elmot 1:d0dfbce63a89 2653 * @param Size: Size of the Input buffer in bytes, must be a multiple of 16.
elmot 1:d0dfbce63a89 2654 * @param outputaddr: Address of the Output buffer.
elmot 1:d0dfbce63a89 2655 * @retval None
elmot 1:d0dfbce63a89 2656 */
elmot 1:d0dfbce63a89 2657 static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
elmot 1:d0dfbce63a89 2658 {
elmot 1:d0dfbce63a89 2659 /* Set the CRYP DMA transfer complete callback */
elmot 1:d0dfbce63a89 2660 hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
elmot 1:d0dfbce63a89 2661 /* Set the DMA error callback */
elmot 1:d0dfbce63a89 2662 hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
elmot 1:d0dfbce63a89 2663
elmot 1:d0dfbce63a89 2664 /* Set the CRYP DMA transfer complete callback */
elmot 1:d0dfbce63a89 2665 hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
elmot 1:d0dfbce63a89 2666 /* Set the DMA error callback */
elmot 1:d0dfbce63a89 2667 hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
elmot 1:d0dfbce63a89 2668
elmot 1:d0dfbce63a89 2669 /* Enable the DMA input stream */
elmot 1:d0dfbce63a89 2670 HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size/4);
elmot 1:d0dfbce63a89 2671
elmot 1:d0dfbce63a89 2672 /* Enable the DMA output stream */
elmot 1:d0dfbce63a89 2673 HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size/4);
elmot 1:d0dfbce63a89 2674
elmot 1:d0dfbce63a89 2675 /* Enable In and Out DMA requests */
elmot 1:d0dfbce63a89 2676 SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN));
elmot 1:d0dfbce63a89 2677
elmot 1:d0dfbce63a89 2678 /* Enable the CRYP peripheral */
elmot 1:d0dfbce63a89 2679 __HAL_CRYP_ENABLE();
elmot 1:d0dfbce63a89 2680 }
elmot 1:d0dfbce63a89 2681
elmot 1:d0dfbce63a89 2682
elmot 1:d0dfbce63a89 2683 /**
elmot 1:d0dfbce63a89 2684 * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised.
elmot 1:d0dfbce63a89 2685 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2686 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2687 * @param Timeout: Timeout duration.
elmot 1:d0dfbce63a89 2688 * @retval HAL status
elmot 1:d0dfbce63a89 2689 */
elmot 1:d0dfbce63a89 2690 static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
elmot 1:d0dfbce63a89 2691 {
elmot 1:d0dfbce63a89 2692 uint32_t tickstart = 0;
elmot 1:d0dfbce63a89 2693
elmot 1:d0dfbce63a89 2694 /* Get timeout */
elmot 1:d0dfbce63a89 2695 tickstart = HAL_GetTick();
elmot 1:d0dfbce63a89 2696
elmot 1:d0dfbce63a89 2697 while(HAL_IS_BIT_CLR(hcryp->Instance->SR, AES_SR_CCF))
elmot 1:d0dfbce63a89 2698 {
elmot 1:d0dfbce63a89 2699 /* Check for the Timeout */
elmot 1:d0dfbce63a89 2700 if(Timeout != HAL_MAX_DELAY)
elmot 1:d0dfbce63a89 2701 {
elmot 1:d0dfbce63a89 2702 if((HAL_GetTick() - tickstart ) > Timeout)
elmot 1:d0dfbce63a89 2703 {
elmot 1:d0dfbce63a89 2704 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 2705 }
elmot 1:d0dfbce63a89 2706 }
elmot 1:d0dfbce63a89 2707 }
elmot 1:d0dfbce63a89 2708 return HAL_OK;
elmot 1:d0dfbce63a89 2709 }
elmot 1:d0dfbce63a89 2710
elmot 1:d0dfbce63a89 2711 /**
elmot 1:d0dfbce63a89 2712 * @brief Wait for Busy Flag to be reset during a GCM payload encryption process suspension.
elmot 1:d0dfbce63a89 2713 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2714 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2715 * @param Timeout: Timeout duration.
elmot 1:d0dfbce63a89 2716 * @retval HAL status
elmot 1:d0dfbce63a89 2717 */
elmot 1:d0dfbce63a89 2718 static HAL_StatusTypeDef CRYP_WaitOnBusyFlagReset(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
elmot 1:d0dfbce63a89 2719 {
elmot 1:d0dfbce63a89 2720 uint32_t tickstart = 0;
elmot 1:d0dfbce63a89 2721
elmot 1:d0dfbce63a89 2722 /* Get timeout */
elmot 1:d0dfbce63a89 2723 tickstart = HAL_GetTick();
elmot 1:d0dfbce63a89 2724
elmot 1:d0dfbce63a89 2725 while(HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY))
elmot 1:d0dfbce63a89 2726 {
elmot 1:d0dfbce63a89 2727 /* Check for the Timeout */
elmot 1:d0dfbce63a89 2728 if(Timeout != HAL_MAX_DELAY)
elmot 1:d0dfbce63a89 2729 {
elmot 1:d0dfbce63a89 2730 if((HAL_GetTick() - tickstart ) > Timeout)
elmot 1:d0dfbce63a89 2731 {
elmot 1:d0dfbce63a89 2732 return HAL_TIMEOUT;
elmot 1:d0dfbce63a89 2733 }
elmot 1:d0dfbce63a89 2734 }
elmot 1:d0dfbce63a89 2735 }
elmot 1:d0dfbce63a89 2736 return HAL_OK;
elmot 1:d0dfbce63a89 2737 }
elmot 1:d0dfbce63a89 2738
elmot 1:d0dfbce63a89 2739
elmot 1:d0dfbce63a89 2740 /**
elmot 1:d0dfbce63a89 2741 * @brief DMA CRYP Input Data process complete callback.
elmot 1:d0dfbce63a89 2742 * @param hdma: DMA handle.
elmot 1:d0dfbce63a89 2743 * @retval None
elmot 1:d0dfbce63a89 2744 */
elmot 1:d0dfbce63a89 2745 static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
elmot 1:d0dfbce63a89 2746 {
elmot 1:d0dfbce63a89 2747 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
elmot 1:d0dfbce63a89 2748
elmot 1:d0dfbce63a89 2749 /* Disable the DMA transfer for input request */
elmot 1:d0dfbce63a89 2750 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN);
elmot 1:d0dfbce63a89 2751
elmot 1:d0dfbce63a89 2752 /* Call input data transfer complete callback */
elmot 1:d0dfbce63a89 2753 HAL_CRYP_InCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2754 }
elmot 1:d0dfbce63a89 2755
elmot 1:d0dfbce63a89 2756 /**
elmot 1:d0dfbce63a89 2757 * @brief DMA CRYP Output Data process complete callback.
elmot 1:d0dfbce63a89 2758 * @param hdma: DMA handle.
elmot 1:d0dfbce63a89 2759 * @retval None
elmot 1:d0dfbce63a89 2760 */
elmot 1:d0dfbce63a89 2761 static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
elmot 1:d0dfbce63a89 2762 {
elmot 1:d0dfbce63a89 2763 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
elmot 1:d0dfbce63a89 2764
elmot 1:d0dfbce63a89 2765 /* Disable the DMA transfer for output request */
elmot 1:d0dfbce63a89 2766 CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN);
elmot 1:d0dfbce63a89 2767
elmot 1:d0dfbce63a89 2768 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2769 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2770
elmot 1:d0dfbce63a89 2771 /* Disable CRYP */
elmot 1:d0dfbce63a89 2772 __HAL_CRYP_DISABLE();
elmot 1:d0dfbce63a89 2773
elmot 1:d0dfbce63a89 2774 /* Change the CRYP state to ready */
elmot 1:d0dfbce63a89 2775 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2776
elmot 1:d0dfbce63a89 2777 /* Call output data transfer complete callback */
elmot 1:d0dfbce63a89 2778 HAL_CRYP_OutCpltCallback(hcryp);
elmot 1:d0dfbce63a89 2779 }
elmot 1:d0dfbce63a89 2780
elmot 1:d0dfbce63a89 2781 /**
elmot 1:d0dfbce63a89 2782 * @brief DMA CRYP communication error callback.
elmot 1:d0dfbce63a89 2783 * @param hdma: DMA handle.
elmot 1:d0dfbce63a89 2784 * @retval None
elmot 1:d0dfbce63a89 2785 */
elmot 1:d0dfbce63a89 2786 static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
elmot 1:d0dfbce63a89 2787 {
elmot 1:d0dfbce63a89 2788 CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
elmot 1:d0dfbce63a89 2789
elmot 1:d0dfbce63a89 2790 hcryp->State= HAL_CRYP_STATE_ERROR;
elmot 1:d0dfbce63a89 2791 hcryp->ErrorCode |= HAL_CRYP_DMA_ERROR;
elmot 1:d0dfbce63a89 2792 HAL_CRYP_ErrorCallback(hcryp);
elmot 1:d0dfbce63a89 2793 /* Clear Error Flag */
elmot 1:d0dfbce63a89 2794 __HAL_CRYP_CLEAR_FLAG(CRYP_ERR_CLEAR);
elmot 1:d0dfbce63a89 2795 }
elmot 1:d0dfbce63a89 2796
elmot 1:d0dfbce63a89 2797 /**
elmot 1:d0dfbce63a89 2798 * @brief Last header or payload block padding when size is not a multiple of 128 bits.
elmot 1:d0dfbce63a89 2799 * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
elmot 1:d0dfbce63a89 2800 * the configuration information for CRYP module.
elmot 1:d0dfbce63a89 2801 * @param difflength: size remainder after having fed all complete 128-bit blocks.
elmot 1:d0dfbce63a89 2802 * @param polling: specifies whether or not polling on CCF must be done after having
elmot 1:d0dfbce63a89 2803 * entered a complete block.
elmot 1:d0dfbce63a89 2804 * @retval None
elmot 1:d0dfbce63a89 2805 */
elmot 1:d0dfbce63a89 2806 static void CRYP_Padding(CRYP_HandleTypeDef *hcryp, uint32_t difflength, uint32_t polling)
elmot 1:d0dfbce63a89 2807 {
elmot 1:d0dfbce63a89 2808 uint32_t index = 0;
elmot 1:d0dfbce63a89 2809 uint32_t difflengthmod4 = difflength%4;
elmot 1:d0dfbce63a89 2810 uint32_t inputaddr = (uint32_t)hcryp->pCrypInBuffPtr;
elmot 1:d0dfbce63a89 2811 uint32_t outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr;
elmot 1:d0dfbce63a89 2812 uint32_t mask[3] = {0x0FF, 0x0FFFF, 0x0FFFFFF};
elmot 1:d0dfbce63a89 2813 uint32_t intermediate_data[4] = {0};
elmot 1:d0dfbce63a89 2814
elmot 1:d0dfbce63a89 2815 /* Software workaround applied to GCM encryption only */
elmot 1:d0dfbce63a89 2816 if ((hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) &&
elmot 1:d0dfbce63a89 2817 (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT))
elmot 1:d0dfbce63a89 2818 {
elmot 1:d0dfbce63a89 2819 /* Change the mode configured in CHMOD bits of CR register to select CTR mode */
elmot 1:d0dfbce63a89 2820 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_CTR);
elmot 1:d0dfbce63a89 2821 }
elmot 1:d0dfbce63a89 2822
elmot 1:d0dfbce63a89 2823 /* Wrap-up entering header data */
elmot 1:d0dfbce63a89 2824 /* Enter complete words when possible */
elmot 1:d0dfbce63a89 2825 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 2826 {
elmot 1:d0dfbce63a89 2827 /* Write the Input block in the Data Input register */
elmot 1:d0dfbce63a89 2828 hcryp->Instance->DINR = *(uint32_t*)(inputaddr);
elmot 1:d0dfbce63a89 2829 inputaddr+=4;
elmot 1:d0dfbce63a89 2830 }
elmot 1:d0dfbce63a89 2831 /* Enter incomplete word padded with zeroes if applicable
elmot 1:d0dfbce63a89 2832 (case of header length not a multiple of 32-bits) */
elmot 1:d0dfbce63a89 2833 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 2834 {
elmot 1:d0dfbce63a89 2835 hcryp->Instance->DINR = ((*(uint32_t*)(inputaddr)) & mask[difflengthmod4-1]);
elmot 1:d0dfbce63a89 2836 }
elmot 1:d0dfbce63a89 2837 /* Pad with zero-words to reach 128-bit long block and wrap-up header feeding to the IP */
elmot 1:d0dfbce63a89 2838 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 2839 {
elmot 1:d0dfbce63a89 2840 hcryp->Instance->DINR = 0;
elmot 1:d0dfbce63a89 2841 }
elmot 1:d0dfbce63a89 2842
elmot 1:d0dfbce63a89 2843 if (polling == CRYP_POLLING_ON)
elmot 1:d0dfbce63a89 2844 {
elmot 1:d0dfbce63a89 2845 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 2846 {
elmot 1:d0dfbce63a89 2847 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2848 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2849 HAL_CRYP_ErrorCallback(hcryp);
elmot 1:d0dfbce63a89 2850 }
elmot 1:d0dfbce63a89 2851
elmot 1:d0dfbce63a89 2852 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2853 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2854 }
elmot 1:d0dfbce63a89 2855
elmot 1:d0dfbce63a89 2856 /* if payload */
elmot 1:d0dfbce63a89 2857 if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE)
elmot 1:d0dfbce63a89 2858 {
elmot 1:d0dfbce63a89 2859
elmot 1:d0dfbce63a89 2860 /* Retrieve intermediate data */
elmot 1:d0dfbce63a89 2861 for(index=0; index < 4; index ++)
elmot 1:d0dfbce63a89 2862 {
elmot 1:d0dfbce63a89 2863 intermediate_data[index] = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2864 }
elmot 1:d0dfbce63a89 2865 /* Retrieve last words of cyphered data */
elmot 1:d0dfbce63a89 2866 /* First, retrieve complete output words */
elmot 1:d0dfbce63a89 2867 for(index=0; index < (difflength/4); index ++)
elmot 1:d0dfbce63a89 2868 {
elmot 1:d0dfbce63a89 2869 *(uint32_t*)(outputaddr) = intermediate_data[index];
elmot 1:d0dfbce63a89 2870 outputaddr+=4;
elmot 1:d0dfbce63a89 2871 }
elmot 1:d0dfbce63a89 2872 /* Next, retrieve partial output word if applicable;
elmot 1:d0dfbce63a89 2873 at the same time, start masking intermediate data
elmot 1:d0dfbce63a89 2874 with a mask of zeros of same size than the padding
elmot 1:d0dfbce63a89 2875 applied to the last block of payload */
elmot 1:d0dfbce63a89 2876 if (difflengthmod4 != 0)
elmot 1:d0dfbce63a89 2877 {
elmot 1:d0dfbce63a89 2878 intermediate_data[difflength/4] &= mask[difflengthmod4-1];
elmot 1:d0dfbce63a89 2879 *(uint32_t*)(outputaddr) = intermediate_data[difflength/4];
elmot 1:d0dfbce63a89 2880 }
elmot 1:d0dfbce63a89 2881
elmot 1:d0dfbce63a89 2882 /* Software workaround applied to GCM encryption only */
elmot 1:d0dfbce63a89 2883 if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT)
elmot 1:d0dfbce63a89 2884 {
elmot 1:d0dfbce63a89 2885 /* Change again CHMOD configuration to GCM mode */
elmot 1:d0dfbce63a89 2886 __HAL_CRYP_SET_CHAININGMODE(CRYP_CHAINMODE_AES_GCM_GMAC);
elmot 1:d0dfbce63a89 2887
elmot 1:d0dfbce63a89 2888 /* Select FINAL phase */
elmot 1:d0dfbce63a89 2889 MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_GCMCMAC_FINAL_PHASE);
elmot 1:d0dfbce63a89 2890
elmot 1:d0dfbce63a89 2891 /* Before inserting the intermediate data, carry on masking operation
elmot 1:d0dfbce63a89 2892 with a mask of zeros of same size than the padding applied to the last block of payload */
elmot 1:d0dfbce63a89 2893 for(index=0; index < (4 - ((difflength+3)/4)); index ++)
elmot 1:d0dfbce63a89 2894 {
elmot 1:d0dfbce63a89 2895 intermediate_data[(difflength+3)/4+index] = 0;
elmot 1:d0dfbce63a89 2896 }
elmot 1:d0dfbce63a89 2897 /* Insert intermediate data */
elmot 1:d0dfbce63a89 2898 for(index=0; index < 4; index ++)
elmot 1:d0dfbce63a89 2899 {
elmot 1:d0dfbce63a89 2900 hcryp->Instance->DINR = intermediate_data[index];
elmot 1:d0dfbce63a89 2901 }
elmot 1:d0dfbce63a89 2902
elmot 1:d0dfbce63a89 2903 /* Wait for completion, and read data on DOUT. This data is to discard. */
elmot 1:d0dfbce63a89 2904 if(CRYP_WaitOnCCFlag(hcryp, CRYP_CCF_TIMEOUTVALUE) != HAL_OK)
elmot 1:d0dfbce63a89 2905 {
elmot 1:d0dfbce63a89 2906 hcryp->State = HAL_CRYP_STATE_READY;
elmot 1:d0dfbce63a89 2907 __HAL_UNLOCK(hcryp);
elmot 1:d0dfbce63a89 2908 HAL_CRYP_ErrorCallback(hcryp);
elmot 1:d0dfbce63a89 2909 }
elmot 1:d0dfbce63a89 2910
elmot 1:d0dfbce63a89 2911 /* Read data to discard */
elmot 1:d0dfbce63a89 2912 /* Clear CCF Flag */
elmot 1:d0dfbce63a89 2913 __HAL_CRYP_CLEAR_FLAG(CRYP_CCF_CLEAR);
elmot 1:d0dfbce63a89 2914 for(index=0; index < 4; index ++)
elmot 1:d0dfbce63a89 2915 {
elmot 1:d0dfbce63a89 2916 intermediate_data[index] = hcryp->Instance->DOUTR;
elmot 1:d0dfbce63a89 2917 }
elmot 1:d0dfbce63a89 2918
elmot 1:d0dfbce63a89 2919 } /* if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_ENCRYPT) */
elmot 1:d0dfbce63a89 2920 } /* if (hcryp->Init.GCMCMACPhase == CRYP_GCM_PAYLOAD_PHASE) */
elmot 1:d0dfbce63a89 2921
elmot 1:d0dfbce63a89 2922 }
elmot 1:d0dfbce63a89 2923
elmot 1:d0dfbce63a89 2924 /**
elmot 1:d0dfbce63a89 2925 * @}
elmot 1:d0dfbce63a89 2926 */
elmot 1:d0dfbce63a89 2927
elmot 1:d0dfbce63a89 2928 /**
elmot 1:d0dfbce63a89 2929 * @}
elmot 1:d0dfbce63a89 2930 */
elmot 1:d0dfbce63a89 2931
elmot 1:d0dfbce63a89 2932 /**
elmot 1:d0dfbce63a89 2933 * @}
elmot 1:d0dfbce63a89 2934 */
elmot 1:d0dfbce63a89 2935
elmot 1:d0dfbce63a89 2936 #endif /* defined (STM32L442xx) || defined (STM32L443xx) || defined(STM32L485xx) || defined(STM32L486xx) */
elmot 1:d0dfbce63a89 2937
elmot 1:d0dfbce63a89 2938 #endif /* HAL_CRYP_MODULE_ENABLED */
elmot 1:d0dfbce63a89 2939 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/