Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
2596-crypto-ecdh_compute_key_nif-for-3.0.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2596-crypto-ecdh_compute_key_nif-for-3.0.patch of Package erlang
From 88be010b54a4ff6208aee274688e1c7b233e12ea Mon Sep 17 00:00:00 2001 From: Hans Nilsson <hans@erlang.org> Date: Thu, 31 Mar 2022 21:42:37 +0200 Subject: [PATCH 6/7] crypto: ecdh_compute_key_nif for 3.0 --- lib/crypto/c_src/ecdh.c | 108 ++++++++++++++++++++++++++++++- lib/crypto/test/crypto_SUITE.erl | 32 ++++++++- 2 files changed, 138 insertions(+), 2 deletions(-) diff --git a/lib/crypto/c_src/ecdh.c b/lib/crypto/c_src/ecdh.c index 092b59e2df..96c57f18e7 100644 --- a/lib/crypto/c_src/ecdh.c +++ b/lib/crypto/c_src/ecdh.c @@ -30,8 +30,113 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a #else +# if defined(HAS_3_0_API) +# include "bn.h" + ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) /* (OtherPublicKey, Curve, My) */ +{ + ERL_NIF_TERM ret = atom_undefined; + ErlNifBinary ret_bin; + size_t sz; + int ret_bin_alloc = 0; + int i = 0, i_key = 0; + OSSL_PARAM params[15]; + EVP_PKEY_CTX *own_pctx = NULL, *peer_pctx = NULL, *pctx_gen = NULL; + EVP_PKEY *own_pkey = NULL, *peer_pkey = NULL; + int err; + + /**** Fetch parameters ****/ + + /* Build peer_pkey */ + i_key = i; + if (!get_ossl_octet_string_param_from_bin(env, "pub", argv[0], ¶ms[i++])) + assign_goto(ret, err, EXCP_BADARG_N(env, 0, "Bad peer public key; binary expected")); + + /* Curve definition/name */ + if (!get_curve_definition(env, &ret, argv[1], params, &i, NULL)) + goto err; + + /* End of params */ + params[i++] = OSSL_PARAM_construct_end(); + + /* Build the remote public key in peer_pkey */ + peer_pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + + if (EVP_PKEY_fromdata_init(peer_pctx) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't init fromdata")); + + if (EVP_PKEY_fromdata(peer_pctx, &peer_pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't do fromdata")); + + if (!peer_pkey) + assign_goto(ret, err, EXCP_ERROR(env, "No peer_pkey")); + + /* Build the local private (and public) key in own_pkey */ + + /* Just replace the pub key with the priv key in params; the + curve definition is of course the same + */ + if (!get_ossl_BN_param_from_bin(env, "priv", argv[2], ¶ms[i_key])) + assign_goto(ret, err, EXCP_BADARG_N(env, 0, "Bad peer public key; binary expected")); + + own_pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + + if (EVP_PKEY_fromdata_init(own_pctx) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't init fromdata")); + + if (EVP_PKEY_fromdata(own_pctx, &own_pkey, EVP_PKEY_KEYPAIR, params) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't do fromdata")); + + if (!own_pkey) + assign_goto(ret, err, EXCP_ERROR(env, "No own_pkey")); + + /**** Derive the common secret from own_pkey and peer_pkey ****/ + + if (!(pctx_gen = EVP_PKEY_CTX_new(own_pkey, NULL))) + assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_CTX_init")); + + if (EVP_PKEY_derive_init(pctx_gen) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't EVP_PKEY_derive_init")); + + if ((err = EVP_PKEY_derive_set_peer_ex(pctx_gen, peer_pkey, 0)) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't derive secret or set peer")); + + if ((err = EVP_PKEY_derive(pctx_gen, NULL, &sz)) <= 0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't get result size")); + + if (!enif_alloc_binary(sz, &ret_bin)) + assign_goto(ret, err, EXCP_ERROR(env, "Can't allcate binary")); + ret_bin_alloc = 1; + + if ((err = EVP_PKEY_derive(pctx_gen, ret_bin.data, &ret_bin.size)) <=0) + assign_goto(ret, err, EXCP_ERROR(env, "Can't get result")); + + if (sz != ret_bin.size) + if (!enif_realloc_binary(&ret_bin, ret_bin.size)) + assign_goto(ret, err, EXCP_ERROR(env, "Can't realloc binary")); + + ret = enif_make_binary(env, &ret_bin); + ret_bin_alloc = 0; + + err: + if (ret_bin_alloc) enif_release_binary(&ret_bin); + if (peer_pctx) EVP_PKEY_CTX_free(peer_pctx); + if (peer_pkey) EVP_PKEY_free(peer_pkey); + if (own_pctx) EVP_PKEY_CTX_free(own_pctx); + if (own_pkey) EVP_PKEY_free(own_pkey); + if (pctx_gen) EVP_PKEY_CTX_free(pctx_gen); + return ret; +} + +# endif /* HAS_3_0_API */ + + + +# if ! defined(HAS_3_0_API) + +ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +/* (OtherPublicKey, {CurveDef,_CurveName}, My) */ { ERL_NIF_TERM ret = atom_undefined; unsigned char *p; @@ -84,5 +189,6 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a EC_KEY_free(key); return ret; -#endif } +# endif /* ! HAS_3_0_API */ +#endif /* HAVE_EC */ diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 968a65318c..156b00688b 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -1194,6 +1194,18 @@ use_all_ec_sign_verify(_Config) -> ok; _ -> ct:log("Fails:~n~p",[Fails]), + Errors = lists:usort([Err || {_,Err} <- Fails]), + FailedCurves = [Curve || {Curve,_} <- Fails], + FailedCurvesPerError = [{E, [C || {C,E0} <- Fails, + E0 == E]} + || E <- Errors], + ct:pal("~p failed curves: ~p", [length(FailedCurves), FailedCurves]), + ct:pal("Failed curves per error:~n~s", + [ + [io_lib:format(" Error: ~p~n Curves: ~p~n~n", [E,Cs]) + || {E,Cs} <- FailedCurvesPerError] + ] + ), ct:fail("Bad curve(s)",[]) end. @@ -1238,13 +1250,31 @@ do_dh_curves(_Config, Curves) -> (_) -> true end, Results), + Succedes = + lists:filter(fun({_,true}) -> true; + (_) -> false + end, Results), + case Fails of [] -> ct:comment("All ~p passed",[length(Results)]), ok; _ -> - ct:comment("passed: ~p, failed: ~p",[length(Results),length(Fails)]), + ct:comment("passed: ~p, failed: ~p",[length(Results)-length(Fails),length(Fails)]), + ct:log("Succedes:~n~p",[Succedes]), ct:log("Fails:~n~p",[Fails]), + Errors = lists:usort([Err || {_,Err} <- Fails]), + FailedCurves = [C || {C,_} <- Fails], + FailedCurvesPerError = [{E, [C || {C,E0} <- Fails, + E == E0]} + || E <- Errors], + ct:pal("~p (~p) failed curves: ~p", [length(FailedCurves), length(Results), FailedCurves]), + ct:pal("Failed curves per error:~n~s", + [ + [io_lib:format(" Error: ~p~n Curves: ~p~n~n", [E,Cs]) + || {E,Cs} <- FailedCurvesPerError] + ] + ), ct:fail("Bad curve(s)",[]) end. -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor