AnsweredAssumed Answered

HMAC with DMA transfert

Question asked by brahem.khaled on Mar 9, 2013
Latest reply on Mar 10, 2013 by brahem.khaled

HI

I used the STM32F4xx_DSP_StdPeriph_Lib_V1.0.0 / HMAC_SHA1_MD5 and  SHA1_MD5_DMA examples to perform a HMAC signature with the use of the dma to transfer the key and main message to the HASH core but the results are not what it’s expected to be any idea where is the problem ??
Thanks for help.

There is the essential part of the code:

</span>




/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hash.h"
#include "stm32f4xx.h"
/** @addtogroup STM32F4xx_StdPeriph_Driver
  * @{
  */
/** @defgroup HASH 
  * @brief HASH driver modules
  * @{
  */


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SHA1BUS_TIMEOUT    ((uint32_t) 0x00010000)
uint8_t Sha1_output[20];
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void HASH_SHA1_DMA(uint32_t* input/*, HASH_MsgDigest* Msg_Digest*/);
void Display_HMAC_SHA1Digest                              (uint8_t* input);
/* Private functions ---------------------------------------------------------*/


/** @defgroup HASH_Private_Functions
  * @{
  */ 


/** @defgroup HASH_Group6 High Level SHA1 functions
 *  @brief   High Level SHA1 Hash and HMAC functions 
 *
@verbatim   
 ===============================================================================
                          High Level SHA1 Hash and HMAC functions
 ===============================================================================*/








/**
  * @brief  Compute the HMAC SHA1 digest.
  * @param  Key: pointer to the Key used for HMAC.
  * @param  Keylen: length of the Key used for HMAC.  
  * @param  Input: pointer to the Input buffer to be treated.
  * @param  Ilen: length of the Input buffer.
  * @param  Output: the returned digest
  * @retval An ErrorStatus enumeration value:
  *          - SUCCESS: digest computation done
  *          - ERROR: digest computation failed
  */
ErrorStatus My_HMAC_SHA1(uint8_t *Key, uint32_t Keylen, uint8_t *Input,
                      uint32_t Ilen, uint8_t Output[20])
{
  HASH_InitTypeDef SHA1_HASH_InitStructure;
  HASH_MsgDigest SHA1_MessageDigest;
  __IO uint16_t nbvalidbitsdata = 0;
  __IO uint16_t nbvalidbitskey = 0;
  uint32_t i = 0;
  __IO uint32_t counter = 0;
  uint32_t busystatus = 0;
  ErrorStatus status = SUCCESS;
  uint32_t keyaddr    = (uint32_t)Key;
  uint32_t inputaddr  = (uint32_t)Input;
  uint32_t outputaddr = (uint32_t)Output;


  /* Number of valid bits in last word of the Input data */
//   nbvalidbitsdata = 8 * (Ilen % 4);


//   /* Number of valid bits in last word of the Key */
//   nbvalidbitskey = 8 * (Keylen % 4);


  /* HASH peripheral initialization */
  HASH_DeInit();


  /* HASH Configuration */
  SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
  SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HMAC;
  SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_32b;
  SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
  HASH_Init(&SHA1_HASH_InitStructure);
  HASH_DMACmd(ENABLE) ;




           HASH_SHA1_DMA((uint32_t*)keyaddr);
          HASH_SHA1_DMA((uint32_t*)inputaddr);
          HASH_SHA1_DMA((uint32_t*)keyaddr);
     
         HASH_GetDigest(&SHA1_MessageDigest);
        *(uint32_t*)(outputaddr)  = __REV(SHA1_MessageDigest.Data[0]);
        outputaddr+=4;
        *(uint32_t*)(outputaddr)  = __REV(SHA1_MessageDigest.Data[1]);
        outputaddr+=4;
        *(uint32_t*)(outputaddr)  = __REV(SHA1_MessageDigest.Data[2]);
        outputaddr+=4;
        *(uint32_t*)(outputaddr)  = __REV(SHA1_MessageDigest.Data[3]);
        outputaddr+=4;
        *(uint32_t*)(outputaddr)  = __REV(SHA1_MessageDigest.Data[4]);
          Display_HMAC_SHA1Digest (Output);
          


  return status;  
}
/******dma conf***************/
void HASH_SHA1_DMA(uint32_t* input)
{

  DMA_InitTypeDef DMA_InitStructure                                       ;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE)                     ;




  /*DMA Configuration*****************************************************/
  DMA_DeInit(DMA2_Stream7)                                                ;
  DMA_InitStructure.DMA_Channel            = DMA_Channel_2                ;
  DMA_InitStructure.DMA_PeripheralBaseAddr = HASH_DIN_REG_ADDR            ;
  DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)input              ;
  DMA_InitStructure.DMA_DIR                = DMA_DIR_MemoryToPeripheral   ;
  DMA_InitStructure.DMA_BufferSize         = (uint32_t) 261  ;
  DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable    ;
  DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable         ;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte  ;
  DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte    ;
  DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal              ;
  DMA_InitStructure.DMA_Priority           = DMA_Priority_High            ;
  DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable         ;
  DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_Full       ;
  DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single       ;
  DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single   ;
  /* Configure the DMA Stream ********************************************/
  DMA_Init(DMA2_Stream7, &DMA_InitStructure);


  /* Enable HASH DMA */
  HASH_DMACmd(ENABLE);


  /* Enable DMA2 Transfer */
  DMA_Cmd(DMA2_Stream7, ENABLE);


  /* Note :  When the DMA is enabled, it provides the information to the hash 
             processor when it is transferring the last data word. Then the 
             padding and digest computation are performed automatically as if 
             DCAL had been written to 1.*/


  /* Wait until DMA Transfer completed */
  while (DMA_GetFlagStatus(DMA2_Stream7, DMA_FLAG_TCIF7) == RESET);
  DMA_Cmd(DMA2_Stream7, DISABLE);
     HASH_DMACmd(DISABLE);
  /* Wait until the Busy flag is RESET */
  while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET);
     
     
  HASH_StartDigest();
     
}
/******main*****************/
#include "stm32f4xx.h"




/** @addtogroup STM32F4xx_StdPeriph_Examples
  * @{
  */


/** @addtogroup HMAC_SHA1_MD5
  * @{
  */ 


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define INPUT_TAB_SIZE        ((uint32_t) 261)
#define KEY_TAB_SIZE          ((uint32_t) 261)


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/


/* "The hash processor is a fully compliant implementation of the secure
    hash algorithm (SHA-1), the MD5 (message-digest algorithm 5) hash 
    algorithm and the HMAC (keyed-hash message authentication code)
    algorithm suitable for a variety of applications.*** STM32 ***"
  */
 uint8_t Input[INPUT_TAB_SIZE] =  
                          {0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
                           0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
                           0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
                           0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
                           0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
                           0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
                           0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
                           0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
                           0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
                           0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
                           0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
                           0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
                           0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
                           0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
                           0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
                           0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
                           0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
                           0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
                           0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
                           0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
                           0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
                           0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
                           0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
                           0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
                           0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
                           0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
                           0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
                           0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
                           0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
                           0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
                           0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
                           0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
                           0x32,0x20,0x2a,0x2a,0x2a};


/* key = "The hash processor is a fully compliant implementation of the secure
          hash algorithm (SHA-1), the MD5 (message-digest algorithm 5) hash algorithm
          and the HMAC (keyed-hash message authentication code)algorithm suitable for 
          a variety of applications.*** STM32 ***" 
  */
 uint8_t Key[KEY_TAB_SIZE] =  
                        {0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
                         0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
                         0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
                         0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
                         0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
                         0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
                         0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
                         0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
                         0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
                         0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
                         0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
                         0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
                         0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
                         0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
                         0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
                         0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
                         0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
                         0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
                         0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
                         0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
                         0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
                         0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
                         0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
                         0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
                         0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
                         0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
                         0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
                         0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
                         0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
                         0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
                         0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
                         0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
                         0x32,0x20,0x2a,0x2a,0x2a};
                                  


uint8_t Sha1output[20];


/* Private function prototypes -----------------------------------------------*/
void USART_Config(void);
void Display_HMAC_MainMessage(uint8_t* input,uint8_t* key,uint32_t input_length, uint32_t key_length);
void Display_HMAC_SHA1Digest                              (uint8_t* input);
ErrorStatus My_HMAC_SHA1(uint8_t *Key, uint32_t Keylen, uint8_t *Input,
                      uint32_t Ilen, uint8_t Output[20]);
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */           
  /* USART configuration */
  USART_Config();
  /* Enable HASH clock */
  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE);
     
  /* Display the original message */
Display_HMAC_MainMessage(Input,Key,INPUT_TAB_SIZE, KEY_TAB_SIZE);


     
/*=============================================================================
  HMAC SHA-1 Digest Computation
==============================================================================*/


  /* HMAC SHA-1 Digest Computation */
//   HMAC_SHA1((uint8_t*)Key, KEY_TAB_SIZE,
//             (uint8_t*)Input, INPUT_TAB_SIZE,
//             Sha1output);
My_HMAC_SHA1((uint8_t*)Key, KEY_TAB_SIZE,
            (uint8_t*)Input, INPUT_TAB_SIZE,
            Sha1output);


  /* Display the HMAC SHA1 digest */
  Display_HMAC_SHA1Digest (Sha1output);








  while(1)
     {}          
}

Outcomes