Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
2594-crypto-introduce-helper-get_curve_definiti...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2594-crypto-introduce-helper-get_curve_definition.patch of Package erlang
From 3dffd15f79ed4bd867f3a6ed0c460bc8683ea365 Mon Sep 17 00:00:00 2001 From: Hans Nilsson <hans@erlang.org> Date: Thu, 21 Apr 2022 20:09:11 +0200 Subject: [PATCH 4/7] crypto: introduce helper get_curve_definition --- lib/crypto/c_src/ec.c | 184 ++++++++++++++++++++++++++++++++++++++++++ lib/crypto/c_src/ec.h | 7 ++ 2 files changed, 191 insertions(+) diff --git a/lib/crypto/c_src/ec.c b/lib/crypto/c_src/ec.c index e1e002aeaa..881e1e0f55 100644 --- a/lib/crypto/c_src/ec.c +++ b/lib/crypto/c_src/ec.c @@ -22,6 +22,190 @@ #include "bn.h" #ifdef HAVE_EC + +# if defined(HAS_3_0_API) + +int get_curve_definition(ErlNifEnv* env, ERL_NIF_TERM *ret, ERL_NIF_TERM def, + OSSL_PARAM params[], int *i, + size_t *order_size) +{ + const ERL_NIF_TERM* curve; + int c_arity = -1; + const ERL_NIF_TERM *prime; + int p_arity = -1; + const ERL_NIF_TERM *field; + int f_arity = -1; + BIGNUM *p = NULL; + + /* Here are two random curve definition examples, one prime_field and + one characteristic_two_field. Both are from the crypto/src/crypto_ec_curves.erl. + + curve(secp192r1) -> + { + {prime_field, <<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF:192>>}, %% Prime + {<<16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC:192>>, %% A + <<16#64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1:192>>, %% B + <<16#3045AE6FC8422F64ED579528D38120EAE12196D5:160>>}, %% Seed + <<16#04:8, + 16#188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012:192, %% X(p0) + 16#07192B95FFC8DA78631011ED6B24CDD573F977A11E794811:192>>, %% Y(p0) + <<16#FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831:192>>, %% Order + <<16#01:8>> %% CoFactor + }; + + curve(c2pnb176v1) -> + { + {characteristic_two_field, 176, {ppbasis,1,2,43}}, + {<<16#E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B:176>>, %% A + <<16#5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2:176>>, %% B + none}, %% Seed + <<16#04:8, + 16#8D16C2866798B600F9F08BB4A8E860F3298CE04A5798:176, %% X(p0) + 16#6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C:176>>, %% Y(p0) + <<16#010092537397ECA4F6145799D62B0A19CE06FE26AD:168>>, %% Order + <<16#FF6E:16>> %% CoFactor + }; + */ + + /* {Field, Prime, Point, Order, CoFactor} = CurveDef */ + if (!enif_get_tuple(env, def, &c_arity, &curve) || + c_arity != 5) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad curve def. Expect 5-tuple.")); + + if (!get_ossl_octet_string_param_from_bin(env, "generator", curve[2], ¶ms[(*i)++])) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad Generator (Point)")); + + if (!get_ossl_BN_param_from_bin_sz(env, "order", curve[3], ¶ms[(*i)++], order_size)) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad order")); + + if (curve[4] == atom_none) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Cofactor must be != none")); + + if (!get_ossl_BN_param_from_bin(env, "cofactor", curve[4], ¶ms[(*i)++])) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad cofactor")); + + /* {A, B, Seed} = Prime = curve[1] */ + if (!enif_get_tuple(env, curve[1], &p_arity, &prime)) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad Prime")); + + if (!get_ossl_BN_param_from_bin(env, "a", prime[0], ¶ms[(*i)++])) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad a")); + + if (!get_ossl_BN_param_from_bin(env, "b", prime[1], ¶ms[(*i)++])) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad b")); + + if (enif_is_binary(env, prime[2])) + if (!get_ossl_octet_string_param_from_bin(env, "seed", prime[2], ¶ms[(*i)++])) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad seed")); + + /* Field = curve[0] */ + if (!enif_get_tuple(env, curve[0], &f_arity, &field)) { + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad Field")); + } + else if (f_arity == 2 && field[0] == atom_prime_field) { + /* {prime_field, Prime} */ + params[(*i)++] = OSSL_PARAM_construct_utf8_string("field-type", "prime-field", 0); + + if (!get_ossl_BN_param_from_bin(env, "p", field[1], ¶ms[(*i)++])) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad p (Prime)")); + } + + else if (f_arity == 3 && field[0] == atom_characteristic_two_field) { + /* {characteristic_two_field, M, Basis} */ +# if defined(OPENSSL_NO_EC2M) + assign_goto(*ret, err, EXCP_NOTSUP_N(env, 1, "Unsupported field-type (characteristic_two_field)")); +# else + int b_arity = -1; + const ERL_NIF_TERM* basis; + long field_bits; + + params[(*i)++] = OSSL_PARAM_construct_utf8_string("field-type", "characteristic-two-field", 0); + + if ((p = BN_new()) == NULL) + assign_goto(*ret, err, EXCP_ERROR(env, "Creating bignum failed")); + + if (!enif_get_long(env, field[1], &field_bits) || + (field_bits > OPENSSL_ECC_MAX_FIELD_BITS || field_bits > INT_MAX) + ) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad field-bits (M)")); + + if (enif_get_tuple(env, field[2], &b_arity, &basis)) { + if (b_arity == 2) { + unsigned int k1; + + if (basis[0] != atom_tpbasis) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad atom")); + if (!enif_get_uint(env, basis[1], &k1)) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "uint expected (k1)")); + + /* {tpbasis, k} = Basis */ + if (field_bits <= k1 || k1 == 0 || k1 > INT_MAX) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "bad values (field_bits or k1)")); + + /* create the polynomial */ + if (!BN_set_bit(p, (int)field_bits) || + !BN_set_bit(p, (int)k1) || + !BN_set_bit(p, 0)) + assign_goto(*ret, err, EXCP_ERROR(env, "Polynom bit setting failed")); + + } else if (b_arity == 4) { + /* {ppbasis, k1, k2, k3} = Basis */ + unsigned int k1, k2, k3; + + if (basis[0] != atom_ppbasis) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad atom")); + + if (!enif_get_uint(env, basis[1], &k1) || + !enif_get_uint(env, basis[2], &k2) || + !enif_get_uint(env, basis[3], &k3)) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Expecting uint (k1,k2,k3)")); + + if (field_bits <= k3 || k3 <= k2 || k2 <= k1 || k1 == 0 || + k3 > INT_MAX || k2 > INT_MAX || k1 > INT_MAX) + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "bad values (field_bits, k1, k2 or k3)")); + + /* create the polynomial */ + if (!BN_set_bit(p, (int)field_bits) || + !BN_set_bit(p, (int)k1) || + !BN_set_bit(p, (int)k2) || + !BN_set_bit(p, (int)k3) || + !BN_set_bit(p, 0) ) + assign_goto(*ret, err, EXCP_ERROR(env, "Polynom bit setting failed")); + + } else + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad tuple")); + + } else if (field[2] == atom_onbasis) { + /* onbasis = Basis */ + /* no parameters */ + assign_goto(*ret, err, EXCP_NOTSUP_N(env, 1, "'onbasis' not supported")); + } 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); + } +# endif + } + else + assign_goto(*ret, err, EXCP_ERROR_N(env, 1, "Bad field-type")); + + if (p) BN_free(p); + return 1; + + err: + if (p) BN_free(p); + return 0; +} + +# endif /* HAS_3_0_API */ + static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg, size_t *size); static ERL_NIF_TERM point2term(ErlNifEnv* env, const EC_GROUP *group, diff --git a/lib/crypto/c_src/ec.h b/lib/crypto/c_src/ec.h index a3827c3a74..3b010f0c42 100644 --- a/lib/crypto/c_src/ec.h +++ b/lib/crypto/c_src/ec.h @@ -24,6 +24,13 @@ #include "common.h" #if defined(HAVE_EC) + +# if defined(HAS_3_0_API) +int get_curve_definition(ErlNifEnv* env, ERL_NIF_TERM *ret, ERL_NIF_TERM def, + OSSL_PARAM params[], int *i, + size_t *order_size); +# endif /* HAS_3_0_API */ + int get_ec_public_key(ErlNifEnv* env, ERL_NIF_TERM key, EVP_PKEY **pkey); int get_ec_private_key(ErlNifEnv* env, ERL_NIF_TERM key, EVP_PKEY **pkey); -- 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