aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src/ecdh.c
diff options
context:
space:
mode:
authorDoug Hogan <[email protected]>2019-01-03 18:32:08 -0800
committerDoug Hogan <[email protected]>2019-01-08 00:08:22 -0800
commite8813319d24ed1f8200b09969b015fb2311967f9 (patch)
treee895b9b294b25059bf102bfa6cc2965f9afa6fef /lib/crypto/c_src/ecdh.c
parent10665143d538b0ed344d172655e174713da3a336 (diff)
downloadotp-e8813319d24ed1f8200b09969b015fb2311967f9.tar.gz
otp-e8813319d24ed1f8200b09969b015fb2311967f9.tar.bz2
otp-e8813319d24ed1f8200b09969b015fb2311967f9.zip
Revamp ecdh_compute_key_nif()
* Bug fix: ECDH_compute_key was not being checked for failures - That function returns 0 on failure and never returns < 0. - Using <= 0 check because OpenSSL uses that internally and on their wiki. * Remove unnecessary variable i * Make the gotos always flow downward rather than jumping back.
Diffstat (limited to 'lib/crypto/c_src/ecdh.c')
-rw-r--r--lib/crypto/c_src/ecdh.c66
1 files changed, 40 insertions, 26 deletions
diff --git a/lib/crypto/c_src/ecdh.c b/lib/crypto/c_src/ecdh.c
index d458f3c48e..ee4b352730 100644
--- a/lib/crypto/c_src/ecdh.c
+++ b/lib/crypto/c_src/ecdh.c
@@ -32,48 +32,62 @@ ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
ERL_NIF_TERM ret;
unsigned char *p;
EC_KEY* key = NULL;
- int field_size = 0;
- int i;
- EC_GROUP *group;
+ int degree;
+ size_t field_size;
+ EC_GROUP *group = NULL;
const BIGNUM *priv_key;
EC_POINT *my_ecpoint = NULL;
EC_KEY *other_ecdh = NULL;
+ if (argc != 3)
+ goto bad_arg;
if (!get_ec_key(env, argv[1], argv[2], atom_undefined, &key))
- return make_badarg_maybe(env);
-
- group = EC_GROUP_dup(EC_KEY_get0_group(key));
+ goto bad_arg;
+ if ((group = EC_GROUP_dup(EC_KEY_get0_group(key))) == NULL)
+ goto bad_arg;
priv_key = EC_KEY_get0_private_key(key);
if (!term2point(env, argv[0], group, &my_ecpoint)) {
- goto out_err;
+ goto err;
}
- if ((other_ecdh = EC_KEY_new()) == NULL
- || !EC_KEY_set_group(other_ecdh, group)
- || !EC_KEY_set_private_key(other_ecdh, priv_key))
- goto out_err;
+ if ((other_ecdh = EC_KEY_new()) == NULL)
+ goto err;
+ if (!EC_KEY_set_group(other_ecdh, group))
+ goto err;
+ if (!EC_KEY_set_private_key(other_ecdh, priv_key))
+ goto err;
- field_size = EC_GROUP_get_degree(group);
- if (field_size <= 0)
- goto out_err;
+ if ((degree = EC_GROUP_get_degree(group)) <= 0)
+ goto err;
- p = enif_make_new_binary(env, (field_size+7)/8, &ret);
- i = ECDH_compute_key(p, (field_size+7)/8, my_ecpoint, other_ecdh, NULL);
+ 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;
- if (i < 0)
- goto out_err;
-out:
- if (group) EC_GROUP_free(group);
- if (my_ecpoint) EC_POINT_free(my_ecpoint);
- if (other_ecdh) EC_KEY_free(other_ecdh);
- if (key) EC_KEY_free(key);
+ goto done;
- return ret;
+ bad_arg:
+ ret = make_badarg_maybe(env);
+ goto done;
-out_err:
+ err:
ret = enif_make_badarg(env);
- goto out;
+
+ done:
+ if (group)
+ EC_GROUP_free(group);
+ if (my_ecpoint)
+ EC_POINT_free(my_ecpoint);
+ if (other_ecdh)
+ EC_KEY_free(other_ecdh);
+ if (key)
+ EC_KEY_free(key);
+
+ return ret;
+
#else
return atom_notsup;
#endif