PSoC 6: Multiple calls to Cy_Crypto_Sha_Run

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
BrVa_4472456
Level 2
Level 2
10 replies posted 5 replies posted 5 questions asked

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?

0 Likes
1 Solution
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

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)

     {

          CY_ASSERT(0);

     }

     /* Enable global interrupts */

     __enable_irq();

     /* Initialize retarget-io to use the debug UART port */

     result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, \

     CY_RETARGET_IO_BAUDRATE);

     /* retarget-io init failed. Stop program execution */

     if (result != CY_RSLT_SUCCESS)

     {

          CY_ASSERT(0);

     }

     /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */

     printf("\x1b[2J\x1b[;H");

     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_Crypto_Core_Enable(CRYPTO);

     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("\n\r");

          }

          printf("0x%0X  ", sha256Digest & 0xFF);

     }

printf("\r\nDemonstration complete \n\r");

}

Hope this helps!

Regards,

Dheeraj

View solution in original post

4 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

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)

     {

          CY_ASSERT(0);

     }

     /* Enable global interrupts */

     __enable_irq();

     /* Initialize retarget-io to use the debug UART port */

     result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, \

     CY_RETARGET_IO_BAUDRATE);

     /* retarget-io init failed. Stop program execution */

     if (result != CY_RSLT_SUCCESS)

     {

          CY_ASSERT(0);

     }

     /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */

     printf("\x1b[2J\x1b[;H");

     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_Crypto_Core_Enable(CRYPTO);

     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("\n\r");

          }

          printf("0x%0X  ", sha256Digest & 0xFF);

     }

printf("\r\nDemonstration complete \n\r");

}

Hope this helps!

Regards,

Dheeraj

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?

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.

0 Likes

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};

Regards,

Dheeraj

0 Likes