Stage cipher block data through aligned buffers in STM32 CRYP and Renesas SCE paths (F-3080, F-3081, F-3345)

pull/11170/head
David Garske 2026-08-12 15:25:06 -07:00
parent c75f9e1143
commit d32dbc5188
2 changed files with 149 additions and 153 deletions

View File

@ -237,6 +237,33 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#define WOLFSSL_ARM32_AES_DISPATCH
#endif
#if defined(STM32_CRYPTO) && !defined(WOLFSSL_STM32_BARE) && \
!defined(WOLFSSL_STM32_CUBEMX)
/* Push one AES block through CRYP. CRYP_DataIn/Out work in 32-bit words,
* so stage the caller's byte buffers through an aligned local. */
static WC_INLINE void wc_Stm32_CrypAesBlock(const byte* in, byte* out)
{
uint32_t tmp[WC_AES_BLOCK_SIZE / sizeof(uint32_t)];
XMEMCPY(tmp, in, WC_AES_BLOCK_SIZE);
CRYP_DataIn(tmp[0]);
CRYP_DataIn(tmp[1]);
CRYP_DataIn(tmp[2]);
CRYP_DataIn(tmp[3]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
tmp[0] = CRYP_DataOut();
tmp[1] = CRYP_DataOut();
tmp[2] = CRYP_DataOut();
tmp[3] = CRYP_DataOut();
XMEMCPY(out, tmp, WC_AES_BLOCK_SIZE);
}
#endif
/* Define AES implementation includes and functions */
#if defined(STM32_CRYPTO) && !defined(WOLF_CRYPTO_CB_ONLY_AES)
/* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
@ -328,18 +355,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&inBlock[0]);
CRYP_DataIn(*(uint32_t*)&inBlock[4]);
CRYP_DataIn(*(uint32_t*)&inBlock[8]);
CRYP_DataIn(*(uint32_t*)&inBlock[12]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&outBlock[0] = CRYP_DataOut();
*(uint32_t*)&outBlock[4] = CRYP_DataOut();
*(uint32_t*)&outBlock[8] = CRYP_DataOut();
*(uint32_t*)&outBlock[12] = CRYP_DataOut();
wc_Stm32_CrypAesBlock(inBlock, outBlock);
/* disable crypto processor */
CRYP_Cmd(DISABLE);
@ -443,18 +459,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&inBlock[0]);
CRYP_DataIn(*(uint32_t*)&inBlock[4]);
CRYP_DataIn(*(uint32_t*)&inBlock[8]);
CRYP_DataIn(*(uint32_t*)&inBlock[12]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&outBlock[0] = CRYP_DataOut();
*(uint32_t*)&outBlock[4] = CRYP_DataOut();
*(uint32_t*)&outBlock[8] = CRYP_DataOut();
*(uint32_t*)&outBlock[12] = CRYP_DataOut();
wc_Stm32_CrypAesBlock(inBlock, outBlock);
/* disable crypto processor */
CRYP_Cmd(DISABLE);
@ -1433,57 +1438,62 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
static WARN_UNUSED_RESULT int AES_ECB_encrypt(
Aes* aes, const byte* inBlock, byte* outBlock, int sz)
{
word32 ret;
word32 ret = SSP_SUCCESS;
/* The SCE driver needs 32-bit words: stage the caller's byte
* buffers through aligned locals, leaving the input untouched. */
word32 in32[WC_AES_BLOCK_SIZE / sizeof(word32)];
word32 out32[WC_AES_BLOCK_SIZE / sizeof(word32)];
int bigEndian = (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
CRYPTO_WORD_ENDIAN_BIG);
int i;
if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
CRYPTO_WORD_ENDIAN_BIG) {
ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
if ((sz % WC_AES_BLOCK_SIZE) != 0) {
return BAD_FUNC_ARG;
}
switch (aes->keylen) {
for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
XMEMCPY(in32, inBlock + i, WC_AES_BLOCK_SIZE);
if (bigEndian) {
ByteReverseWords(in32, in32, WC_AES_BLOCK_SIZE);
}
switch (aes->keylen) {
#ifdef WOLFSSL_AES_128
case AES_128_KEY_SIZE:
ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
NULL, (sz / sizeof(word32)), (word32*)inBlock,
(word32*)outBlock);
break;
case AES_128_KEY_SIZE:
ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, NULL,
(WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
break;
#endif
#ifdef WOLFSSL_AES_192
case AES_192_KEY_SIZE:
ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
NULL, (sz / sizeof(word32)), (word32*)inBlock,
(word32*)outBlock);
break;
case AES_192_KEY_SIZE:
ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, NULL,
(WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
break;
#endif
#ifdef WOLFSSL_AES_256
case AES_256_KEY_SIZE:
ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
NULL, (sz / sizeof(word32)), (word32*)inBlock,
(word32*)outBlock);
break;
case AES_256_KEY_SIZE:
ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, NULL,
(WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
break;
#endif
default:
WOLFSSL_MSG("Unknown key size");
return BAD_FUNC_ARG;
}
if (ret != SSP_SUCCESS) {
/* revert input */
ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
return WC_HW_E;
}
if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
CRYPTO_WORD_ENDIAN_BIG) {
ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
if (inBlock != outBlock) {
/* revert input */
ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
default:
WOLFSSL_MSG("Unknown key size");
return BAD_FUNC_ARG;
}
if (ret != SSP_SUCCESS) {
return WC_HW_E;
}
if (bigEndian) {
ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE);
}
XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE);
}
return 0;
}
@ -1491,53 +1501,63 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
static WARN_UNUSED_RESULT int AES_ECB_decrypt(
Aes* aes, const byte* inBlock, byte* outBlock, int sz)
{
word32 ret;
word32 ret = SSP_SUCCESS;
/* The SCE driver needs 32-bit words: stage the caller's byte
* buffers through aligned locals, leaving the input untouched. */
word32 in32[WC_AES_BLOCK_SIZE / sizeof(word32)];
word32 out32[WC_AES_BLOCK_SIZE / sizeof(word32)];
int bigEndian = (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
CRYPTO_WORD_ENDIAN_BIG);
int i;
if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
CRYPTO_WORD_ENDIAN_BIG) {
ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
if ((sz % WC_AES_BLOCK_SIZE) != 0) {
return BAD_FUNC_ARG;
}
switch (aes->keylen) {
for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
XMEMCPY(in32, inBlock + i, WC_AES_BLOCK_SIZE);
if (bigEndian) {
ByteReverseWords(in32, in32, WC_AES_BLOCK_SIZE);
}
switch (aes->keylen) {
#ifdef WOLFSSL_AES_128
case AES_128_KEY_SIZE:
ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
(sz / sizeof(word32)), (word32*)inBlock,
(word32*)outBlock);
break;
case AES_128_KEY_SIZE:
ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
aes->reg,
(WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
break;
#endif
#ifdef WOLFSSL_AES_192
case AES_192_KEY_SIZE:
ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
(sz / sizeof(word32)), (word32*)inBlock,
(word32*)outBlock);
break;
case AES_192_KEY_SIZE:
ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
aes->reg,
(WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
break;
#endif
#ifdef WOLFSSL_AES_256
case AES_256_KEY_SIZE:
ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
(sz / sizeof(word32)), (word32*)inBlock,
(word32*)outBlock);
break;
case AES_256_KEY_SIZE:
ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
aes->reg,
(WC_AES_BLOCK_SIZE / sizeof(word32)), in32, out32);
break;
#endif
default:
WOLFSSL_MSG("Unknown key size");
return BAD_FUNC_ARG;
}
if (ret != SSP_SUCCESS) {
return WC_HW_E;
}
if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
CRYPTO_WORD_ENDIAN_BIG) {
ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
if (inBlock != outBlock) {
/* revert input */
ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
default:
WOLFSSL_MSG("Unknown key size");
return BAD_FUNC_ARG;
}
if (ret != SSP_SUCCESS) {
return WC_HW_E;
}
if (bigEndian) {
ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE);
}
XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE);
}
return 0;
@ -6539,18 +6559,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
CRYP_DataIn(*(uint32_t*)&in[8]);
CRYP_DataIn(*(uint32_t*)&in[12]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
*(uint32_t*)&out[8] = CRYP_DataOut();
*(uint32_t*)&out[12] = CRYP_DataOut();
wc_Stm32_CrypAesBlock(in, out);
/* store iv for next call */
XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
@ -6635,18 +6644,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
CRYP_DataIn(*(uint32_t*)&in[8]);
CRYP_DataIn(*(uint32_t*)&in[12]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
*(uint32_t*)&out[8] = CRYP_DataOut();
*(uint32_t*)&out[12] = CRYP_DataOut();
wc_Stm32_CrypAesBlock(in, out);
/* store iv for next call */
XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
@ -7779,18 +7777,7 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
CRYP_DataIn(*(uint32_t*)&in[8]);
CRYP_DataIn(*(uint32_t*)&in[12]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
*(uint32_t*)&out[8] = CRYP_DataOut();
*(uint32_t*)&out[12] = CRYP_DataOut();
wc_Stm32_CrypAesBlock(in, out);
/* disable crypto processor */
CRYP_Cmd(DISABLE);

View File

@ -71,6 +71,29 @@
/* Hardware Acceleration */
#if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY)
/* Push one DES block through CRYP. CRYP_DataIn/Out work in 32-bit words,
* so stage the caller's byte buffers through an aligned local. */
#ifndef WOLFSSL_STM32_CUBEMX
static WC_INLINE void wc_Stm32_CrypDesBlock(const byte* in, byte* out)
{
uint32_t tmp[DES_BLOCK_SIZE / sizeof(uint32_t)];
XMEMCPY(tmp, in, DES_BLOCK_SIZE);
CRYP_DataIn(tmp[0]);
CRYP_DataIn(tmp[1]);
/* wait until the complete message has been processed */
while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
tmp[0] = CRYP_DataOut();
tmp[1] = CRYP_DataOut();
XMEMCPY(out, tmp, DES_BLOCK_SIZE);
}
#endif
/*
* STM32F2/F4 hardware DES/3DES support through the standard
* peripheral library. (See note in README).
@ -261,14 +284,7 @@
/* if input and output same will overwrite input iv */
XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
wc_Stm32_CrypDesBlock(in, out);
/* store iv for next call */
XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
@ -418,14 +434,7 @@
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
CRYP_DataIn(*(uint32_t*)&in[0]);
CRYP_DataIn(*(uint32_t*)&in[4]);
/* wait until the complete message has been processed */
while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
*(uint32_t*)&out[0] = CRYP_DataOut();
*(uint32_t*)&out[4] = CRYP_DataOut();
wc_Stm32_CrypDesBlock(in, out);
/* store iv for next call */
XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);