This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

HMAC SHA 256 Signature Does not match

Hi,

I'm referring document SW-TM4C-DRL-UG-2.0 from Tivaware, topic 25 SHA/MD5. I'm trying example code. The example code works. But when i tried to verify the result  with some python script, they don't match.  My python script works properly as I can verify HMAC result with some online calculators available. Why do the HMAC signature calculated by Tivaware example not match with online calculators available?

As per sample example in the document mentioned above -data and key are defined as

uint32_t

g_ui32HMACKey[16] =

{

0x8a5f1b22, 0xcb935d29, 0xcc1ac092, 0x5dad8c9e,

0x6a83b39f, 0x8607dc60, 0xda0ba4d2, 0xf49b0fa2,

0xaf35d524, 0xffa8001d, 0xbcc931e8, 0x4a2c99ef,

0x7fa297ab, 0xab943bae, 0x07c61cc4, 0x47c8627d

};

g_ui32RandomData[16] =

{

0xe2bec16b, 0x969f402e, 0x117e3de9, 0x2a179373,

0x578a2dae, 0x9cac031e, 0xac6fb79e, 0x518eaf45,

0x461cc830, 0x11e45ca3, 0x19c1fbe5, 0xef520a1a,

0x45249ff6, 0x179b4fdf, 0x7b412bad, 0x10376ce6

};

To feed above data to python script, I'm attaching all the hex numbers in above arrays as a string as below

g_ui32HMACKey='5f8a221b93cb295d1acc92c0ad5d9e8c836a9fb3078660dc0bdad2a49bf4a20f35af24d5a8ff1d00c9bce8312c4aef99a27fab9794abae3bc607c41cc8477d62'
g_ui32RandomData='e2bec16b969f402e117e3de92a179373578a2dae9cac031eac6fb79e518eaf45461cc83011e45ca319c1fbe5ef520a1a45249ff6179b4fdf7b412bad10376ce6'

Is the above method of treating key and message data as a string correct?

 

  • I'm tyring with SHA1 in the example given not SHA 256 as per the heading of the post

  • Hello Abhay,

    There was a similar post on CRC32 where the computation of CRC by a script and TM4C129 device was not matching. You may want to first look at the way the scripts work (since details on the internals of SHA in TM4C129 is not public information)

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/364008.aspx

    Regards

    Amit

  • Hi Amit,

    Do you mean to say that the results generated by driverlib fuction to calculate HMAC must be correct in this case? As we are evaluating the script results also with the online HMAC calculator with the same keys and they are matching.

    Looking for how the script is calculating HMAC is definitely one of the way to look for, but isn't there any better way to solve this problem in some quik steps.

  • Hi Amit,

    I've put in some work on this this morning, and I had some questions for you. We're following the TI hash example given in the User's Guide for TivaWare, but so far as we can tell, there's no way to make that agree with any other HMAC SHA256 implementation. Obviously, the goal of a hash algorithm is to get the same answer in all places, so this is somewhat problematic.

    Currently, I'm using the code in the HMAC Example given in the user guide, with two exceptions:

    • I've replaced the key with { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 'AB', 'C123' };
    • I've replaced the data with { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 'he', 'llow', 'orld'};

    Using the online calculator located at http://asecuritysite.com/Encryption/hmac, you get this result: 3E2435D1F85D4B8E969BE3B290579F3DB4DFD9624EEF6D8767CE4C960DE408BC. Using the example code, you get: {0xD409EC4F, 0xCDDD2525, 0x295C9F05, 0xA5EE2775, 0xF1BAE1C6, 0xE2D1E41B, 0xCAB9509E, 0xF07505E2}

    Note that I also tried this with the key being: { 'ABC1', '23\0\0', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

    and the data being: { 'hell', 'owor', 'ld\0\0', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

    And this did not match the online calculator any more closely.

    How can I achieve a result that matches anyone else's result using TI hardware?

  • Hello benjamin, srikant,

    I will need to debug the application code that you have. Can you attach the same so that we are all on the same page. Then I can run the online calculator to see why the difference.

    Regards

    Amit

  • Hi Amit,

    Here is the entirety of my code. As you can see, the only thing that is different from the programming example is the content of the key and data registers.

    uint32_t g_ui32HMACKey[16] = { 'ABC1', '23\0\0', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
    uint32_t g_ui32RandomData[16] = { 'hell', 'owor', 'ld\0\0', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};


    uint32_t pui32HashResult[30];

    SysCtlPeripheralEnable(SYSCTL_PERIPH_CCM0);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CCM0))
    {
    }

    SHAMD5Reset(SHAMD5_BASE);

    SHAMD5ConfigSet(SHAMD5_BASE, SHAMD5_ALGO_HMAC_SHA256);

    SHAMD5HMACKeySet(SHAMD5_BASE, g_ui32HMACKey);

    SHAMD5HMACProcess(SHAMD5_BASE, g_ui32RandomData, 8, pui32HashResult);

    Thanks,

    Ben

  • Hello Benjamin.

    Thanks for sharing the code. I will check it up and provide a resolution. However since it would need some study work on the weblink for SHA, it may take upto a few days

    Regards

    Amit

  • Hello Benjamin,

    Attached is the modified code that matches the HMAC calculator. I know it is delayed, but hopefully it would still be useful. This one matches the online tool and also I have tested it with the RFC standard Tests 1-2.

    3365.TM4C129_SHA.c
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_uart.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/rom.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/shamd5.h"
    #include "utils/uartstdio.h"
    
    //*****************************************************************************
    //
    // Number of bytes to send and receive.
    //
    //*****************************************************************************
    #if 0
    uint32_t g_ui32HMACKey[16] 		=  {0x6566654a, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0
    								   };
    uint32_t g_ui32RandomData[16] 	=  {0x74616877, 0x206f6420, 0x77206179, 0x20746e61,
    									0x20726f66, 0x68746f6e, 0x3f676e69, 0x0,
    									0x0, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0
    	   	   	   	   	   	   	   	   };
    #define STRINGLENGTH 28
    #endif
    #if 0
    uint8_t g_ui8HMACKey[64] = "Jefe";
    uint8_t g_ui8RandomData[64] = "what do ya want for nothing?";
    #define STRINGLENGTH 28
    #endif
    #if 1
    uint8_t g_ui8HMACKey[64] = "ABC123";
    uint8_t g_ui8RandomData[64] = "helloworld";
    #define STRINGLENGTH 10
    #endif
    #if 0
    uint32_t g_ui32HMACKey[16] 		=  {0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b,
    									0x0b0b0b0b, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0
    								   };
    uint32_t g_ui32RandomData[16] 	=  {0x54206948, 0x65726568, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0,
    									0x0, 0x0, 0x0, 0x0
    	   	   	   	   	   	   	   	   };
    #endif
    //*****************************************************************************
    //
    // This function sets up UART0 to be used for a console to display information
    // as the example is running.
    //
    //*****************************************************************************
    void
    InitConsole(void)
    {
        //
        // Enable GPIO port A which is used for UART0 pins.
        // TODO: change this to whichever GPIO port you are using.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Configure the pin muxing for UART0 functions on port A0 and A1.
        // This step is not necessary if your part does not support pin muxing.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
    
        //
        // Enable UART0 so that we can configure the clock.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
        //
        // Use the internal 16MHz oscillator as the UART clock source.
        //
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
        //
        // Select the alternate (UART) function for these pins.
        // TODO: change this to select the port/pin you are using.
        //
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Initialize the UART for console I/O.
        //
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    //*****************************************************************************
    //
    // Configure SSI3 in master Freescale (SPI) mode.  This example will send out
    // 3 bytes of data, then wait for 3 bytes of data to come in.  This will all be
    // done using the polling method.
    //
    //*****************************************************************************
    int
    main(void)
    {
    	uint32_t ui32Counter;
    	uint32_t pui32HashResult[32];
    	uint8_t  *ptr;
    
    	InitConsole();
    
    	SysCtlPeripheralDisable(SYSCTL_PERIPH_CCM0);
    	SysCtlPeripheralReset(SYSCTL_PERIPH_CCM0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_CCM0);
    
    	while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CCM0))
    	{
    	}
    
    	SHAMD5Reset(SHAMD5_BASE);
    
    	SHAMD5ConfigSet(SHAMD5_BASE, SHAMD5_ALGO_HMAC_SHA256);
    
    	//SHAMD5HMACKeySet(SHAMD5_BASE, g_ui32HMACKey);
    	//SHAMD5HMACProcess(SHAMD5_BASE, g_ui32RandomData, 28, pui32HashResult); // orig -> 8
    
    	SHAMD5HMACKeySet(SHAMD5_BASE, (uint32_t *) g_ui8HMACKey);
    	SHAMD5HMACProcess(SHAMD5_BASE, (uint32_t *) g_ui8RandomData, STRINGLENGTH, pui32HashResult); // orig -> 8
    
    	ptr = (uint8_t *)&pui32HashResult[0];
    
    	for(ui32Counter=0;ui32Counter<32;ui32Counter++)
    	{
    		UARTprintf("%02x",*ptr++);
    	}
    
        //
        // Loop Here
        //
        while(1);
    }
    

    Regards

    Amit