Skip to content

Commit 06d5897

Browse files
Merge pull request #6362 from dgarske/stm32_hash
Improved fix for STM32 hashing on U5
2 parents c84abaf + 7576380 commit 06d5897

2 files changed

Lines changed: 43 additions & 23 deletions

File tree

wolfcrypt/src/port/st/stm32.c

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ static void wc_Stm32_Hash_Data(STM32_HASH_Context* stmCtx, word32 len)
234234
if (len > stmCtx->buffLen)
235235
len = stmCtx->buffLen;
236236

237-
/* calculate number of 32-bit blocks */
237+
/* calculate number of 32-bit blocks - round up */
238238
blocks = ((len + STM32_HASH_REG_SIZE-1) / STM32_HASH_REG_SIZE);
239239
#ifdef DEBUG_STM32_HASH
240240
printf("STM DIN %d blocks\n", blocks);
@@ -268,17 +268,16 @@ int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo,
268268
byte* local = (byte*)stmCtx->buffer;
269269
int wroteToFifo = 0;
270270
const word32 fifoSz = (STM32_HASH_FIFO_SIZE * STM32_HASH_REG_SIZE);
271-
272-
if (blockSize > fifoSz)
273-
blockSize = fifoSz;
271+
word32 chunkSz;
274272

275273
#ifdef DEBUG_STM32_HASH
276274
printf("STM Hash Update: algo %x, len %d, blockSz %d\n",
277275
algo, len, blockSize);
278276
#endif
277+
(void)blockSize;
279278

280279
/* check that internal buffLen is valid */
281-
if (stmCtx->buffLen > blockSize) {
280+
if (stmCtx->buffLen > (word32)sizeof(stmCtx->buffer)) {
282281
return BUFFER_E;
283282
}
284283

@@ -288,37 +287,44 @@ int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo,
288287
/* restore hash context or init as new hash */
289288
wc_Stm32_Hash_RestoreContext(stmCtx, algo);
290289

290+
chunkSz = fifoSz;
291+
#ifdef STM32_HASH_FIFO_WORKAROUND
292+
/* if FIFO already has bytes written then fill remainder first */
293+
if (stmCtx->fifoBytes > 0) {
294+
chunkSz -= stmCtx->fifoBytes;
295+
stmCtx->fifoBytes = 0;
296+
}
297+
#endif
298+
291299
/* write blocks to FIFO */
292300
while (len) {
293-
word32 fillBlockSz = blockSize, add;
294-
295-
/* if FIFO already has bytes written then fill remainder first */
296-
if (stmCtx->fifoBytes > 0) {
297-
fillBlockSz -= stmCtx->fifoBytes;
298-
stmCtx->fifoBytes = 0;
299-
}
300-
301-
add = min(len, fillBlockSz - stmCtx->buffLen);
301+
word32 add = min(len, chunkSz - stmCtx->buffLen);
302302
XMEMCPY(&local[stmCtx->buffLen], data, add);
303303

304304
stmCtx->buffLen += add;
305305
data += add;
306306
len -= add;
307307

308-
if (len > 0 && stmCtx->buffLen == fillBlockSz) {
308+
#ifdef STM32_HASH_FIFO_WORKAROUND
309+
/* We cannot leave the FIFO full and do save/restore
310+
* the last must be large enough to flush block from FIFO */
311+
if (stmCtx->buffLen + len <= fifoSz * 2) {
312+
chunkSz = fifoSz + STM32_HASH_REG_SIZE;
313+
}
314+
#endif
315+
316+
if (len >= 0 && stmCtx->buffLen == chunkSz) {
309317
wc_Stm32_Hash_Data(stmCtx, stmCtx->buffLen);
310318
wroteToFifo = 1;
319+
#ifdef STM32_HASH_FIFO_WORKAROUND
320+
if (chunkSz > fifoSz)
321+
stmCtx->fifoBytes = chunkSz - fifoSz;
322+
chunkSz = fifoSz;
323+
#endif
311324
}
312325
}
313326

314327
if (wroteToFifo) {
315-
#ifdef STM32_HASH_FIFO_WORKAROUND
316-
/* If we wrote a block send one more 32-bit to FIFO to trigger start.
317-
* The save/restore feature cannot leave 16 deep FIFO filled. */
318-
wc_Stm32_Hash_Data(stmCtx, 4);
319-
stmCtx->fifoBytes += 4;
320-
#endif
321-
322328
/* make sure hash operation is done */
323329
ret = wc_Stm32_Hash_WaitDone(stmCtx);
324330

wolfssl/wolfcrypt/port/st/stm32.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,22 @@
7474
#if (defined(WOLFSSL_STM32U5) || defined(WOLFSSL_STM32H5) || \
7575
defined(WOLFSSL_STM32H7)) && !defined(NO_STM32_HASH_FIFO_WORKAROUND)
7676
/* workaround for hash FIFO to write one extra to finalize */
77+
/* RM: Message Data Feeding: Data are entered into the HASH
78+
* one 32-bit word at a time, by writing them into the HASH_DIN register.
79+
* The current contents of the HASH_DIN register are transferred to the
80+
* 16 words input FIFO each time the register is written with new data.
81+
* Hence HASH_DIN and the FIFO form a seventeen 32-bit words length FIFO. */
82+
#undef STM32_HASH_BUFFER_SIZE
83+
#define STM32_HASH_BUFFER_SIZE 17
84+
7785
#undef STM32_HASH_FIFO_WORKAROUND
7886
#define STM32_HASH_FIFO_WORKAROUND
7987
#endif
8088

89+
#ifndef STM32_HASH_BUFFER_SIZE
90+
#define STM32_HASH_BUFFER_SIZE STM32_HASH_FIFO_SIZE
91+
#endif
92+
8193

8294
/* STM32 Hash Context */
8395
typedef struct {
@@ -88,11 +100,13 @@ typedef struct {
88100
uint32_t HASH_CSR[HASH_CR_SIZE];
89101

90102
/* Hash state / buffers */
91-
word32 buffer[STM32_HASH_FIFO_SIZE]; /* partial word buffer */
103+
word32 buffer[STM32_HASH_BUFFER_SIZE]; /* partial word buffer */
92104
word32 buffLen; /* partial word remain */
93105
word32 loLen; /* total update bytes
94106
(only lsb 6-bits is used for nbr valid bytes in last word) */
107+
#ifdef STM32_HASH_FIFO_WORKAROUND
95108
int fifoBytes; /* number of currently filled FIFO bytes */
109+
#endif
96110
} STM32_HASH_Context;
97111

98112

0 commit comments

Comments
 (0)