aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh')
-rw-r--r--lib/ssh/doc/src/notes.xml2
-rw-r--r--lib/ssh/doc/src/ssh.xml2
-rw-r--r--lib/ssh/src/ssh.hrl2
-rw-r--r--lib/ssh/src/ssh_sftpd.erl2
-rw-r--r--lib/ssh/src/ssh_transport.erl553
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl2
-rw-r--r--lib/ssh/test/ssh_bench_SUITE.erl10
-rw-r--r--lib/ssh/test/ssh_chan_behaviours_SUITE.erl4
-rw-r--r--lib/ssh/test/ssh_chan_behaviours_client.erl2
-rw-r--r--lib/ssh/test/ssh_chan_behaviours_server.erl2
-rw-r--r--lib/ssh/test/ssh_compat_SUITE.erl17
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl4
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl2
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl6
-rw-r--r--lib/ssh/test/ssh_test_lib.erl4
-rw-r--r--lib/ssh/test/ssh_trpt_test_lib.erl69
16 files changed, 213 insertions, 470 deletions
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 1bc4f866ce..78990c48f2 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -2995,7 +2995,7 @@
</item>
<item>
<p>
- Fixed internal error on when client and server can not
+ Fixed internal error on when client and server cannot
agree o which authmethod to use.</p>
<p>
Own Id: OTP-10731 Aux Id: seq12237 </p>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index 1a53a2ea98..3fd6eae423 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -46,7 +46,7 @@
In that encrypted connection one or more channels could be opened with
<seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/2,4</seealso>.
</p>
- <p>Each channel is an isolated "pipe" between a client-side process and a server-side process. Thoose process
+ <p>Each channel is an isolated "pipe" between a client-side process and a server-side process. Those process
pairs could handle for example file transfers (sftp) or remote command execution (shell, exec and/or cli).
If a custom shell is implemented, the user of the client could execute the special commands remotely. Note that
the user is not necessarily a human but probably a system interfacing the SSH app.
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 923e9309f4..04453e6ef0 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -396,11 +396,13 @@
recv_mac_size = 0,
encrypt = none, %% encrypt algorithm
+ encrypt_cipher, %% cipher. could be different from the algorithm
encrypt_keys, %% encrypt keys
encrypt_block_size = 8,
encrypt_ctx,
decrypt = none, %% decrypt algorithm
+ decrypt_cipher, %% cipher. could be different from the algorithm
decrypt_keys, %% decrypt keys
decrypt_block_size = 8,
decrypt_ctx, %% Decryption context
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index aa9ba0f9bb..5ec12e2d04 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -508,7 +508,7 @@ close_our_file({_,Fd}, FileMod, FS0) ->
FS1.
%%% stat: do the stat
-stat(Vsn, ReqId, Data, State, F) ->
+stat(_Vsn, ReqId, Data, State, F) ->
<<?UINT32(BLen), BPath:BLen/binary, _/binary>> = Data,
stat(ReqId, unicode:characters_to_list(BPath), State, F).
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 9ff20454cd..eaab13433a 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -162,15 +162,15 @@ supported_algorithms(cipher) ->
select_crypto_supported(
[
{'[email protected]', [{ciphers,chacha20}, {macs,poly1305}]},
- {'[email protected]', [{ciphers,{aes_gcm,256}}]},
- {'aes256-ctr', [{ciphers,{aes_ctr,256}}]},
- {'aes192-ctr', [{ciphers,{aes_ctr,192}}]},
- {'[email protected]', [{ciphers,{aes_gcm,128}}]},
- {'aes128-ctr', [{ciphers,{aes_ctr,128}}]},
- {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
- {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
- {'aes128-cbc', [{ciphers,aes_cbc128}]},
- {'3des-cbc', [{ciphers,des3_cbc}]}
+ {'[email protected]', [{ciphers,aes_256_gcm}]},
+ {'aes256-ctr', [{ciphers,aes_256_ctr}]},
+ {'aes192-ctr', [{ciphers,aes_192_ctr}]},
+ {'[email protected]', [{ciphers,aes_128_gcm}]},
+ {'aes128-ctr', [{ciphers,aes_128_ctr}]},
+ {'AEAD_AES_256_GCM', [{ciphers,aes_256_gcm}]},
+ {'AEAD_AES_128_GCM', [{ciphers,aes_128_gcm}]},
+ {'aes128-cbc', [{ciphers,aes_128_cbc}]},
+ {'3des-cbc', [{ciphers,des_ede3_cbc}]}
]
));
supported_algorithms(mac) ->
@@ -179,8 +179,8 @@ supported_algorithms(mac) ->
[{'hmac-sha2-256', [{macs,hmac}, {hashs,sha256}]},
{'hmac-sha2-512', [{macs,hmac}, {hashs,sha512}]},
{'hmac-sha1', [{macs,hmac}, {hashs,sha}]},
- {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
- {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]}
+ {'AEAD_AES_128_GCM', [{ciphers,aes_128_gcm}]},
+ {'AEAD_AES_256_GCM', [{ciphers,aes_256_gcm}]}
]
));
supported_algorithms(compression) ->
@@ -1256,11 +1256,6 @@ get_length(aead, EncryptedBuffer, Ssh) ->
end.
-pkt_type('AEAD_AES_128_GCM') -> aead;
-pkt_type('AEAD_AES_256_GCM') -> aead;
-pkt_type('[email protected]') -> aead;
-pkt_type(_) -> common.
-
payload(<<PacketLen:32, PaddingLen:8, PayloadAndPadding/binary>>) ->
PayloadLen = PacketLen - PaddingLen - 1,
<<Payload:PayloadLen/binary, _/binary>> = PayloadAndPadding,
@@ -1323,231 +1318,163 @@ verify(PlainText, HashAlg, Sig, Key, _) ->
%%% Unit: bytes
--record(cipher_data, {
- key_bytes,
- iv_bytes,
- block_bytes
- }).
+-record(cipher, {
+ impl,
+ key_bytes,
+ iv_bytes,
+ block_bytes,
+ pkt_type = common
+ }).
%%% Start of a more parameterized crypto handling.
cipher('AEAD_AES_128_GCM') ->
- #cipher_data{key_bytes = 16,
- iv_bytes = 12,
- block_bytes = 16};
+ #cipher{impl = aes_128_gcm,
+ key_bytes = 16,
+ iv_bytes = 12,
+ block_bytes = 16,
+ pkt_type = aead};
cipher('AEAD_AES_256_GCM') ->
- #cipher_data{key_bytes = 32,
- iv_bytes = 12,
- block_bytes = 16};
+ #cipher{impl = aes_256_gcm,
+ key_bytes = 32,
+ iv_bytes = 12,
+ block_bytes = 16,
+ pkt_type = aead};
cipher('3des-cbc') ->
- #cipher_data{key_bytes = 24,
- iv_bytes = 8,
- block_bytes = 8};
+ #cipher{impl = des_ede3_cbc,
+ key_bytes = 24,
+ iv_bytes = 8,
+ block_bytes = 8};
cipher('aes128-cbc') ->
- #cipher_data{key_bytes = 16,
- iv_bytes = 16,
- block_bytes = 16};
+ #cipher{impl = aes_128_cbc,
+ key_bytes = 16,
+ iv_bytes = 16,
+ block_bytes = 16};
cipher('aes128-ctr') ->
- #cipher_data{key_bytes = 16,
- iv_bytes = 16,
- block_bytes = 16};
+ #cipher{impl = aes_128_ctr,
+ key_bytes = 16,
+ iv_bytes = 16,
+ block_bytes = 16};
cipher('aes192-ctr') ->
- #cipher_data{key_bytes = 24,
- iv_bytes = 16,
- block_bytes = 16};
+ #cipher{impl = aes_192_ctr,
+ key_bytes = 24,
+ iv_bytes = 16,
+ block_bytes = 16};
cipher('aes256-ctr') ->
- #cipher_data{key_bytes = 32,
- iv_bytes = 16,
- block_bytes = 16};
+ #cipher{impl = aes_256_ctr,
+ key_bytes = 32,
+ iv_bytes = 16,
+ block_bytes = 16};
cipher('[email protected]') -> % FIXME: Verify!!
- #cipher_data{key_bytes = 32,
- iv_bytes = 12,
- block_bytes = 8}.
-
+ #cipher{impl = chacha20_poly1305,
+ key_bytes = 32,
+ iv_bytes = 12,
+ block_bytes = 8,
+ pkt_type = aead};
+
+cipher(_) ->
+ #cipher{}.
+
+
+pkt_type(SshCipher) -> (cipher(SshCipher))#cipher.pkt_type.
+
+decrypt_magic(server) -> {"A", "C"};
+decrypt_magic(client) -> {"B", "D"}.
+
+encrypt_magic(client) -> decrypt_magic(server);
+encrypt_magic(server) -> decrypt_magic(client).
+
encrypt_init(#ssh{encrypt = none} = Ssh) ->
{ok, Ssh};
-encrypt_init(#ssh{encrypt = '[email protected]', role = client} = Ssh) ->
+
+encrypt_init(#ssh{encrypt = '[email protected]', role = Role} = Ssh) ->
%% [email protected] uses two independent crypto streams, one (chacha20)
%% for the length used in stream mode, and the other (chacha20-poly1305) as AEAD for
%% the payload and to MAC the length||payload.
%% See draft-josefsson-ssh-chacha20-poly1305-openssh-00
- <<K2:32/binary,K1:32/binary>> = hash(Ssh, "C", 512),
+ {_, KeyMagic} = encrypt_magic(Role),
+ <<K2:32/binary,K1:32/binary>> = hash(Ssh, KeyMagic, 8*64),
{ok, Ssh#ssh{encrypt_keys = {K1,K2}
% encrypt_block_size = 16, %default = 8. What to set it to? 64 (openssl chacha.h)
% ctx and iv is setup for each packet
}};
-encrypt_init(#ssh{encrypt = '[email protected]', role = server} = Ssh) ->
- <<K2:32/binary,K1:32/binary>> = hash(Ssh, "D", 512),
- {ok, Ssh#ssh{encrypt_keys = {K1,K2}
- % encrypt_block_size = 16, %default = 8. What to set it to?
- }};
-encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 12*8),
- <<K:16/binary>> = hash(Ssh, "C", 128),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 12*8),
- <<K:16/binary>> = hash(Ssh, "D", 128),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 12*8),
- <<K:32/binary>> = hash(Ssh, "C", 256),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 12*8),
- <<K:32/binary>> = hash(Ssh, "D", 256),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = '3des-cbc', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 64),
- <<K1:8/binary, K2:8/binary, K3:8/binary>> = hash(Ssh, "C", 192),
- {ok, Ssh#ssh{encrypt_keys = {K1,K2,K3},
- encrypt_block_size = 8,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = '3des-cbc', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 64),
- <<K1:8/binary, K2:8/binary, K3:8/binary>> = hash(Ssh, "D", 192),
- {ok, Ssh#ssh{encrypt_keys = {K1,K2,K3},
- encrypt_block_size = 8,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = 'aes128-cbc', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:16/binary>> = hash(Ssh, "C", 128),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
+
+encrypt_init(#ssh{encrypt = SshCipher, role = Role} = Ssh) when SshCipher == 'AEAD_AES_128_GCM';
+ SshCipher == 'AEAD_AES_256_GCM' ->
+ {IvMagic, KeyMagic} = encrypt_magic(Role),
+ #cipher{impl = CryptoCipher,
+ key_bytes = KeyBytes,
+ iv_bytes = IvBytes,
+ block_bytes = BlockBytes} = cipher(SshCipher),
+ IV = hash(Ssh, IvMagic, 8*IvBytes),
+ K = hash(Ssh, KeyMagic, 8*KeyBytes),
+ {ok, Ssh#ssh{encrypt_cipher = CryptoCipher,
+ encrypt_keys = K,
+ encrypt_block_size = BlockBytes,
encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = 'aes128-cbc', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:16/binary>> = hash(Ssh, "D", 128),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = IV}};
-encrypt_init(#ssh{encrypt = 'aes128-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:16/binary>> = hash(Ssh, "C", 128),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = State}};
-encrypt_init(#ssh{encrypt = 'aes192-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:24/binary>> = hash(Ssh, "C", 192),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = State}};
-encrypt_init(#ssh{encrypt = 'aes256-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:32/binary>> = hash(Ssh, "C", 256),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = State}};
-encrypt_init(#ssh{encrypt = 'aes128-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:16/binary>> = hash(Ssh, "D", 128),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = State}};
-encrypt_init(#ssh{encrypt = 'aes192-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:24/binary>> = hash(Ssh, "D", 192),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = State}};
-encrypt_init(#ssh{encrypt = 'aes256-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:32/binary>> = hash(Ssh, "D", 256),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{encrypt_keys = K,
- encrypt_block_size = 16,
- encrypt_ctx = State}}.
+
+encrypt_init(#ssh{encrypt = SshCipher, role = Role} = Ssh) ->
+ {IvMagic, KeyMagic} = encrypt_magic(Role),
+ #cipher{impl = CryptoCipher,
+ key_bytes = KeyBytes,
+ iv_bytes = IvBytes,
+ block_bytes = BlockBytes} = cipher(SshCipher),
+ IV = hash(Ssh, IvMagic, 8*IvBytes),
+ K = hash(Ssh, KeyMagic, 8*KeyBytes),
+ Ctx0 = crypto:crypto_init(CryptoCipher, K, IV, true),
+ {ok, Ssh#ssh{encrypt_cipher = CryptoCipher,
+ encrypt_block_size = BlockBytes,
+ encrypt_ctx = Ctx0}}.
encrypt_final(Ssh) ->
- {ok, Ssh#ssh{encrypt = none,
+ {ok, Ssh#ssh{encrypt = none,
encrypt_keys = undefined,
encrypt_block_size = 8,
encrypt_ctx = undefined
}}.
+
encrypt(#ssh{encrypt = none} = Ssh, Data) ->
{Ssh, Data};
+
encrypt(#ssh{encrypt = '[email protected]',
encrypt_keys = {K1,K2},
send_sequence = Seq} = Ssh,
<<LenData:4/binary, PayloadData/binary>>) ->
%% Encrypt length
IV1 = <<0:8/unit:8, Seq:8/unit:8>>,
- {_,EncLen} = crypto:stream_encrypt(crypto:stream_init(chacha20, K1, IV1),
- LenData),
+ EncLen = crypto:crypto_one_time(chacha20, K1, IV1, LenData, true),
%% Encrypt payload
IV2 = <<1:8/little-unit:8, Seq:8/unit:8>>,
- {_,EncPayloadData} = crypto:stream_encrypt(crypto:stream_init(chacha20, K2, IV2),
- PayloadData),
-
+ EncPayloadData = crypto:crypto_one_time(chacha20, K2, IV2, PayloadData, true),
%% MAC tag
- {_,PolyKey} = crypto:stream_encrypt(crypto:stream_init(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>),
- <<0:32/unit:8>>),
+ PolyKey = crypto:crypto_one_time(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>, <<0:32/unit:8>>, true),
EncBytes = <<EncLen/binary,EncPayloadData/binary>>,
Ctag = crypto:poly1305(PolyKey, EncBytes),
%% Result
{Ssh, {EncBytes,Ctag}};
-encrypt(#ssh{encrypt = 'AEAD_AES_128_GCM',
- encrypt_keys = K,
+
+encrypt(#ssh{encrypt = SshCipher,
+ encrypt_cipher = CryptoCipher,
+ encrypt_keys = K,
encrypt_ctx = IV0} = Ssh,
- <<LenData:4/binary, PayloadData/binary>>) ->
- {Ctext,Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, {LenData,PayloadData}),
+ <<LenData:4/binary, PayloadData/binary>>) when SshCipher == 'AEAD_AES_128_GCM' ;
+ SshCipher == 'AEAD_AES_256_GCM' ->
+ {Ctext,Ctag} = crypto:crypto_one_time_aead(CryptoCipher, K, IV0, PayloadData, LenData, true),
IV = next_gcm_iv(IV0),
{Ssh#ssh{encrypt_ctx = IV}, {<<LenData/binary,Ctext/binary>>,Ctag}};
-encrypt(#ssh{encrypt = 'AEAD_AES_256_GCM',
- encrypt_keys = K,
- encrypt_ctx = IV0} = Ssh,
- <<LenData:4/binary, PayloadData/binary>>) ->
- {Ctext,Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, {LenData,PayloadData}),
- IV = next_gcm_iv(IV0),
- {Ssh#ssh{encrypt_ctx = IV}, {<<LenData/binary,Ctext/binary>>,Ctag}};
-encrypt(#ssh{encrypt = '3des-cbc',
- encrypt_keys = {K1,K2,K3},
- encrypt_ctx = IV0} = Ssh, Data) ->
- Enc = crypto:block_encrypt(des3_cbc, [K1,K2,K3], IV0, Data),
- IV = crypto:next_iv(des3_cbc, Enc),
- {Ssh#ssh{encrypt_ctx = IV}, Enc};
-encrypt(#ssh{encrypt = 'aes128-cbc',
- encrypt_keys = K,
- encrypt_ctx = IV0} = Ssh, Data) ->
- Enc = crypto:block_encrypt(aes_cbc128, K,IV0,Data),
- IV = crypto:next_iv(aes_cbc, Enc),
- {Ssh#ssh{encrypt_ctx = IV}, Enc};
-encrypt(#ssh{encrypt = 'aes128-ctr',
- encrypt_ctx = State0} = Ssh, Data) ->
- {State, Enc} = crypto:stream_encrypt(State0,Data),
- {Ssh#ssh{encrypt_ctx = State}, Enc};
-encrypt(#ssh{encrypt = 'aes192-ctr',
- encrypt_ctx = State0} = Ssh, Data) ->
- {State, Enc} = crypto:stream_encrypt(State0,Data),
- {Ssh#ssh{encrypt_ctx = State}, Enc};
-encrypt(#ssh{encrypt = 'aes256-ctr',
- encrypt_ctx = State0} = Ssh, Data) ->
- {State, Enc} = crypto:stream_encrypt(State0,Data),
- {Ssh#ssh{encrypt_ctx = State}, Enc}.
-
+
+encrypt(#ssh{encrypt_ctx = Ctx0} = Ssh, Data) ->
+ Enc = crypto:crypto_update(Ctx0, Data),
+ {Ssh, Enc}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Decryption
@@ -1555,181 +1482,92 @@ encrypt(#ssh{encrypt = 'aes256-ctr',
decrypt_init(#ssh{decrypt = none} = Ssh) ->
{ok, Ssh};
-decrypt_init(#ssh{decrypt = '[email protected]', role = client} = Ssh) ->
- <<K2:32/binary,K1:32/binary>> = hash(Ssh, "D", 512),
- {ok, Ssh#ssh{decrypt_keys = {K1,K2}
- }};
-decrypt_init(#ssh{decrypt = '[email protected]', role = server} = Ssh) ->
- <<K2:32/binary,K1:32/binary>> = hash(Ssh, "C", 512),
+
+decrypt_init(#ssh{decrypt = '[email protected]', role = Role} = Ssh) ->
+ {_, KeyMagic} = decrypt_magic(Role),
+ <<K2:32/binary,K1:32/binary>> = hash(Ssh, KeyMagic, 8*64),
{ok, Ssh#ssh{decrypt_keys = {K1,K2}
}};
-decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
- IV = hash(Ssh, "B", 12*8),
- <<K:16/binary>> = hash(Ssh, "D", 128),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = IV}};
-decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
- IV = hash(Ssh, "A", 12*8),
- <<K:16/binary>> = hash(Ssh, "C", 128),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = IV}};
-decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
- IV = hash(Ssh, "B", 12*8),
- <<K:32/binary>> = hash(Ssh, "D", 256),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = IV}};
-decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
- IV = hash(Ssh, "A", 12*8),
- <<K:32/binary>> = hash(Ssh, "C", 256),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
+
+decrypt_init(#ssh{decrypt = SshCipher, role = Role} = Ssh) when SshCipher == 'AEAD_AES_128_GCM';
+ SshCipher == 'AEAD_AES_256_GCM' ->
+ {IvMagic, KeyMagic} = decrypt_magic(Role),
+ #cipher{impl = CryptoCipher,
+ key_bytes = KeyBytes,
+ iv_bytes = IvBytes,
+ block_bytes = BlockBytes} = cipher(SshCipher),
+ IV = hash(Ssh, IvMagic, 8*IvBytes),
+ K = hash(Ssh, KeyMagic, 8*KeyBytes),
+ {ok, Ssh#ssh{decrypt_cipher = CryptoCipher,
+ decrypt_keys = K,
+ decrypt_block_size = BlockBytes,
decrypt_ctx = IV}};
-decrypt_init(#ssh{decrypt = '3des-cbc', role = client} = Ssh) ->
- {IV, KD} = {hash(Ssh, "B", 64),
- hash(Ssh, "D", 192)},
- <<K1:8/binary, K2:8/binary, K3:8/binary>> = KD,
- {ok, Ssh#ssh{decrypt_keys = {K1,K2,K3}, decrypt_ctx = IV,
- decrypt_block_size = 8}};
-decrypt_init(#ssh{decrypt = '3des-cbc', role = server} = Ssh) ->
- {IV, KD} = {hash(Ssh, "A", 64),
- hash(Ssh, "C", 192)},
- <<K1:8/binary, K2:8/binary, K3:8/binary>> = KD,
- {ok, Ssh#ssh{decrypt_keys = {K1, K2, K3}, decrypt_ctx = IV,
- decrypt_block_size = 8}};
-decrypt_init(#ssh{decrypt = 'aes128-cbc', role = client} = Ssh) ->
- {IV, KD} = {hash(Ssh, "B", 128),
- hash(Ssh, "D", 128)},
- <<K:16/binary>> = KD,
- {ok, Ssh#ssh{decrypt_keys = K, decrypt_ctx = IV,
- decrypt_block_size = 16}};
-decrypt_init(#ssh{decrypt = 'aes128-cbc', role = server} = Ssh) ->
- {IV, KD} = {hash(Ssh, "A", 128),
- hash(Ssh, "C", 128)},
- <<K:16/binary>> = KD,
- {ok, Ssh#ssh{decrypt_keys = K, decrypt_ctx = IV,
- decrypt_block_size = 16}};
-decrypt_init(#ssh{decrypt = 'aes128-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:16/binary>> = hash(Ssh, "D", 128),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = State}};
-decrypt_init(#ssh{decrypt = 'aes192-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:24/binary>> = hash(Ssh, "D", 192),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = State}};
-decrypt_init(#ssh{decrypt = 'aes256-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "B", 128),
- <<K:32/binary>> = hash(Ssh, "D", 256),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = State}};
-decrypt_init(#ssh{decrypt = 'aes128-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:16/binary>> = hash(Ssh, "C", 128),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = State}};
-decrypt_init(#ssh{decrypt = 'aes192-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:24/binary>> = hash(Ssh, "C", 192),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = State}};
-decrypt_init(#ssh{decrypt = 'aes256-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "A", 128),
- <<K:32/binary>> = hash(Ssh, "C", 256),
- State = crypto:stream_init(aes_ctr, K, IV),
- {ok, Ssh#ssh{decrypt_keys = K,
- decrypt_block_size = 16,
- decrypt_ctx = State}}.
-
-
+
+decrypt_init(#ssh{decrypt = SshCipher, role = Role} = Ssh) ->
+ {IvMagic, KeyMagic} = decrypt_magic(Role),
+ #cipher{impl = CryptoCipher,
+ key_bytes = KeyBytes,
+ iv_bytes = IvBytes,
+ block_bytes = BlockBytes} = cipher(SshCipher),
+ IV = hash(Ssh, IvMagic, 8*IvBytes),
+ K = hash(Ssh, KeyMagic, 8*KeyBytes),
+ Ctx0 = crypto:crypto_init(CryptoCipher, K, IV, false),
+ {ok, Ssh#ssh{decrypt_cipher = CryptoCipher,
+ decrypt_block_size = BlockBytes,
+ decrypt_ctx = Ctx0}}.
+
+
decrypt_final(Ssh) ->
{ok, Ssh#ssh {decrypt = none,
decrypt_keys = undefined,
decrypt_ctx = undefined,
decrypt_block_size = 8}}.
+
decrypt(Ssh, <<>>) ->
{Ssh, <<>>};
+
decrypt(#ssh{decrypt = '[email protected]',
- decrypt_keys = {K1,_K2},
- recv_sequence = Seq} = Ssh, {length,EncryptedLen}) ->
- {_State,PacketLenBin} =
- crypto:stream_decrypt(crypto:stream_init(chacha20, K1, <<0:8/unit:8, Seq:8/unit:8>>),
- EncryptedLen),
- {Ssh, PacketLenBin};
-decrypt(#ssh{decrypt = '[email protected]',
- decrypt_keys = {_K1,K2},
- recv_sequence = Seq} = Ssh, {AAD,Ctext,Ctag}) ->
- %% The length is already decoded and used to divide the input
- %% Check the mac (important that it is timing-safe):
- {_,PolyKey} =
- crypto:stream_encrypt(crypto:stream_init(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>),
- <<0:32/unit:8>>),
- case equal_const_time(Ctag, crypto:poly1305(PolyKey, <<AAD/binary,Ctext/binary>>)) of
- true ->
- %% MAC is ok, decode
- IV2 = <<1:8/little-unit:8, Seq:8/unit:8>>,
- {_,PlainText} =
- crypto:stream_decrypt(crypto:stream_init(chacha20,K2,IV2), Ctext),
- {Ssh, PlainText};
- false ->
- {Ssh,error}
+ decrypt_keys = {K1,K2},
+ recv_sequence = Seq} = Ssh, Data) ->
+ case Data of
+ {length,EncryptedLen} ->
+ %% The length is decrypted separately in a first step
+ PacketLenBin = crypto:crypto_one_time(chacha20, K1, <<0:8/unit:8, Seq:8/unit:8>>, EncryptedLen, false),
+ {Ssh, PacketLenBin};
+ {AAD,Ctext,Ctag} ->
+ %% The length is already decrypted and used to divide the input
+ %% Check the mac (important that it is timing-safe):
+ PolyKey = crypto:crypto_one_time(chacha20, K2, <<0:8/unit:8,Seq:8/unit:8>>, <<0:32/unit:8>>, false),
+ case equal_const_time(Ctag, crypto:poly1305(PolyKey, <<AAD/binary,Ctext/binary>>)) of
+ true ->
+ %% MAC is ok, decode
+ IV2 = <<1:8/little-unit:8, Seq:8/unit:8>>,
+ PlainText = crypto:crypto_one_time(chacha20, K2, IV2, Ctext, false),
+ {Ssh, PlainText};
+ false ->
+ {Ssh,error}
+ end
end;
+
decrypt(#ssh{decrypt = none} = Ssh, Data) ->
{Ssh, Data};
-decrypt(#ssh{decrypt = 'AEAD_AES_128_GCM',
- decrypt_keys = K,
- decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
- Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
- IV = next_gcm_iv(IV0),
- {Ssh#ssh{decrypt_ctx = IV}, Dec};
-decrypt(#ssh{decrypt = 'AEAD_AES_256_GCM',
+
+decrypt(#ssh{decrypt = SshCipher,
+ decrypt_cipher = CryptoCipher,
decrypt_keys = K,
- decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
- Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ decrypt_ctx = IV0} = Ssh, {AAD,Ctext,Ctag}) when SshCipher == 'AEAD_AES_128_GCM' ;
+ SshCipher == 'AEAD_AES_256_GCM' ->
+ Dec = crypto:crypto_one_time_aead(CryptoCipher, K, IV0, Ctext, AAD, Ctag, false),
IV = next_gcm_iv(IV0),
{Ssh#ssh{decrypt_ctx = IV}, Dec};
-decrypt(#ssh{decrypt = '3des-cbc', decrypt_keys = Keys,
- decrypt_ctx = IV0} = Ssh, Data) ->
- {K1, K2, K3} = Keys,
- Dec = crypto:block_decrypt(des3_cbc, [K1,K2,K3], IV0, Data),
- IV = crypto:next_iv(des3_cbc, Data),
- {Ssh#ssh{decrypt_ctx = IV}, Dec};
-decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key,
- decrypt_ctx = IV0} = Ssh, Data) ->
- Dec = crypto:block_decrypt(aes_cbc128, Key,IV0,Data),
- IV = crypto:next_iv(aes_cbc, Data),
- {Ssh#ssh{decrypt_ctx = IV}, Dec};
-decrypt(#ssh{decrypt = 'aes128-ctr',
- decrypt_ctx = State0} = Ssh, Data) ->
- {State, Enc} = crypto:stream_decrypt(State0,Data),
- {Ssh#ssh{decrypt_ctx = State}, Enc};
-decrypt(#ssh{decrypt = 'aes192-ctr',
- decrypt_ctx = State0} = Ssh, Data) ->
- {State, Enc} = crypto:stream_decrypt(State0,Data),
- {Ssh#ssh{decrypt_ctx = State}, Enc};
-decrypt(#ssh{decrypt = 'aes256-ctr',
- decrypt_ctx = State0} = Ssh, Data) ->
- {State, Enc} = crypto:stream_decrypt(State0,Data),
- {Ssh#ssh{decrypt_ctx = State}, Enc}.
+decrypt(#ssh{decrypt_ctx = Ctx0} = Ssh, Data) ->
+ Dec = crypto:crypto_update(Ctx0, Data),
+ {Ssh, Dec}.
next_gcm_iv(<<Fixed:32, InvCtr:64>>) -> <<Fixed:32, (InvCtr+1):64>>.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compression
%%
@@ -2058,9 +1896,9 @@ compute_key(Algorithm, OthersPublic, MyPrivate, Args) ->
dh_bits(#alg{encrypt = Encrypt,
send_mac = SendMac}) ->
C = cipher(Encrypt),
- 8 * lists:max([C#cipher_data.key_bytes,
- C#cipher_data.block_bytes,
- C#cipher_data.iv_bytes,
+ 8 * lists:max([C#cipher.key_bytes,
+ C#cipher.block_bytes,
+ C#cipher.iv_bytes,
mac_key_bytes(SendMac)
]).
@@ -2091,40 +1929,13 @@ select_crypto_supported(L) ->
crypto_supported(Conditions, Supported) ->
lists:all( fun({Tag,CryptoName}) when is_atom(CryptoName) ->
- crypto_name_supported(Tag,CryptoName,Supported);
- ({Tag,{Name,Len}}) when is_integer(Len) ->
- crypto_name_supported(Tag,Name,Supported) andalso
- len_supported(Name,Len)
+ crypto_name_supported(Tag,CryptoName,Supported)
end, Conditions).
crypto_name_supported(Tag, CryptoName, Supported) ->
- Vs = case proplists:get_value(Tag,Supported,[]) of
- [] when Tag == curves -> crypto:ec_curves();
- L -> L
- end,
+ Vs = proplists:get_value(Tag,Supported,[]),
lists:member(CryptoName, Vs).
-len_supported(Name, Len) ->
- try
- case Name of
- aes_ctr ->
- {_, <<_/binary>>} =
- %% Test encryption
- crypto:stream_encrypt(crypto:stream_init(Name, <<0:Len>>, <<0:128>>), <<"">>);
- aes_gcm ->
- {<<_/binary>>, <<_/binary>>} =
- crypto:block_encrypt(Name,
- _Key = <<0:Len>>,
- _IV = <<0:12/unsigned-unit:8>>,
- {<<"AAD">>,"PT"})
- end
- of
- _ -> true
- catch
- _:_ -> false
- end.
-
-
same(Algs) -> [{client2server,Algs}, {server2client,Algs}].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 5de6d52092..9b987dea5a 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -1399,7 +1399,7 @@ rekey_chk(Config, RLdaemon, RLclient) ->
Kex1 = ssh_test_lib:get_kex_init(ConnectionRef),
%% Make both sides send something:
- {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+ {ok, _SftpPid} = ssh_sftp:start_channel(ConnectionRef),
%% Check rekeying
timer:sleep(?REKEY_DATA_TMO),
diff --git a/lib/ssh/test/ssh_bench_SUITE.erl b/lib/ssh/test/ssh_bench_SUITE.erl
index 2ac4e5636a..880c519a5e 100644
--- a/lib/ssh/test/ssh_bench_SUITE.erl
+++ b/lib/ssh/test/ssh_bench_SUITE.erl
@@ -178,7 +178,7 @@ gen_data(DataSz) ->
connect_measure(Port, Cipher, Mac, Data, Options) ->
- AES_GCM = {cipher,
+ _AES_GCM = {cipher,
[]},
@@ -187,22 +187,22 @@ connect_measure(Port, Cipher, Mac, Data, Options) ->
{none,none} ->
[{modify_algorithms,[{prepend, [{cipher,[Cipher]},
{mac,[Mac]}]}
-%%% ,{rm,[AES_GCM]}
+%%% ,{rm,[_AES_GCM]}
]}];
{none,_} ->
[{modify_algorithms,[{prepend, [{cipher,[Cipher]}]}
-%%% ,{rm,[AES_GCM]}
+%%% ,{rm,[_AES_GCM]}
]},
{preferred_algorithms, [{mac,[Mac]}]}];
{_,none} ->
[{modify_algorithms,[{prepend, [{mac,[Mac]}]}
-%%% ,{rm,[AES_GCM]}
+%%% ,{rm,[_AES_GCM]}
]},
{preferred_algorithms, [{cipher,[Cipher]}]}];
_ ->
[{preferred_algorithms, [{cipher,[Cipher]},
{mac,[Mac]}]}
-%%% ,{modify_algorithms, [{rm,[AES_GCM]}]}
+%%% ,{modify_algorithms, [{rm,[_AES_GCM]}]}
]
end,
Times =
diff --git a/lib/ssh/test/ssh_chan_behaviours_SUITE.erl b/lib/ssh/test/ssh_chan_behaviours_SUITE.erl
index 16ed152bcd..103d7253fd 100644
--- a/lib/ssh/test/ssh_chan_behaviours_SUITE.erl
+++ b/lib/ssh/test/ssh_chan_behaviours_SUITE.erl
@@ -128,8 +128,8 @@ subsystem_client(Config) ->
C = proplists:get_value(connref, Config),
{ok,ChRef} = ssh_chan_behaviours_client:start_link(C),
- IDclt = ?EXPECT({{C,Ch1clt}, {ssh_channel_up,Ch1clt,C}}, {C,Ch1clt}),
- IDsrv = ?EXPECT({{_Csrv,Ch1srv}, {ssh_channel_up,Ch1srv,_Csrv}}, {_Csrv,Ch1srv}),
+ IDclt = ?EXPECT({{C,_Ch1clt}, {ssh_channel_up,_Ch1clt,C}}, {C,_Ch1clt}),
+ IDsrv = ?EXPECT({{_Csrv,_Ch1srv}, {ssh_channel_up,_Ch1srv,_Csrv}}, {_Csrv,_Ch1srv}),
ok = ssh_chan_behaviours_client:stop(ChRef),
?EXPECT({IDclt, {terminate,normal}}, []), % From the proper channel handler
diff --git a/lib/ssh/test/ssh_chan_behaviours_client.erl b/lib/ssh/test/ssh_chan_behaviours_client.erl
index 15f17733d6..8dd18973ad 100644
--- a/lib/ssh/test/ssh_chan_behaviours_client.erl
+++ b/lib/ssh/test/ssh_chan_behaviours_client.erl
@@ -94,7 +94,7 @@ handle_ssh_msg({ssh_cm, C, {eof, Ch}}=M, #state{ch=Ch,cm=C} = State) ->
?DBG(State, "eof",[]),
{ok, State};
-handle_ssh_msg({ssh_cm, C, {signal, _Ch, _SigNameStr}=Sig} = M, #state{ch=Ch,cm=C} = State) ->
+handle_ssh_msg({ssh_cm, C, {signal, Ch, _SigNameStr}=Sig} = M, #state{ch=Ch,cm=C} = State) ->
%% Ignore signals according to RFC 4254 section 6.9.
tell_parent(M, State),
?DBG(State, "~p",[Sig]),
diff --git a/lib/ssh/test/ssh_chan_behaviours_server.erl b/lib/ssh/test/ssh_chan_behaviours_server.erl
index 1408675a6e..1d504b1bc6 100644
--- a/lib/ssh/test/ssh_chan_behaviours_server.erl
+++ b/lib/ssh/test/ssh_chan_behaviours_server.erl
@@ -65,7 +65,7 @@ handle_ssh_msg({ssh_cm, C, {eof, Ch}}=M, #state{ch=Ch,cm=C} = State) ->
?DBG(State, "eof",[]),
{ok, State};
-handle_ssh_msg({ssh_cm, C, {signal, _Ch, _SigNameStr}=Sig} = M, #state{ch=Ch,cm=C} = State) ->
+handle_ssh_msg({ssh_cm, C, {signal, Ch, _SigNameStr}=Sig} = M, #state{ch=Ch,cm=C} = State) ->
%% Ignore signals according to RFC 4254 section 6.9.
tell_parent(M, State),
?DBG(State, "~p",[Sig]),
diff --git a/lib/ssh/test/ssh_compat_SUITE.erl b/lib/ssh/test/ssh_compat_SUITE.erl
index 8e82527c6e..06ed9082cf 100644
--- a/lib/ssh/test/ssh_compat_SUITE.erl
+++ b/lib/ssh/test/ssh_compat_SUITE.erl
@@ -150,8 +150,7 @@ init_per_group(G, Config0) ->
stop_docker(ID),
{fail, "Can't contact docker sshd"}
catch
- Class:Exc ->
- ST = erlang:get_stacktrace(),
+ Class:Exc:ST ->
ct:log("common_algs: ~p:~p~n~p",[Class,Exc,ST]),
stop_docker(ID),
{fail, "Failed during setup"}
@@ -160,8 +159,7 @@ init_per_group(G, Config0) ->
cant_start_docker ->
{skip, "Can't start docker"};
- C:E ->
- ST = erlang:get_stacktrace(),
+ C:E:ST ->
ct:log("No ~p~n~p:~p~n~p",[G,C,E,ST]),
{skip, "Can't start docker"}
end;
@@ -1026,8 +1024,7 @@ receive_hello(S) ->
Result ->
Result
catch
- Class:Error ->
- ST = erlang:get_stacktrace(),
+ Class:Error:ST ->
{error, {Class,Error,ST}}
end.
@@ -1104,8 +1101,7 @@ sftp_tests_erl_server(Config, ServerIP, ServerPort, ServerRootDir, UserDir) ->
call_sftp_in_docker(Config, ServerIP, ServerPort, Cmnds, UserDir),
check_local_directory(ServerRootDir)
catch
- Class:Error ->
- ST = erlang:get_stacktrace(),
+ Class:Error:ST ->
{error, {Class,Error,ST}}
end.
@@ -1133,7 +1129,7 @@ check_local_directory(ServerRootDir) ->
check_local_directory(ServerRootDir, SleepTime, N) ->
case do_check_local_directory(ServerRootDir) of
- {error,Error} when N>0 ->
+ {error,_Error} when N>0 ->
%% Could be that the erlang side is faster and the docker's operations
%% are not yet finalized.
%% Sleep for a while and retry a few times:
@@ -1347,8 +1343,7 @@ one_test_erl_client(SFTP, Id, C) when SFTP==sftp ; SFTP==sftp_async ->
catch ssh_sftp:stop_channel(Ch),
R
catch
- Class:Error ->
- ST = erlang:get_stacktrace(),
+ Class:Error:ST ->
{error, {SFTP,Id,Class,Error,ST}}
end.
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index 778e4a5fc8..6aa587dc7f 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -1124,12 +1124,12 @@ start_our_shell(_User, _Peer) ->
ssh_exec_echo(Cmd) ->
spawn(fun() ->
- io:format("echo "++Cmd ++ "\n")
+ io:format("echo ~s\n", [Cmd])
end).
ssh_exec_echo(Cmd, User) ->
spawn(fun() ->
- io:format(io_lib:format("echo ~s ~s\n",[User,Cmd]))
+ io:format("echo ~s ~s\n",[User,Cmd])
end).
ssh_exec_echo(Cmd, User, _PeerAddr) ->
ssh_exec_echo(Cmd,User).
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
index 60d0da2a39..bf90f74324 100644
--- a/lib/ssh/test/ssh_options_SUITE.erl
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -214,7 +214,7 @@ init_per_testcase(_TestCase, Config) ->
file:make_dir(UserDir),
[{user_dir,UserDir}|Config].
-end_per_testcase(_TestCase, Config) ->
+end_per_testcase(_TestCase, _Config) ->
ssh:stop(),
ok.
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
index 3e3e151781..b12ddfeef6 100644
--- a/lib/ssh/test/ssh_protocol_SUITE.erl
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -38,7 +38,11 @@
-define(EXTRA_KEX, 'diffie-hellman-group1-sha1').
-define(CIPHERS, ['aes256-ctr','aes192-ctr','aes128-ctr','aes128-cbc','3des-cbc']).
--define(DEFAULT_CIPHERS, [{client2server,?CIPHERS}, {server2client,?CIPHERS}]).
+-define(DEFAULT_CIPHERS, (fun() -> Ciphs = filter_supported(cipher, ?CIPHERS),
+ [{client2server,Ciphs}, {server2client,Ciphs}]
+ end)()
+ ).
+
-define(v(Key, Config), proplists:get_value(Key, Config)).
-define(v(Key, Config, Default), proplists:get_value(Key, Config, Default)).
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index a1a7eebcde..1129303414 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -409,7 +409,7 @@ ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file
setup_ecdsa_auth_keys(Size, DataDir, UserDir).
setup_eddsa(Alg, DataDir, UserDir) ->
- {IdPriv, IdPub, HostPriv, HostPub} =
+ {IdPriv, _IdPub, HostPriv, HostPub} =
case Alg of
ed25519 -> {"id_ed25519", "id_ed25519.pub", "ssh_host_ed25519_key", "ssh_host_ed25519_key.pub"};
ed448 -> {"id_ed448", "id_ed448.pub", "ssh_host_ed448_key", "ssh_host_ed448_key.pub"}
@@ -970,7 +970,7 @@ expected_state(_) -> false.
%%%----------------------------------------------------------------
%%% Return a string with N random characters
%%%
-random_chars(N) -> [crypto:rand_uniform($a,$z) || _<-lists:duplicate(N,x)].
+random_chars(N) -> [($a-1)+rand:uniform($z-$a) || _<-lists:duplicate(N,x)].
create_random_dir(Config) ->
diff --git a/lib/ssh/test/ssh_trpt_test_lib.erl b/lib/ssh/test/ssh_trpt_test_lib.erl
index f2c9892f95..3f4df2c986 100644
--- a/lib/ssh/test/ssh_trpt_test_lib.erl
+++ b/lib/ssh/test/ssh_trpt_test_lib.erl
@@ -570,75 +570,6 @@ receive_binary_msg(S0=#s{}) ->
-old_receive_binary_msg(S0=#s{ssh=C0=#ssh{decrypt_block_size = BlockSize,
- recv_mac_size = MacSize
- }
- }) ->
- case size(S0#s.encrypted_data_buffer) >= max(8,BlockSize) of
- false ->
- %% Need more bytes to decode the packet_length field
- Remaining = max(8,BlockSize) - size(S0#s.encrypted_data_buffer),
- receive_binary_msg( receive_wait(Remaining, S0) );
- true ->
- %% Has enough bytes to decode the packet_length field
- {_, <<?UINT32(PacketLen), _/binary>>, _} =
- ssh_transport:decrypt_blocks(S0#s.encrypted_data_buffer, BlockSize, C0), % FIXME: BlockSize should be at least 4
-
- %% FIXME: Check that ((4+PacketLen) rem BlockSize) == 0 ?
-
- S1 = if
- PacketLen > ?SSH_MAX_PACKET_SIZE ->
- fail({too_large_message,PacketLen},S0); % FIXME: disconnect
-
- ((4+PacketLen) rem BlockSize) =/= 0 ->
- fail(bad_packet_length_modulo, S0); % FIXME: disconnect
-
- size(S0#s.encrypted_data_buffer) >= (4 + PacketLen + MacSize) ->
- %% has the whole packet
- S0;
-
- true ->
- %% need more bytes to get have the whole packet
- Remaining = (4 + PacketLen + MacSize) - size(S0#s.encrypted_data_buffer),
- receive_wait(Remaining, S0)
- end,
-
- %% Decrypt all, including the packet_length part (re-use the initial #ssh{})
- {C1, SshPacket = <<?UINT32(_),?BYTE(PadLen),Tail/binary>>, EncRest} =
- ssh_transport:decrypt_blocks(S1#s.encrypted_data_buffer, PacketLen+4, C0),
-
- PayloadLen = PacketLen - 1 - PadLen,
- <<CompressedPayload:PayloadLen/binary, _Padding:PadLen/binary>> = Tail,
-
- {C2, Payload} = ssh_transport:decompress(C1, CompressedPayload),
-
- <<Mac:MacSize/binary, Rest/binary>> = EncRest,
-
- case {ssh_transport:is_valid_mac(Mac, SshPacket, C2),
- catch ssh_message:decode(set_prefix_if_trouble(Payload,S1))}
- of
- {false, _} -> fail(bad_mac,S1);
- {_, {'EXIT',_}} -> fail(decode_failed,S1);
-
- {true, Msg} ->
- C3 = case Msg of
- #ssh_msg_kexinit{} ->
- ssh_transport:key_init(opposite_role(C2), C2, Payload);
- _ ->
- C2
- end,
- S2 = opt(print_messages, S1,
- fun(X) when X==true;X==detail -> {"Recv~n~s~n",[format_msg(Msg)]} end),
- S3 = opt(print_messages, S2,
- fun(detail) -> {"decrypted bytes ~p~n",[SshPacket]} end),
- S3#s{ssh = inc_recv_seq_num(C3),
- encrypted_data_buffer = Rest,
- return_value = Msg
- }
- end
- end.
-
-
set_prefix_if_trouble(Msg = <<?BYTE(Op),_/binary>>, #s{alg=#alg{kex=Kex}})
when Op == 30;
Op == 31