4 Replies Latest reply on Feb 12, 2020 3:55 AM by DheerajK_81

    PSoC 6: Multiple calls to Cy_Crypto_Sha_Run


      I would like to use the crypto HW calculate the SHA-256 of a dataset, but can't I am unable to have all the data present in contiguous memory. Is it possible to calculate the running SHA by making subsequent calls to Cy_Crypto_Sha_Run()? Or how could this be made possible?

        • 1. Re: PSoC 6: Multiple calls to Cy_Crypto_Sha_Run

          You can make use of the Core Crypto SHA PDL APIs for this purpose where there is a provision to pass chunks of data and then calculate the digest. Provided below is a simple snippet which demonstrates this.


          #include "cy_pdl.h"
          #include "cyhal.h"
          #include "cybsp.h"
          #include "cy_retarget_io.h"
          #include "cy_crypto.h"
          #include "cy_crypto_core.h"
          #define plainTextSize 128
          uint8_t sha256PlainText_1[plainTextSize] = {
               0x45, 0x11, 0x01, 0x25, 0x0e, 0xc6, 0xf2, 0x66,
               0x52, 0x24, 0x9d, 0x59, 0xdc, 0x97, 0x4b, 0x73,
               0x61, 0xd5, 0x71, 0xa8, 0x10, 0x1c, 0xdf, 0xd3,
               0x6a, 0xba, 0x3b, 0x58, 0x54, 0xd3, 0xae, 0x08,
               0x6b, 0x5f, 0xdd, 0x45, 0x97, 0x72, 0x1b, 0x66,
               0xe3, 0xc0, 0xdc, 0x5d, 0x8c, 0x60, 0x6d, 0x96,
               0x57, 0xd0, 0xe3, 0x23, 0x28, 0x3a, 0x52, 0x17,
               0xd1, 0xf5, 0x3f, 0x2f, 0x28, 0x4f, 0x57, 0xb8,
               0x5c, 0x8a, 0x61, 0xac, 0x89, 0x24, 0x71, 0x1f,
               0x89, 0x5c, 0x5e, 0xd9, 0x0e, 0xf1, 0x77, 0x45,
               0xed, 0x2d, 0x72, 0x8a, 0xbd, 0x22, 0xa5, 0xf7,
               0xa1, 0x34, 0x79, 0xa4, 0x62, 0xd7, 0x1b, 0x56,
               0xc1, 0x9a, 0x74, 0xa4, 0x0b, 0x65, 0x5c, 0x58,
               0xed, 0xfe, 0x0a, 0x18, 0x8a, 0xd2, 0xcf, 0x46,
               0xcb, 0xf3, 0x05, 0x24, 0xf6, 0x5d, 0x42, 0x3c,
               0x83, 0x7d, 0xd1, 0xff, 0x2b, 0xf4, 0x62, 0xac
          /* Calculated SHA-256 digest */
          uint8_t sha256Digest[CY_CRYPTO_SHA256_DIGEST_SIZE] = {0};
          uint8_t shaBuffer[plainTextSize] = {0};
          int main(void)
               cy_rslt_t result;
               /* Initialize the device and board peripherals */
               result = cybsp_init();
               /* Board init failed. Stop program execution */
               if (result != CY_RSLT_SUCCESS)
               /* Enable global interrupts */
               /* Initialize retarget-io to use the debug UART port */
               result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, \
               /* retarget-io init failed. Stop program execution */
               if (result != CY_RSLT_SUCCESS)
               /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
               printf("****************** "
               "PSoC 6 SHA Calculation Example "
               "****************** \r\n\n");
               uint8_t* messagePtr = (uint8_t*)sha256PlainText_1;
               uint32_t messageSize = sizeof(sha256PlainText_1);
               /* Enable the Crypto block */
               cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
               /* Allocate space for the structure which stores the SHA context */
               cy_stc_crypto_sha_state_t hashState = { 0 };
               tmpResult = Cy_Crypto_Core_Sha_Init(CRYPTO, &hashState, CY_CRYPTO_MODE_SHA256, (uint8_t*)shaBuffer);
               /* Start the Hash of the message by SHA256 */
               if (CY_CRYPTO_SUCCESS == tmpResult)
                    printf("Start calculation \n\r");
                    tmpResult = Cy_Crypto_Core_Sha_Start(CRYPTO, &hashState);
               /* Process all chunks of the message */
               while ((messageSize != 0) && (CY_CRYPTO_SUCCESS == tmpResult))
                    uint32_t chunkSize = (messageSize >= CY_CRYPTO_SHA256_BLOCK_SIZE) ? CY_CRYPTO_SHA256_BLOCK_SIZE : messageSize;
                    tmpResult = Cy_Crypto_Core_Sha_Update (CRYPTO, &hashState, messagePtr, chunkSize);
                    messagePtr += chunkSize;
                    messageSize -= chunkSize;
               if (CY_CRYPTO_SUCCESS == tmpResult)
                    tmpResult = Cy_Crypto_Core_Sha_Finish(CRYPTO, &hashState, sha256Digest);
               if (CY_CRYPTO_SUCCESS == tmpResult)
                    tmpResult = Cy_Crypto_Core_Sha_Free(CRYPTO, &hashState);
               printf("Calculated digest: \n\r");
               for(int i = 0; i < CY_CRYPTO_SHA256_DIGEST_SIZE; i++){
                    if((i > 0) && (i % 8 == 0)){
                    printf("0x%0X  ", sha256Digest[i] & 0xFF);
          printf("\r\nDemonstration complete \n\r");


          Hope this helps!




          2 of 2 people found this helpful
          • 2. Re: PSoC 6: Multiple calls to Cy_Crypto_Sha_Run

            Yes! Thank you the above template worked for me. Just curious though, I was having problems until I made the hash, SHA buffer, and message buffer global variables. I was figuring having them as locals was fine since I was calling the crypto functions all within the function scope, any insight?

            • 3. Re: PSoC 6: Multiple calls to Cy_Crypto_Sha_Run

              If you are using Cy_Crypto_Sha_Run() the documentation says the message and digest address must be 4-byte aligned.  Maybe declaring the buffer as global instead of local just happens to place them at 4-byte aligned addresses.

              • 4. Re: PSoC 6: Multiple calls to Cy_Crypto_Sha_Run

                I declared them in the local scope and was able to observe the output. Not sure what's going wrong in your case, please attach your main.c file so that I can have a look.


                And yes, JeHu_3414236 suggestion to align it on a 4-byte boundary can be done to see if it works. You can do it this way:

                CY_ALIGN(4) uint8_t sha256Digest[CY_CRYPTO_SHA256_DIGEST_SIZE] = {0};