Skip to content

Commit 395ddca

Browse files
committed
Restore AesCipherMode; Use BlockImpl instead of BouncyCastleImpl for 3DES-CFB on lower targets.
1 parent 305a874 commit 395ddca

File tree

16 files changed

+248
-235
lines changed

16 files changed

+248
-235
lines changed

src/Renci.SshNet/ConnectionInfo.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
using Renci.SshNet.Security.Cryptography;
1414
using Renci.SshNet.Security.Cryptography.Ciphers;
1515

16+
using CipherMode = System.Security.Cryptography.CipherMode;
17+
1618
namespace Renci.SshNet
1719
{
1820
/// <summary>
@@ -362,16 +364,16 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy
362364

363365
Encryptions = new Dictionary<string, CipherInfo>
364366
{
365-
{ "aes128-ctr", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CTR, pkcs7Padding: false)) },
366-
{ "aes192-ctr", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CTR, pkcs7Padding: false)) },
367-
{ "aes256-ctr", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CTR, pkcs7Padding: false)) },
367+
{ "aes128-ctr", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)) },
368+
{ "aes192-ctr", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)) },
369+
{ "aes256-ctr", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)) },
368370
{ "[email protected]", new CipherInfo(128, (key, iv) => new AesGcmCipher(key, iv, aadLength: 4), isAead: true) },
369371
{ "[email protected]", new CipherInfo(256, (key, iv) => new AesGcmCipher(key, iv, aadLength: 4), isAead: true) },
370372
{ "[email protected]", new CipherInfo(512, (key, iv) => new ChaCha20Poly1305Cipher(key, aadLength: 4), isAead: true) },
371-
{ "aes128-cbc", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false)) },
372-
{ "aes192-cbc", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false)) },
373-
{ "aes256-cbc", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false)) },
374-
{ "3des-cbc", new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false)) },
373+
{ "aes128-cbc", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)) },
374+
{ "aes192-cbc", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)) },
375+
{ "aes256-cbc", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)) },
376+
{ "3des-cbc", new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)) },
375377
};
376378

377379
HmacAlgorithms = new Dictionary<string, HashInfo>

src/Renci.SshNet/PrivateKeyFile.OpenSSH.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using Renci.SshNet.Security.Cryptography;
1010
using Renci.SshNet.Security.Cryptography.Ciphers;
1111

12+
using CipherMode = System.Security.Cryptography.CipherMode;
13+
1214
namespace Renci.SshNet
1315
{
1416
public partial class PrivateKeyFile
@@ -90,25 +92,25 @@ public Key Parse()
9092
{
9193
case "3des-cbc":
9294
ivLength = 8;
93-
cipherInfo = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false));
95+
cipherInfo = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false));
9496
break;
9597
case "aes128-cbc":
96-
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false));
98+
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false));
9799
break;
98100
case "aes192-cbc":
99-
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false));
101+
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false));
100102
break;
101103
case "aes256-cbc":
102-
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: false));
104+
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false));
103105
break;
104106
case "aes128-ctr":
105-
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CTR, pkcs7Padding: false));
107+
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false));
106108
break;
107109
case "aes192-ctr":
108-
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CTR, pkcs7Padding: false));
110+
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false));
109111
break;
110112
case "aes256-ctr":
111-
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CTR, pkcs7Padding: false));
113+
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false));
112114
break;
113115
114116
cipherInfo = new CipherInfo(128, (key, iv) => new AesGcmCipher(key, iv, aadLength: 0), isAead: true);

src/Renci.SshNet/PrivateKeyFile.PKCS1.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
using Renci.SshNet.Security;
1111
using Renci.SshNet.Security.Cryptography.Ciphers;
1212

13+
using CipherMode = System.Security.Cryptography.CipherMode;
14+
1315
namespace Renci.SshNet
1416
{
1517
public partial class PrivateKeyFile
@@ -49,19 +51,19 @@ public Key Parse()
4951
switch (_cipherName)
5052
{
5153
case "DES-EDE3-CBC":
52-
cipher = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: true));
54+
cipher = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, CipherMode.CBC, pkcs7Padding: true));
5355
break;
5456
case "DES-EDE3-CFB":
55-
cipher = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, BlockCipherMode.CFB, pkcs7Padding: false));
57+
cipher = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, CipherMode.CFB, pkcs7Padding: false));
5658
break;
5759
case "AES-128-CBC":
58-
cipher = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: true));
60+
cipher = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: true));
5961
break;
6062
case "AES-192-CBC":
61-
cipher = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: true));
63+
cipher = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: true));
6264
break;
6365
case "AES-256-CBC":
64-
cipher = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, BlockCipherMode.CBC, pkcs7Padding: true));
66+
cipher = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: true));
6567
break;
6668
default:
6769
throw new SshException(string.Format(CultureInfo.InvariantCulture, "Private key cipher \"{0}\" is not supported.", _cipherName));

src/Renci.SshNet/PrivateKeyFile.PuTTY.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public Key Parse()
111111
throw new SshException("PuTTY key file version " + _version + " is not supported");
112112
}
113113

114-
using (var cipher = new AesCipher(cipherKey, cipherIV, BlockCipherMode.CBC, pkcs7Padding: false))
114+
using (var cipher = new AesCipher(cipherKey, cipherIV, AesCipherMode.CBC, pkcs7Padding: false))
115115
{
116116
privateKey = cipher.Decrypt(_data);
117117
}

src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using Renci.SshNet.Security;
99
using Renci.SshNet.Security.Cryptography.Ciphers;
1010

11+
using CipherMode = System.Security.Cryptography.CipherMode;
12+
1113
namespace Renci.SshNet
1214
{
1315
public partial class PrivateKeyFile
@@ -50,7 +52,7 @@ public Key Parse()
5052
}
5153

5254
var key = GetCipherKey(_passPhrase, 192 / 8);
53-
var ssh2Сipher = new TripleDesCipher(key, new byte[8], BlockCipherMode.CBC, pkcs7Padding: false);
55+
var ssh2Сipher = new TripleDesCipher(key, new byte[8], CipherMode.CBC, pkcs7Padding: false);
5456
keyData = ssh2Сipher.Decrypt(reader.ReadBytes(blobSize));
5557
}
5658
else

src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,22 @@ public sealed partial class AesCipher : BlockCipher, IDisposable
2323
/// <param name="pkcs7Padding">Enable PKCS7 padding.</param>
2424
/// <exception cref="ArgumentNullException"><paramref name="key"/> is <see langword="null"/>.</exception>
2525
/// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
26-
public AesCipher(byte[] key, byte[] iv, BlockCipherMode mode, bool pkcs7Padding = false)
26+
public AesCipher(byte[] key, byte[] iv, AesCipherMode mode, bool pkcs7Padding = false)
2727
: base(key, 16, mode: null, padding: null)
2828
{
29-
if (mode == BlockCipherMode.OFB)
29+
if (mode == AesCipherMode.OFB)
3030
{
3131
// OFB is not supported on modern .NET
3232
_impl = new BlockImpl(key, new OfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
3333
}
3434
#if !NET6_0_OR_GREATER
35-
else if (mode == BlockCipherMode.CFB)
35+
else if (mode == AesCipherMode.CFB)
3636
{
3737
// CFB not supported on NetStandard 2.1
3838
_impl = new BlockImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
3939
}
4040
#endif
41-
else if (mode == BlockCipherMode.CTR)
41+
else if (mode == AesCipherMode.CTR)
4242
{
4343
// CTR not supported by the BCL, use an optimized implementation
4444
_impl = new CtrImpl(key, iv);

src/Renci.SshNet/Security/Cryptography/Ciphers/BlockCipherMode.cs renamed to src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipherMode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/// <summary>
44
/// Custom Cipher Mode, follows System.Security.Cryptography.CipherMode.
55
/// </summary>
6-
public enum BlockCipherMode
6+
public enum AesCipherMode
77
{
88
/// <summary>Cipher Block Chain Mode.</summary>
99
CBC = 1,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#if !NET6_0_OR_GREATER
2+
using System;
3+
using System.Security.Cryptography;
4+
5+
using Org.BouncyCastle.Crypto.Paddings;
6+
7+
namespace Renci.SshNet.Security.Cryptography.Ciphers
8+
{
9+
public partial class TripleDesCipher
10+
{
11+
private sealed class BlockImpl : BlockCipher, IDisposable
12+
{
13+
private readonly TripleDES _tripleDES;
14+
private readonly ICryptoTransform _encryptor;
15+
private readonly ICryptoTransform _decryptor;
16+
17+
public BlockImpl(byte[] key, CipherMode mode, IBlockCipherPadding padding)
18+
: base(key, 8, mode, padding)
19+
{
20+
var tripleDES = TripleDES.Create();
21+
tripleDES.Key = key;
22+
tripleDES.Mode = System.Security.Cryptography.CipherMode.ECB;
23+
tripleDES.Padding = PaddingMode.None;
24+
_tripleDES = tripleDES;
25+
_encryptor = tripleDES.CreateEncryptor();
26+
_decryptor = tripleDES.CreateDecryptor();
27+
}
28+
29+
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
30+
{
31+
return _encryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
32+
}
33+
34+
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
35+
{
36+
return _decryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
37+
}
38+
39+
public void Dispose()
40+
{
41+
_tripleDES.Dispose();
42+
_encryptor.Dispose();
43+
_decryptor.Dispose();
44+
}
45+
}
46+
}
47+
}
48+
#endif

src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.BouncyCastleImpl.cs

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Security.Cryptography;
33

4-
#if !NET
4+
#if !NET6_0_OR_GREATER
55
using Org.BouncyCastle.Crypto.Paddings;
66

77
using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
@@ -28,21 +28,21 @@ public sealed partial class TripleDesCipher : BlockCipher, IDisposable
2828
/// <param name="mode">The mode.</param>
2929
/// <param name="pkcs7Padding">Enable PKCS7 padding.</param>
3030
/// <exception cref="ArgumentNullException"><paramref name="key"/> is <see langword="null"/>.</exception>
31-
public TripleDesCipher(byte[] key, byte[] iv, BlockCipherMode mode, bool pkcs7Padding)
31+
public TripleDesCipher(byte[] key, byte[] iv, System.Security.Cryptography.CipherMode mode, bool pkcs7Padding)
3232
: base(key, 8, mode: null, padding: null)
3333
{
3434
#if !NET6_0_OR_GREATER
35-
if (mode == BlockCipherMode.CFB)
35+
if (mode == System.Security.Cryptography.CipherMode.CFB)
3636
{
3737
// CFB8 not supported on .NET Framework, but supported on .NET
3838
// see https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs#L76-L78
3939
// see https://github.com/dotnet/runtime/blob/e7d837da5b1aacd9325a8b8f2214cfaf4d3f0ff6/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDesImplementation.cs#L229-L236
40-
_impl = new BouncyCastleImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
40+
_impl = new BlockImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
4141
}
4242
else
4343
#endif
4444
{
45-
_impl = new BclImpl(key, iv, (System.Security.Cryptography.CipherMode)mode, pkcs7Padding ? PaddingMode.PKCS7 : PaddingMode.None);
45+
_impl = new BclImpl(key, iv, mode, pkcs7Padding ? PaddingMode.PKCS7 : PaddingMode.None);
4646
}
4747
}
4848

0 commit comments

Comments
 (0)