Ejemplo n.º 1
0
/**
  * @brief  generate the GCM authentication TAG.
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  AuthTag: Pointer to the authentication buffer
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
{
  uint32_t tickstart = 0U;    
  uint64_t headerlength = hcryp->Init.HeaderSize * 32U; /* Header length in bits */
  uint64_t inputlength = (hcryp->Size) * 32U; /* input length in bits */
  uint32_t tagaddr = (uint32_t)AuthTag;  
  
  if(hcryp->State == HAL_CRYP_STATE_READY)
  {  
    /* Process locked */
    __HAL_LOCK(hcryp);
    
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_BUSY;
    
    /* Check if initialization phase has already been performed */
    if(hcryp->Phase == CRYPEx_PHASE_PROCESS)
    {
      /* Change the CRYP phase */
      hcryp->Phase = CRYPEx_PHASE_FINAL;
    }
    else /* Initialization phase has not been performed*/
    { 
      /* Disable the Peripheral */
      __HAL_CRYP_DISABLE(hcryp);
      
      /* Sequence error code field */ 
      hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; 
      
      /* Change the CRYP peripheral state */
      hcryp->State = HAL_CRYP_STATE_READY;    
      
      /* Process unlocked */
      __HAL_UNLOCK(hcryp);
      return HAL_ERROR;
    }
    
    /* Disable CRYP to start the final phase */
    __HAL_CRYP_DISABLE(hcryp);
    
    /* Select final phase */  
    MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH, CRYP_PHASE_FINAL);  
    
    /*ALGODIR bit must be set to ‘0’.*/ 
    hcryp->Instance->CR &=  ~CRYP_CR_ALGODIR;
    
    /* Enable the CRYP peripheral */
    __HAL_CRYP_ENABLE(hcryp);
    
    /* Write the number of bits in header (64 bits) followed by the number of bits
    in the payload */
    if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __RBIT((uint32_t)(headerlength));
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __RBIT((uint32_t)(inputlength));
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __REV((uint32_t)(headerlength));
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __REV((uint32_t)(inputlength));    
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __ROR((uint32_t)headerlength, 16U);
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = __ROR((uint32_t)inputlength, 16U);
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_32B)
    {
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = (uint32_t)(headerlength);
      hcryp->Instance->DIN = 0U;
      hcryp->Instance->DIN = (uint32_t)(inputlength);
    }  
    
    /* Wait for OFNE flag to be raised */
    tickstart = HAL_GetTick();
    while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
        {       
          /* Disable the CRYP Peripheral Clock */
          __HAL_CRYP_DISABLE(hcryp);
          
          /* Change state */
          hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
          hcryp->State = HAL_CRYP_STATE_READY;  
          
          /* Process unlocked */          
          __HAL_UNLOCK(hcryp); 
          return HAL_ERROR;
        }
      }
    }          
    
    /* Read the authentication TAG in the output FIFO */
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;      
    
    /* Disable the peripheral */
    __HAL_CRYP_DISABLE(hcryp);
    
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_READY;    
    
    /* Process unlocked */
    __HAL_UNLOCK(hcryp);
  }
  else
  {
    /* Busy error code field */
    hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; 
    return HAL_ERROR;
  }   
  /* Return function status */
  return HAL_OK;
}
Ejemplo n.º 2
0
/**
  * @brief  AES CCM Authentication TAG generation.
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @param  AuthTag: Pointer to the authentication buffer
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout)
{
  uint32_t tagaddr = (uint32_t)AuthTag;
  uint32_t ctr0 [4]={0};
  uint32_t ctr0addr = (uint32_t)ctr0;
  uint32_t tickstart = 0U;  
  
  if(hcryp->State == HAL_CRYP_STATE_READY)
  {  
    /* Process locked */
    __HAL_LOCK(hcryp);
    
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_BUSY;
    
    /* Check if initialization phase has already been performed */
    if(hcryp->Phase == CRYPEx_PHASE_PROCESS)
    {
      /* Change the CRYP phase */
      hcryp->Phase = CRYPEx_PHASE_FINAL;
    }
    else /* Initialization phase has not been performed*/
    { 
      /* Disable the peripheral */
      __HAL_CRYP_DISABLE(hcryp);
            
      /* Sequence error code field */   
     hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE;      
      
     /* Change the CRYP peripheral state */
      hcryp->State = HAL_CRYP_STATE_READY;    
      
      /* Process unlocked */
      __HAL_UNLOCK(hcryp);
      return HAL_ERROR;
    } 
    
    /* Disable CRYP to start the final phase */
    __HAL_CRYP_DISABLE(hcryp);   
    
    /* Select final phase & ALGODIR bit must be set to ‘0’. */
    MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH|CRYP_CR_ALGODIR, CRYP_PHASE_FINAL|CRYP_OPERATINGMODE_ENCRYPT);     
    
    /* Enable the CRYP peripheral */
    __HAL_CRYP_ENABLE(hcryp);
    
    /* Write the counter block in the IN FIFO, CTR0 information from B0
    data has to be swapped according to the DATATYPE*/
    ctr0[0]=(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0;
    ctr0[1]=hcryp->Init.B0[1];
    ctr0[2]=hcryp->Init.B0[2];
    ctr0[3]=hcryp->Init.B0[3] &  CRYP_CCM_CTR0_3; 
    
    if(hcryp->Init.DataType == CRYP_DATATYPE_8B)
    {   
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4;
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4;
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
      ctr0addr+=4;
      hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr));
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_16B)
    {
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4;
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4;
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
      ctr0addr+=4;
      hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U);
    }
    else if(hcryp->Init.DataType == CRYP_DATATYPE_1B)
    { 
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4;
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4;
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr));
      ctr0addr+=4;
      hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr)); 
    }
    else
    {
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
      ctr0addr+=4;
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
      ctr0addr+=4;
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);
      ctr0addr+=4;
      hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);;
    }   
    /* Wait for OFNE flag to be raised */
    tickstart = HAL_GetTick();
    while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
        {       
          /* Disable the CRYP peripheral Clock */
          __HAL_CRYP_DISABLE(hcryp);
         
          /* Change state */
          hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
          hcryp->State = HAL_CRYP_STATE_READY;  
         
          /* Process unlocked */          
          __HAL_UNLOCK(hcryp); 
          return HAL_ERROR;
        }
      }
    }
    
    /* Read the Auth TAG in the IN FIFO */
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;
    tagaddr+=4U;
    *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT;      
    
    /* Change the CRYP peripheral state */
    hcryp->State = HAL_CRYP_STATE_READY;
   
    /* Process unlocked */
    __HAL_UNLOCK(hcryp);
  
    /* Disable CRYP  */
    __HAL_CRYP_DISABLE(hcryp);  
  }
  else
  {
    /* Busy error code field */
    hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY; 
    return HAL_ERROR;
  }   
  /* Return function status */
  return HAL_OK;   
}
Ejemplo n.º 3
0
/**
  * @brief  Initialize the CRYP according to the specified
  *         parameters in the CRYP_InitTypeDef and initialize the associated handle.
  * @param  hcryp: pointer to a CRYP_HandleTypeDef structure that contains
  *         the configuration information for CRYP module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
{   
  /* Check the CRYP handle allocation */
  if(hcryp == NULL)
  {
    return HAL_ERROR;
  }
  
  /* Check the instance */
  assert_param(IS_AES_ALL_INSTANCE(hcryp->Instance));
  
  /* Check the parameters */
  assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
  assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
  assert_param(IS_CRYP_ALGOMODE(hcryp->Init.OperatingMode));
  /* ChainingMode parameter is irrelevant when mode is set to Key derivation */
  if (hcryp->Init.OperatingMode != CRYP_ALGOMODE_KEYDERIVATION)
  {
    assert_param(IS_CRYP_CHAINMODE(hcryp->Init.ChainingMode));
  }
  assert_param(IS_CRYP_WRITE(hcryp->Init.KeyWriteFlag));
  
  /*========================================================*/
  /* Check the proper operating/chaining modes combinations */
  /*========================================================*/  
  /* Check the proper chaining when the operating mode is key derivation and decryption */
  if ((hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION_DECRYPT) &&\
         ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CTR)           \
       || (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)      \
       || (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC)))        
  {
    return HAL_ERROR;
  }  
  /* Check that key derivation is not set in CMAC mode */  
  if ((hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION) 
   && (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC))        
  {
    return HAL_ERROR;
  }
  
  
  /*================*/
  /* Initialization */
  /*================*/  
  /* Initialization start */
  if(hcryp->State == HAL_CRYP_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    hcryp->Lock = HAL_UNLOCKED;

    /* Init the low level hardware */
    HAL_CRYP_MspInit(hcryp);
  }
  
  /* Change the CRYP state */
  hcryp->State = HAL_CRYP_STATE_BUSY;  
  
  /* Disable the Peripheral */
  __HAL_CRYP_DISABLE();
  
  /*=============================================================*/
  /* AES initialization common to all operating modes            */ 
  /*=============================================================*/
  /* Set the Key size selection */
  MODIFY_REG(hcryp->Instance->CR, AES_CR_KEYSIZE, hcryp->Init.KeySize);
  
  /* Set the default CRYP phase when this parameter is not used.
     Phase is updated below in case of GCM/GMAC/CMAC setting. */
  hcryp->Phase = HAL_CRYP_PHASE_NOT_USED;
  
  

  /*=============================================================*/
  /* Carry on the initialization based on the AES operating mode */ 
  /*=============================================================*/
  /* Key derivation */ 
  if (hcryp->Init.OperatingMode == CRYP_ALGOMODE_KEYDERIVATION)
  {
    MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_ALGOMODE_KEYDERIVATION);
    
    /* Configure the Key registers */
    if (CRYP_SetKey(hcryp) != HAL_OK)
    {
      return HAL_ERROR;
    }
  }
  else
  /* Encryption / Decryption (with or without key derivation) / authentication */
  {    
    /* Set data type, operating and chaining modes.
       In case of GCM or GMAC, data type is forced to 0b00 */
    if (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
    {
      MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE|AES_CR_MODE|AES_CR_CHMOD, hcryp->Init.OperatingMode|hcryp->Init.ChainingMode);
    }
    else
    {
      MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE|AES_CR_MODE|AES_CR_CHMOD, hcryp->Init.DataType|hcryp->Init.OperatingMode|hcryp->Init.ChainingMode);
    }

    
   /* Specify the encryption/decryption phase in case of Galois counter mode (GCM), 
      Galois message authentication code (GMAC) or cipher message authentication code (CMAC) */
   if ((hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_GCM_GMAC)
    || (hcryp->Init.ChainingMode == CRYP_CHAINMODE_AES_CMAC))
    {
      MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, hcryp->Init.GCMCMACPhase);
      hcryp->Phase = HAL_CRYP_PHASE_START;
    }

    
    /* Configure the Key registers if no need to bypass this step */
    if (hcryp->Init.KeyWriteFlag == CRYP_KEY_WRITE_ENABLE)
    {
      if (CRYP_SetKey(hcryp) != HAL_OK)
      {
        return HAL_ERROR;
      }      
    }
    
    /* If applicable, configure the Initialization Vector */
    if (hcryp->Init.ChainingMode != CRYP_CHAINMODE_AES_ECB)
    {
      if (CRYP_SetInitVector(hcryp) != HAL_OK)
      {
        return HAL_ERROR;
      }
    }
  }

  /* Reset CrypInCount and CrypOutCount */
  hcryp->CrypInCount = 0;
  hcryp->CrypOutCount = 0;
  
  /* Reset ErrorCode field */
  hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
  
  /* Reset Mode suspension request */
  hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE;
  
  /* Change the CRYP state */
  hcryp->State = HAL_CRYP_STATE_READY;
  
  /* Enable the Peripheral */
  __HAL_CRYP_ENABLE();
  
  /* Return function status */
  return HAL_OK;
}