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.

CC2642R: Issue with aes and sha drivers

Part Number: CC2642R

Can we use SHA2 and AES drivers in polling mode in multithreaded environment for simultaneous process? We are seeing an abnormal behaviour in case of such simultaneous access, the SHA function addData() does not return.

  • The SDK version is 5.10.

  • I am able to reproduce this very easily by modifying the existing example project under ti\simplelink_cc13x2_26x2_sdk_5_10_00_48\examples\rtos\CC26X2R1_LAUNCHXL\drivers\sha2hash. As soon as the PuTTY stops printing any new data, that is where the SHA2_addData() does not return. I have attached two updated project source files. Search for "ISSUE"  in the sha2hash.c where the function never returns after the issue..

    Since the forum does not allow me to atatche syscfg file.

    /**
    * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
    * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
    * @cliArgs --board "/ti/boards/CC26X2R1_LAUNCHXL" --product "simplelink_cc13x2_26x2_sdk@5.10.00.48"
    * @versions {"data":"2021031521","timestamp":"2021031521","tool":"1.8.0+1863","templates":null}
    */

    /**
    * Import the modules used in this configuration.
    */
    const AESCCM = scripting.addModule("/ti/drivers/AESCCM", {}, false);
    const AESCCM1 = AESCCM.addInstance();
    const RTOS = scripting.addModule("/ti/drivers/RTOS");
    const SHA2 = scripting.addModule("/ti/drivers/SHA2");
    const SHA21 = SHA2.addInstance();
    const UART = scripting.addModule("/ti/drivers/UART");
    const UART1 = UART.addInstance();

    /**
    * Write custom configuration values to the imported modules.
    */
    AESCCM1.$name = "CONFIG_AESCCM_0";

    const CCFG = scripting.addModule("/ti/devices/CCFG", {}, false);
    CCFG.ccfgTemplate.$name = "ti_devices_CCFGTemplate0";

    SHA21.$name = "CONFIG_SHA2_0";

    UART1.$name = "CONFIG_UART_0";
    UART1.$hardware = system.deviceData.board.components.XDS110UART;
    UART1.txPinInstance.$name = "CONFIG_PIN_0";
    UART1.rxPinInstance.$name = "CONFIG_PIN_1";

    /**
    * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
    * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to
    * re-solve from scratch.
    */
    UART1.uart.$suggestSolution = "UART1";
    UART1.uart.txPin.$suggestSolution = "boosterpack.4";
    UART1.uart.rxPin.$suggestSolution = "boosterpack.3";

    /*
     * Copyright (c) 2016-2020, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== main_tirtos.c ========
     */
    #include <stdint.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    
    /* RTOS header files */
    #include <ti/sysbios/BIOS.h>
    
    #include <ti/drivers/Board.h>
    
    extern void *mainThread(void *arg0);
    extern void *mainThread2(void *arg0);
    
    /* Stack size in bytes */
    #define THREADSTACKSIZE    2048
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        pthread_t           thread;
        pthread_attr_t      attrs;
        struct sched_param  priParam;
        int                 retc;
    
        Board_init();
    
        /* Initialize the attributes structure with default values */
        pthread_attr_init(&attrs);
    
        /* Set priority, detach state, and stack size attributes */
        priParam.sched_priority = 1;
        retc = pthread_attr_setschedparam(&attrs, &priParam);
        retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0) {
            /* failed to set attributes */
            while (1) {}
        }
    
        retc = pthread_create(&thread, &attrs, mainThread, NULL);
        if (retc != 0) {
            /* pthread_create() failed */
            while (1) {}
        }
    
        pthread_t           thread2;
        pthread_attr_t      attrs2;
        struct sched_param  priParam2;
        int                 retc2;
    
    
        /* Initialize the attributes structure with default values */
        pthread_attr_init(&attrs2);
    
        /* Set priority, detach state, and stack size attributes */
        priParam2.sched_priority = 2;
        retc2 = pthread_attr_setschedparam(&attrs2, &priParam2);
        retc2 |= pthread_attr_setdetachstate(&attrs2, PTHREAD_CREATE_DETACHED);
        retc2 |= pthread_attr_setstacksize(&attrs2, THREADSTACKSIZE);
        if (retc != 0) {
            /* failed to set attributes */
            while (1) {}
        }
    
        retc2 = pthread_create(&thread2, &attrs2, mainThread2, NULL);
        if (retc2 != 0) {
            /* pthread_create() failed */
            while (1) {}
        }
    
    
        BIOS_start();
    
        return (0);
    }
    
    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== sha2hash.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>        // For Task_construct and task related configuration
    
    #include <ti/drivers/utils/Random.h>                                // for Random_getNumber()
    
    
    /* Driver Header files */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SHA2.h>
    #include <ti/drivers/AESCCM.h>                                  // for AES-CCM
    #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>                      // for CryptoKeyPlaintext_initKey()
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* Defines */
    #define MAX_MSG_LENGTH 256
    
    /* UART pre-formated strings */
    static const char promptStartup[]  = "\n\n\rSHA2 Driver hash demo.";
    static const char promptHash[]     = "\n\n\rRandom Number: ";
    
    /* Message buffers */
    static char       formatedMsg[MAX_MSG_LENGTH];
    
    
    /*
     *  ======== printHash ========
     */
    void printHash(UART_Handle handle, uint8_t* msg)
    {
        uint32_t i;
    
        /* Format the message as printable hex */
        for (i = 0; i < 1; i++) {
            sprintf(formatedMsg + (i * 2), "%02X", *(msg + i));
        }
    
        /* Print prompt */
        UART_write(handle, promptHash, strlen(promptHash));
        /* Print result */
        UART_write(handle, formatedMsg, strlen(formatedMsg));
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        int_fast16_t result;
    
        /* Driver handles */
        UART_Handle                 uartHandle;
        SHA2_Handle                 sha2Handle;
    
        /* UART variables */
        UART_Params                 uartParams;
    
        /* Call driver initialization functions */
        UART_init();
        SHA2_init();
    
        /* Open UART for console output */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uartHandle = UART_open(CONFIG_UART_0, &uartParams);
    
        if (!uartHandle) {
            /* UART_open() failed */
            while (1);
        }
    
        SHA2_Params params;
        SHA2_Params_init(&params);
        params.hashType = SHA2_HASH_TYPE_512;
        params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
        sha2Handle = SHA2_open(0, &params);
    
        if (!sha2Handle) {
            /* SHA2_open() failed */
            while(1);
        }
    
        /* Prompt startup message */
        UART_write(uartHandle, promptStartup, strlen(promptStartup));
    
    
        for(;;)
        {
            uint32_t randomNumber = Random_getNumber();
            unsigned char* input_correct_2 = (unsigned char *)(randomNumber % 1000);
    
            // Verify correct input generates expected output
            result = SHA2_addData(sha2Handle, input_correct_2, 8192); // --> ISSUE: Never returns
    
            randomNumber %= 17;
            Task_sleep((xdc_UInt32)randomNumber);
    
            printHash(uartHandle, &randomNumber);
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread2(void *arg0)
    {
        //
        // SETUP
        //
            AESCCM_Handle aeshandle;
            AESCCM_Params  params;
            CryptoKey cryptoKey;
            AESCCM_Operation operation;
            int_fast16_t status = 0;
    
            // Initialize the AES-CCM peripheral
            AESCCM_init();
            AESCCM_Params_init(&params);
            params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
    
            for(;;)
            {
                aeshandle = AESCCM_open(0, &params);
                if (!aeshandle) {
                    while (1);
                }
    
                uint8_t nonce[]            = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
                uint8_t aad[]              = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
                uint8_t plaintext[]        = {0x20, 0x21, 0x22, 0x23};
                uint8_t keyingMaterial[]   = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                                              0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                                              0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                                              0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};
                uint8_t mac[4];
    
                uint8_t ciphertext_generated[4];
                memset(ciphertext_generated, 0, 4);
                uint8_t plaintext_generated[4];
                memset(plaintext_generated, 0, 4);
    
                // Create the key
                CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, 32);
    
                // Verify Encryption
                AESCCM_Operation_init(&operation);
                operation.key            = &cryptoKey;
                operation.aad            = &aad[0];
                operation.aadLength      = 8;
                operation.input          = &plaintext[0];
                operation.output         = &ciphertext_generated[0];
                operation.inputLength    = 4;
                operation.nonce          = &nonce[0];
                operation.nonceLength    = 7;
                operation.mac            = &mac[0];
                operation.macLength      = 4;
    
                status = AESCCM_oneStepEncrypt(aeshandle, &operation);
    
                AESCCM_close(aeshandle);
    
                // again wait so TDC_REF clock request can be acknowledge
                //Task_sleep((xdc_UInt32)100);
                uint32_t randomNumber = Random_getNumber();
                Task_sleep((xdc_UInt32)randomNumber % 23);
    
            }
    }
    

    .

  • I have found a documentation specifying that SHA and AES cannot be used together:

    https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_6_20_00_29/docs/driverlib_cc13xx_cc26xx/cc13x2_cc26x2/driverlib/group__aes__api.html

    Introduction

    The AES (advanced encryption standard) API provides access to the AES and key store functionality of the crypto core. The SHA2 accelerator is also contained within the crypto core. Hence, only one of SHA2 and AES may be used at the same time. This module offers hardware acceleration for several protocols using the AES block cypher. The protocols below are supported by the hardware. The driverlib documentation only explicitly references the most commonly used ones.

    Knowing this now, whether it is possible to put the SHA operation in critical section? If not, whether under mutex?

  • Hi Mehul,

    The issue is most likely related to the way in which you are using SHA2_addData.  I took an example from the TI Drivers Runtime APIs and did not experience problems coexisting with the second thread using AES CCM.

    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== sha2hash.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>        // For Task_construct and task related configuration
    
    #include <ti/drivers/utils/Random.h>                                // for Random_getNumber()
    
    
    /* Driver Header files */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SHA2.h>
    #include <ti/drivers/AESCCM.h>                                  // for AES-CCM
    #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>                      // for CryptoKeyPlaintext_initKey()
    #include <ti/drivers/dpl/HwiP.h>
    
    const char message[] =
            "Premature optimization is the root of all evil (or at least most of it) in programming.";
    
    uint8_t actualDigest[SHA2_DIGEST_LENGTH_BYTES_256];
    uint8_t expectedDigest[] = {
        0xF2, 0x6A, 0xFF, 0x01,
        0x11, 0x6B, 0xF6, 0x77,
        0x63, 0x91, 0xFE, 0xD9,
        0x47, 0x56, 0x99, 0xB2,
        0xAD, 0x7D, 0x64, 0x16,
        0xF7, 0x40, 0x1A, 0x5B,
        0xCC, 0xC7, 0x08, 0x3D,
        0xE8, 0x6B, 0x35, 0x6D,
    };
    
    SHA2_Handle handle;
    int_fast16_t result;
    SHA2_Params params;
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    int intState;
    
    /* Defines */
    #define MAX_MSG_LENGTH 256
    
    /* UART pre-formated strings */
    static const char promptStartup[]  = "\n\n\rSHA2 Driver hash demo.";
    static const char promptHash[]     = "\n\n\rRandom Number: ";
    
    /* Message buffers */
    static char       formatedMsg[MAX_MSG_LENGTH];
    
    
    /*
     *  ======== printHash ========
     */
    void printHash(UART_Handle handle, uint8_t* msg)
    {
        uint32_t i;
    
        /* Format the message as printable hex */
        for (i = 0; i < 1; i++) {
            sprintf(formatedMsg + (i * 2), "%02X", *(msg + i));
        }
    
        /* Print prompt */
        UART_write(handle, promptHash, strlen(promptHash));
        /* Print result */
        UART_write(handle, formatedMsg, strlen(formatedMsg));
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        int_fast16_t result;
    
        /* Driver handles */
        UART_Handle                 uartHandle;
        SHA2_Handle                 sha2Handle;
    
        /* UART variables */
        UART_Params                 uartParams;
    
        /* Call driver initialization functions */
        UART_init();
        SHA2_init();
    
        /* Open UART for console output */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uartHandle = UART_open(CONFIG_UART_0, &uartParams);
    
        if (!uartHandle) {
            /* UART_open() failed */
            while (1);
        }
    
    
        SHA2_Params_init(&params);
        params.returnBehavior = SHA2_RETURN_BEHAVIOR_BLOCKING;
    
        /* Prompt startup message */
        UART_write(uartHandle, promptStartup, strlen(promptStartup));
    
    
        for(;;)
        {
            handle = SHA2_open(0, &params);
            if(handle == NULL) {while(1);}
    
            // We can configure the driver even after SHA2_open()
            result = SHA2_setHashType(handle, SHA2_HASH_TYPE_256);
            if(result != SHA2_STATUS_SUCCESS){while(1);}
            // Process data in chunks. The driver buffers incomplete blocks internally.
            result = SHA2_addData(handle, &message[0], 17);
            if(result != SHA2_STATUS_SUCCESS){while(1);}
            result = SHA2_addData(handle, &message[17], strlen(message) - 17);
            if(result != SHA2_STATUS_SUCCESS){while(1);}
            // Compute the resulting digest
            result = SHA2_finalize(handle, actualDigest);
            if(result != SHA2_STATUS_SUCCESS){while(1);}
            // Verify
            result = memcmp(actualDigest, expectedDigest, SHA2_DIGEST_LENGTH_BYTES_256);
    
            SHA2_close(handle);
    
            uint32_t randomNumber = Random_getNumber();
            randomNumber %= 17;
            Task_sleep((xdc_UInt32)randomNumber);
    
            printHash(uartHandle, &randomNumber);
    
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread2(void *arg0)
    {
        //
        // SETUP
        //
            AESCCM_Handle aeshandle;
            AESCCM_Params  params;
            CryptoKey cryptoKey;
            AESCCM_Operation operation;
            int_fast16_t status = 0;
    
            // Initialize the AES-CCM peripheral
            AESCCM_init();
            AESCCM_Params_init(&params);
            params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
    
            for(;;)
            {
                aeshandle = AESCCM_open(0, &params);
                if (!aeshandle) {
                    while (1);
                }
    
                uint8_t nonce[]            = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
                uint8_t aad[]              = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
                uint8_t plaintext[]        = {0x20, 0x21, 0x22, 0x23};
                uint8_t keyingMaterial[]   = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                                              0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                                              0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                                              0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};
                uint8_t mac[4];
    
                uint8_t ciphertext_generated[4];
                memset(ciphertext_generated, 0, 4);
                uint8_t plaintext_generated[4];
                memset(plaintext_generated, 0, 4);
    
                // Create the key
                CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, 32);
    
                // Verify Encryption
                AESCCM_Operation_init(&operation);
                operation.key            = &cryptoKey;
                operation.aad            = &aad[0];
                operation.aadLength      = 8;
                operation.input          = &plaintext[0];
                operation.output         = &ciphertext_generated[0];
                operation.inputLength    = 4;
                operation.nonce          = &nonce[0];
                operation.nonceLength    = 7;
                operation.mac            = &mac[0];
                operation.macLength      = 4;
    
                status = AESCCM_oneStepEncrypt(aeshandle, &operation);
    
                AESCCM_close(aeshandle);
    
                // again wait so TDC_REF clock request can be acknowledge
                //Task_sleep((xdc_UInt32)100);
                uint32_t randomNumber = Random_getNumber();
                Task_sleep((xdc_UInt32)randomNumber % 23);
    
            }
    }
    

    Regards,
    Ryan

  • Ryan,

    Please check the link above. It says that the SHA and AES cannot be used simultaneous.

    dev.ti.com/.../group__aes__api.html

    Can you comment?

    Mehul

  • The documentation states that "only one of SHA2 and AES may be used at the same time", meaning both can be used simultaneously but two instances of either cannot be used at the same time.

    Regards,
    Ryan

  • Hi Ryan, 

    I'm working with Mehul on this issue. I noticed in the example code you posted, the SHA2 module is being configured with the return behavior set to blocking mode, where as the example Mehul posted had the SHA2 module being configured for polling mode. Could this have an impact and possibly explain the difference in behavior you're seeing versus the behavior we're seeing?

  • That's a great observation, however my code does not fail with SHA2_RETURN_BEHAVIOR_POLLING whereas Mehul's code exhibited the same behavior with SHA2_RETURN_BEHAVIOR_BLOCKING.

    Regards,
    Ryan

  • Ryan,

    Can you point exactly what is wrong I am doing in my original code? 

    The code you have have another difference is that it is getting the input data for the SHA from the RAM. I have data from the internal flash. Can you try doing that?

    Mehul

  • I was able to run your original code without error once the SHA2_addData length parameter was reduced to represent the size of the data variable used.

    Regards,
    Ryan

  • Hi Ryan,

    I am not sure if I have understood your point on the length. The code I had provided was just about a starting point of the address from the internal flash data on which the SHA is calculated. Also, the issue happens when the data length is reasonably large not 1 bytes or so (<50 bytes).

    I agree to the point that using AES at the same time of using SHA is not an issue. I have reproduced the issue where "SHA module is stuck in the SHA2_addData() and never returns" in the Simple Peripheral example project as well. I will put the required details in another reply.

  • I've split your Simple Peripheral & SHA investigation into a new post: https://e2e.ti.com/f/1/t/1135928 

    A BLE expert will further assist you from that thread.

    Regards,
    Ryan

  • Okay. Thanks Ryan.

    Are you still going to look into the original issue? I and Matt both are able to reproduce the issue without AES task as well in the original code.

  • Can you please provide your code changes to sha2hash which reproduces the issue without using a second AES task?

    Regards,
    Ryan

  • Hi Ryan,

    You mean you have kept the length of data to be performed SHA against as 1 byte? If we have less size in SHA, the operation is completed sooner and so the issue is not observed. If we keep the length large like 1024, the issue is observed. I am going to put the latest code soon.

    Mehul

  • Here is the code snippet.

    AES operation is not performed, but its Open() and Close() are being called from the high priority thread just to preempt the SHA thread.

    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== sha2hash.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <ti/sysbios/hal/Hwi.h>               // For interrupt enable and disable
    #include <ti/sysbios/knl/Swi.h>
    
    #include <ti/sysbios/knl/Task.h>        // For Task_construct and task related configuration
    
    #include <ti/drivers/utils/Random.h>                                // for Random_getNumber()
    
    
    /* Driver Header files */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SHA2.h>
    #include <ti/drivers/AESCCM.h>                                  // for AES-CCM
    #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>                      // for CryptoKeyPlaintext_initKey()
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* Defines */
    #define MAX_MSG_LENGTH 256
    
    /* UART pre-formated strings */
    static const char promptStartup[]  = "\n\n\rSHA2 Driver hash demo.";
    static const char promptHash[]     = "\n\n\rRandom Number: ";
    
    /* Message buffers */
    static char       formatedMsg[MAX_MSG_LENGTH];
    
    
    /*
     *  ======== printHash ========
     */
    void printHash(UART_Handle handle, uint8_t* msg)
    {
        uint32_t i;
    
        /* Format the message as printable hex */
        for (i = 0; i < 1; i++) {
            sprintf(formatedMsg + (i * 2), "%02X", *(msg + i));
        }
    
        /* Print prompt */
        UART_write(handle, promptHash, strlen(promptHash));
        /* Print result */
        UART_write(handle, formatedMsg, strlen(formatedMsg));
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        int_fast16_t result;
    
        /* Driver handles */
        UART_Handle                 uartHandle;
        SHA2_Handle                 sha2Handle;
    
        /* UART variables */
        UART_Params                 uartParams;
    
        /* Call driver initialization functions */
        UART_init();
        SHA2_init();
    
        /* Open UART for console output */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uartHandle = UART_open(CONFIG_UART_0, &uartParams);
    
        if (!uartHandle) {
            /* UART_open() failed */
            while (1);
        }
    
        SHA2_Params params;
        SHA2_Params_init(&params);
        params.hashType = SHA2_HASH_TYPE_512;
        params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
        sha2Handle = SHA2_open(0, &params);
    
        if (!sha2Handle) {
            /* SHA2_open() failed */
            while(1);
        }
    
        /* Prompt startup message */
        UART_write(uartHandle, promptStartup, strlen(promptStartup));
    
    
        for(;;)
        {
            uint32_t randomNumber = Random_getNumber();
            unsigned char* input_correct_2 = (unsigned char *)(randomNumber % 1000);
    
            // Verify correct input generates expected output
            // Note that the input_correct_2 is a pointer to ad address to the internal flash data from where the SHA is calculated for 1024 bytes
            result = SHA2_addData(sha2Handle, (void *)input_correct_2, 1024); // --> ISSUE: Never returns
    
    
    
            randomNumber %= 17;
            Task_sleep((xdc_UInt32)randomNumber);
    
            printHash(uartHandle, &randomNumber);
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread2(void *arg0)
    {
        //
        // SETUP
        //
            AESCCM_Handle aeshandle;
            AESCCM_Params  params;
            CryptoKey cryptoKey;
            AESCCM_Operation operation;
            int_fast16_t status = 0;
    
            // Initialize the AES-CCM peripheral
            AESCCM_init();
            AESCCM_Params_init(&params);
            params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
    
            for(;;)
            {
                aeshandle = AESCCM_open(0, &params);
                if (!aeshandle) {
                    while (1);
                }
    
                uint8_t nonce[]            = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
                uint8_t aad[]              = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
                uint8_t plaintext[]        = {0x20, 0x21, 0x22, 0x23};
                uint8_t keyingMaterial[]   = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                                              0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                                              0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                                              0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};
                uint8_t mac[4];
    
                uint8_t ciphertext_generated[4];
                memset(ciphertext_generated, 0, 4);
                uint8_t plaintext_generated[4];
                memset(plaintext_generated, 0, 4);
    
                // Create the key
                CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, 32);
    
                // Verify Encryption
                AESCCM_Operation_init(&operation);
                operation.key            = &cryptoKey;
                operation.aad            = &aad[0];
                operation.aadLength      = 8;
                operation.input          = &plaintext[0];
                operation.output         = &ciphertext_generated[0];
                operation.inputLength    = 4;
                operation.nonce          = &nonce[0];
                operation.nonceLength    = 7;
                operation.mac            = &mac[0];
                operation.macLength      = 4;
    
                //status = AESCCM_oneStepEncrypt(aeshandle, &operation);
    
                AESCCM_close(aeshandle);
    
                // again wait so TDC_REF clock request can be acknowledge
                //Task_sleep((xdc_UInt32)100);
                uint32_t randomNumber = Random_getNumber();
                Task_sleep((xdc_UInt32)randomNumber % 23);
    
            }
    }
    

    Mehul

  • The issue is related to your usage of pointers.  When I change input_correct_2 to a global variable and assign its address to SHA2_addData the code never breaks.  I know little about your intention behind the input_correct_2, however it would be best to optimize how it is used.

    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== sha2hash.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>        // For Task_construct and task related configuration
    
    #include <ti/drivers/utils/Random.h>                                // for Random_getNumber()
    
    
    /* Driver Header files */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SHA2.h>
    #include <ti/drivers/AESCCM.h>                                  // for AES-CCM
    #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>                      // for CryptoKeyPlaintext_initKey()
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* Defines */
    #define MAX_MSG_LENGTH 256
    
    /* UART pre-formated strings */
    static const char promptStartup[]  = "\n\n\rSHA2 Driver hash demo.";
    static const char promptHash[]     = "\n\n\rRandom Number: ";
    
    /* Message buffers */
    static char       formatedMsg[MAX_MSG_LENGTH];
    
    unsigned char input_correct_2;
    
    
    /*
     *  ======== printHash ========
     */
    void printHash(UART_Handle handle, uint8_t* msg)
    {
        uint32_t i;
    
        /* Format the message as printable hex */
        for (i = 0; i < 1; i++) {
            sprintf(formatedMsg + (i * 2), "%02X", *(msg + i));
        }
    
        /* Print prompt */
        UART_write(handle, promptHash, strlen(promptHash));
        /* Print result */
        UART_write(handle, formatedMsg, strlen(formatedMsg));
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        int_fast16_t result;
    
        /* Driver handles */
        UART_Handle                 uartHandle;
        SHA2_Handle                 sha2Handle;
    
        /* UART variables */
        UART_Params                 uartParams;
    
        /* Call driver initialization functions */
        UART_init();
        SHA2_init();
    
        /* Open UART for console output */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uartHandle = UART_open(CONFIG_UART_0, &uartParams);
    
        if (!uartHandle) {
            /* UART_open() failed */
            while (1);
        }
    
        SHA2_Params params;
        SHA2_Params_init(&params);
        params.hashType = SHA2_HASH_TYPE_512;
        params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
        sha2Handle = SHA2_open(0, &params);
    
        if (!sha2Handle) {
            /* SHA2_open() failed */
            while(1);
        }
    
        /* Prompt startup message */
        UART_write(uartHandle, promptStartup, strlen(promptStartup));
    
    
        for(;;)
        {
            uint32_t randomNumber = Random_getNumber();
            input_correct_2 = (randomNumber % 1000);
    
            // Verify correct input generates expected output
            result = SHA2_addData(sha2Handle, &input_correct_2, 8192); // --> ISSUE: Never returns
    
            randomNumber %= 17;
            Task_sleep((xdc_UInt32)randomNumber);
    
            printHash(uartHandle, &randomNumber);
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread2(void *arg0)
    {
        //
        // SETUP
        //
            AESCCM_Handle aeshandle;
            AESCCM_Params  params;
            CryptoKey cryptoKey;
            AESCCM_Operation operation;
            int_fast16_t status = 0;
    
            // Initialize the AES-CCM peripheral
            AESCCM_init();
            AESCCM_Params_init(&params);
            params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
    
            for(;;)
            {
                aeshandle = AESCCM_open(0, &params);
                if (!aeshandle) {
                    while (1);
                }
    
                uint8_t nonce[]            = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
                uint8_t aad[]              = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
                uint8_t plaintext[]        = {0x20, 0x21, 0x22, 0x23};
                uint8_t keyingMaterial[]   = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                                              0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                                              0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                                              0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};
                uint8_t mac[4];
    
                uint8_t ciphertext_generated[4];
                memset(ciphertext_generated, 0, 4);
                uint8_t plaintext_generated[4];
                memset(plaintext_generated, 0, 4);
    
                // Create the key
                CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, 32);
    
                // Verify Encryption
                AESCCM_Operation_init(&operation);
                operation.key            = &cryptoKey;
                operation.aad            = &aad[0];
                operation.aadLength      = 8;
                operation.input          = &plaintext[0];
                operation.output         = &ciphertext_generated[0];
                operation.inputLength    = 4;
                operation.nonce          = &nonce[0];
                operation.nonceLength    = 7;
                operation.mac            = &mac[0];
                operation.macLength      = 4;
    
                status = AESCCM_oneStepEncrypt(aeshandle, &operation);
    
                AESCCM_close(aeshandle);
    
                // again wait so TDC_REF clock request can be acknowledge
                //Task_sleep((xdc_UInt32)100);
                uint32_t randomNumber = Random_getNumber();
                Task_sleep((xdc_UInt32)randomNumber % 23);
    
            }
    }
    

    Regards,
    Ryan

  • Hi Ryan,

    Thanks for your inputs.

    However, the updated code you have is different than what I was trying to do. Essentially, all I wanted was to give a start address of data to hash from the internal flash (the internal flash base address is 0x00000000). The code you have updated as input_correct_2 variable allocated in the RAM data section and when you pass its address to the Hash function (i.e. &input_correct_2), it is a start address from the RAM data section not the one I have in my code. Have you tried passing the start address tot he hash from the internal flash address? We have some data in the internal flash against which we want to calculate the hash to ensure its integrity.

    Here is the updated code I have. Even though I have allocated the start_address_for_hash_data as a global data, the code still gets stuck. The main point over here is that the data against which the SHA operation is performed is coming from the internal flash address not from the RAM. Hope it helps:

    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== sha2hash.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <ti/sysbios/hal/Hwi.h>               // For interrupt enable and disable
    #include <ti/sysbios/knl/Swi.h>
    
    #include <ti/sysbios/knl/Task.h>        // For Task_construct and task related configuration
    
    #include <ti/drivers/utils/Random.h>                                // for Random_getNumber()
    
    
    /* Driver Header files */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SHA2.h>
    #include <ti/drivers/AESCCM.h>                                  // for AES-CCM
    #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>                      // for CryptoKeyPlaintext_initKey()
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* Defines */
    #define MAX_MSG_LENGTH 256
    
    /* UART pre-formated strings */
    static const char promptStartup[]  = "\n\n\rSHA2 Driver hash demo.";
    static const char promptHash[]     = "\n\n\rRandom Number: ";
    
    /* Message buffers */
    static char       formatedMsg[MAX_MSG_LENGTH];
    unsigned char*    start_address_for_hash_data;  // Pointer to the start address to perform SHA operation
    
    
    /*
     *  ======== printHash ========
     */
    void printHash(UART_Handle handle, uint8_t* msg)
    {
        uint32_t i;
    
        /* Format the message as printable hex */
        for (i = 0; i < 1; i++) {
            sprintf(formatedMsg + (i * 2), "%02X", *(msg + i));
        }
    
        /* Print prompt */
        UART_write(handle, promptHash, strlen(promptHash));
        /* Print result */
        UART_write(handle, formatedMsg, strlen(formatedMsg));
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        int_fast16_t result;
    
        /* Driver handles */
        UART_Handle                 uartHandle;
        SHA2_Handle                 sha2Handle;
    
        /* UART variables */
        UART_Params                 uartParams;
    
        /* Call driver initialization functions */
        UART_init();
        SHA2_init();
    
        /* Open UART for console output */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uartHandle = UART_open(CONFIG_UART_0, &uartParams);
    
        if (!uartHandle) {
            /* UART_open() failed */
            while (1);
        }
    
        SHA2_Params params;
        SHA2_Params_init(&params);
        params.hashType = SHA2_HASH_TYPE_512;
        params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
        sha2Handle = SHA2_open(0, &params);
    
        if (!sha2Handle) {
            /* SHA2_open() failed */
            while(1);
        }
    
        /* Prompt startup message */
        UART_write(uartHandle, promptStartup, strlen(promptStartup));
    
    
        for(;;)
        {
            uint32_t randomNumber = Random_getNumber();
            start_address_for_hash_data = (unsigned char *)(randomNumber % 1000);
    
            // Verify correct input generates expected output
            // Note that the input_correct_2 is a pointer to ad address to the internal flash data from where the SHA is calculated for 1024 bytes
            result = SHA2_addData(sha2Handle, (void *)start_address_for_hash_data, 1024); // --> ISSUE: Never returns
    
    
    
            randomNumber %= 17;
            Task_sleep((xdc_UInt32)randomNumber);
    
            printHash(uartHandle, &randomNumber);
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread2(void *arg0)
    {
        //
        // SETUP
        //
            AESCCM_Handle aeshandle;
            AESCCM_Params  params;
            CryptoKey cryptoKey;
            AESCCM_Operation operation;
            int_fast16_t status = 0;
    
            // Initialize the AES-CCM peripheral
            AESCCM_init();
            AESCCM_Params_init(&params);
            params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
    
            for(;;)
            {
                aeshandle = AESCCM_open(0, &params);
                if (!aeshandle) {
                    while (1);
                }
    
                uint8_t nonce[]            = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
                uint8_t aad[]              = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
                uint8_t plaintext[]        = {0x20, 0x21, 0x22, 0x23};
                uint8_t keyingMaterial[]   = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                                              0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                                              0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                                              0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};
                uint8_t mac[4];
    
                uint8_t ciphertext_generated[4];
                memset(ciphertext_generated, 0, 4);
                uint8_t plaintext_generated[4];
                memset(plaintext_generated, 0, 4);
    
                // Create the key
                CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, 32);
    
                // Verify Encryption
                AESCCM_Operation_init(&operation);
                operation.key            = &cryptoKey;
                operation.aad            = &aad[0];
                operation.aadLength      = 8;
                operation.input          = &plaintext[0];
                operation.output         = &ciphertext_generated[0];
                operation.inputLength    = 4;
                operation.nonce          = &nonce[0];
                operation.nonceLength    = 7;
                operation.mac            = &mac[0];
                operation.macLength      = 4;
    
                //status = AESCCM_oneStepEncrypt(aeshandle, &operation);
    
                AESCCM_close(aeshandle);
    
                // again wait so TDC_REF clock request can be acknowledge
                //Task_sleep((xdc_UInt32)100);
                uint32_t randomNumber = Random_getNumber();
                Task_sleep((xdc_UInt32)randomNumber % 23);
    
            }
    }
    

  • Yes, I have passed internal flash addresses to SHA2_addData.  That's what I did with const "message" as shared on 9/16.  It is located at address 0x00006546 and I performed a length of 1024 which surpasses the length of the array.  However, it would be best to avoid the .resetVecs stored at the beginning of flash.  I can add an offset to your randomized assignment(0x3C) and did not experience any further issues.  Conversely, passing an address of 0x0000 will also cause the code to fail.

    Regards,
    Ryan

  • Ryan,

    Interesting. Do you know why the start address 0x00000000 is an issue? I understand that the vector table resides from there. But the SHA operation should be reading this data not to perform any write operation on this data? Here is what the MAP file show:

    run origin load origin length init length attrs members
    ---------- ----------- ---------- ----------- ----- -------
    00000000 00000000 000068f0 000068f0 r-x
    00000000 00000000 0000003c 0000003c r-- .resetVecs

    Also, I have updated the code to pass the 0x00000000 as start address with the data length as 0x3C. Which means that the SHA is performed on the vector table only. Yet, the code never stuck. See attached source file. So, the start address from the reset vector table to the SHA should not be an issue?

    result = SHA2_addData(sha2Handle, (void *)0x00000000, 0x3C);

    I also want to clarify that our application firmware issue is very close to the Simple Peripheral example we have modified. I hope Ammar is getting closer to the root cause. However, we thought that understanding the root cause of the issue in both the projects will be better.

    /*
     * Copyright (c) 2017-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== sha2hash.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <ti/sysbios/hal/Hwi.h>               // For interrupt enable and disable
    #include <ti/sysbios/knl/Swi.h>
    
    #include <ti/sysbios/knl/Task.h>        // For Task_construct and task related configuration
    
    #include <ti/drivers/utils/Random.h>                                // for Random_getNumber()
    
    
    /* Driver Header files */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/SHA2.h>
    #include <ti/drivers/AESCCM.h>                                  // for AES-CCM
    #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>                      // for CryptoKeyPlaintext_initKey()
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* Defines */
    #define MAX_MSG_LENGTH 256
    
    /* UART pre-formated strings */
    static const char promptStartup[]  = "\n\n\rSHA2 Driver hash demo.";
    static const char promptHash[]     = "\n\n\rRandom Number: ";
    
    /* Message buffers */
    static char       formatedMsg[MAX_MSG_LENGTH];
    unsigned char*    start_address_for_hash_data;  // Pointer to the start address to perform SHA operation
    
    
    /*
     *  ======== printHash ========
     */
    void printHash(UART_Handle handle, uint8_t* msg)
    {
        uint32_t i;
    
        /* Format the message as printable hex */
        for (i = 0; i < 1; i++) {
            sprintf(formatedMsg + (i * 2), "%02X", *(msg + i));
        }
    
        /* Print prompt */
        UART_write(handle, promptHash, strlen(promptHash));
        /* Print result */
        UART_write(handle, formatedMsg, strlen(formatedMsg));
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        int_fast16_t result;
    
        /* Driver handles */
        UART_Handle                 uartHandle;
        SHA2_Handle                 sha2Handle;
    
        /* UART variables */
        UART_Params                 uartParams;
    
        /* Call driver initialization functions */
        UART_init();
        SHA2_init();
    
        /* Open UART for console output */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uartHandle = UART_open(CONFIG_UART_0, &uartParams);
    
        if (!uartHandle) {
            /* UART_open() failed */
            while (1);
        }
    
        SHA2_Params params;
        SHA2_Params_init(&params);
        params.hashType = SHA2_HASH_TYPE_512;
        params.returnBehavior = SHA2_RETURN_BEHAVIOR_POLLING;
        sha2Handle = SHA2_open(0, &params);
    
        if (!sha2Handle) {
            /* SHA2_open() failed */
            while(1);
        }
    
        /* Prompt startup message */
        UART_write(uartHandle, promptStartup, strlen(promptStartup));
    
    
        for(;;)
        {
            uint32_t randomNumber = Random_getNumber();
            //start_address_for_hash_data = (unsigned char *)(0x00);
    
            // Verify correct input generates expected output
            // Note that the input_correct_2 is a pointer to ad address to the internal flash data from where the SHA is calculated for 1024 bytes
            result = SHA2_addData(sha2Handle, (void *)0x00000000, 0x3C); // --> ISSUE: Never returns
    
    
    
            randomNumber %= 17;
            Task_sleep((xdc_UInt32)randomNumber);
    
            printHash(uartHandle, &randomNumber);
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread2(void *arg0)
    {
        //
        // SETUP
        //
            AESCCM_Handle aeshandle;
            AESCCM_Params  params;
            CryptoKey cryptoKey;
            AESCCM_Operation operation;
            int_fast16_t status = 0;
    
            // Initialize the AES-CCM peripheral
            AESCCM_init();
            AESCCM_Params_init(&params);
            params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
    
            for(;;)
            {
                aeshandle = AESCCM_open(0, &params);
                if (!aeshandle) {
                    while (1);
                }
    
                uint8_t nonce[]            = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
                uint8_t aad[]              = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
                uint8_t plaintext[]        = {0x20, 0x21, 0x22, 0x23};
                uint8_t keyingMaterial[]   = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                                              0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
                                              0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
                                              0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F};
                uint8_t mac[4];
    
                uint8_t ciphertext_generated[4];
                memset(ciphertext_generated, 0, 4);
                uint8_t plaintext_generated[4];
                memset(plaintext_generated, 0, 4);
    
                // Create the key
                CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, 32);
    
                // Verify Encryption
                AESCCM_Operation_init(&operation);
                operation.key            = &cryptoKey;
                operation.aad            = &aad[0];
                operation.aadLength      = 8;
                operation.input          = &plaintext[0];
                operation.output         = &ciphertext_generated[0];
                operation.inputLength    = 4;
                operation.nonce          = &nonce[0];
                operation.nonceLength    = 7;
                operation.mac            = &mac[0];
                operation.macLength      = 4;
    
                //status = AESCCM_oneStepEncrypt(aeshandle, &operation);
    
                AESCCM_close(aeshandle);
    
                // again wait so TDC_REF clock request can be acknowledge
                //Task_sleep((xdc_UInt32)100);
                uint32_t randomNumber = Random_getNumber();
                Task_sleep((xdc_UInt32)randomNumber % 23);
    
            }
    }
    

  • The combined factors of starting at the beginning of flash and having a lengthy number of bytes to process is causing SHA2_addData to fail.  I am unsure of the root cause but you are now aware of what should be avoided to work around the issue.  The simple_peripheral behavior likely has a different cause given that both factors stated do not apply.  I'm certain you will know more once Ammar has finished processing and provides a response.

    Regards,
    Ryan

  • Ryan,

    This seems odd. Reading the data from the vector table should not be an issue ideally. But then, the memcpy() from the vector table should be an issue as well?

    I understand that the issue in the BLE example is more closer to the one we are facing. It would be good to understand the root cause for above as well.

    If you check the other thread, there have been a comment that using AES and SHA together would be an issue. But we already have discussed above in this thread that this is not an issue.