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.

MSP432E401Y: MD5 Accelerator in multiple calls ?

Part Number: MSP432E401Y
Other Parts Discussed in Thread: SHA-256

Hi,

I would like to compute the MD5 hash for a file on the embedded file system (SPIFFS) I do access in multiple rounds. While it always works if(!) the file is small and I can read the whole file in one round and call:

MAP_SHAMD5HMACProcess(SHAMD5_BASE, (uint32_t *) ptrRdData, res, (uint32_t *) ucHashResult);

it never works on multiple rounds, where I need to read several blocks of file data from the system. The read buffer is not big enough to hold all the data from the file read in one round.

Q: What do I need to do in order to run the accelerator several times until all blocks read are processed and I do get

the correct hash value?

Markus

  • Hi,

    we're trying to pull in an expert on this, and come back to you as seen as possible.

    Best regards

    Peter

  • Hi,

    according to our expert re-entrant processing should work, unless the file size is such that it cannot meet the length requirement.

    Best regards

    Peter

  • Hi thanks's for the update.

    Up to now I did assume the length requirement is handled by the function call it meaning padding is done automatically. I already use it to compute the message digest for the firmware stored in flash and do compare it with the firmare file on my windows 10 PC. This works the numbers do match. And I don't need to do anything than to input the length of the firmware. Therefore I am a little confused about what frame length requirement of the file we do reference.

    For the firmware to check against the image on the PC (still needs hex2bin) I run the following code and the numbers computed do match.

                sysCfg_ComputeMD5SHADigest( iAlgo,
                                            NULL,
                                            NULL,    // The first address in flash
                                            iLength, // The length of the data to compute the hash
                                            (uint32_t *) ucHashResult);

    where iAlgo is the type of msg digest to be used. MD5 or SHA1 in my example.

    where iLength is the effective size of the fw being downloaded ->

    // Compute and print the MD5 & SHA-1 hash value for the firmware
    int        iLength = (int) _symval(&__TI_CINIT_Limit); // fw code size

    The function itself decomposes to the following:

    void sysCfg_ComputeMD5SHADigest( int        iAlgo,       // Can be MD5, SHA1, SHA-224 or SHA-256
                                     uint32_t * ptrStartKey, // Optionally specify a key to start with
                                     uint32_t * ptrData,     // A reference to the start of the data
                                     int        iLength,     // The length of the data in number of bytes
                                     uint32_t * ptrResult){  // A reference where to store the hash value

        // Select the hash algorithm to be used
        MAP_SHAMD5ConfigSet(SHAMD5_BASE, iAlgo);

        // Copy a custom key to fill the pipe of the SHA/MD5 module?
        if (ptrStartKey) {
            MAP_SHAMD5HMACKeySet(SHAMD5_BASE, ptrStartKey);
        }

        // Do the computation. Make sure the size of the result buffer is big enough!
        MAP_SHAMD5HMACProcess(SHAMD5_BASE, ptrData, iLength, ptrResult);

    } // sysCfg_ComputeMD5SHADigest

    As you can easily see, I don't take care of the effective length. I just use what the linker variable reports.

    Q: What is the frame length requirement I have to take care of it?

    Q: Can I just call my hash computation function several times with the buffer pointer and the length adjusted?

    And if so do I need some padding which I did not use in the firmware example described above?

    br

    Markus

  • I am still having no solution on how to use the driverlib API to perform a non auto-closing hashing operation for multiple rounds. It works always in one round due to the autoclosing functionality in the mode register of the accelerator, most example do use.

    Q: How do I need to configure the mode register of the accelerator in order to compute the message digest on multiple computational rounds?

    br

    Markus

  • Hi

    I do have some news, but I am not ready yet. The multiround does work only-and-only if I have the two things.

    - A HW breakpoint &(!) the register view within CCS studio pointing to the register set of the SHAMD5 component.

    If this is the case I can compute msg digest for large files that I read from the on-chip flash file system (SPIFFS) and

    the signature does match the signature I get for the same file on a W10 machine. So far so good. It seems that I do lack

    some register readings or settings that the debugger does when it updates the register view.

    Any help would be appreciated.

    br

    Markus

    below is the code block that does work if I step & view inside CCS

    MAP_SHAMD5Reset(SHAMD5_BASE);        // Reset before use
            MAP_SHAMD5ConfigSet(SHAMD5_BASE, i); // Select the hash algorithm to be used

            // Disable auto close, since it is very likely that multiple rounds are needed
            HWREG(SHAMD5_BASE + SHAMD5_O_MODE) &= ~(SHAMD5_MODE_CLOSE_HASH);

            /* Read chunks of data from the file & compute hash until EOF
             * We need to align the buffer used to an int addr offset!
             */

            uint32_t * ptrRdData = (uint32_t *) ((((uint32_t) buffer) + 3) & 0xfffffffc);
            uint32_t * ptrWrData = NULL;

            do { // fixme!

                /* Read a chunk of data from the file. We use the terminal reply
                 * buffer to hold the amount of temporary file data to process
                 * the hash algo.
                 */

                // Digest computation rounds must match input block width!
                res = SPIFFS_read(&fs, fd, (u8_t *) ptrRdData, iBuffLength - (iBuffLength % 64));

                if (SPIFFS_eof(&fs, fd)) { // Activate auto-close on the last round

                    HWREG(SHAMD5_BASE + SHAMD5_O_MODE) |= (SHAMD5_MODE_CLOSE_HASH);

                    if (res > 0) {

                        // Last round any length. Mostly not modulo 64
                        SHAMD5DataProcess(SHAMD5_BASE, (uint32_t *) ptrRdData, res, (uint32_t *) ucHashResult);
                    }

                    break;
                }

                // Wait for the accelerator context registers to become ready
                while( ( HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_CONTEXT_READY) == 0 ) { ; }

                // Update the length register. The length should be modulo 64!
                HWREG(SHAMD5_BASE + SHAMD5_O_LENGTH) = res;

                // Compute number of 64 bytes blocks of data to feed the accelerator
                res = res / 64;
                ptrWrData = ptrRdData;

                /* Loop through all the blocks and write them into the data registers
                 * making sure to block additional operations until we can write the
                 * next 16 words.
                 */

                for(n = 0; n < res; n++) {

                    SHAMD5DataWrite(SHAMD5_BASE, ptrWrData); // Write one block
                    ptrWrData += 16;
                }

                // Preserve intermediate values
                HWREG(SHAMD5_BASE + SHAMD5_O_MODE) &= ~(SHAMD5_MODE_ALGO_CONSTANT);

            } while (1);

**Attention** This is a public forum