cancel
Showing results for 
Search instead for 
Did you mean: 

HMAC with DMA transfert

khaled3310
Associate II
Posted on March 09, 2013 at 14:40

The original post was too long to process during our migration. Please click on the attachment to read the original post.
10 REPLIES 10
Posted on March 09, 2013 at 15:21

Is the result predictable? What is the expected output? What is the observed output?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
khaled3310
Associate II
Posted on March 09, 2013 at 15:49

expected results

======================================

 ====         HMAC Example         ====

 ======================================

 ---------------------------------------

 Text to be Hashed ( 2088 bits): 

 ---------------------------------------

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 ***

 ---------------------------------------

 HMAC Key ( 2088 bits): 

 ---------------------------------------

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 ***

 ---------------------------------------

  SHA1 Message Digest (160 bits):

 ---------------------------------------

 H0 = [0x2b47ef34]  

 H1 = [0xf66658be]  

 H2 = [0x3b2ac6ec]  

 H3 = [0x5885f21e]  

 H4 = [0xd59fddad]  

 

Results: note that the results change when i change 1 of this parametrs 

  DMA_InitStructure.DMA_BufferSize         = (uint32_t) 261  ;  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word  ;

  DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Word   ;

 ======================================

 ====         HMAC Example         ====

 ======================================

 ---------------------------------------

 Text to be Hashed ( 2088 bits): 

 ---------------------------------------

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 ***

 ---------------------------------------

 HMAC Key ( 2088 bits): 

 ---------------------------------------

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 ***

 ---------------------------------------

 ---------------------------------------

  SHA1 Message Digest (160 bits):

 ---------------------------------------

 H0 = [0x10032a68]  

 H1 = [0x5e144fec]  

 H2 = [0xa982eb98]  

 H3 = [0x83bea196]  

 H4 = [0x21096620]  

khaled3310
Associate II
Posted on March 09, 2013 at 15:55

i used this function as example you can find it  on stm32F4xx_hash_sha1.c  and it works fine i just need to transfer data to the hash possessor with dma (data are the key and the message to hash)

ErrorStatus 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_8b;

  if(Keylen > 64)

  {

    /* HMAC long Key */

    SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;

  }

  else

  {

    /* HMAC short Key */

    SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;

  }

  HASH_Init(&SHA1_HASH_InitStructure);

  /* Configure the number of valid bits in last word of the Key */

  HASH_SetLastWordValidBitsNbr(nbvalidbitskey);

  /* Write the Key */

  for(i=0; i<Keylen; i+=4)

  {

    HASH_DataIn(*(uint32_t*)keyaddr);

    keyaddr+=4;

  }

  /* Start the HASH processor */

  HASH_StartDigest();

  /* wait until the Busy flag is RESET */

  do

  {

    busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);

    counter++;

  }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));

  if (busystatus != RESET)

  {

     status = ERROR;

  }

  else

  {

    /* Configure the number of valid bits in last word of the Input data */

    HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);

    /* Write the Input block in the IN FIFO */

    for(i=0; i<Ilen; i+=4)

    {

      HASH_DataIn(*(uint32_t*)inputaddr);

      inputaddr+=4;

    }

    /* Start the HASH processor */

    HASH_StartDigest();

    /* wait until the Busy flag is RESET */

    counter =0;

    do

    {

      busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);

      counter++;

    }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));

    if (busystatus != RESET)

    {

      status = ERROR;

    }

    else

    {  

      /* Configure the number of valid bits in last word of the Key */

      HASH_SetLastWordValidBitsNbr(nbvalidbitskey);

      /* Write the Key */

      keyaddr = (uint32_t)Key;

      for(i=0; i<Keylen; i+=4)

      {

        HASH_DataIn(*(uint32_t*)keyaddr);

        keyaddr+=4;

      }

      /* Start the HASH processor */

      HASH_StartDigest();

      /* wait until the Busy flag is RESET */

      counter =0;

      do

      {

        busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY);

        counter++;

      }while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET));

      if (busystatus != RESET)

      {

        status = ERROR;

      }

      else

      {

        /* Read the message digest */

        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]);

      }

    }  

  }

  return status;  

}

Posted on March 09, 2013 at 17:01

261 bytes, not 261 words = 261 x 4

The DMA count is in units, to do words the buffer must have such alignment, ie 261 is not divisible by 4
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
khaled3310
Associate II
Posted on March 09, 2013 at 19:24

Posted on March 09, 2013 at 22:38

so im supposed to change the buffer to one with a size that is multiple of 4?

What I'm saying is you can't expect to hash data 32-bits at a time if you aren't working with integral lumps of 4 bytes. Using Word or HalfWord for a group of 261 bytes ain't going to work. Maybe you can decompose the transfer into runs which are optimal for different DMA transfer widths? Or course you might want to consider doing that with a scatter/gather list or chain under interrupt, rather than polling completion.

260 bytes would be 65 words (32-bit), and that would be the length programmed into the DMA controller for word transfers.

I'd need to do a SHA1 of your original data to confirm the correct response, and the go dig up my F215 board to confirm the computation via the chip.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
khaled3310
Associate II
Posted on March 10, 2013 at 18:55

Thank you clive i added 3 more bytes and it worked well 

can i ask you an other favor??
Posted on March 10, 2013 at 19:14

can i ask you an other favor??

Sure, if it can be asked in the form of a question.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
khaled3310
Associate II
Posted on March 10, 2013 at 19:26

In my application i need to use the

Cryptographic processor (CRYP) some times to encrypt and other times to decrypt all this with the use of dma and with the minimum lost of time in the initialization  i figured out that there’s only few differences between crypt and decrypt initialization but if change only the parameters that are deferent results come out corrupted .

any idea to minimize the number of parameters to configure ???