diff --git a/tests/api/test_sha256.c b/tests/api/test_sha256.c index c7af4d3416..73014d68f9 100644 --- a/tests/api/test_sha256.c +++ b/tests/api/test_sha256.c @@ -214,6 +214,57 @@ int test_wc_Sha256Transform(void) return EXPECT_RESULT(); } +/* + * wc_Sha256HashBlock() takes a caller block pointer of any alignment, so the + * same bytes at an aligned and an unaligned offset must hash the same. + */ +int test_wc_Sha256HashBlock_unaligned(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH) + 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 off; + word32 i; + + for (i = 0; i < (word32)sizeof(buf); i++) { + buf[i] = (byte)(i * 7 + 1); + } + + XMEMSET(&sha256, 0, sizeof(sha256)); + ExpectIntEQ(wc_InitSha256_ex(&sha256, HEAP_HINT, testDevId), 0); + if (EXPECT_SUCCESS()) initDone = 1; + + /* Reference digest of the block at offset 0. */ + ExpectIntEQ(wc_Sha256HashBlock(&sha256, buf, aligned), 0); + + /* 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; + } + ExpectIntEQ(wc_InitSha256_ex(&sha256, HEAP_HINT, testDevId), 0); + if (EXPECT_SUCCESS()) initDone = 1; + ExpectIntEQ(wc_Sha256HashBlock(&sha256, buf + off, unaligned), 0); + ExpectBufEQ(unaligned, aligned, WC_SHA256_DIGEST_SIZE); + } + + if (initDone) { + wc_Sha256Free(&sha256); + } +#endif + return EXPECT_RESULT(); +} + int test_wc_Sha256_Flags(void) { EXPECT_DECLS; diff --git a/tests/api/test_sha256.h b/tests/api/test_sha256.h index 09b2f42696..fbbfde365f 100644 --- a/tests/api/test_sha256.h +++ b/tests/api/test_sha256.h @@ -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), \ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index a3aa862885..192259f117 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -237,6 +237,34 @@ 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 the CRYP peripheral. The public API takes + * byte buffers of any alignment; CRYP_DataIn/Out work in 32-bit words, so + * stage 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 +356,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 +460,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 +1439,63 @@ 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; + /* in/out are caller byte pointers of any alignment; ByteReverseWords + * and the SCE driver need 32-bit words. Stage through aligned locals, + * which also leaves the caller's 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; - } + 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 (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); + if (bigEndian) { + ByteReverseWords(out32, out32, WC_AES_BLOCK_SIZE); } + XMEMCPY(outBlock + i, out32, WC_AES_BLOCK_SIZE); } + return 0; } @@ -1491,53 +1503,64 @@ 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; + /* in/out are caller byte pointers of any alignment; ByteReverseWords + * and the SCE driver need 32-bit words. Stage through aligned locals, + * which also leaves the caller's 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; - } + default: + WOLFSSL_MSG("Unknown key size"); + return BAD_FUNC_ARG; + } - 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); + 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; @@ -3332,17 +3355,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 - no alignment + * guarantee, 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; @@ -3353,14 +3385,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) { @@ -3368,18 +3396,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) { @@ -3392,14 +3414,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); } } } @@ -6523,18 +6541,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); @@ -6619,18 +6626,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); @@ -7763,18 +7759,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); diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index a35fe82695..2dbdb5ff42 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -71,6 +71,30 @@ /* Hardware Acceleration */ #if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY) +/* Push one DES block through the CRYP peripheral. The public API takes + * byte buffers of any alignment; CRYP_DataIn/Out work in 32-bit words, so + * stage 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 +285,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 +435,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); diff --git a/wolfcrypt/src/port/arm/cryptoCell.c b/wolfcrypt/src/port/arm/cryptoCell.c index a170470a5b..957432ede2 100644 --- a/wolfcrypt/src/port/arm/cryptoCell.c +++ b/wolfcrypt/src/port/arm/cryptoCell.c @@ -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 must give + * the not-known mode, not fall through to the next one. */ + 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 diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index 16e11c12ec..169159a635 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -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 + /* Unaligned read: x is an allocator byte array. The big-endian + * path below already assembles this byte-wise. */ #ifdef WORD64_AVAILABLE - j = (word32)(*(word64*)(x + (2*r - 1) * 64) & (n-1)); + 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; diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 0c6650d60a..b4ca8201b5 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -2397,7 +2397,10 @@ 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, + /* Copy then reverse in place: data is caller-supplied and may + * be unaligned, sha256->buffer is not. */ + XMEMCPY(sha256->buffer, data, WC_SHA256_BLOCK_SIZE); + ByteReverseWords(sha256->buffer, sha256->buffer, WC_SHA256_BLOCK_SIZE); data = (const unsigned char*)sha256->buffer; }