Skip to content

Commit a64d510

Browse files
committed
fix(crc): Make the PAL layer multi-context-safe
Fix #65 issue
1 parent 5c2a674 commit a64d510

5 files changed

Lines changed: 120 additions & 42 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- **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`
2020
- **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
2121
- **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
22+
- **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))
2223

2324
### Added
2425

2526
- `stse_platform_store_aes_key()` — new platform function to store an AES key into platform secure storage and retrieve its index
2627
- `stse_platform_delete_aes_key()` — new platform function to delete an AES key from platform secure storage by index
2728
- `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
29+
- `stse_platform_Crc16_ContextInit()` — new platform function to initialize a CRC16 context
30+
- `stse_platform_Crc16_ContextRelease()` — new platform function to release a CRC16 context
2831

2932
### Changed
33+
- `stse_platform_Crc16_Accumulate()` — Now it takes `stse_crc16_context_t *crc16_context` as param
3034

3135
### Deprecated
3236

3337
### Removed
3438
- `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.
39+
- `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()`.
3540

3641
### Fixed
3742

core/stse_frame.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,32 @@
2323
#include "core/stse_frame.h"
2424

2525
stse_ReturnCode_t stse_frame_crc16_compute(stse_frame_t *pFrame, PLAT_UI16 *pCrc) {
26+
stse_ReturnCode_t ret;
2627
stse_frame_element_t *pCurrent_element;
28+
stse_crc16_context_t crc_ctx;
2729

2830
if (pFrame == NULL || pCrc == NULL) {
2931
return STSE_CORE_INCONSISTENT_FRAME;
3032
}
3133

32-
pCurrent_element = pFrame->first_element;
33-
*pCrc = stse_platform_Crc16_Calculate(pCurrent_element->pData, pCurrent_element->length);
34-
pCurrent_element = pCurrent_element->next;
35-
while (pCurrent_element != NULL) {
36-
if (pCurrent_element->length != 0) {
37-
if (pCurrent_element->pData == NULL) {
38-
return STSE_CORE_INCONSISTENT_FRAME;
34+
ret = stse_platform_Crc16_ContextInit(&crc_ctx);
35+
if (ret == STSE_OK) {
36+
pCurrent_element = pFrame->first_element;
37+
while (pCurrent_element != NULL) {
38+
if (pCurrent_element->length != 0) {
39+
if (pCurrent_element->pData == NULL) {
40+
ret = STSE_CORE_INCONSISTENT_FRAME;
41+
break;
42+
}
43+
*pCrc = stse_platform_Crc16_Accumulate(pCurrent_element->pData, pCurrent_element->length, &crc_ctx);
3944
}
40-
*pCrc = stse_platform_Crc16_Accumulate(pCurrent_element->pData, pCurrent_element->length);
45+
pCurrent_element = pCurrent_element->next;
4146
}
42-
pCurrent_element = pCurrent_element->next;
47+
48+
stse_platform_Crc16_ContextRelease(&crc_ctx);
4349
}
4450

45-
return STSE_OK;
51+
return ret;
4652
}
4753

4854
void stse_frame_element_swap_byte_order(stse_frame_element_t *pElement) {

core/stse_platform.h

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333
#include "core/stse_util.h"
3434
#include "stse_platform_generic.h"
3535

36+
typedef struct stse_crc16_context_t stse_crc16_context_t;
37+
38+
struct stse_crc16_context_t {
39+
PLAT_UI16 value;
40+
};
41+
3642
/*--------------------- STSAFE platform HAL functions --------------------------- */
3743

3844
/*!
@@ -82,20 +88,37 @@ void stse_platform_printf(const char *format, ...);
8288
PLAT_UI32 stse_platform_generate_random(void);
8389

8490
/*!
85-
* \brief Compute a 16-bit crc value on specific 8-bit buffer of buffer length
86-
* \param[in] pbuffer pointer to crc input buffer
87-
* \param[in] length input buffer length
88-
* \return 16-bit CRC value
91+
* \brief Initializes a CRC16 context.
92+
*
93+
* Initializes the specified CRC16 context and prepares it for use with `stse_platform_Crc16_Accumulate()`.
94+
* The same context instance shall be passed unchanged to all subsequent accumulation calls.
95+
*
96+
* \param[in] crc16_context Pointer to the CRC16 context to initialize.
97+
* \return \ref STSE_OK on success; \ref stse_ReturnCode_t error code otherwise.
8998
*/
90-
PLAT_UI16 stse_platform_Crc16_Calculate(PLAT_UI8 *pbuffer, PLAT_UI16 length);
99+
stse_ReturnCode_t stse_platform_Crc16_ContextInit(stse_crc16_context_t *crc16_context);
91100

92101
/*!
93102
* \brief Accumulate an 8-bit buffer of buffer length in crc unit
94-
* \param[in] pbuffer pointer to crc input buffer
95-
* \param[in] length input buffer length
103+
* \param[in] pbuffer pointer to crc input buffer
104+
* \param[in] length input buffer length
105+
* \param[in] crc16_context Pointer to the CRC context holder previously initialized successfully
106+
* via `stse_platform_Crc16_ContextInit()`. This context is used internally to maintain the state
107+
* required for incremental CRC computation across multiple calls to `stse_platform_Crc16_Accumulate()`.
96108
* \return 16-bit CRC value
97109
*/
98-
PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length);
110+
PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length,
111+
stse_crc16_context_t *crc16_context);
112+
113+
/*!
114+
* \brief Releases resources associated with a CRC16 context.
115+
*
116+
* Releases any resources allocated or acquired by `stse_platform_Crc16_ContextInit()`. Once
117+
* released, the context shall no longer be used unless it is reinitialized.
118+
*
119+
* \param[in] crc16_context Pointer to a CRC context previously initialized with `stse_platform_Crc16_ContextInit()`.
120+
*/
121+
void stse_platform_Crc16_ContextRelease(stse_crc16_context_t *crc16_context);
99122

100123
/*!
101124
* \brief Perform a delay of "delay_val" ms

doc/resources/Markdown/04_PORTING_GUIDE/PAL_files/stse_platform_crc.c.md

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,35 @@ The stse_platform_crc.c file provides CRC16 functions for the STSecureElement li
1111

1212
<b> Implementation directives :</b> This abstaction function should implement or call a platform function/driver that perform CRC16 calculation process.
1313

14-
## stse_platform_Crc16_Calculate:
14+
## stse_platform_Crc16_ContextInit:
1515

16-
- Purpose: Calculates the CRC16 checksum for the given buffer.
16+
- Purpose: Initializes a CRC16 context.
1717
- Parameters:
18-
- pbuffer: Pointer to the buffer.
19-
- length: Length of the buffer.
20-
- Return Value: Returns the calculated CRC16 checksum.
18+
- crc16_context: Pointer to the CRC16 context to initialize.
19+
- Return Value: Returns `STSE_OK` to indicate successful context initialization.
2120

22-
<b> Implementation directives :</b> This abstaction function should implement or call a platform function/driver that perform CRC16 calculation process.
21+
<b> Implementation directives :</b> This abstraction function should implement or call a platform function/driver that perform CRC16 accumulate process.
2322

2423
## stse_platform_Crc16_Accumulate:
2524

2625
- Purpose: Accumulates the CRC16 checksum for the given buffer.
2726
- Parameters:
2827
- pbuffer: Pointer to the buffer.
2928
- length: Length of the buffer.
29+
- crc16_context: Pointer to the CRC context holder previously initialized successfully via `stse_platform_Crc16_ContextInit()`.
30+
This context is used internally to maintain the state required for incremental CRC computation across multiple calls to `stse_platform_Crc16_Accumulate()`.
3031
- Return Value: Returns the accumulated CRC16 checksum.
3132

3233
<b> Implementation directives :</b> This abstaction function should implement or call a platform function/driver that perform CRC16 acumulate process.
3334

35+
## stse_platform_Crc16_ContextRelease:
36+
37+
- Purpose: Releases resources associated with a CRC16 context.
38+
- Parameters:
39+
- crc16_context: Pointer to a CRC context previously initialized with `stse_platform_Crc16_ContextInit()`.
40+
41+
<b> Implementation directives :</b> This abstraction function should implement or call a platform function/driver that perform CRC16 accumulate process.
42+
3443
Please find below an extract
3544

3645
```c
@@ -65,24 +74,53 @@ stse_ReturnCode_t stse_platform_crc16_init(void *pArg)
6574
}
6675

6776
/**
68-
* \brief Calculates the CRC16 checksum for the given buffer.
69-
* \param pbuffer Pointer to the buffer.
70-
* \param length Length of the buffer.
71-
* \return The calculated CRC16 checksum.
77+
* \brief Initializes a CRC16 context.
78+
*
79+
* Initializes the specified CRC16 context and prepares it for use with `stse_platform_Crc16_Accumulate()`.
80+
* The same context instance shall be passed unchanged to all subsequent accumulation calls.
81+
*
82+
* \param crc16_context Pointer to the CRC16 context to initialize.
83+
* \return \ref STSE_OK on success; \ref stse_ReturnCode_t error code otherwise.
7284
*/
73-
PLAT_UI16 stse_platform_Crc16_Calculate(PLAT_UI8 *pbuffer, PLAT_UI16 length)
85+
stse_ReturnCode_t stse_platform_Crc16_ContextInit(stse_crc16_context_t *crc16_context)
7486
{
75-
return crc16_Calculate(pbuffer, length);
87+
// If hardware CRC is used...
88+
// mutex_lock() if the same CRC hardware module is used by multiple thread
89+
__HAL_CRC_DR_RESET(&stm32_crc_hal);
90+
91+
// or just initialize the context if CRC computation is done in software
92+
crc16_context->value = (PLAT_UI16)0xFFFF;
7693
}
7794

7895
/**
7996
* \brief Accumulates the CRC16 checksum for the given buffer.
80-
* \param pbuffer Pointer to the buffer.
81-
* \param length Length of the buffer.
97+
* \param pbuffer Pointer to the buffer.
98+
* \param length Length of the buffer.
99+
* \param crc16_context Pointer to the CRC context holder previously initialized successfully
100+
* via `stse_platform_Crc16_ContextInit()`. This context is used internally to maintain the state
101+
* required for incremental CRC computation across multiple calls to `stse_platform_Crc16_Accumulate()`.
82102
* \return The accumulated CRC16 checksum.
83103
*/
84-
PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length)
104+
PLAT_UI16 stse_platform_Crc16_Accumulate(PLAT_UI8 *pbuffer, PLAT_UI16 length,
105+
stse_crc16_context_t *crc16_context);
106+
{
107+
// If hardware CRC computation is used...
108+
return ~HAL_CRC_Accumulate(&stm32_crc_hal, (uint32_t *)pbuffer, length);
109+
110+
// If software CRC computation is used...
111+
return crc16_Accumulate(pbuffer, length, crc16_context);
112+
}
113+
114+
/**
115+
* \brief Releases resources associated with a CRC16 context.
116+
*
117+
* Releases any resources allocated or acquired by `stse_platform_Crc16_ContextInit()`. Once
118+
* released, the context shall no longer be used unless it is reinitialized.
119+
*
120+
* \param crc16_context Pointer to a CRC context previously initialized with `stse_platform_Crc16_ContextInit()`.
121+
*/
122+
void stse_platform_Crc16_ContextRelease(stse_crc16_context_t *crc16_context)
85123
{
86-
return crc16_Accumulate(pbuffer, length);
124+
// mutex_unlock() if the same CRC hardware module is used by multiple thread
87125
}
88126
```

services/stsafea/stsafea_frame_transfer.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,22 +219,28 @@ stse_ReturnCode_t stsafea_frame_receive(stse_Handle_t *pSTSE, stse_frame_t *pFra
219219
/* ====================================================== */
220220
/* ====== compute CRC for response without payload ====== */
221221

222-
computed_crc = stse_platform_Crc16_Calculate(&received_header, STSE_RSP_FRAME_HEADER_SIZE);
222+
stse_crc16_context_t crc_ctx;
223+
ret = stse_platform_Crc16_ContextInit(&crc_ctx);
224+
if (ret == STSE_OK) {
225+
computed_crc = stse_platform_Crc16_Accumulate(&received_header, STSE_RSP_FRAME_HEADER_SIZE, &crc_ctx);
226+
227+
stse_platform_Crc16_ContextRelease(&crc_ctx);
223228

229+
/* - Verify CRC */
230+
if (computed_crc != ((received_crc[0] << 8) + received_crc[1])) {
231+
ret = STSE_SERVICE_FRAME_CRC_ERROR;
232+
} else {
233+
ret = (stse_ReturnCode_t)(received_header & STSE_STSAFEA_RSP_STATUS_MASK);
234+
}
235+
}
236+
224237
#ifdef STSE_FRAME_DEBUG_LOG
225238
stse_platform_printf("\n\r STSAFE Frame < (%d-byte) : { 0x%02X } { 0x%02X 0x%02X }\n\r",
226239
received_length + STSE_FRAME_CRC_SIZE,
227240
received_header,
228241
received_crc[0],
229242
received_crc[1]);
230243
#endif /* STSE_FRAME_DEBUG_LOG */
231-
232-
/* - Verify CRC */
233-
if (computed_crc != ((received_crc[0] << 8) + received_crc[1])) {
234-
return (STSE_SERVICE_FRAME_CRC_ERROR);
235-
}
236-
237-
ret = (stse_ReturnCode_t)(received_header & STSE_STSAFEA_RSP_STATUS_MASK);
238244
} else {
239245
/* ======================================================= */
240246
/* ====== Format the frame to handle CRC and filler ====== */

0 commit comments

Comments
 (0)