- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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