Skip to content

Commit 9785464

Browse files
authored
Merge pull request #135 from haydenroche5/alignment
Fix alignment crash with SHA-512/384.
2 parents c9355ff + 6cec00a commit 9785464

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

configure.ac

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ then
8686
AM_CFLAGS="$AM_CFLAGS -DWE_NO_DYNAMIC_ENGINE"
8787
fi
8888

89+
# Support for fixing memory alignment bugs at the wolfEngine level.
90+
AC_ARG_ENABLE([alignment-safety],
91+
[AS_HELP_STRING([--enable-alignment-safety],[Fixes certain wolfCrypt alignment bugs at the wolfEngine level. (default: disabled).])],
92+
[ ENABLED_ALIGNMENT_SAFETY=$enableval ],
93+
[ ENABLED_ALIGNMENT_SAFETY=no ]
94+
)
95+
96+
if test "$ENABLED_ALIGNMENT_SAFETY" = "yes"
97+
then
98+
AM_CFLAGS="$AM_CFLAGS -DWE_ALIGNMENT_SAFETY"
99+
fi
100+
89101
# Single threaded
90102
AC_ARG_ENABLE([singlethreaded],
91103
[AS_HELP_STRING([--enable-singlethreaded],[Enable wolfEngine single threaded (default: disabled).])],
@@ -677,6 +689,7 @@ echo
677689
echo " Features "
678690
echo " * User settings: $ENABLED_USERSETTINGS"
679691
echo " * Dynamic engine: $ENABLED_DYNAMIC_ENGINE"
692+
echo " * Alignment safety: $ENABLED_ALIGNMENT_SAFETY"
680693
echo " * Digest:"
681694
echo " * - SHA-1: $ENABLED_SHA1"
682695
echo " * - SHA-224: $ENABLED_SHA224"

src/we_digest.c

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ static int we_sha3_512_init(EVP_MD_CTX *ctx)
791791
* @param len [in] Length of data to digest.
792792
* @return 1 on success and 0 on failure.
793793
*/
794+
794795
static int we_digest_update(EVP_MD_CTX *ctx, const void *data, size_t len)
795796
{
796797
int ret = 1, rc;
@@ -802,13 +803,71 @@ static int we_digest_update(EVP_MD_CTX *ctx, const void *data, size_t len)
802803

803804
digest = (we_Digest *)EVP_MD_CTX_md_data(ctx);
804805

805-
rc = wc_HashUpdate(&digest->hash, digest->hashType, (const byte*)data,
806-
(word32)len);
807-
if (rc != 0) {
808-
WOLFENGINE_ERROR_FUNC(WE_LOG_DIGEST, "wc_HashUpdate", rc);
806+
if (digest == NULL) {
807+
WOLFENGINE_ERROR_MSG(WE_LOG_DIGEST, "digest was NULL");
809808
ret = 0;
810809
}
811810

811+
#ifdef WE_ALIGNMENT_SAFETY
812+
const word32 ALIGNMENT_REQ = 8;
813+
word32 add = 0;
814+
byte* tmp = NULL;
815+
if (ret == 1 && (digest->hashType == WC_HASH_TYPE_SHA384 ||
816+
digest->hashType == WC_HASH_TYPE_SHA512)) {
817+
add = len > (WC_SHA512_BLOCK_SIZE - digest->hash.sha512.buffLen) ?
818+
(WC_SHA512_BLOCK_SIZE - digest->hash.sha512.buffLen) : len;
819+
}
820+
/* If the conditions below are satisfied, just calling wc_HashUpdate with
821+
* the passed in buffer and length can cause a memory alignment crash on
822+
* certain platforms. The alternate algorithm used below (2 calls to
823+
* wc_HashUpdate) avoids this crash. */
824+
if (len > 0 && add > 0 && ((len - add) >= WC_SHA512_BLOCK_SIZE) &&
825+
(((unsigned long)data + add) % ALIGNMENT_REQ != 0)) {
826+
/* Update the hash with "add" bytes of data, which will result in
827+
* an update with a full WC_SHA512_BLOCK_SIZE number of bytes with no
828+
* leftovers. */
829+
rc = wc_HashUpdate(&digest->hash, digest->hashType,
830+
(const byte*)data, add);
831+
if (rc != 0) {
832+
WOLFENGINE_ERROR_FUNC(WE_LOG_DIGEST, "wc_HashUpdate", rc);
833+
ret = 0;
834+
}
835+
if (ret == 1) {
836+
/* Allocate new, aligned buffer. */
837+
tmp = (byte*)XMALLOC(len - add, NULL, DYNAMIC_TYPE_TMP_BUFFER);
838+
if (tmp == NULL) {
839+
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_DIGEST, "XMALLOC",
840+
tmp);
841+
ret = 0;
842+
}
843+
}
844+
if (ret == 1) {
845+
/* Copy remaining data from the unaligned buffer to the aligned one
846+
* and update the hash. */
847+
XMEMCPY(tmp, (byte*)data + add, len - add);
848+
rc = wc_HashUpdate(&digest->hash, digest->hashType,
849+
(const byte*)tmp, len - add);
850+
if (rc != 0) {
851+
WOLFENGINE_ERROR_FUNC(WE_LOG_DIGEST, "wc_HashUpdate", rc);
852+
ret = 0;
853+
}
854+
}
855+
856+
if (tmp != NULL) {
857+
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
858+
}
859+
}
860+
else
861+
#endif
862+
if (ret == 1) {
863+
rc = wc_HashUpdate(&digest->hash, digest->hashType, (const byte*)data,
864+
(word32)len);
865+
if (rc != 0) {
866+
WOLFENGINE_ERROR_FUNC(WE_LOG_DIGEST, "wc_HashUpdate", rc);
867+
ret = 0;
868+
}
869+
}
870+
812871
WOLFENGINE_LEAVE(WE_LOG_DIGEST, "we_digest_update", ret);
813872

814873
return ret;

0 commit comments

Comments
 (0)