File 0948-crypto-Fix-SHAKE-128-256-xoflen-default-for-OpenSSL-.patch of Package erlang

From 8d1be17d648c80c1aed9dbc2231eb28f7d7219dd Mon Sep 17 00:00:00 2001
From: Fredrik Frantzen <frazze@erlang.org>
Date: Tue, 10 Jun 2025 10:42:49 +0200
Subject: [PATCH] crypto: Fix SHAKE-128/256 xoflen default for OpenSSL 3.4+ in
 hash_nif (fixes #8997)

---
 lib/crypto/c_src/hash.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/lib/crypto/c_src/hash.c b/lib/crypto/c_src/hash.c
index e821464105..36bcdfc1ba 100644
--- a/lib/crypto/c_src/hash.c
+++ b/lib/crypto/c_src/hash.c
@@ -106,6 +106,9 @@ ERL_NIF_TERM hash_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
     ERL_NIF_TERM         ret;
     unsigned             ret_size;
     unsigned char        *outp;
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(3,4,0)
+    EVP_MD_CTX *ctx = NULL;
+#endif
 
     if ((digp = get_digest_type(argv[0])) == NULL)
         return EXCP_BADARG_N(env, 0, "Bad digest type");
@@ -117,6 +120,42 @@ ERL_NIF_TERM hash_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
     if (!enif_inspect_iolist_as_binary(env, argv[1], &data))
         return EXCP_BADARG_N(env, 1, "Not iolist");
 
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(3,4,0)
+    /* Set xoflen for SHAKE digests if needed */
+    if (digp->xof_default_length) {
+        int ok = 0;
+        ctx = EVP_MD_CTX_new();
+        if (!ctx)
+            return EXCP_ERROR(env, "Low-level call EVP_MD_CTX_new failed");
+        if (EVP_DigestInit(ctx, md) != 1) {
+            EVP_MD_CTX_free(ctx);
+            return EXCP_ERROR(env, "Low-level call EVP_DigestInit failed");
+        }
+        OSSL_PARAM params[2];
+        params[0] = OSSL_PARAM_construct_uint("xoflen", &digp->xof_default_length);
+        params[1] = OSSL_PARAM_construct_end();
+        if (!EVP_MD_CTX_set_params(ctx, params)) {
+            EVP_MD_CTX_free(ctx);
+            return EXCP_ERROR(env, "Can't set param xoflen");
+        }
+        ret_size = digp->xof_default_length;
+        if ((outp = enif_make_new_binary(env, ret_size, &ret)) == NULL) {
+            EVP_MD_CTX_free(ctx);
+            return EXCP_ERROR(env, "Can't allocate binary");
+        }
+        if (EVP_DigestUpdate(ctx, data.data, data.size) != 1) {
+            EVP_MD_CTX_free(ctx);
+            return EXCP_ERROR(env, "Low-level call EVP_DigestUpdate failed");
+        }
+        if (EVP_DigestFinalXOF(ctx, outp, ret_size) != 1) {
+            EVP_MD_CTX_free(ctx);
+            return EXCP_ERROR(env, "Low-level call EVP_DigestFinalXOF failed");
+        }
+        EVP_MD_CTX_free(ctx);
+        CONSUME_REDS(env, data);
+        return ret;
+    }
+#endif
 
     ret_size = (unsigned)EVP_MD_size(md);
     ASSERT(0 < ret_size && ret_size <= EVP_MAX_MD_SIZE);
-- 
2.43.0

openSUSE Build Service is sponsored by