STM32H735xx HAL User Manual
stm32h7xx_hal_cryp_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_cryp_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extended CRYP HAL module driver
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of CRYP extension peripheral:
00008   *           + Extended AES processing functions
00009   *
00010   ******************************************************************************
00011   * @attention
00012   *
00013   * Copyright (c) 2017 STMicroelectronics.
00014   * All rights reserved.
00015   *
00016   * This software is licensed under terms that can be found in the LICENSE file
00017   * in the root directory of this software component.
00018   * If no LICENSE file comes with this software, it is provided AS-IS.
00019   *
00020   ******************************************************************************
00021   @verbatim
00022   ==============================================================================
00023                      ##### How to use this driver #####
00024   ==============================================================================
00025     [..]
00026     The CRYP extension HAL driver can be used after AES-GCM or AES-CCM
00027     Encryption/Decryption to get the authentication messages.
00028 
00029   @endverbatim
00030   */
00031 
00032 /* Includes ------------------------------------------------------------------*/
00033 #include "stm32h7xx_hal.h"
00034 
00035 /** @addtogroup STM32H7xx_HAL_Driver
00036   * @{
00037   */
00038 #if defined (CRYP)
00039 /** @defgroup CRYPEx CRYPEx
00040   * @brief CRYP Extension HAL module driver.
00041   * @{
00042   */
00043 
00044 #ifdef HAL_CRYP_MODULE_ENABLED
00045 
00046 /* Private typedef -----------------------------------------------------------*/
00047 /* Private define ------------------------------------------------------------*/
00048 /** @addtogroup CRYPEx_Private_Defines
00049   * @{
00050   */
00051 
00052 #define CRYP_PHASE_INIT                 0x00000000U
00053 #define CRYP_PHASE_HEADER               CRYP_CR_GCM_CCMPH_0
00054 #define CRYP_PHASE_PAYLOAD              CRYP_CR_GCM_CCMPH_1
00055 #define CRYP_PHASE_FINAL                CRYP_CR_GCM_CCMPH
00056 
00057 #define CRYP_OPERATINGMODE_ENCRYPT      0x00000000U
00058 #define CRYP_OPERATINGMODE_DECRYPT      CRYP_CR_ALGODIR
00059 
00060 #define  CRYPEx_PHASE_PROCESS       0x02U     /*!< CRYP peripheral is in processing phase */
00061 #define  CRYPEx_PHASE_FINAL         0x03U     /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */
00062 
00063 /*  CTR0 information to use in CCM algorithm */
00064 #define CRYP_CCM_CTR0_0            0x07FFFFFFU
00065 #define CRYP_CCM_CTR0_3            0xFFFFFF00U
00066 
00067 /**
00068   * @}
00069   */
00070 
00071 /* Private macro -------------------------------------------------------------*/
00072 /* Private variables ---------------------------------------------------------*/
00073 /* Private function prototypes -----------------------------------------------*/
00074 
00075 
00076 
00077 /* Exported functions---------------------------------------------------------*/
00078 /** @addtogroup CRYPEx_Exported_Functions
00079   * @{
00080   */
00081 
00082 /** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions
00083   *  @brief    CRYPEx Extended processing functions.
00084   *
00085 @verbatim
00086   ==============================================================================
00087               ##### Extended AES processing functions #####
00088   ==============================================================================
00089     [..]  This section provides functions allowing to generate the authentication
00090           TAG in Polling mode
00091       (+)HAL_CRYPEx_AESGCM_GenerateAuthTAG
00092       (+)HAL_CRYPEx_AESCCM_GenerateAuthTAG
00093          they should be used after Encrypt/Decrypt operation.
00094 
00095 @endverbatim
00096   * @{
00097   */
00098 
00099 
00100 /**
00101   * @brief  generate the GCM authentication TAG.
00102   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00103   *         the configuration information for CRYP module
00104   * @param  AuthTag: Pointer to the authentication buffer
00105   *         the AuthTag generated here is 128bits length, if the TAG length is 
00106   *         less than 128bits, user should consider only the valid part of AuthTag
00107   *         buffer which correspond exactly to TAG length.  
00108   * @param  Timeout: Timeout duration
00109   * @retval HAL status
00110   */
00111 HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
00112 {
00113   uint32_t tickstart;
00114   uint64_t headerlength = (uint64_t)(hcryp->Init.HeaderSize) * 32U; /* Header length in bits */
00115   uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */
00116   uint32_t tagaddr = (uint32_t)AuthTag;
00117 
00118    /* Correct header length if Init.HeaderSize is actually in bytes */
00119   if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE)
00120   {
00121     headerlength /= 4U;
00122   }
00123 
00124   if (hcryp->State == HAL_CRYP_STATE_READY)
00125   {
00126     /* Process locked */
00127     __HAL_LOCK(hcryp);
00128 
00129     /* Change the CRYP peripheral state */
00130     hcryp->State = HAL_CRYP_STATE_BUSY;
00131 
00132     /* Check if initialization phase has already been performed */
00133     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
00134     {
00135       /* Change the CRYP phase */
00136       hcryp->Phase = CRYPEx_PHASE_FINAL;
00137     }
00138     else /* Initialization phase has not been performed*/
00139     {
00140       /* Disable the Peripheral */
00141       __HAL_CRYP_DISABLE(hcryp);
00142 
00143       /* Sequence error code field */
00144       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
00145 
00146       /* Change the CRYP peripheral state */
00147       hcryp->State = HAL_CRYP_STATE_READY;
00148 
00149       /* Process unlocked */
00150       __HAL_UNLOCK(hcryp);
00151       return HAL_ERROR;
00152     }
00153 
00154     /* Disable CRYP to start the final phase */
00155     __HAL_CRYP_DISABLE(hcryp);
00156 
00157     /* Select final phase */
00158     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);
00159 
00160     /*ALGODIR bit must be set to '0'.*/
00161     hcryp->Instance->CR &=  ~CRYP_CR_ALGODIR;
00162 
00163     /* Enable the CRYP peripheral */
00164     __HAL_CRYP_ENABLE(hcryp);
00165 
00166     /* Write the number of bits in header (64 bits) followed by the number of bits
00167     in the payload */
00168 #if !defined (CRYP_VER_2_2)
00169     /* STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
00170     if (hcryp->Version >= REV_ID_B)
00171 #endif /*End of not defined CRYP_VER_2_2*/
00172     {
00173       hcryp->Instance->DIN = 0U;
00174       hcryp->Instance->DIN = (uint32_t)(headerlength);
00175       hcryp->Instance->DIN = 0U;
00176       hcryp->Instance->DIN = (uint32_t)(inputlength);
00177     }
00178 #if !defined (CRYP_VER_2_2)
00179     else/* data has to be swapped according to the DATATYPE */
00180     {
00181       if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
00182       {
00183         hcryp->Instance->DIN = 0U;
00184         hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
00185         hcryp->Instance->DIN = 0U;
00186         hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
00187       }
00188       else if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
00189       {
00190         hcryp->Instance->DIN = 0U;
00191         hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
00192         hcryp->Instance->DIN = 0U;
00193         hcryp->Instance->DIN = __REV((uint32_t)(inputlength));
00194       }
00195       else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
00196       {
00197         hcryp->Instance->DIN = 0U;
00198         hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
00199         hcryp->Instance->DIN = 0U;
00200         hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
00201       }
00202       else if (hcryp->Init.DataType == CRYP_DATATYPE_32B)
00203       {
00204         hcryp->Instance->DIN = 0U;
00205         hcryp->Instance->DIN = (uint32_t)(headerlength);
00206         hcryp->Instance->DIN = 0U;
00207         hcryp->Instance->DIN = (uint32_t)(inputlength);
00208       }
00209       else
00210       {
00211         /* Nothing to do */
00212       }
00213     }
00214 #endif /*End of not defined CRYP_VER_2_2*/
00215     /* Wait for OFNE flag to be raised */
00216     tickstart = HAL_GetTick();
00217     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
00218     {
00219       /* Check for the Timeout */
00220       if (Timeout != HAL_MAX_DELAY)
00221       {
00222         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
00223         {
00224           /* Disable the CRYP Peripheral Clock */
00225           __HAL_CRYP_DISABLE(hcryp);
00226 
00227           /* Change state */
00228           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
00229           hcryp->State = HAL_CRYP_STATE_READY;
00230 
00231           /* Process unlocked */
00232           __HAL_UNLOCK(hcryp);
00233           return HAL_ERROR;
00234         }
00235       }
00236     }
00237 
00238     /* Read the authentication TAG in the output FIFO */
00239     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00240     tagaddr += 4U;
00241     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00242     tagaddr += 4U;
00243     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00244     tagaddr += 4U;
00245     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00246 
00247     /* Disable the peripheral */
00248     __HAL_CRYP_DISABLE(hcryp);
00249 
00250     /* Change the CRYP peripheral state */
00251     hcryp->State = HAL_CRYP_STATE_READY;
00252 
00253     /* Process unlocked */
00254     __HAL_UNLOCK(hcryp);
00255   }
00256   else
00257   {
00258     /* Busy error code field */
00259     hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
00260     return HAL_ERROR;
00261   }
00262   /* Return function status */
00263   return HAL_OK;
00264 }
00265 
00266 /**
00267   * @brief  AES CCM Authentication TAG generation.
00268   * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
00269   *         the configuration information for CRYP module
00270   * @param  AuthTag: Pointer to the authentication buffer
00271   *         the AuthTag generated here is 128bits length, if the TAG length is 
00272   *         less than 128bits, user should consider only the valid part of AuthTag
00273   *         buffer which correspond exactly to TAG length.  
00274   * @param  Timeout: Timeout duration
00275   * @retval HAL status
00276   */
00277 HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
00278 {
00279   uint32_t tagaddr = (uint32_t)AuthTag;
00280   uint32_t ctr0 [4] = {0};
00281   uint32_t ctr0addr = (uint32_t)ctr0;
00282   uint32_t tickstart;
00283 
00284   if (hcryp->State == HAL_CRYP_STATE_READY)
00285   {
00286     /* Process locked */
00287     __HAL_LOCK(hcryp);
00288 
00289     /* Change the CRYP peripheral state */
00290     hcryp->State = HAL_CRYP_STATE_BUSY;
00291 
00292     /* Check if initialization phase has already been performed */
00293     if (hcryp->Phase == CRYPEx_PHASE_PROCESS)
00294     {
00295       /* Change the CRYP phase */
00296       hcryp->Phase = CRYPEx_PHASE_FINAL;
00297     }
00298     else /* Initialization phase has not been performed*/
00299     {
00300       /* Disable the peripheral */
00301       __HAL_CRYP_DISABLE(hcryp);
00302 
00303       /* Sequence error code field */
00304       hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;
00305 
00306       /* Change the CRYP peripheral state */
00307       hcryp->State = HAL_CRYP_STATE_READY;
00308 
00309       /* Process unlocked */
00310       __HAL_UNLOCK(hcryp);
00311       return HAL_ERROR;
00312     }
00313 
00314     /* Disable CRYP to start the final phase */
00315     __HAL_CRYP_DISABLE(hcryp);
00316 
00317     /* Select final phase & ALGODIR bit must be set to '0'. */
00318     MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH | CRYP_CR_ALGODIR, CRYP_PHASE_FINAL | CRYP_OPERATINGMODE_ENCRYPT);
00319 
00320     /* Enable the CRYP peripheral */
00321     __HAL_CRYP_ENABLE(hcryp);
00322 
00323     /* Write the counter block in the IN FIFO, CTR0 information from B0
00324     data has to be swapped according to the DATATYPE*/
00325     ctr0[0] = (hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
00326     ctr0[1] = hcryp->Init.B0[1];
00327     ctr0[2] = hcryp->Init.B0[2];
00328     ctr0[3] = hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3;
00329 
00330 #if !defined (CRYP_VER_2_2)
00331     /*STM32H7 rev.B and above : data has to be inserted normally (no swapping)*/
00332     if (hcryp->Version >= REV_ID_B)
00333 #endif /*End of not defined CRYP_VER_2_2*/
00334     {
00335       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00336       ctr0addr += 4U;
00337       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00338       ctr0addr += 4U;
00339       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00340       ctr0addr += 4U;
00341       hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00342     }
00343 #if !defined (CRYP_VER_2_2)
00344     else /* data has to be swapped according to the DATATYPE */
00345     {
00346       if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
00347       {
00348         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
00349         ctr0addr += 4U;
00350         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
00351         ctr0addr += 4U;
00352         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
00353         ctr0addr += 4U;
00354         hcryp->Instance->DIN = __REV(*(uint32_t *)(ctr0addr));
00355       }
00356       else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
00357       {
00358         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
00359         ctr0addr += 4U;
00360         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
00361         ctr0addr += 4U;
00362         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
00363         ctr0addr += 4U;
00364         hcryp->Instance->DIN = __ROR(*(uint32_t *)(ctr0addr), 16U);
00365       }
00366       else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
00367       {
00368         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
00369         ctr0addr += 4U;
00370         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
00371         ctr0addr += 4U;
00372         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
00373         ctr0addr += 4U;
00374         hcryp->Instance->DIN = __RBIT(*(uint32_t *)(ctr0addr));
00375       }
00376       else
00377       {
00378         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00379         ctr0addr += 4U;
00380         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00381         ctr0addr += 4U;
00382         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00383         ctr0addr += 4U;
00384         hcryp->Instance->DIN = *(uint32_t *)(ctr0addr);
00385       }
00386     }
00387 #endif /*End of not defined CRYP_VER_2_2*/
00388     /* Wait for OFNE flag to be raised */
00389     tickstart = HAL_GetTick();
00390     while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
00391     {
00392       /* Check for the Timeout */
00393       if (Timeout != HAL_MAX_DELAY)
00394       {
00395         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
00396         {
00397           /* Disable the CRYP peripheral Clock */
00398           __HAL_CRYP_DISABLE(hcryp);
00399 
00400           /* Change state */
00401           hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
00402           hcryp->State = HAL_CRYP_STATE_READY;
00403 
00404           /* Process unlocked */
00405           __HAL_UNLOCK(hcryp);
00406           return HAL_ERROR;
00407         }
00408       }
00409     }
00410 
00411     /* Read the Auth TAG in the IN FIFO */
00412     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00413     tagaddr += 4U;
00414     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00415     tagaddr += 4U;
00416     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00417     tagaddr += 4U;
00418     *(uint32_t *)(tagaddr) = hcryp->Instance->DOUT;
00419 
00420     /* Change the CRYP peripheral state */
00421     hcryp->State = HAL_CRYP_STATE_READY;
00422 
00423     /* Process unlocked */
00424     __HAL_UNLOCK(hcryp);
00425 
00426     /* Disable CRYP  */
00427     __HAL_CRYP_DISABLE(hcryp);
00428   }
00429   else
00430   {
00431     /* Busy error code field */
00432     hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY;
00433     return HAL_ERROR;
00434   }
00435   /* Return function status */
00436   return HAL_OK;
00437 }
00438 
00439 /**
00440   * @}
00441   */
00442 
00443 
00444 #endif /* HAL_CRYP_MODULE_ENABLED */
00445 
00446 /**
00447   * @}
00448   */
00449 #endif /* CRYP */
00450 /**
00451   * @}
00452   */
00453 
00454 /**
00455   * @}
00456   */