Skip to content

Commit 93d3bf6

Browse files
committed
Merge 'sverker/crypto/dh-max-key-length' into maint
OTP-19872
2 parents 6e1a4d3 + 5746c1e commit 93d3bf6

File tree

4 files changed

+38
-19
lines changed

4 files changed

+38
-19
lines changed

lib/crypto/c_src/bn.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,14 @@ int get_ossl_octet_string_param_from_bin(ErlNifEnv* env, const char* key, ERL_NI
209209
}
210210

211211

212-
int get_ossl_BN_param_from_bin(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest)
212+
int get_ossl_BN_param_from_bin_x(ErlNifEnv* env, char* key, ERL_NIF_TERM bin,
213+
OSSL_PARAM *dest, BIGNUM** bn_out)
213214
{
214-
return get_ossl_BN_param_from_bin_sz(env, key, bin, dest, NULL);
215+
return get_ossl_BN_param_from_bin_sz_x(env, key, bin, dest, NULL, bn_out);
215216
}
216217

217-
int get_ossl_BN_param_from_bin_sz(ErlNifEnv* env, char* key, ERL_NIF_TERM bin,
218-
OSSL_PARAM *dest, size_t *size)
218+
int get_ossl_BN_param_from_bin_sz_x(ErlNifEnv* env, char* key, ERL_NIF_TERM bin,
219+
OSSL_PARAM *dest, size_t *size, BIGNUM** bn_out)
219220
{
220221
BIGNUM *bn = NULL;
221222
int ok = 0;
@@ -224,7 +225,11 @@ int get_ossl_BN_param_from_bin_sz(ErlNifEnv* env, char* key, ERL_NIF_TERM bin,
224225
return 0;
225226

226227
ok = get_ossl_BN_param_from_bn(env, key, bn, dest);
227-
BN_free(bn);
228+
if (ok && bn_out) {
229+
*bn_out = bn;
230+
} else {
231+
BN_free(bn);
232+
}
228233
return ok;
229234
}
230235

@@ -246,13 +251,15 @@ int get_ossl_BN_param_from_bn(ErlNifEnv* env, char* key, const BIGNUM* bn,
246251

247252

248253

249-
int get_ossl_param_from_bin_in_list(ErlNifEnv* env, char* key, ERL_NIF_TERM *listcell, OSSL_PARAM *dest)
254+
int get_ossl_param_from_bin_in_list_x(ErlNifEnv* env, char* key,
255+
ERL_NIF_TERM *listcell, OSSL_PARAM *dest,
256+
BIGNUM** bn_out)
250257
{
251258
ERL_NIF_TERM head;
252259

253260
return
254261
enif_get_list_cell(env, *listcell, &head, listcell) &&
255-
get_ossl_BN_param_from_bin(env, key, head, dest);
262+
get_ossl_BN_param_from_bin_x(env, key, head, dest, bn_out);
256263
}
257264

258265
#endif

lib/crypto/c_src/bn.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,17 @@ int get_bn_from_bin_sz(ErlNifEnv* env, ERL_NIF_TERM term, BIGNUM** bnp, size_t*
3838

3939
#ifdef HAS_3_0_API
4040
int get_ossl_octet_string_param_from_bin(ErlNifEnv* env, const char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest);
41-
int get_ossl_BN_param_from_bin(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest);
42-
int get_ossl_BN_param_from_bin_sz(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest, size_t *size);
41+
int get_ossl_BN_param_from_bin_x(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest, BIGNUM** bn_out);
42+
#define get_ossl_BN_param_from_bin(ENV,KEY,BIN,DEST) get_ossl_BN_param_from_bin_x(ENV,KEY,BIN,DEST,NULL)
43+
44+
int get_ossl_BN_param_from_bin_sz_x(ErlNifEnv* env, char* key, ERL_NIF_TERM bin, OSSL_PARAM *dest, size_t *size, BIGNUM** bn_out);
45+
#define get_ossl_BN_param_from_bin_sz(ENV,KEY,BIN,DEST,SIZE) get_ossl_BN_param_from_bin_sz_x(ENV,KEY,BIN,DEST,SIZE,NULL)
46+
4347
int get_ossl_BN_param_from_bn(ErlNifEnv* env, char* key, const BIGNUM* bn, OSSL_PARAM *dest);
4448

45-
int get_ossl_param_from_bin_in_list(ErlNifEnv* env, char* key, ERL_NIF_TERM *listcell, OSSL_PARAM *dest);
49+
int get_ossl_param_from_bin_in_list_x(ErlNifEnv* env, char* key, ERL_NIF_TERM *listcell, OSSL_PARAM *dest, BIGNUM** bn_out);
50+
#define get_ossl_param_from_bin_in_list(ENV,KEY,CELL,DEST) get_ossl_param_from_bin_in_list_x(ENV,KEY,CELL,DEST,NULL)
51+
4652
#endif
4753

4854
#endif /* E_BN_H__ */

lib/crypto/c_src/dh.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
4848
OSSL_PARAM params[8];
4949
EVP_PKEY *pkey = NULL, *pkey_gen = NULL;
5050
EVP_PKEY_CTX *pctx = NULL, *pctx_gen = NULL;
51+
BIGNUM *p_bn = NULL;
5152
BIGNUM *pub_key_gen = NULL, *priv_key_gen = NULL;
5253
unsigned char *pub_ptr, *prv_ptr;
5354
int pub_len, prv_len;
@@ -64,7 +65,7 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
6465
ERL_NIF_TERM head, tail;
6566

6667
head = argv[1];
67-
if (!get_ossl_param_from_bin_in_list(env, "p", &head, &params[i++]) ) {
68+
if (!get_ossl_param_from_bin_in_list_x(env, "p", &head, &params[i++], &p_bn) ) {
6869
ret = EXCP_BADARG_N(env, 1, "Bad value of 'p'");
6970
goto done;
7071
}
@@ -91,9 +92,13 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
9192
ret = EXCP_BADARG_N(env, 3, "Bad value of length element");
9293
goto done;
9394
}
94-
else if (len)
95+
else if (len) {
96+
if (len >= BN_num_bits(p_bn)) {
97+
len = BN_num_bits(p_bn) - 1;
98+
}
9599
params[i++] = OSSL_PARAM_construct_uint64("priv_len", &len);
96-
100+
}
101+
97102
/* End of parameter fetching */
98103
params[i++] = OSSL_PARAM_construct_end();
99104

@@ -159,6 +164,7 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
159164
ret = enif_make_tuple2(env, ret_pub, ret_prv);
160165

161166
done:
167+
if (p_bn) BN_free(p_bn);
162168
if (pub_key_gen) BN_free(pub_key_gen);
163169
if (priv_key_gen) BN_free(priv_key_gen);
164170
if (pkey) EVP_PKEY_free(pkey);
@@ -334,9 +340,9 @@ ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
334340
if ((bn_len = BN_num_bits(dh_p_shared)) < 0)
335341
assign_goto(ret, err, EXCP_ERROR(env, "BN_num_bits < 0"));
336342
dh_p_shared = NULL; /* dh_params owns the reference */
337-
if (len >= (size_t)bn_len)
338-
assign_goto(ret, err, EXCP_ERROR_N(env, 3, "Too big length"));
339-
343+
if (len >= (size_t)bn_len) {
344+
len = bn_len - 1;
345+
}
340346
if (!DH_set_length(dh_params, (long)len))
341347
assign_goto(ret, err, EXCP_ERROR_N(env, 3, "The length is not accepted"));
342348
}

lib/crypto/src/crypto.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,11 @@ Scrambler is `u` (optional will be generated if not provided) from
454454
-type dh_private() :: key_integer() .
455455
-doc """
456456
```text
457-
dh_params() = [P, G] | [P, G, PrivateKeyBitLength]
457+
dh_params() = [P, G] | [P, G, MaxPrivateKeyBitLength]
458458
```
459459
""".
460460
-doc(#{group => <<"Diffie-Hellman Keys and parameters">>}).
461-
-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength]
461+
-type dh_params() :: [key_integer()] . % [P, G] | [P, G, MaxPrivateKeyBitLength]
462462

463463
-doc(#{group => <<"Diffie-Hellman Keys and parameters">>,
464464
equiv => ecdh_params()}).
@@ -2963,7 +2963,7 @@ Uses the [3-tuple style](`m:crypto#error_3tup`) for error handling.
29632963
> - and the `Type` is `dh` (diffie-hellman)
29642964
> - and the parameter `P` (in `t:dh_params/0`) is one of the MODP groups (see
29652965
> [RFC 3526](https://tools.ietf.org/html/rfc3526))
2966-
> - and the optional `PrivateKeyBitLength` parameter (in `t:dh_params/0`) is
2966+
> - and the optional `MaxPrivateKeyBitLength` parameter (in `t:dh_params/0`) is
29672967
> present,
29682968
>
29692969
> then the optional key length parameter must be at least 224, 256, 302, 352 and

0 commit comments

Comments
 (0)