aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src
diff options
context:
space:
mode:
authorDoug Hogan <[email protected]>2019-01-07 00:39:03 -0800
committerDoug Hogan <[email protected]>2019-01-08 01:11:58 -0800
commitfba65fa791a44b5d0226bd150e8d9accab1e442a (patch)
tree50176f97c793f1010d36c439ce8893dbf7590221 /lib/crypto/c_src
parenta8382439ac61e942bd36c228e533864814f53666 (diff)
downloadotp-fba65fa791a44b5d0226bd150e8d9accab1e442a.tar.gz
otp-fba65fa791a44b5d0226bd150e8d9accab1e442a.tar.bz2
otp-fba65fa791a44b5d0226bd150e8d9accab1e442a.zip
Revamp ec_key_new()
Diffstat (limited to 'lib/crypto/c_src')
-rw-r--r--lib/crypto/c_src/ec.c290
1 files changed, 158 insertions, 132 deletions
diff --git a/lib/crypto/c_src/ec.c b/lib/crypto/c_src/ec.c
index 6d831ec9d2..98d3007f13 100644
--- a/lib/crypto/c_src/ec.c
+++ b/lib/crypto/c_src/ec.c
@@ -50,157 +50,183 @@ static EC_KEY* ec_key_new(ErlNifEnv* env, ERL_NIF_TERM curve_arg)
BIGNUM *cofactor = NULL;
EC_GROUP *group = NULL;
EC_POINT *point = NULL;
+ int f_arity = -1;
+ const ERL_NIF_TERM *field;
+ int p_arity = -1;
+ const ERL_NIF_TERM *prime;
+ long field_bits;
/* {Field, Prime, Point, Order, CoFactor} = Curve */
- if (enif_get_tuple(env,curve_arg,&c_arity,&curve)
- && c_arity == 5
- && get_bn_from_bin(env, curve[3], &bn_order)
- && (curve[4] != atom_none && get_bn_from_bin(env, curve[4], &cofactor))) {
-
- int f_arity = -1;
- const ERL_NIF_TERM* field;
- int p_arity = -1;
- const ERL_NIF_TERM* prime;
-
- long field_bits;
-
- /* {A, B, Seed} = Prime */
- if (!enif_get_tuple(env,curve[1],&p_arity,&prime)
- || !get_bn_from_bin(env, prime[0], &a)
- || !get_bn_from_bin(env, prime[1], &b))
- goto out_err;
-
- if (!enif_get_tuple(env,curve[0],&f_arity,&field))
- goto out_err;
-
- if (f_arity == 2 && field[0] == atom_prime_field) {
- /* {prime_field, Prime} */
-
- if (!get_bn_from_bin(env, field[1], &p))
- goto out_err;
-
- if (BN_is_negative(p) || BN_is_zero(p))
- goto out_err;
-
- field_bits = BN_num_bits(p);
- if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
- goto out_err;
-
- /* create the EC_GROUP structure */
- group = EC_GROUP_new_curve_GFp(p, a, b, NULL);
+ if (!enif_get_tuple(env, curve_arg, &c_arity, &curve))
+ goto err;
+ if (c_arity != 5)
+ goto err;
+ if (!get_bn_from_bin(env, curve[3], &bn_order))
+ goto err;
+ if (curve[4] != atom_none) {
+ if (!get_bn_from_bin(env, curve[4], &cofactor))
+ goto err;
+ }
- } else if (f_arity == 3 && field[0] == atom_characteristic_two_field) {
+ /* {A, B, Seed} = Prime */
+ if (!enif_get_tuple(env, curve[1], &p_arity, &prime))
+ goto err;
+ if (!get_bn_from_bin(env, prime[0], &a))
+ goto err;
+ if (!get_bn_from_bin(env, prime[1], &b))
+ goto err;
+
+ if (!enif_get_tuple(env, curve[0], &f_arity, &field))
+ goto err;
+
+ if (f_arity == 2 && field[0] == atom_prime_field) {
+ /* {prime_field, Prime} */
+ if (!get_bn_from_bin(env, field[1], &p))
+ goto err;
+ if (BN_is_negative(p))
+ goto err;
+ if (BN_is_zero(p))
+ goto err;
+
+ field_bits = BN_num_bits(p);
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
+ goto err;
+
+ /* create the EC_GROUP structure */
+ if ((group = EC_GROUP_new_curve_GFp(p, a, b, NULL)) == NULL)
+ goto err;
+
+ } else if (f_arity == 3 && field[0] == atom_characteristic_two_field) {
#if defined(OPENSSL_NO_EC2M)
- enif_raise_exception(env, atom_notsup);
- goto out_err;
+ enif_raise_exception(env, atom_notsup);
+ goto out_err;
#else
- /* {characteristic_two_field, M, Basis} */
-
- int b_arity = -1;
- const ERL_NIF_TERM* basis;
- unsigned int k1, k2, k3;
-
- if ((p = BN_new()) == NULL)
- goto out_err;
-
- if (!enif_get_long(env, field[1], &field_bits)
- || field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
- goto out_err;
-
- if (enif_get_tuple(env,field[2],&b_arity,&basis)) {
- if (b_arity == 2
- && basis[0] == atom_tpbasis
- && enif_get_uint(env, basis[1], &k1)) {
- /* {tpbasis, k} = Basis */
-
- if (!(field_bits > k1 && k1 > 0))
- goto out_err;
-
- /* create the polynomial */
- if (!BN_set_bit(p, (int)field_bits)
- || !BN_set_bit(p, (int)k1)
- || !BN_set_bit(p, 0))
- goto out_err;
-
- } else if (b_arity == 4
- && basis[0] == atom_ppbasis
- && enif_get_uint(env, basis[1], &k1)
- && enif_get_uint(env, basis[2], &k2)
- && enif_get_uint(env, basis[3], &k3)) {
- /* {ppbasis, k1, k2, k3} = Basis */
-
- if (!(field_bits > k3 && k3 > k2 && k2 > k1 && k1 > 0))
- goto out_err;
-
- /* 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))
- goto out_err;
-
- } else
- goto out_err;
- } else if (field[2] == atom_onbasis) {
- /* onbasis = Basis */
- /* no parameters */
- goto out_err;
-
- } else
- goto out_err;
-
- group = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+ /* {characteristic_two_field, M, Basis} */
+ int b_arity = -1;
+ const ERL_NIF_TERM* basis;
+
+ if ((p = BN_new()) == NULL)
+ goto err;
+ if (!enif_get_long(env, field[1], &field_bits))
+ goto err;
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS || field_bits > INT_MAX)
+ goto err;
+
+ if (enif_get_tuple(env, field[2], &b_arity, &basis)) {
+ if (b_arity == 2) {
+ unsigned int k1;
+
+ if (basis[0] != atom_tpbasis)
+ goto err;
+ if (!enif_get_uint(env, basis[1], &k1))
+ goto err;
+
+ /* {tpbasis, k} = Basis */
+ if (field_bits <= k1 || k1 == 0 || k1 > INT_MAX)
+ goto err;
+
+ /* create the polynomial */
+ if (!BN_set_bit(p, (int)field_bits))
+ goto err;
+ if (!BN_set_bit(p, (int)k1))
+ goto err;
+ if (!BN_set_bit(p, 0))
+ goto err;
+
+ } else if (b_arity == 4) {
+ unsigned int k1, k2, k3;
+
+ if (basis[0] != atom_ppbasis)
+ goto err;
+ if (!enif_get_uint(env, basis[1], &k1))
+ goto err;
+ if (!enif_get_uint(env, basis[2], &k2))
+ goto err;
+ if (!enif_get_uint(env, basis[3], &k3))
+ goto err;
+
+ /* {ppbasis, k1, k2, k3} = Basis */
+ if (field_bits <= k3 || k3 <= k2 || k2 <= k1 || k1 == 0 || k3 > INT_MAX || k2 > INT_MAX || k1 > INT_MAX)
+ goto err;
+
+ /* create the polynomial */
+ if (!BN_set_bit(p, (int)field_bits))
+ goto err;
+ if (!BN_set_bit(p, (int)k1))
+ goto err;
+ if (!BN_set_bit(p, (int)k2))
+ goto err;
+ if (!BN_set_bit(p, (int)k3))
+ goto err;
+ if (!BN_set_bit(p, 0))
+ goto err;
+
+ } else
+ goto err;
+ } else if (field[2] == atom_onbasis) {
+ /* onbasis = Basis */
+ /* no parameters */
+ goto err;
+
+ } else
+ goto err;
+
+ if ((group = EC_GROUP_new_curve_GF2m(p, a, b, NULL)) == NULL)
+ goto err;
#endif
- } else
- goto out_err;
-
- if (!group)
- goto out_err;
+ } else
+ goto err;
- if (enif_inspect_binary(env, prime[2], &seed)) {
- EC_GROUP_set_seed(group, seed.data, seed.size);
- }
+ if (enif_inspect_binary(env, prime[2], &seed)) {
+ if (!EC_GROUP_set_seed(group, seed.data, seed.size))
+ goto err;
+ }
- if (!term2point(env, curve[2], group, &point))
- goto out_err;
+ if (!term2point(env, curve[2], group, &point))
+ goto err;
- if (BN_is_negative(bn_order)
- || BN_is_zero(bn_order)
- || BN_num_bits(bn_order) > (int)field_bits + 1)
- goto out_err;
+ if (BN_is_negative(bn_order))
+ goto err;
+ if (BN_is_zero(bn_order))
+ goto err;
+ if (BN_num_bits(bn_order) > (int)field_bits + 1)
+ goto err;
- if (!EC_GROUP_set_generator(group, point, bn_order, cofactor))
- goto out_err;
+ if (!EC_GROUP_set_generator(group, point, bn_order, cofactor))
+ goto err;
- EC_GROUP_set_asn1_flag(group, 0x0);
+ EC_GROUP_set_asn1_flag(group, 0x0);
- key = EC_KEY_new();
- if (!key)
- goto out_err;
- EC_KEY_set_group(key, group);
- }
- else {
- goto out_err;
- }
+ if ((key = EC_KEY_new()) == NULL)
+ goto err;
+ if (!EC_KEY_set_group(key, group))
+ goto err;
- goto out;
+ goto done;
-out_err:
- if (key) EC_KEY_free(key);
+ err:
+ if (key)
+ EC_KEY_free(key);
key = NULL;
-out:
+ done:
/* some OpenSSL structures are mem-dup'ed into the key,
so we have to free our copies here */
- if (p) BN_free(p);
- if (a) BN_free(a);
- if (b) BN_free(b);
- if (bn_order) BN_free(bn_order);
- if (cofactor) BN_free(cofactor);
- if (group) EC_GROUP_free(group);
- if (point) EC_POINT_free(point);
+ if (bn_order)
+ BN_free(bn_order);
+ if (cofactor)
+ BN_free(cofactor);
+ if (a)
+ BN_free(a);
+ if (b)
+ BN_free(b);
+ if (p)
+ BN_free(p);
+ if (group)
+ EC_GROUP_free(group);
+ if (point)
+ EC_POINT_free(point);
return key;
}