mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
Merge pull request #11170 from dgarske/fenrir_align_ports
Alignment and vendor port hardening
This commit is contained in:
@@ -214,6 +214,85 @@ int test_wc_Sha256Transform(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Same bytes at an aligned and an unaligned offset must hash the same. The
|
||||
* offset comparison alone cannot fail where unaligned word loads are
|
||||
* tolerated, so the block is also pinned to a known answer. */
|
||||
int test_wc_Sha256HashBlock_unaligned(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH) && \
|
||||
!defined(NO_SHA256) && !defined(WOLFSSL_KCAPI_HASH) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_SHA256)
|
||||
wc_Sha256 sha256;
|
||||
byte buf[WC_SHA256_BLOCK_SIZE * 2];
|
||||
byte aligned[WC_SHA256_DIGEST_SIZE];
|
||||
byte unaligned[WC_SHA256_DIGEST_SIZE];
|
||||
int initDone = 0;
|
||||
int initRet;
|
||||
int off;
|
||||
word32 i;
|
||||
|
||||
for (i = 0; i < (word32)sizeof(buf); i++) {
|
||||
buf[i] = (byte)(i * 7 + 1);
|
||||
}
|
||||
|
||||
XMEMSET(&sha256, 0, sizeof(sha256));
|
||||
initRet = wc_InitSha256_ex(&sha256, HEAP_HINT, testDevId);
|
||||
ExpectIntEQ(initRet, 0);
|
||||
if (initRet == 0) initDone = 1;
|
||||
|
||||
/* Bad arguments - neither touches the hash state. */
|
||||
ExpectIntEQ(wc_Sha256HashBlock(NULL, buf, aligned),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_Sha256HashBlock(&sha256, NULL, aligned),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
|
||||
/* Reference digest at offset 0. This is the FIPS 180-4 compression of
|
||||
* the block from the standard initial state, not a padded SHA-256 of
|
||||
* it, so it is reproducible from the spec alone. */
|
||||
ExpectIntEQ(wc_Sha256HashBlock(&sha256, buf, aligned), 0);
|
||||
ExpectBufEQ(aligned,
|
||||
"\x17\x6c\x96\x15\x3a\x1e\x47\xe6"
|
||||
"\x54\x65\x59\x49\xa2\xa3\x4f\xa0"
|
||||
"\x0a\x62\xd2\x43\x51\x46\xce\x18"
|
||||
"\x3c\x51\xd9\xd2\x85\x0e\x1a\x5f",
|
||||
WC_SHA256_DIGEST_SIZE);
|
||||
|
||||
/* Same bytes at every non-zero offset within a word. */
|
||||
for (off = 1; off < 4; off++) {
|
||||
if (!EXPECT_SUCCESS()) break;
|
||||
|
||||
for (i = 0; i < (word32)WC_SHA256_BLOCK_SIZE; i++) {
|
||||
buf[(word32)off + i] = (byte)(i * 7 + 1);
|
||||
}
|
||||
if (initDone) {
|
||||
wc_Sha256Free(&sha256);
|
||||
initDone = 0;
|
||||
}
|
||||
initRet = wc_InitSha256_ex(&sha256, HEAP_HINT, testDevId);
|
||||
ExpectIntEQ(initRet, 0);
|
||||
if (initRet == 0) initDone = 1;
|
||||
ExpectIntEQ(wc_Sha256HashBlock(&sha256, buf + off, unaligned), 0);
|
||||
ExpectBufEQ(unaligned, aligned, WC_SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
/* hash is optional - block absorbed, no digest written out. */
|
||||
if (initDone) {
|
||||
wc_Sha256Free(&sha256);
|
||||
initDone = 0;
|
||||
}
|
||||
initRet = wc_InitSha256_ex(&sha256, HEAP_HINT, testDevId);
|
||||
ExpectIntEQ(initRet, 0);
|
||||
if (initRet == 0) initDone = 1;
|
||||
ExpectIntEQ(wc_Sha256HashBlock(&sha256, buf, NULL), 0);
|
||||
|
||||
if (initDone) {
|
||||
wc_Sha256Free(&sha256);
|
||||
}
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_wc_Sha256_Flags(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
|
||||
@@ -34,6 +34,7 @@ int test_wc_Sha256Copy(void);
|
||||
int test_wc_Sha256GetHash(void);
|
||||
int test_wc_Sha256Transform(void);
|
||||
int test_wc_Sha256_Flags(void);
|
||||
int test_wc_Sha256HashBlock_unaligned(void);
|
||||
|
||||
int test_wc_InitSha224(void);
|
||||
int test_wc_Sha224Update(void);
|
||||
@@ -54,7 +55,8 @@ int test_wc_Sha224_Flags(void);
|
||||
TEST_DECL_GROUP("sha256", test_wc_Sha256Copy), \
|
||||
TEST_DECL_GROUP("sha256", test_wc_Sha256GetHash), \
|
||||
TEST_DECL_GROUP("sha256", test_wc_Sha256Transform), \
|
||||
TEST_DECL_GROUP("sha256", test_wc_Sha256_Flags)
|
||||
TEST_DECL_GROUP("sha256", test_wc_Sha256_Flags), \
|
||||
TEST_DECL_GROUP("sha256", test_wc_Sha256HashBlock_unaligned)
|
||||
|
||||
#define TEST_SHA224_DECLS \
|
||||
TEST_DECL_GROUP("sha224", test_wc_InitSha224), \
|
||||
|
||||
@@ -244,6 +244,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 */
|
||||
@@ -335,18 +362,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);
|
||||
@@ -450,18 +466,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);
|
||||
@@ -1440,57 +1445,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;
|
||||
}
|
||||
|
||||
@@ -1498,53 +1508,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;
|
||||
@@ -3339,17 +3359,26 @@ static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
|
||||
}
|
||||
|
||||
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
|
||||
/* Rotate the input 8 bits to the left */
|
||||
/* Rotate left 8 bits. The key schedule is a byte array, so use the
|
||||
* unaligned accessors. */
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
*(word32*)out = rotrFixed(*(word32*)in, 8);
|
||||
(void)writeUnalignedWord32(out, rotrFixed(readUnalignedWord32(in), 8));
|
||||
#else
|
||||
*(word32*)out = rotlFixed(*(word32*)in, 8);
|
||||
(void)writeUnalignedWord32(out, rotlFixed(readUnalignedWord32(in), 8));
|
||||
#endif
|
||||
bs_ke_sub_bytes(out, out);
|
||||
/* On just the first byte, add 2^i to the byte */
|
||||
out[0] ^= bs_rcon[i];
|
||||
}
|
||||
|
||||
/* r = a ^ b, on schedule words in byte arrays of unknown alignment. */
|
||||
static void bs_ke_xor(unsigned char* r, const unsigned char* a,
|
||||
const unsigned char* b)
|
||||
{
|
||||
(void)writeUnalignedWord32(r,
|
||||
readUnalignedWord32(a) ^ readUnalignedWord32(b));
|
||||
}
|
||||
|
||||
static void bs_expand_key(unsigned char *in, word32 sz) {
|
||||
unsigned char t[4];
|
||||
word32 o;
|
||||
@@ -3360,14 +3389,10 @@ static void bs_expand_key(unsigned char *in, word32 sz) {
|
||||
for (o = 16; o < sz; o += 16) {
|
||||
bs_ke_transform(t, in + o - 4, i);
|
||||
i++;
|
||||
*(word32*)(in + o + 0) = *(word32*)(in + o - 16) ^
|
||||
*(word32*) t;
|
||||
*(word32*)(in + o + 4) = *(word32*)(in + o - 12) ^
|
||||
*(word32*)(in + o + 0);
|
||||
*(word32*)(in + o + 8) = *(word32*)(in + o - 8) ^
|
||||
*(word32*)(in + o + 4);
|
||||
*(word32*)(in + o + 12) = *(word32*)(in + o - 4) ^
|
||||
*(word32*)(in + o + 8);
|
||||
bs_ke_xor(in + o + 0, in + o - 16, t);
|
||||
bs_ke_xor(in + o + 4, in + o - 12, in + o + 0);
|
||||
bs_ke_xor(in + o + 8, in + o - 8, in + o + 4);
|
||||
bs_ke_xor(in + o + 12, in + o - 4, in + o + 8);
|
||||
}
|
||||
}
|
||||
else if (sz == 208) {
|
||||
@@ -3375,18 +3400,12 @@ static void bs_expand_key(unsigned char *in, word32 sz) {
|
||||
for (o = 24; o < sz; o += 24) {
|
||||
bs_ke_transform(t, in + o - 4, i);
|
||||
i++;
|
||||
*(word32*)(in + o + 0) = *(word32*)(in + o - 24) ^
|
||||
*(word32*) t;
|
||||
*(word32*)(in + o + 4) = *(word32*)(in + o - 20) ^
|
||||
*(word32*)(in + o + 0);
|
||||
*(word32*)(in + o + 8) = *(word32*)(in + o - 16) ^
|
||||
*(word32*)(in + o + 4);
|
||||
*(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
|
||||
*(word32*)(in + o + 8);
|
||||
*(word32*)(in + o + 16) = *(word32*)(in + o - 8) ^
|
||||
*(word32*)(in + o + 12);
|
||||
*(word32*)(in + o + 20) = *(word32*)(in + o - 4) ^
|
||||
*(word32*)(in + o + 16);
|
||||
bs_ke_xor(in + o + 0, in + o - 24, t);
|
||||
bs_ke_xor(in + o + 4, in + o - 20, in + o + 0);
|
||||
bs_ke_xor(in + o + 8, in + o - 16, in + o + 4);
|
||||
bs_ke_xor(in + o + 12, in + o - 12, in + o + 8);
|
||||
bs_ke_xor(in + o + 16, in + o - 8, in + o + 12);
|
||||
bs_ke_xor(in + o + 20, in + o - 4, in + o + 16);
|
||||
}
|
||||
}
|
||||
else if (sz == 240) {
|
||||
@@ -3399,14 +3418,10 @@ static void bs_expand_key(unsigned char *in, word32 sz) {
|
||||
else {
|
||||
bs_ke_sub_bytes(t, in + o - 4);
|
||||
}
|
||||
*(word32*)(in + o + 0) = *(word32*)(in + o - 32) ^
|
||||
*(word32*) t;
|
||||
*(word32*)(in + o + 4) = *(word32*)(in + o - 28) ^
|
||||
*(word32*)(in + o + 0);
|
||||
*(word32*)(in + o + 8) = *(word32*)(in + o - 24) ^
|
||||
*(word32*)(in + o + 4);
|
||||
*(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
|
||||
*(word32*)(in + o + 8);
|
||||
bs_ke_xor(in + o + 0, in + o - 32, t);
|
||||
bs_ke_xor(in + o + 4, in + o - 28, in + o + 0);
|
||||
bs_ke_xor(in + o + 8, in + o - 24, in + o + 4);
|
||||
bs_ke_xor(in + o + 12, in + o - 20, in + o + 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6619,18 +6634,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);
|
||||
@@ -6715,18 +6719,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);
|
||||
@@ -7905,18 +7898,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -309,7 +309,17 @@ WC_MISC_STATIC WC_INLINE word32 readUnalignedWord32(const byte *in)
|
||||
|
||||
WC_MISC_STATIC WC_INLINE word32 writeUnalignedWord32(void *out, word32 in)
|
||||
{
|
||||
#ifndef WOLFSSL_RW_UNALIGNED_32
|
||||
#ifdef WOLFSSL_WIDE_BYTE
|
||||
/* CHAR_BIT != 8 (e.g. TI C28x): one octet per cell, so store 4 octets
|
||||
* little-endian rather than aliasing cells as a word32. Mirrors
|
||||
* readUnalignedWord32() so a read/write pair spans the same cells. */
|
||||
byte* out8 = (byte*)out;
|
||||
|
||||
out8[0] = (byte)( in & 0xFF);
|
||||
out8[1] = (byte)((in >> 8) & 0xFF);
|
||||
out8[2] = (byte)((in >> 16) & 0xFF);
|
||||
out8[3] = (byte)((in >> 24) & 0xFF);
|
||||
#elif !defined(WOLFSSL_RW_UNALIGNED_32)
|
||||
if (((wc_ptr_t)out & (wc_ptr_t)(sizeof(word32) - 1U)) == (wc_ptr_t)0) {
|
||||
*(word32 *)out = in;
|
||||
}
|
||||
|
||||
@@ -142,39 +142,72 @@ CRYS_ECPKI_DomainID_t cc310_mapCurve(int curve_id)
|
||||
#ifndef NO_RSA
|
||||
CRYS_RSA_HASH_OpMode_t cc310_hashModeRSA(enum wc_HashType hash_type, int isHashed)
|
||||
{
|
||||
/* Every case assigns and breaks - a compiled-out algorithm gives the
|
||||
* not-known mode rather than falling through. */
|
||||
CRYS_RSA_HASH_OpMode_t hash_mode;
|
||||
|
||||
switch(hash_type)
|
||||
{
|
||||
case WC_HASH_TYPE_MD5:
|
||||
#ifndef NO_MD5
|
||||
return isHashed? CRYS_RSA_After_MD5_mode : CRYS_RSA_HASH_MD5_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_MD5_mode :
|
||||
CRYS_RSA_HASH_MD5_mode;
|
||||
#else
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
#endif
|
||||
break;
|
||||
case WC_HASH_TYPE_SHA:
|
||||
#ifndef NO_SHA
|
||||
return isHashed? CRYS_RSA_After_SHA1_mode : CRYS_RSA_HASH_SHA1_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_SHA1_mode :
|
||||
CRYS_RSA_HASH_SHA1_mode;
|
||||
#else
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
#endif
|
||||
break;
|
||||
case WC_HASH_TYPE_SHA224:
|
||||
#ifdef WOLFSSL_SHA224
|
||||
return isHashed? CRYS_RSA_After_SHA224_mode : CRYS_RSA_HASH_SHA224_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_SHA224_mode :
|
||||
CRYS_RSA_HASH_SHA224_mode;
|
||||
#else
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
#endif
|
||||
break;
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
#ifndef NO_SHA256
|
||||
return isHashed? CRYS_RSA_After_SHA256_mode : CRYS_RSA_HASH_SHA256_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_SHA256_mode :
|
||||
CRYS_RSA_HASH_SHA256_mode;
|
||||
#else
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
#endif
|
||||
break;
|
||||
case WC_HASH_TYPE_SHA384:
|
||||
#ifdef WOLFSSL_SHA384
|
||||
return isHashed? CRYS_RSA_After_SHA384_mode : CRYS_RSA_HASH_SHA384_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_SHA384_mode :
|
||||
CRYS_RSA_HASH_SHA384_mode;
|
||||
#else
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
#endif
|
||||
break;
|
||||
case WC_HASH_TYPE_SHA512:
|
||||
#ifdef WOLFSSL_SHA512
|
||||
return isHashed? CRYS_RSA_After_SHA512_mode : CRYS_RSA_HASH_SHA512_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_SHA512_mode :
|
||||
CRYS_RSA_HASH_SHA512_mode;
|
||||
#else
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
#endif
|
||||
break;
|
||||
case WC_HASH_TYPE_NONE:
|
||||
/* default to SHA256 */
|
||||
return isHashed? CRYS_RSA_After_SHA256_mode : CRYS_RSA_HASH_SHA256_mode;
|
||||
hash_mode = isHashed? CRYS_RSA_After_SHA256_mode :
|
||||
CRYS_RSA_HASH_SHA256_mode;
|
||||
break;
|
||||
default:
|
||||
return CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
hash_mode = CRYS_RSA_After_HASH_NOT_KNOWN_mode;
|
||||
break;
|
||||
}
|
||||
return hash_mode;
|
||||
}
|
||||
|
||||
#endif /* !NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
|
||||
@@ -985,10 +985,12 @@ static void scryptROMix(byte* x, byte* v, byte* y, int r, word32 n)
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
#ifdef WORD64_AVAILABLE
|
||||
j = (word32)(*(word64*)(x + (2*r - 1) * 64) & (n-1));
|
||||
/* x is an allocator byte array; the big-endian path below already
|
||||
* assembles this byte-wise. */
|
||||
#if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_NO_WORD64_OPS)
|
||||
j = (word32)(readUnalignedWord64(x + (2*r - 1) * 64) & (n-1));
|
||||
#else
|
||||
j = *(word32*)(x + (2*r - 1) * 64) & (n-1);
|
||||
j = readUnalignedWord32(x + (2*r - 1) * 64) & (n-1);
|
||||
#endif
|
||||
#else
|
||||
byte* t = x + (2*r - 1) * 64;
|
||||
|
||||
@@ -2397,8 +2397,20 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
|
||||
}
|
||||
|
||||
if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
|
||||
ByteReverseWords(sha256->buffer, (const word32*)data,
|
||||
#ifdef WOLFSSL_WIDE_BYTE
|
||||
/* CHAR_BIT != 8: pack 16 big-endian schedule words octet-wise */
|
||||
WordsFromBytesBE32(sha256->buffer, data,
|
||||
WC_SHA256_BLOCK_SIZE / 4);
|
||||
#else
|
||||
/* Reverse in place. Stage first only when data is the caller's
|
||||
* own buffer, which may be unaligned - LMS hands us
|
||||
* sha256->buffer itself, and copying that onto itself is UB. */
|
||||
if (data != (const unsigned char*)sha256->buffer) {
|
||||
XMEMCPY(sha256->buffer, data, WC_SHA256_BLOCK_SIZE);
|
||||
}
|
||||
ByteReverseWords(sha256->buffer, sha256->buffer,
|
||||
WC_SHA256_BLOCK_SIZE);
|
||||
#endif
|
||||
data = (const unsigned char*)sha256->buffer;
|
||||
}
|
||||
ret = XTRANSFORM(sha256, data);
|
||||
|
||||
Reference in New Issue
Block a user