diff --git a/CHANGELOG.md b/CHANGELOG.md index 11b11fd..9b512c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,19 +19,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Platform AES API change** — all platform AES cryptographic functions now reference keys by secure storage index (`PLAT_UI32 key_idx`) instead of raw key pointer and length (`PLAT_UI8 *pKey, PLAT_UI16 key_length`). Affected functions: `stse_platform_aes_cmac_init`, `stse_platform_aes_cmac_compute`, `stse_platform_aes_cmac_verify`, `stse_platform_aes_cbc_enc`, `stse_platform_aes_cbc_dec`, `stse_platform_aes_ecb_enc` - **Renamed** `stsafea_open_host_session` to `stsafea_open_host_session_from_idx` — signature updated to accept key indices (`PLAT_UI32 host_MAC_key_idx`, `PLAT_UI32 host_cypher_key_idx`) instead of raw key pointers - **printf() calls replaced** with `stse_platform_printf()` in all library code to abstract away standard I/O and allow platform-specific implementations for logging and output +- **Platform CRC API change** — introduces a context (`stse_crc16_context_t *`) parameter to make the CRC PAL APIs multi-context-safe. Affected functions: `stse_platform_Crc16_Accumulate` (PR [#90](https://github.com/STMicroelectronics/STSELib/pull/90)) ### Added - `stse_platform_store_aes_key()` — new platform function to store an AES key into platform secure storage and retrieve its index - `stse_platform_delete_aes_key()` — new platform function to delete an AES key from platform secure storage by index - `stse_platform_printf()` — new platform function for formatted output, replacing all direct calls to `printf()` in the library with this abstraction to allow platform-specific implementations and avoid direct use of standard I/O in library code +- `stse_platform_Crc16_ContextInit()` — new platform function to initialize a CRC16 context +- `stse_platform_Crc16_ContextRelease()` — new platform function to release a CRC16 context ### Changed +- `stse_platform_Crc16_Accumulate()` — Now it takes `stse_crc16_context_t *crc16_context` as param ### Deprecated ### Removed - `stsafea_open_host_session` function. Now replaced by `stsafea_open_host_session_from_idx` which accepts key indices instead of raw key pointers. Note that you must first store the AES keys in platform secure storage using `stse_platform_store_aes_key()` to obtain the required indices before opening a host session. +- `stse_platform_Crc16_Calculate()` — Now replaced by `stse_platform_Crc16_ContextInit()` which doesn't calculate a CRC16 but initialize the CRC context which will be used to calculate the CRC via `stse_platform_Crc16_Accumulate()`. ### Fixed diff --git a/core/stse_frame.c b/core/stse_frame.c index eac1f53..9056cc1 100644 --- a/core/stse_frame.c +++ b/core/stse_frame.c @@ -23,26 +23,32 @@ #include "core/stse_frame.h" stse_ReturnCode_t stse_frame_crc16_compute(stse_frame_t *pFrame, PLAT_UI16 *pCrc) { + stse_ReturnCode_t ret; stse_frame_element_t *pCurrent_element; + stse_crc16_context_t crc_ctx; if (pFrame == NULL || pCrc == NULL) { return STSE_CORE_INCONSISTENT_FRAME; } - pCurrent_element = pFrame->first_element; - *pCrc = stse_platform_Crc16_Calculate(pCurrent_element->pData, pCurrent_element->length); - pCurrent_element = pCurrent_element->next; - while (pCurrent_element != NULL) { - if (pCurrent_element->length != 0) { - if (pCurrent_element->pData == NULL) { - return STSE_CORE_INCONSISTENT_FRAME; + ret = stse_platform_Crc16_ContextInit(&crc_ctx); + if (ret == STSE_OK) { + pCurrent_element = pFrame->first_element; + while (pCurrent_element != NULL) { + if (pCurrent_element->length != 0) { + if (pCurrent_element->pData == NULL) { + ret = STSE_CORE_INCONSISTENT_FRAME; + break; + } + *pCrc = stse_platform_Crc16_Accumulate(pCurrent_element->pData, pCurrent_element->length, &crc_ctx); } - *pCrc = stse_platform_Crc16_Accumulate(pCurrent_element->pData, pCurrent_element->length); + pCurrent_element = pCurrent_element->next; } - pCurrent_element = pCurrent_element->next; + + stse_platform_Crc16_ContextRelease(&crc_ctx); } - return STSE_OK; + return ret; } void stse_frame_element_swap_byte_order(stse_frame_element_t *pElement) { diff --git a/core/stse_platform.h b/core/stse_platform.h index 6dafd3a..9553e80 100644 --- a/core/stse_platform.h +++ b/core/stse_platform.h @@ -33,6 +33,12 @@ #include "core/stse_util.h" #include "stse_platform_generic.h" +typedef struct stse_crc16_context_t stse_crc16_context_t; + +struct stse_crc16_context_t { + PLAT_UI16 value; +}; + /*--------------------- STSAFE platform HAL functions --------------------------- */ /*! @@ -82,20 +88,37 @@ void stse_platform_printf(const char *format, ...); PLAT_UI32 stse_platform_generate_random(void); /*! - * \brief Compute a 16-bit crc value on specific 8-bit buffer of buffer length - * \param[in] pbuffer pointer to crc input buffer - * \param[in] length input buffer length - * \return 16-bit CRC value + * \brief Initializes a CRC16 context. + * + * Initializes the specified CRC16 context and prepares it for use with `stse_platform_Crc16_Accumulate()`. + * The same context instance shall be passed unchanged to all subsequent accumulation calls. + * + * \param[in] crc16_context Pointer to the CRC16 context to initialize. + * \return \ref STSE_OK on success; \ref stse_ReturnCode_t error code otherwise. */ -PLAT_UI16 stse_platform_Crc16_Calculate(PLAT_UI8 *pbuffer, PLAT_UI16 length); +stse_ReturnCode_t stse_platform_Crc16_ContextInit(stse_crc16_context_t *crc16_context); /*! * \brief Accumulate an 8-bit buffer of buffer length in crc unit - * \param[in] pbuffer pointer to crc input buffer - * \param[in] length input buffer length + * \param[in] pbuffer pointer to crc input buffer + * \param[in] length input buffer length + * \param[in] crc16_context Pointer to the CRC context holder previously initialized successfully + * via `stse_platform_Crc16_ContextInit()`. This context is used internally to maintain the state + * required for incremental CRC computation across multiple calls to `stse_platform_Crc16_Accumulate()`. * \return 16-bit CRC value */ -PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length); +PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length, + stse_crc16_context_t *crc16_context); + +/*! + * \brief Releases resources associated with a CRC16 context. + * + * Releases any resources allocated or acquired by `stse_platform_Crc16_ContextInit()`. Once + * released, the context shall no longer be used unless it is reinitialized. + * + * \param[in] crc16_context Pointer to a CRC context previously initialized with `stse_platform_Crc16_ContextInit()`. +*/ +void stse_platform_Crc16_ContextRelease(stse_crc16_context_t *crc16_context); /*! * \brief Perform a delay of "delay_val" ms diff --git a/doc/resources/Markdown/04_PORTING_GUIDE/PAL_files/stse_platform_crc.c.md b/doc/resources/Markdown/04_PORTING_GUIDE/PAL_files/stse_platform_crc.c.md index d6b10d9..2876861 100644 --- a/doc/resources/Markdown/04_PORTING_GUIDE/PAL_files/stse_platform_crc.c.md +++ b/doc/resources/Markdown/04_PORTING_GUIDE/PAL_files/stse_platform_crc.c.md @@ -11,15 +11,14 @@ The stse_platform_crc.c file provides CRC16 functions for the STSecureElement li Implementation directives : This abstaction function should implement or call a platform function/driver that perform CRC16 calculation process. -## stse_platform_Crc16_Calculate: +## stse_platform_Crc16_ContextInit: -- Purpose: Calculates the CRC16 checksum for the given buffer. +- Purpose: Initializes a CRC16 context. - Parameters: - - pbuffer: Pointer to the buffer. - - length: Length of the buffer. -- Return Value: Returns the calculated CRC16 checksum. + - crc16_context: Pointer to the CRC16 context to initialize. +- Return Value: Returns `STSE_OK` to indicate successful context initialization. - Implementation directives : This abstaction function should implement or call a platform function/driver that perform CRC16 calculation process. + Implementation directives : This abstraction function should implement or call a platform function/driver that perform CRC16 accumulate process. ## stse_platform_Crc16_Accumulate: @@ -27,10 +26,20 @@ The stse_platform_crc.c file provides CRC16 functions for the STSecureElement li - Parameters: - pbuffer: Pointer to the buffer. - length: Length of the buffer. + - crc16_context: Pointer to the CRC context holder previously initialized successfully via `stse_platform_Crc16_ContextInit()`. + This context is used internally to maintain the state required for incremental CRC computation across multiple calls to `stse_platform_Crc16_Accumulate()`. - Return Value: Returns the accumulated CRC16 checksum. Implementation directives : This abstaction function should implement or call a platform function/driver that perform CRC16 acumulate process. +## stse_platform_Crc16_ContextRelease: + +- Purpose: Releases resources associated with a CRC16 context. +- Parameters: + - crc16_context: Pointer to a CRC context previously initialized with `stse_platform_Crc16_ContextInit()`. + + Implementation directives : This abstraction function should implement or call a platform function/driver that perform CRC16 accumulate process. + Please find below an extract ```c @@ -65,24 +74,53 @@ stse_ReturnCode_t stse_platform_crc16_init(void *pArg) } /** - * \brief Calculates the CRC16 checksum for the given buffer. - * \param pbuffer Pointer to the buffer. - * \param length Length of the buffer. - * \return The calculated CRC16 checksum. + * \brief Initializes a CRC16 context. + * + * Initializes the specified CRC16 context and prepares it for use with `stse_platform_Crc16_Accumulate()`. + * The same context instance shall be passed unchanged to all subsequent accumulation calls. + * + * \param crc16_context Pointer to the CRC16 context to initialize. + * \return \ref STSE_OK on success; \ref stse_ReturnCode_t error code otherwise. */ -PLAT_UI16 stse_platform_Crc16_Calculate(PLAT_UI8 *pbuffer, PLAT_UI16 length) +stse_ReturnCode_t stse_platform_Crc16_ContextInit(stse_crc16_context_t *crc16_context) { - return crc16_Calculate(pbuffer, length); + // If hardware CRC is used... + // mutex_lock() if the same CRC hardware module is used by multiple thread + __HAL_CRC_DR_RESET(&stm32_crc_hal); + + // or just initialize the context if CRC computation is done in software + crc16_context->value = (PLAT_UI16)0xFFFF; } /** * \brief Accumulates the CRC16 checksum for the given buffer. - * \param pbuffer Pointer to the buffer. - * \param length Length of the buffer. + * \param pbuffer Pointer to the buffer. + * \param length Length of the buffer. + * \param crc16_context Pointer to the CRC context holder previously initialized successfully + * via `stse_platform_Crc16_ContextInit()`. This context is used internally to maintain the state + * required for incremental CRC computation across multiple calls to `stse_platform_Crc16_Accumulate()`. * \return The accumulated CRC16 checksum. */ -PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length) +PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length, + stse_crc16_context_t *crc16_context); +{ + // If hardware CRC computation is used... + return ~HAL_CRC_Accumulate(&stm32_crc_hal, (uint32_t *)pbuffer, length); + + // If software CRC computation is used... + return crc16_Accumulate(pbuffer, length, crc16_context); +} + +/** + * \brief Releases resources associated with a CRC16 context. + * + * Releases any resources allocated or acquired by `stse_platform_Crc16_ContextInit()`. Once + * released, the context shall no longer be used unless it is reinitialized. + * + * \param crc16_context Pointer to a CRC context previously initialized with `stse_platform_Crc16_ContextInit()`. +*/ +void stse_platform_Crc16_ContextRelease(stse_crc16_context_t *crc16_context) { - return crc16_Accumulate(pbuffer, length); + // mutex_unlock() if the same CRC hardware module is used by multiple thread } ``` diff --git a/services/stsafea/stsafea_frame_transfer.c b/services/stsafea/stsafea_frame_transfer.c index e07b7f1..894b604 100644 --- a/services/stsafea/stsafea_frame_transfer.c +++ b/services/stsafea/stsafea_frame_transfer.c @@ -219,8 +219,21 @@ stse_ReturnCode_t stsafea_frame_receive(stse_Handle_t *pSTSE, stse_frame_t *pFra /* ====================================================== */ /* ====== compute CRC for response without payload ====== */ - computed_crc = stse_platform_Crc16_Calculate(&received_header, STSE_RSP_FRAME_HEADER_SIZE); + stse_crc16_context_t crc_ctx; + ret = stse_platform_Crc16_ContextInit(&crc_ctx); + if (ret == STSE_OK) { + computed_crc = stse_platform_Crc16_Accumulate(&received_header, STSE_RSP_FRAME_HEADER_SIZE, &crc_ctx); + + stse_platform_Crc16_ContextRelease(&crc_ctx); + /* - Verify CRC */ + if (computed_crc != ((received_crc[0] << 8) + received_crc[1])) { + ret = STSE_SERVICE_FRAME_CRC_ERROR; + } else { + ret = (stse_ReturnCode_t)(received_header & STSE_STSAFEA_RSP_STATUS_MASK); + } + } + #ifdef STSE_FRAME_DEBUG_LOG stse_platform_printf("\n\r STSAFE Frame < (%d-byte) : { 0x%02X } { 0x%02X 0x%02X }\n\r", received_length + STSE_FRAME_CRC_SIZE, @@ -228,13 +241,6 @@ stse_ReturnCode_t stsafea_frame_receive(stse_Handle_t *pSTSE, stse_frame_t *pFra received_crc[0], received_crc[1]); #endif /* STSE_FRAME_DEBUG_LOG */ - - /* - Verify CRC */ - if (computed_crc != ((received_crc[0] << 8) + received_crc[1])) { - return (STSE_SERVICE_FRAME_CRC_ERROR); - } - - ret = (stse_ReturnCode_t)(received_header & STSE_STSAFEA_RSP_STATUS_MASK); } else { /* ======================================================= */ /* ====== Format the frame to handle CRC and filler ====== */