diff options
author | Erlang/OTP <otp@erlang.org> | 2020-01-16 16:41:48 +0100 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2020-01-16 16:41:48 +0100 |
commit | e677c99701bc36b6d1096e7013576137ae84b882 (patch) | |
tree | d4d3db81c040324ec0dceb7341d8136dda2b6489 | |
parent | f1dd879fef88db3252a90b457d10a567ecaf936a (diff) | |
parent | ee9567ba1af27ef5d7a22271cb08643330720be3 (diff) | |
download | erlang-e677c99701bc36b6d1096e7013576137ae84b882.tar.gz |
Merge branch 'hans/ssh/fix_timing_20/OTP-16376' into maint-20
* hans/ssh/fix_timing_20/OTP-16376:
ssh: Update crypto dependency
ssh: Use constant time comparision in some places
crypto: Add an equal-time comparision function. (NIF candidate)
-rw-r--r-- | lib/crypto/src/crypto.erl | 36 | ||||
-rw-r--r-- | lib/ssh/src/ssh.app.src | 2 | ||||
-rw-r--r-- | lib/ssh/src/ssh_auth.erl | 2 | ||||
-rw-r--r-- | lib/ssh/src/ssh_transport.erl | 2 |
4 files changed, 39 insertions, 3 deletions
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 0d85b94b57..60f257f49f 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -24,6 +24,7 @@ -export([start/0, stop/0, info_lib/0, info_fips/0, supports/0, enable_fips_mode/1, version/0, bytes_to_integer/1]). +-export([equal_const_time/2]). -export([hash/2, hash_init/1, hash_update/2, hash_final/1]). -export([sign/4, sign/5, verify/5, verify/6]). -export([generate_key/2, generate_key/3, compute_key/4]). @@ -130,6 +131,41 @@ info_lib() -> ?nif_stub. info_fips() -> ?nif_stub. +%%%================================================================ +%%% +%%% Compare in constant time +%%% +%%%================================================================ + +%%% Candidate for a NIF + +equal_const_time(X1, X2) -> + equal_const_time(X1, X2, true). + + +equal_const_time(<<B1,R1/binary>>, <<B2,R2/binary>>, Truth) -> + equal_const_time(R1, R2, Truth and (B1 == B2)); +equal_const_time(<<_,R1/binary>>, <<>>, Truth) -> + equal_const_time(R1, <<>>, Truth and false); +equal_const_time(<<>>, <<>>, Truth) -> + Truth; + +equal_const_time([H1|T1], [H2|T2], Truth) -> + equal_const_time(T1, T2, Truth and (H1 == H2)); +equal_const_time([_|T1], [], Truth) -> + equal_const_time(T1, [], Truth and false); +equal_const_time([], [], Truth) -> + Truth; + +equal_const_time(_, _, _) -> + false. + +%%%================================================================ +%%% +%%% Hashing +%%% +%%%================================================================ + -spec enable_fips_mode(boolean()) -> boolean(). enable_fips_mode(_) -> ?nif_stub. diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src index 4a22322333..59f6dd6cab 100644 --- a/lib/ssh/src/ssh.app.src +++ b/lib/ssh/src/ssh.app.src @@ -42,7 +42,7 @@ {env, []}, {mod, {ssh_app, []}}, {runtime_dependencies, [ - "crypto-4.2", + "crypto-@OTP-16376@", "erts-6.0", "kernel-3.0", "public_key-1.5.2", diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index 03d264745b..6d9373e9db 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -473,7 +473,7 @@ check_password(User, Password, Opts, Ssh) -> case ?GET_OPT(pwdfun, Opts) of undefined -> Static = get_password_option(Opts, User), - {Password == Static, Ssh}; + {crypto:equal_const_time(Password,Static), Ssh}; Checker when is_function(Checker,2) -> {Checker(User, Password), Ssh}; diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl index 171c9abfee..87a81920b2 100644 --- a/lib/ssh/src/ssh_transport.erl +++ b/lib/ssh/src/ssh_transport.erl @@ -222,7 +222,7 @@ is_valid_mac(_, _ , #ssh{recv_mac_size = 0}) -> true; is_valid_mac(Mac, Data, #ssh{recv_mac = Algorithm, recv_mac_key = Key, recv_sequence = SeqNum}) -> - Mac == mac(Algorithm, Key, SeqNum, Data). + crypto:equal_const_time(Mac, mac(Algorithm, Key, SeqNum, Data)). format_version({Major,Minor}, SoftwareVersion) -> "SSH-" ++ integer_to_list(Major) ++ "." ++ |