Bas Vermeulen

MCF5329 - Using the Message Digest Hardware Accelerator (MDHA)

Discussion created by Bas Vermeulen on Sep 28, 2006
Latest reply on Sep 8, 2008 by Georg Brechlin
Hi all,

We're trying to use the MDHA to generate an SHA-1 hash from some data we have in memory.
The first block generates the right hash, but more blocks get us a wrong result.

The code we are using:

int main()
{
    int     iRetVal = 0;
    uint32  pu32TestData[32];
    uint32 *pu32HeaderPtr;
    uint32  u32HeaderSize;
    uint32  u32TotalBytes;
    uint8   u8Counter;
    uint32  u32BytesInFifo;

    uint32  u32h0;
    uint32  u32h1;
    uint32  u32h2;
    uint32  u32h3;
    uint32  u32h4;

    memset(pu32TestData, 0x0, 256);
      
    /*
     * Start initializing the MDHA (the hardware module that calculates the
     * hash
     */
  
    /* Reset the MDHA */
    MCF_MDHA_MDCMR = MCF_MDHA_MDCMR_SWR;
  
    while ((MCF_MDHA_MDSR & MCF_MDHA_MDSR_RD) == 0)
    {
        /* Wait until the reset completed */
    }

    /* The first 4 calculations no DMA and no interrupts are used */
    MCF_MDHA_MDCR = MCF_MDHA_MDCR_DMAL(1) | MCF_MDHA_MDCR_ENDIAN;
  
    /* Initialise the SHA algorithm's starting registers */
    MCF_MDHA_MDMR = MCF_MDHA_MDMR_INIT | MCF_MDHA_MDMR_PDATA;

    u32HeaderSize = 68;
    u32TotalBytes = 0;
    pu32HeaderPtr = pu32TestData;
  
    while (u32HeaderSize > 0)
    {
        /* Now fill the FIFO with the first 16 uint32's */
        u8Counter = 0;
        u32BytesInFifo = 0;

        while ((u8Counter  16) && u32HeaderSize > 3)
        {
            MCF_MDHA_MDIN = *pu32HeaderPtr++;
            u32HeaderSize -= 4;
            u32BytesInFifo += 4;
            u8Counter++;
        }
      
        if ((u8Counter  16) && (u32HeaderSize > 0))
        {
            MCF_MDHA_MDIN = *pu32HeaderPtr++;
            u32BytesInFifo += (uint8)u32HeaderSize;
            u32HeaderSize = 0;
        }
      
        /* Fifo Filled */
        MCF_MDHA_MDDSR = u32BytesInFifo;
      
        /* GO!!!!! */
        MCF_MDHA_MDCMR = MCF_MDHA_MDCMR_GO;
      
        /* Now keep polling until the hash is calculated */
        while ((MCF_MDHA_MDSR & MCF_MDHA_MDSR_INT) != 1)
        {
            /*
             * For the time being, do nothing
             */
        }
      
        if ((MCF_MDHA_MDSR & MCF_MDHA_MDSR_ERR) != 0)
        {
            printf("An error occurred generating the SHA-1 hash\n\r");
            iRetVal = -1;
            u32TotalBytes = 0;
        }
        else if ((MCF_MDHA_MDSR & MCF_MDHA_MDSR_DONE) != 0)
        {
            u32TotalBytes += u32BytesInFifo;

            if (u32HeaderSize == 0)
            {
                u32h0 = MCF_MDHA_MDA0;
                u32h1 = MCF_MDHA_MDB0;
                u32h2 = MCF_MDHA_MDC0;
                u32h3 = MCF_MDHA_MDD0;
                u32h4 = MCF_MDHA_MDE0;

                if ((u32h0 == 0x46fe3f0a) &&
                    (u32h1 == 0x75b18d40) &&
                    (u32h2 == 0x6d86aca0) &&
                    (u32h3 == 0xed37bb70) &&
                    (u32h4 == 0x6ed8246b))
                {
                    printf("HASH OK\n\r");
                }
                else
                {
                    printf("HASH INCORRECT\n\r");
                }
            }
            else
            {
                MCF_MDHA_MDCMR = MCF_MDHA_MDCMR_CI;
            }
        }
    }
  
    return iRetVal;
}


If anyone can tell us what we are doing wrong, or if anyone can post some (working) example code (no matter how simple), that would be great.

Regards,

Bas Vermeulen

Outcomes