File 8654-crypto-generate_key-and-compute_key-error-ERR-error-.patch of Package erlang
From 8aa62ec02cd5cf5acd49f30dc532f9a3d3ae47d8 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Wed, 9 Mar 2022 09:03:29 +0100
Subject: [PATCH 4/8] crypto:generate_key and compute_key error:ERR ->
error:{ERR,FileInfo,Description}
---
lib/crypto/c_src/crypto.c | 2 +-
lib/crypto/c_src/dh.c | 101 ++++++++++++++++------------------
lib/crypto/c_src/ec.c | 22 ++++----
lib/crypto/c_src/ec.h | 2 +-
lib/crypto/c_src/ecdh.c | 41 ++++++--------
lib/crypto/c_src/evp.c | 67 +++++++++++-----------
lib/crypto/doc/src/crypto.xml | 1 +
lib/crypto/src/crypto.erl | 46 ++++++++++------
8 files changed, 141 insertions(+), 141 deletions(-)
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 519d35b93f..042d122f53 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -109,7 +109,7 @@ static ErlNifFunc nif_funcs[] = {
{"srp_user_secret_nif", 7, srp_user_secret_nif, 0},
{"srp_host_secret_nif", 5, srp_host_secret_nif, 0},
- {"ec_key_generate", 2, ec_key_generate, 0},
+ {"ec_generate_key_nif", 2, ec_generate_key_nif, 0},
{"ecdh_compute_key_nif", 3, ecdh_compute_key_nif, 0},
{"rand_seed_nif", 1, rand_seed_nif, 0},
diff --git a/lib/crypto/c_src/dh.c b/lib/crypto/c_src/dh.c
index 67be0c81f0..8d3f53d06e 100644
--- a/lib/crypto/c_src/dh.c
+++ b/lib/crypto/c_src/dh.c
@@ -45,43 +45,43 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
if (argv[0] != atom_undefined) {
if (!get_bn_from_bin(env, argv[0], &priv_key_in))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 0, "Can't get bignum from binary"));
}
if (!enif_get_list_cell(env, argv[1], &head, &tail))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "List with exactly two elements expected"));
if (!get_bn_from_bin(env, head, &dh_p))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "Can't get bignum from binary"));
if (!enif_get_list_cell(env, tail, &head, &tail))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "List with exactly two elements expected"));
if (!get_bn_from_bin(env, head, &dh_g))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "Can't get bignum from binary"));
if (!enif_is_empty_list(env, tail))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "List with exactly two elements expected"));
if (!enif_get_uint(env, argv[2], &mpint))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "Integer expected"));
if (mpint != 0 && mpint != 4)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "Integer 0 or 4 expected"));
if (!enif_get_ulong(env, argv[3], &len))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 3, "Integer expected"));
if (len > LONG_MAX)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 3, "Too big integer"));
/* Load dh_params with values to use by the generator.
Mem mgmnt transferred from dh_p etc to dh_params */
if ((dh_params = DH_new()) == NULL)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't do DH_new"));
if (priv_key_in) {
if (!DH_set0_key(dh_params, NULL, priv_key_in))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 0, "Not accepted as private key"));
/* On success, dh_params owns priv_key_in */
priv_key_in = NULL;
}
if (!DH_set0_pqg(dh_params, dh_p, NULL, dh_g))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "P and/or G not accepted"));
dh_p_shared = dh_p; /* Don't free this because dh_params owns it */
/* On success, dh_params owns dh_p and dh_g */
dh_p = NULL;
@@ -91,56 +91,56 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
int bn_len;
if ((bn_len = BN_num_bits(dh_p_shared)) < 0)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR(env, "BN_num_bits < 0"));
dh_p_shared = NULL; /* dh_params owns the reference */
if (len >= (size_t)bn_len)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 3, "Too big length"));
if (!DH_set_length(dh_params, (long)len))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 3, "The length is not accepted"));
}
#if defined(HAS_EVP_PKEY_CTX) && (! DISABLE_EVP_DH)
if ((params = EVP_PKEY_new()) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_new"));
/* set the key referenced by params to dh_params... */
if (EVP_PKEY_set1_DH(params, dh_params) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_set1_DH"));
if ((ctx = EVP_PKEY_CTX_new(params, NULL)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_CTX_new"));
if (EVP_PKEY_keygen_init(ctx) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_keygen_init"));
if ((dhkey = EVP_PKEY_new()) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_new"));
/* key gen op, key written to ppkey (=last arg) */
if (EVP_PKEY_keygen(ctx, &dhkey) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_keygen"));
DH_free(dh_params);
if ((dh_params = EVP_PKEY_get1_DH(dhkey)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_get1_DH"));
#else
if (!DH_generate_key(dh_params))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't DH_generate_key"));
#endif
DH_get0_key(dh_params, &pub_key_gen, &priv_key_gen);
if ((pub_len = BN_num_bytes(pub_key_gen)) < 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't get public key length"));
if ((prv_len = BN_num_bytes(priv_key_gen)) < 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't get private key length"));
if ((pub_ptr = enif_make_new_binary(env, (size_t)pub_len+mpint, &ret_pub)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't allocate pub_ptr"));
if ((prv_ptr = enif_make_new_binary(env, (size_t)prv_len+mpint, &ret_prv)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't allocate prv_ptr"));
if (mpint) {
put_uint32(pub_ptr, (unsigned int)pub_len);
@@ -151,9 +151,9 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
}
if (BN_bn2bin(pub_key_gen, pub_ptr) < 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't BN_bn2bin"));
if (BN_bn2bin(priv_key_gen, prv_ptr) < 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't BN_bn2bin"));
ERL_VALGRIND_MAKE_MEM_DEFINED(pub_ptr, pub_len);
ERL_VALGRIND_MAKE_MEM_DEFINED(prv_ptr, prv_len);
@@ -161,13 +161,7 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
ret = enif_make_tuple2(env, ret_pub, ret_prv);
goto done;
- bad_arg:
- ret = enif_make_badarg(env);
- goto done;
-
err:
- ret = atom_error;
-
done:
if (priv_key_in)
BN_free(priv_key_in);
@@ -216,22 +210,22 @@ ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
ASSERT(argc == 3);
if (!get_bn_from_bin(env, argv[0], &other_pub_key))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 0, "Can't get bignum from binary"));
if (!get_bn_from_bin(env, argv[1], &priv_key))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "Can't get bignum from binary"));
if (!enif_get_list_cell(env, argv[2], &head, &tail))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "List with exactly two elements expected"));
if (!get_bn_from_bin(env, head, &dh_p))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "Can't get bignum from binary"));
if (!enif_get_list_cell(env, tail, &head, &tail))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "List with exactly two elements expected"));
if (!get_bn_from_bin(env, head, &dh_g))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "Can't get bignum from binary"));
if (!enif_is_empty_list(env, tail))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "List with exactly two elements expected"));
/* Note: DH_set0_key() does not allow setting only the
* private key, although DH_compute_key() does not use the
@@ -239,48 +233,45 @@ ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
* the public key to a copy of the private key.
*/
if ((dummy_pub_key = BN_dup(priv_key)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't BN_dup"));
if ((dh_priv = DH_new()) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't DH_new"));
if (!DH_set0_key(dh_priv, dummy_pub_key, priv_key))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't DH_set0_key"));
/* dh_priv owns dummy_pub_key and priv_key now */
dummy_pub_key = NULL;
priv_key = NULL;
if (!DH_set0_pqg(dh_priv, dh_p, NULL, dh_g))
- goto err;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "P and/or G not accepted"));
/* dh_priv owns dh_p and dh_g now */
dh_p = NULL;
dh_g = NULL;
if ((dh_size = DH_size(dh_priv)) < 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't DH_size"));
if (!enif_alloc_binary((size_t)dh_size, &ret_bin))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't allcate binary"));
ret_bin_alloc = 1;
if ((size = DH_compute_key(ret_bin.data, other_pub_key, dh_priv)) < 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't DH_compute_key"));
if (size == 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "size == 0"));
if ((size_t)size != ret_bin.size) {
if (!enif_realloc_binary(&ret_bin, (size_t)size))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't realloc binary"));
}
ret = enif_make_binary(env, &ret_bin);
ret_bin_alloc = 0;
goto done;
- bad_arg:
err:
if (ret_bin_alloc)
enif_release_binary(&ret_bin);
- ret = enif_make_badarg(env);
-
done:
if (other_pub_key)
BN_free(other_pub_key);
diff --git a/lib/crypto/c_src/ec.c b/lib/crypto/c_src/ec.c
index fd66ecfab4..a7497f014a 100644
--- a/lib/crypto/c_src/ec.c
+++ b/lib/crypto/c_src/ec.c
@@ -426,11 +426,9 @@ int get_ec_key_sz(ErlNifEnv* env,
return 1;
}
-#endif /* HAVE_EC */
-ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+ERL_NIF_TERM ec_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{ /* (Curve, PrivKey) */
-#if defined(HAVE_EC)
EC_KEY *key = NULL;
const EC_GROUP *group;
const EC_POINT *public_key;
@@ -440,11 +438,11 @@ ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
size_t size;
if (!get_ec_key_sz(env, argv[0], argv[1], atom_undefined, &key, &size))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "Couldn't get EC key"));
if (argv[1] == atom_undefined) {
if (!EC_KEY_generate_key(key))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't generate EC key"));
}
group = EC_KEY_get0_group(key);
@@ -463,15 +461,17 @@ ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
goto done;
err:
- bad_arg:
- ret = make_badarg_maybe(env);
-
done:
if (key)
EC_KEY_free(key);
return ret;
+}
+#endif /* HAVE_EC */
-#else
- return atom_notsup;
-#endif
+
+#if ! defined(HAVE_EC)
+ERL_NIF_TERM ec_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{ /* (Curve, PrivKey) */
+ return EXCP_NOTSUP_N(env, 0, "EC not supported");
}
+#endif
diff --git a/lib/crypto/c_src/ec.h b/lib/crypto/c_src/ec.h
index e7b885cb0f..96e02643c8 100644
--- a/lib/crypto/c_src/ec.h
+++ b/lib/crypto/c_src/ec.h
@@ -33,6 +33,6 @@ int term2point(ErlNifEnv* env, ERL_NIF_TERM term, EC_GROUP *group, EC_POINT **pp
ERL_NIF_TERM make_badarg_maybe(ErlNifEnv* env);
#endif
-ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM ec_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
#endif /* E_EC_H__ */
diff --git a/lib/crypto/c_src/ecdh.c b/lib/crypto/c_src/ecdh.c
index 041c658808..9133878b58 100644
--- a/lib/crypto/c_src/ecdh.c
+++ b/lib/crypto/c_src/ecdh.c
@@ -29,7 +29,7 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
/* (OtherPublicKey, Curve, My) */
{
#if defined(HAVE_EC)
- ERL_NIF_TERM ret;
+ ERL_NIF_TERM ret = atom_undefined;
unsigned char *p;
EC_KEY* key = NULL;
int degree;
@@ -39,44 +39,37 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
EC_POINT *my_ecpoint = NULL;
EC_KEY *other_ecdh = NULL;
- ASSERT(argc == 3);
-
if (!get_ec_key_sz(env, argv[1], argv[2], atom_undefined, &key, NULL)) // my priv key
- goto bad_arg;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "Couldn't get local key"));
+
if ((group = EC_GROUP_dup(EC_KEY_get0_group(key))) == NULL)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't duplicate EC key"));
+
priv_key = EC_KEY_get0_private_key(key);
- if (!term2point(env, argv[0], group, &my_ecpoint)) {
- goto err;
- }
+ if (!term2point(env, argv[0], group, &my_ecpoint))
+ assign_goto(ret, err, EXCP_BADARG_N(env, 0, "Couldn't get ecpoint"));
if ((other_ecdh = EC_KEY_new()) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't allocate EC_KEY"));
+
if (!EC_KEY_set_group(other_ecdh, group))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't set group"));
+
if (!EC_KEY_set_private_key(other_ecdh, priv_key))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't set private key"));
if ((degree = EC_GROUP_get_degree(group)) <= 0)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't get degree"));
field_size = (size_t)degree;
if ((p = enif_make_new_binary(env, (field_size+7)/8, &ret)) == NULL)
- goto err;
- if (ECDH_compute_key(p, (field_size+7)/8, my_ecpoint, other_ecdh, NULL) < 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't allocate binary"));
- goto done;
-
- bad_arg:
- ret = make_badarg_maybe(env);
- goto done;
+ if (ECDH_compute_key(p, (field_size+7)/8, my_ecpoint, other_ecdh, NULL) < 1)
+ assign_goto(ret, err, EXCP_ERROR(env, "Couldn't compute key"));
err:
- ret = enif_make_badarg(env);
-
- done:
if (group)
EC_GROUP_free(group);
if (my_ecpoint)
@@ -89,6 +82,6 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
return ret;
#else
- return atom_notsup;
+ return EXCP_NOTSUP_N(env, 0, "EC not supported");
#endif
}
diff --git a/lib/crypto/c_src/evp.c b/lib/crypto/c_src/evp.c
index 7491db3d57..00a6fe16ed 100644
--- a/lib/crypto/c_src/evp.c
+++ b/lib/crypto/c_src/evp.c
@@ -34,43 +34,53 @@ ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
ASSERT(argc == 3);
+ /* Arg 0, Curve */
if (argv[0] == atom_x25519)
type = EVP_PKEY_X25519;
else if (argv[0] == atom_x448)
type = EVP_PKEY_X448;
else
- goto bad_arg;
+ assign_goto(ret, bad_arg, EXCP_BADARG_N(env, 0, "Bad curve"));
- if (!enif_inspect_binary(env, argv[1], &peer_bin))
- goto bad_arg;
+ /* Arg 2, MyBin (My private key) */
if (!enif_inspect_binary(env, argv[2], &my_bin))
- goto bad_arg;
+ assign_goto(ret, bad_arg, EXCP_BADARG_N(env, 2, "Binary expected"));
if ((my_key = EVP_PKEY_new_raw_private_key(type, NULL, my_bin.data, my_bin.size)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 2, "Not a valid raw private key"));
+
if ((ctx = EVP_PKEY_CTX_new(my_key, NULL)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 2, "Can't make context"));
if (EVP_PKEY_derive_init(ctx) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_derive_init"));
+
+ /* Arg 1, PeerBin (Peer public key) */
+ if (!enif_inspect_binary(env, argv[1], &peer_bin))
+ assign_goto(ret, bad_arg, EXCP_BADARG_N(env, 1, "Binary expected"));
if ((peer_key = EVP_PKEY_new_raw_public_key(type, NULL, peer_bin.data, peer_bin.size)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_BADARG_N(env, 1, "Not a raw public peer key"));
+
if (EVP_PKEY_derive_set_peer(ctx, peer_key) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 1, "Can't EVP_PKEY_derive_set_peer"));
+ /* Find max size of the common key */
if (EVP_PKEY_derive(ctx, NULL, &max_size) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 1, "Can't get max size"));
if (!enif_alloc_binary(max_size, &key_bin))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't allocate"));
+
key_bin_alloc = 1;
+
+ /* Derive the common key */
if (EVP_PKEY_derive(ctx, key_bin.data, &key_bin.size) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_derive"));
if (key_bin.size < max_size) {
if (!enif_realloc_binary(&key_bin, (size_t)key_bin.size))
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't shrink binary"));
}
ret = enif_make_binary(env, &key_bin);
@@ -81,7 +91,6 @@ ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
err:
if (key_bin_alloc)
enif_release_binary(&key_bin);
- ret = enif_make_badarg(env);
done:
if (my_key)
@@ -98,6 +107,7 @@ ERL_NIF_TERM evp_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
#endif
}
+
ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* (Curve) */
{
@@ -119,46 +129,41 @@ ERL_NIF_TERM evp_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
else if (argv[0] == atom_ed448)
type = EVP_PKEY_ED448;
else
- goto bad_arg;
+ assign_goto(ret, bad_arg, EXCP_BADARG_N(env, 0, "Bad curve"));
if (argv[1] == atom_undefined) {
if ((ctx = EVP_PKEY_CTX_new_id(type, NULL)) == NULL)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't make context"));
if (EVP_PKEY_keygen_init(ctx) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_keygen_init"));
if (EVP_PKEY_keygen(ctx, &pkey) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_keygen"));
} else {
if (!enif_inspect_binary(env, argv[1], &prv_key))
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 1, "Can't get max size"));
if ((pkey = EVP_PKEY_new_raw_private_key(type, NULL, prv_key.data, prv_key.size)) == NULL)
- goto bad_arg;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 1, "Can't EVP_PKEY_new_raw_private_key"));
}
if (EVP_PKEY_get_raw_public_key(pkey, NULL, &key_len) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 1, "Can't get max size"));
if ((out_pub = enif_make_new_binary(env, key_len, &ret_pub)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't allocate"));
if (EVP_PKEY_get_raw_public_key(pkey, out_pub, &key_len) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_get_raw_public_key"));
if (EVP_PKEY_get_raw_private_key(pkey, NULL, &key_len) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR_N(env, 1, "Can't get max size"));
if ((out_priv = enif_make_new_binary(env, key_len, &ret_prv)) == NULL)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't allocate"));
if (EVP_PKEY_get_raw_private_key(pkey, out_priv, &key_len) != 1)
- goto err;
+ assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_get_raw_private_key"));
ret = enif_make_tuple2(env, ret_pub, ret_prv);
goto done;
bad_arg:
- ret = enif_make_badarg(env);
- goto done;
-
err:
- ret = atom_error;
-
done:
if (pkey)
EVP_PKEY_free(pkey);
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 0b20d715df..9ee2653c0c 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -1050,6 +1050,7 @@ end
<name name="compute_key" arity="4" since="OTP R16B01"/>
<fsummary>Computes the shared secret</fsummary>
<desc>
+ <p>Uses the <seeerl marker="#error_3tup">3-tuple style</seeerl> for error handling.</p>
<p>Computes the shared secret from the private key and the other party's public key.
See also <seemfa marker="public_key:public_key#compute_key/2">public_key:compute_key/2</seemfa>
</p>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index bfdc8b784c..bffaacb043 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -1602,9 +1602,11 @@ generate_key(dh, DHParameters0, PrivateKey) ->
[P,G,L] -> {[P,G], L};
[P,G] -> {[P,G], 0}
end,
- dh_generate_key_nif(ensure_int_as_bin(PrivateKey),
- map_ensure_int_as_bin(DHParameters),
- 0, Len);
+ ?nif_call(dh_generate_key_nif(ensure_int_as_bin(PrivateKey),
+ map_ensure_int_as_bin(DHParameters),
+ 0, Len),
+ {3, 2, -1, 2},
+ [dh, DHParameters0, PrivateKey]);
generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivArg)
when is_binary(Verifier), is_binary(Generator), is_binary(Prime), is_atom(Version) ->
@@ -1648,14 +1650,20 @@ generate_key(ecdh, Curve, PrivKey) when Curve == x448 ;
generate_key(eddh, Curve, PrivKey);
generate_key(eddh, Curve, PrivKey) when Curve == x448 ;
Curve == x25519 ->
- evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey));
+ ?nif_call(evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey)),
+ {2, 3},
+ [eddh, Curve, PrivKey]
+ );
generate_key(ecdh, Curve, PrivKey) ->
- ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey));
+ ?nif_call(ec_generate_key_nif(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)));
generate_key(eddsa, Curve, PrivKey) when Curve == ed448 ;
Curve == ed25519 ->
- evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey)).
+ ?nif_call(evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey)),
+ {2, 3},
+ [eddsa, Curve, PrivKey]
+ ).
evp_generate_key_nif(_Curve, _PrivKey) -> ?nif_stub.
@@ -1670,13 +1678,11 @@ evp_generate_key_nif(_Curve, _PrivKey) -> ?nif_stub.
.
compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
- case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
- ensure_int_as_bin(MyPrivateKey),
- map_ensure_int_as_bin(DHParameters)) of
- error -> erlang:error(computation_failed,
- [dh,OthersPublicKey,MyPrivateKey,DHParameters]);
- Ret -> Ret
- end;
+ ?nif_call(dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
+ ensure_int_as_bin(MyPrivateKey),
+ map_ensure_int_as_bin(DHParameters)),
+ {2, 3, 4},
+ [dh, OthersPublicKey, MyPrivateKey, DHParameters]);
compute_key(srp, HostPublic, {UserPublic, UserPrivate},
{user, [DerivedKey, Prime, Generator, Version | ScramblerArg]}) when
@@ -1715,12 +1721,16 @@ compute_key(ecdh, Others, My, Curve) when Curve == x448 ;
compute_key(eddh, Others, My, Curve) when Curve == x448 ;
Curve == x25519 ->
- evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My));
+ ?nif_call(evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My)),
+ {2, 3, 4},
+ [eddh, Others, My, Curve]);
compute_key(ecdh, Others, My, Curve) ->
- ecdh_compute_key_nif(ensure_int_as_bin(Others),
- nif_curve_params(Curve),
- ensure_int_as_bin(My)).
+ ?nif_call(ecdh_compute_key_nif(ensure_int_as_bin(Others),
+ nif_curve_params(Curve),
+ ensure_int_as_bin(My)),
+ {2, 4, 3},
+ [ecdh, Others, My, Curve]).
evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub.
@@ -2274,7 +2284,7 @@ dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint, _Length) -> ?nif_stub.
%% MyPrivKey, OthersPublicKey = mpint()
dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
-ec_key_generate(_Curve, _Key) -> ?nif_stub.
+ec_generate_key_nif(_Curve, _Key) -> ?nif_stub.
ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.
--
2.34.1