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,