Commit 85f6102785 for openssl.org
commit 85f6102785af5b9382e5a449e5a2bc183c32e0f6
Author: Neil Horman <nhorman@openssl.org>
Date: Tue Jan 20 12:14:04 2026 -0500
Do thunking of SHA256_Update
The SHA256_Update function (in fact all functions implemented via the
HASH_UPDATE macro) have mismatched prototypes with the
OSSL_FUNC_digest_update_fn.
This leads to ubsan errors with more recent versions of clang
Create a Thunk that does the proper casting on those function pointer
callbacks
Fixes #29615
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/29650)
diff --git a/crypto/sha/sha256.c b/crypto/sha/sha256.c
index 0268e09dde..5a038dc050 100644
--- a/crypto/sha/sha256.c
+++ b/crypto/sha/sha256.c
@@ -119,7 +119,8 @@ int SHA224_Final(unsigned char *md, SHA256_CTX *c)
} \
} while (0)
-#define HASH_UPDATE SHA256_Update
+#define HASH_UPDATE_THUNK
+#define HASH_UPDATE SHA256_Update_thunk
#define HASH_TRANSFORM SHA256_Transform
#define HASH_FINAL SHA256_Final
#define HASH_BLOCK_DATA_ORDER sha256_block_data_order
@@ -133,6 +134,12 @@ void sha256_block_data_order_c(SHA256_CTX *ctx, const void *in, size_t num);
void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
#include "crypto/md32_common.h"
+#undef HASH_UPDATE_THUNK
+
+int SHA256_Update(SHA256_CTX *ctx, const void *data, size_t sz)
+{
+ return SHA256_Update_thunk((void *)ctx, (const unsigned char *)data, sz);
+}
#if !defined(SHA256_ASM) || defined(INCLUDE_C_SHA256)
static const SHA_LONG K256[64] = {
diff --git a/include/crypto/md32_common.h b/include/crypto/md32_common.h
index 9ad2e328bd..9d8f6beb1d 100644
--- a/include/crypto/md32_common.h
+++ b/include/crypto/md32_common.h
@@ -154,8 +154,16 @@
* Time for some action :-)
*/
+#ifdef HASH_UPDATE_THUNK
+int HASH_UPDATE(void *cp, const unsigned char *data_, size_t len);
+int HASH_UPDATE(void *cp, const unsigned char *data_, size_t len)
+#else
int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+#endif
{
+#ifdef HASH_UPDATE_THUNK
+ HASH_CTX *c = (HASH_CTX *)cp;
+#endif
const unsigned char *data = data_;
unsigned char *p;
HASH_LONG l;
diff --git a/providers/implementations/digests/sha2_prov.c b/providers/implementations/digests/sha2_prov.c
index c75b6d9b3f..0f8cdc929c 100644
--- a/providers/implementations/digests/sha2_prov.c
+++ b/providers/implementations/digests/sha2_prov.c
@@ -30,6 +30,8 @@
#define SHA2_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
+extern int SHA256_Update_thunk(void *ctx, const unsigned char *data, size_t sz);
+
/* Special set_params method for SSL3 */
static int sha1_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
@@ -293,13 +295,13 @@ IMPLEMENT_digest_functions_with_serialize(sha224, SHA256_CTX,
IMPLEMENT_digest_functions_with_serialize(sha256, SHA256_CTX,
SHA256_CBLOCK, SHA256_DIGEST_LENGTH,
SHA2_FLAGS, SHA256_Init,
- SHA256_Update, SHA256_Final,
+ SHA256_Update_thunk, SHA256_Final,
SHA256_Serialize, SHA256_Deserialize)
/* ossl_sha256_192_internal_functions */
IMPLEMENT_digest_functions_with_serialize(sha256_192_internal, SHA256_CTX,
SHA256_CBLOCK, SHA256_192_DIGEST_LENGTH,
SHA2_FLAGS, ossl_sha256_192_init,
- SHA256_Update, SHA256_Final,
+ SHA256_Update_thunk, SHA256_Final,
SHA256_Serialize, SHA256_Deserialize)
/* ossl_sha384_functions */
IMPLEMENT_digest_functions_with_serialize(sha384, SHA512_CTX,