@@ -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+
794795static 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