103 lines
4.0 KiB
Diff
103 lines
4.0 KiB
Diff
|
From: Sverker Eriksson <sverker@erlang.org>
|
||
|
Date: Wed, 7 Jun 2023 18:50:23 +0200
|
||
|
Subject: [PATCH] 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.
|
||
|
|
||
|
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, ¶ms[(*i)++]))
|
||
|
+ assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "BN padding failed"));
|
||
|
# endif
|
||
|
}
|
||
|
else
|