From 4f5f693bf4ece8c102a2f2f10c8d4693d2957a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Dimitrov?= Date: Fri, 14 Dec 2018 13:20:14 +0100 Subject: ssl: Add support for x25519 and x448 in ECDH Change-Id: I206b851fc616c53475f4a2935f6f52baf8f3e1e6 --- lib/ssl/src/ssl_cipher.erl | 15 +++++++++------ lib/ssl/src/tls_connection_1_3.erl | 9 +++++++-- lib/ssl/src/tls_v1.erl | 24 +++++++++++++++++------- 3 files changed, 33 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 0628299d98..46885130d3 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -681,10 +681,9 @@ hash_size(sha) -> hash_size(sha256) -> 32; hash_size(sha384) -> - 48. -%% Uncomment when adding cipher suite that needs it -%hash_size(sha512) -> -% 64. + 48; +hash_size(sha512) -> + 64. %%-------------------------------------------------------------------- %%% Internal functions @@ -888,8 +887,8 @@ scheme_to_components(ecdsa_secp521r1_sha512) -> {sha512, ecdsa, secp521r1}; scheme_to_components(rsa_pss_rsae_sha256) -> {sha256, rsa_pss_rsae, undefined}; scheme_to_components(rsa_pss_rsae_sha384) -> {sha384, rsa_pss_rsae, undefined}; scheme_to_components(rsa_pss_rsae_sha512) -> {sha512, rsa_pss_rsae, undefined}; -%% scheme_to_components(ed25519) -> {undefined, undefined, undefined}; -%% scheme_to_components(ed448) -> {undefined, undefined, undefined}; +scheme_to_components(ed25519) -> {undefined, undefined, undefined}; +scheme_to_components(ed448) -> {undefined, undefined, undefined}; scheme_to_components(rsa_pss_pss_sha256) -> {sha256, rsa_pss_pss, undefined}; scheme_to_components(rsa_pss_pss_sha384) -> {sha384, rsa_pss_pss, undefined}; scheme_to_components(rsa_pss_pss_sha512) -> {sha512, rsa_pss_pss, undefined}; @@ -1231,6 +1230,10 @@ generate_key_exchange(secp384r1) -> public_key:generate_key({namedCurve, secp384r1}); generate_key_exchange(secp521r1) -> public_key:generate_key({namedCurve, secp521r1}); +generate_key_exchange(x25519) -> + crypto:generate_key(ecdh, x25519); +generate_key_exchange(x448) -> + crypto:generate_key(ecdh, x448); generate_key_exchange(FFDHE) -> public_key:generate_key(ssl_dh_groups:dh_params(FFDHE)). diff --git a/lib/ssl/src/tls_connection_1_3.erl b/lib/ssl/src/tls_connection_1_3.erl index 42ae784222..4795ade2a1 100644 --- a/lib/ssl/src/tls_connection_1_3.erl +++ b/lib/ssl/src/tls_connection_1_3.erl @@ -269,14 +269,19 @@ get_private_key(#key_share_entry{ PrivateKey. -%% DH +%% X25519, X448 +calculate_shared_secret(OthersKey, MyKey, Group) + when is_binary(OthersKey) andalso is_binary(MyKey) andalso + (Group =:= x25519 orelse Group =:= x448)-> + crypto:compute_key(ecdh, OthersKey, MyKey, Group); +%% FFDHE calculate_shared_secret(OthersKey, MyKey, Group) when is_binary(OthersKey) andalso is_binary(MyKey) -> Params = #'DHParameter'{prime = P} = ssl_dh_groups:dh_params(Group), S = public_key:compute_key(OthersKey, MyKey, Params), Size = byte_size(binary:encode_unsigned(P)), ssl_cipher:add_zero_padding(S, Size); -%% ECDH +%% ECDHE calculate_shared_secret(OthersKey, MyKey = #'ECPrivateKey'{}, _Group) when is_binary(OthersKey) -> Point = #'ECPoint'{point = OthersKey}, diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl index 16b24c4a5d..df2a421bce 100644 --- a/lib/ssl/src/tls_v1.erl +++ b/lib/ssl/src/tls_v1.erl @@ -747,7 +747,9 @@ ecc_curves(_Minor, TLSCurves) -> -spec groups(4 | all | default) -> [group()]. groups(all) -> - [secp256r1, + [x25519, + x448, + secp256r1, secp384r1, secp521r1, ffdhe2048, @@ -756,27 +758,33 @@ groups(all) -> ffdhe6144, ffdhe8192]; groups(default) -> - [secp256r1, - secp384r1, - secp521r1, - ffdhe2048]; + [x25519, + x448, + secp256r1, + secp384r1]; groups(Minor) -> TLSGroups = groups(all), groups(Minor, TLSGroups). %% -spec groups(4, [group()]) -> [group()]. groups(_Minor, TLSGroups) -> - %% TODO: Adding FFDHE groups to crypto? - CryptoGroups = crypto:ec_curves() ++ [ffdhe2048,ffdhe3072,ffdhe4096,ffdhe6144,ffdhe8192], + CryptoGroups = supported_groups(), lists:filter(fun(Group) -> proplists:get_bool(Group, CryptoGroups) end, TLSGroups). default_groups(Minor) -> TLSGroups = groups(default), groups(Minor, TLSGroups). +supported_groups() -> + %% TODO: Add new function to crypto? + proplists:get_value(curves, crypto:supports()) ++ + [ffdhe2048,ffdhe3072,ffdhe4096,ffdhe6144,ffdhe8192]. + group_to_enum(secp256r1) -> 23; group_to_enum(secp384r1) -> 24; group_to_enum(secp521r1) -> 25; +group_to_enum(x25519) -> 29; +group_to_enum(x448) -> 30; group_to_enum(ffdhe2048) -> 256; group_to_enum(ffdhe3072) -> 257; group_to_enum(ffdhe4096) -> 258; @@ -786,6 +794,8 @@ group_to_enum(ffdhe8192) -> 260. enum_to_group(23) -> secp256r1; enum_to_group(24) -> secp384r1; enum_to_group(25) -> secp521r1; +enum_to_group(29) -> x25519; +enum_to_group(30) -> x448; enum_to_group(256) -> ffdhe2048; enum_to_group(257) -> ffdhe3072; enum_to_group(258) -> ffdhe4096; -- cgit v1.2.3