aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto/c_src
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2017-01-31 17:02:23 +0100
committerHans Nilsson <[email protected]>2017-01-31 17:02:23 +0100
commit9b133547ba26090dfc0dd457fa7ec8dc8329109c (patch)
tree0485c93182c16bdfdd65c43fef4e2e3589e60e79 /lib/crypto/c_src
parent9bdaf40c9e5242593e011a3f5fb4e37818ddc459 (diff)
parent21d21786abdaae2ae0a601baf5102412399d7af6 (diff)
downloadotp-9b133547ba26090dfc0dd457fa7ec8dc8329109c.tar.gz
otp-9b133547ba26090dfc0dd457fa7ec8dc8329109c.tar.bz2
otp-9b133547ba26090dfc0dd457fa7ec8dc8329109c.zip
Merge branch 'maint'
Conflicts: lib/crypto/c_src/crypto.c lib/crypto/src/crypto.erl
Diffstat (limited to 'lib/crypto/c_src')
-rw-r--r--lib/crypto/c_src/crypto.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 38b49c7a76..44c3fc4f06 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -61,7 +61,6 @@
#include <openssl/evp.h>
#include <openssl/hmac.h>
-
/* Helper macro to construct a OPENSSL_VERSION_NUMBER.
* See openssl/opensslv.h
*/
@@ -285,6 +284,7 @@ static INLINE int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
static INLINE int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
static INLINE int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+static INLINE int DH_set_length(DH *dh, long length);
static INLINE void DH_get0_pqg(const DH *dh,
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
static INLINE void DH_get0_key(const DH *dh,
@@ -305,6 +305,12 @@ static INLINE int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
return 1;
}
+static INLINE int DH_set_length(DH *dh, long length)
+{
+ dh->length = length;
+ return 1;
+}
+
static INLINE void
DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
{
@@ -430,7 +436,7 @@ static ErlNifFunc nif_funcs[] = {
{"rsa_private_crypt", 4, rsa_private_crypt},
{"dh_generate_parameters_nif", 2, dh_generate_parameters_nif},
{"dh_check", 1, dh_check},
- {"dh_generate_key_nif", 3, dh_generate_key_nif},
+ {"dh_generate_key_nif", 4, dh_generate_key_nif},
{"dh_compute_key_nif", 3, dh_compute_key_nif},
{"srp_value_B_nif", 5, srp_value_B_nif},
{"srp_user_secret_nif", 7, srp_user_secret_nif},
@@ -2867,7 +2873,7 @@ static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
}
static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{/* (PrivKey, DHParams=[P,G], Mpint) */
+{/* (PrivKey|undefined, DHParams=[P,G], Mpint, Len|0) */
DH* dh_params;
int pub_len, prv_len;
unsigned char *pub_ptr, *prv_ptr;
@@ -2875,6 +2881,7 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
int mpint; /* 0 or 4 */
BIGNUM *priv_key = NULL;
BIGNUM *dh_p = NULL, *dh_g = NULL;
+ unsigned long len = 0;
if (!(get_bn_from_bin(env, argv[0], &priv_key)
|| argv[0] == atom_undefined)
@@ -2883,8 +2890,10 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
|| !enif_get_list_cell(env, tail, &head, &tail)
|| !get_bn_from_bin(env, head, &dh_g)
|| !enif_is_empty_list(env, tail)
- || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)) {
- if (priv_key) BN_free(priv_key);
+ || !enif_get_int(env, argv[2], &mpint) || (mpint & ~4)
+ || !enif_get_ulong(env, argv[3], &len) ) {
+
+ if (priv_key) BN_free(priv_key);
if (dh_p) BN_free(dh_p);
if (dh_g) BN_free(dh_g);
return enif_make_badarg(env);
@@ -2894,6 +2903,15 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
DH_set0_key(dh_params, NULL, priv_key);
DH_set0_pqg(dh_params, dh_p, NULL, dh_g);
+ if (len) {
+ if (len < BN_num_bits(dh_p))
+ DH_set_length(dh_params, len);
+ else {
+ DH_free(dh_params);
+ return enif_make_badarg(env);
+ }
+ }
+
if (DH_generate_key(dh_params)) {
const BIGNUM *pub_key, *priv_key;
DH_get0_key(dh_params, &pub_key, &priv_key);