File 8742-crypto-Fix-get_ossl_BN_param_from_bin_sz-to-not-abus.patch of Package erlang

From 22aaa17a0af6a20c712bd0071337f8cb5e486676 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Wed, 7 Jun 2023 18:50:23 +0200
Subject: [PATCH 02/14] crypto: Fix get_ossl_BN_param_from_bin_sz() to not
 abuse ErlNifBinary

It is not allowed to write to the binary buffer returned by
enif_inspect_binary() (even if you created the binary yourself).

In DEBUG built VM such abuse will be punished with:

"Readonly data written by NIF, checksums differ 8000425 != 25040008
ABORTING"

Instead use enif_make_new_binary() to create a writable binary buffer.
---
 lib/crypto/c_src/bn.c | 35 +++++++++++++++++++++++++----------
 lib/crypto/c_src/bn.h |  1 +
 lib/crypto/c_src/ec.c | 11 ++---------
 3 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/lib/crypto/c_src/bn.c b/lib/crypto/c_src/bn.c
index f06ed9002e..5e9fec5093 100644
--- a/lib/crypto/c_src/bn.c
+++ b/lib/crypto/c_src/bn.c
@@ -212,23 +212,38 @@ int get_ossl_BN_param_from_bin(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL
     return get_ossl_BN_param_from_bin_sz(env, key, bin, dest, NULL);
 }
 
-int get_ossl_BN_param_from_bin_sz(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest, size_t *size)
+int get_ossl_BN_param_from_bin_sz(ErlNifEnv* env, char* key, ERL_NIF_TERM bin,
+                                  OSSL_PARAM *dest, size_t *size)
 {
     BIGNUM *bn = NULL;
-    ErlNifBinary tmp;
+    int ok = 0;
 
-    if (!get_bn_from_bin_sz(env, bin, &bn, size) ||
-        !enif_inspect_binary(env, bin_from_bn(env,bn), &tmp) || // Allocate buf
-        BN_bn2nativepad(bn, tmp.data, tmp.size) < 0) {// Fill with BN in right endianity
-        if (bn) BN_free(bn);
+    if (!get_bn_from_bin_sz(env, bin, &bn, size))
         return 0;
-    }
-    
-    *dest = OSSL_PARAM_construct_BN(key, tmp.data, tmp.size);
-    if (bn) BN_free(bn);
+
+    ok = get_ossl_BN_param_from_bn(env, key, bn, dest);
+    BN_free(bn);
+    return ok;
+}
+
+int get_ossl_BN_param_from_bn(ErlNifEnv* env, char* key, const BIGNUM* bn,
+                              OSSL_PARAM *dest)
+{
+    const size_t bn_sz = BN_num_bytes(bn);
+    unsigned char* tmp_buf;
+    ERL_NIF_TERM dummy_term;
+
+    /* Create a binary term just as a convenient tmp buffer */
+    tmp_buf = enif_make_new_binary(env, bn_sz, &dummy_term);
+    if (BN_bn2nativepad(bn, tmp_buf, bn_sz) < 0) // Fill with BN in right endianity
+        return 0;
+
+    *dest = OSSL_PARAM_construct_BN(key, tmp_buf, bn_sz);
     return 1;
 }
 
+
+
 int get_ossl_param_from_bin_in_list(ErlNifEnv* env, char* key, ERL_NIF_TERM *listcell, OSSL_PARAM *dest)
 {
     ERL_NIF_TERM head;
diff --git a/lib/crypto/c_src/bn.h b/lib/crypto/c_src/bn.h
index 5e207aed2d..662a32dc29 100644
--- a/lib/crypto/c_src/bn.h
+++ b/lib/crypto/c_src/bn.h
@@ -38,6 +38,7 @@ int get_bn_from_bin_sz(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp, size_t*
 int get_ossl_octet_string_param_from_bin(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest);
 int get_ossl_BN_param_from_bin(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest);
 int get_ossl_BN_param_from_bin_sz(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest, size_t *size);
+int get_ossl_BN_param_from_bn(ErlNifEnv* env, char* key, const BIGNUM* bn, OSSL_PARAM *dest);
 
 int get_ossl_param_from_bin_in_list(ErlNifEnv* env, char* key, ERL_NIF_TERM *listcell, OSSL_PARAM *dest);
 #endif
diff --git a/lib/crypto/c_src/ec.c b/lib/crypto/c_src/ec.c
index 852f3ba79c..af5f5d6f4a 100644
--- a/lib/crypto/c_src/ec.c
+++ b/lib/crypto/c_src/ec.c
@@ -189,15 +189,8 @@ int get_curve_definition(ErlNifEnv* env, ERL_NIF_TERM *ret, ERL_NIF_TERM def,
         } else
             assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad last field"));
 
-        {
-            ErlNifBinary tmp;
-                        
-            if (!enif_inspect_binary(env, bin_from_bn(env,p), &tmp) || // Allocate buf
-                BN_bn2nativepad(p, tmp.data, tmp.size) < 0) {// Fill with BN in right endianity
-                assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "BN padding failed"));
-            }
-            params[(*i)++] = OSSL_PARAM_construct_BN("p", tmp.data, tmp.size);
-        }
+        if (!get_ossl_BN_param_from_bn(env, "p", p, &params[(*i)++]))
+            assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "BN padding failed"));
 #  endif
     }
     else
-- 
2.35.3

openSUSE Build Service is sponsored by