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.

Problems using SHAMD5DataWrite & SHAMD5HashLengthSet in incrementall hash calculation.

I'm trying to use the Tivaware hash acceleration functions to process  (Sha256) of a very long file by calling the SHAMD5DataWrite () & SHAMD5ResultRead () Tivaware API. But looking at the examples, I observed that this function(SHAMD5DataWrite (())  requires the prior use of SHAMD5HashLengthSet (), that requires to know a priori   the total length of bytes to be processed for the hash calculation . Looking at the  source code,  I noticed this function resets the calculation of the hash whenever it is called:

Void SHAMD5HashLengthSet (uint32_t ui32Base, uint32_t ui32Length)
{
    //
    // Check the arguments.
    //
    ASSERT (ui32Base == SHAMD5_BASE);

    //
    // Set the LENGTH register and start processing
    //
    HWREG (ui32Base + SHAMD5_O_LENGTH) = ui32Length;
}

I have tested, and I have concluded. that  SHAMD5HashLengthSet () is called incrementally, the previous hash calculation is lost.

In my case to know the total length of the data in bytes precisely, it is necessary to process the entire file to count the bytes (which would take precious  time) or load the file into memory (which is not possible due to  big size of  file , dozens of Mbytes.)

So I ask  if    it be possible to save the previous state of the hash calculation using  SHAMD5DataWrite ()  in order  to process the hash  in a really incremental manner, without prior knowledge of the total bytes to be processed, as it happens in some SW libraries ( which  are very slow  to use,.wasting about 30% time of saving of file with same size  in USB Pen drive).

  • I tried  to use the procedures  described in the table above , but it did not work.

    For the first  64 bytes it works and calculates the digest corretly , but when I try to write to the LENGHT, ALGO, ALGO_CONSTANT or SHA MODE registers for the second interration,   the value of the previous DIGEST is lost ( all of theh go to ZERO)  and  even  if  I restore the previous parcial  digest  writing it directly  in the SHA_IDIGEST_A to SHA_IDIGEST_H registers ,   it  does not work,  because that registers seem to be  read only and doesnt accept the writen values at all.

  • Hi Ricardo,
    Is it possible for you to precalculate the length of your input and encode this length information as part of your payload, i.e. the first word of your payload will contain the length of the input file.
  • I have solved the problem just doing the hash finalization by software, I put some code bellow.
    In my tests it worked well,  doing the  hash   40x faster  than software only.

    static unsigned char sha256_padding[64] =
    {
    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };

    #define PUT_UINT32(n,b,i) \
    { \
    (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
    (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
    (b)[(i) + 3] = (unsigned char) ( (n) ); \
    }


    // Write blocks of 64 bytes
    void SHAMD5DataWriteInc(uint32_t ui32Base, uint32_t * pui32Src, int Block)
    {
    uint32_t ui32Counter;

    if( Block==0) HashCount=0;
    else HashCount+=64;


    if(Block>0)
    {

    // Blocks > 0;
    // ALGO_CONSTANT=0
    if( HWREG(ui32Base + SHAMD5_O_MODE)|SHAMD5_MODE_ALGO_CONSTANT )
    HWREG(ui32Base + SHAMD5_O_MODE) &= ~(SHAMD5_MODE_ALGO_CONSTANT);

    HWREG(ui32Base +SHAMD5_O_DIGEST_COUNT) =HashCount;

    }
    else{
    // Block = 0;
    // ALGO_CONSTANT=1
    HWREG(ui32Base + SHAMD5_O_MODE)= SHAMD5_ALGO_SHA256 |SHAMD5_MODE_ALGO_CONSTANT;
    }

    if( ( HWREG(ui32Base + SHAMD5_O_MODE)| (SHAMD5_MODE_CLOSE_HASH)))
    HWREG(ui32Base + SHAMD5_O_MODE) &= ~(SHAMD5_MODE_CLOSE_HASH);

    //
    // Wait for the module to be ready to accept data.
    //

    HWREG(ui32Base + SHAMD5_O_LENGTH) = 64;


    while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_INPUT_READY) == 0)
    {
    }


    //
    // Write the 16 words of data.
    //
    for(ui32Counter = 0; ui32Counter < 64; ui32Counter += 4)
    {
    HWREG(ui32Base + SHAMD5_O_DATA_0_IN + ui32Counter) = *pui32Src++;
    }

    // Write the last bytes and close the hash
    void SHAMD5DataWriteLast(uint32_t ui32Base, uint32_t * pui32Src, int last, int lenght, int Block)
    {
    uint32_t ui32Counter;
    unsigned char msglen[8];
    unsigned int padn=0;


    if(Block > 0)
    {
    // Hash Finalization by softwate
    memset(LastBuffer,0,sizeof(LastBuffer));
    memcpy(LastBuffer,pui32Src,last);
    unsigned int high = ( lenght>> 29 );
    unsigned int low = ( lenght << 3 );

    PUT_UINT32( high, msglen, 0 );
    PUT_UINT32( low, msglen, 4 );
    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
    memcpy(&LastBuffer[last],sha256_padding,padn);

    memcpy(&LastBuffer[last+padn],msglen,8);
    lenght=last +padn+8;

    pui32Src=( uint32_t *) LastBuffer;

    }

    if(Block > 0){
    // ALGO_CONSTANT=0
    HWREG(ui32Base + SHAMD5_O_LENGTH) = lenght;
    HWREG(ui32Base + SHAMD5_O_MODE) &= ~(SHAMD5_MODE_ALGO_CONSTANT);
    HWREG(ui32Base + SHAMD5_O_MODE) |= (SHAMD5_MODE_CLOSE_HASH);
    }
    else{
    // ALGO_CONSTANT=1
    HWREG(ui32Base + + SHAMD5_O_MODE)= SHAMD5_ALGO_SHA256|SHAMD5_MODE_ALGO_CONSTANT
    HWREG(ui32Base + SHAMD5_O_LENGTH) = lenght;
    }


    //
    // Wait for the module to be ready to accept data.
    //
    while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_INPUT_READY ) == 0 && lenght>0)
    {
    }

    //
    // Write the last words of data.
    //
    for(ui32Counter = 0; ui32Counter < lenght; ui32Counter += 4)
    {
    HWREG(ui32Base + SHAMD5_O_DATA_0_IN + ui32Counter) = *pui32Src++;
    }


    while((HWREG(ui32Base + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) ==
    0)
    {
    }
    }