-
-
Notifications
You must be signed in to change notification settings - Fork 941
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use BCL CipherMode enum for AesCipher class just like TripleDesCipher…
… class; Create a dedicated AesCtrCipher class just like AesGcmCipher class.
- Loading branch information
Showing
11 changed files
with
290 additions
and
305 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -364,15 +364,15 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy | |
|
||
Encryptions = new Dictionary<string, CipherInfo> | ||
{ | ||
{ "aes128-ctr", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)) }, | ||
{ "aes192-ctr", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)) }, | ||
{ "aes256-ctr", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)) }, | ||
{ "aes128-ctr", new CipherInfo(128, (key, iv) => new AesCtrCipher(key, iv)) }, | ||
{ "aes192-ctr", new CipherInfo(192, (key, iv) => new AesCtrCipher(key, iv)) }, | ||
{ "aes256-ctr", new CipherInfo(256, (key, iv) => new AesCtrCipher(key, iv)) }, | ||
{ "[email protected]", new CipherInfo(128, (key, iv) => new AesGcmCipher(key, iv, aadLength: 4), isAead: true) }, | ||
{ "[email protected]", new CipherInfo(256, (key, iv) => new AesGcmCipher(key, iv, aadLength: 4), isAead: true) }, | ||
{ "[email protected]", new CipherInfo(512, (key, iv) => new ChaCha20Poly1305Cipher(key, aadLength: 4), isAead: true) }, | ||
{ "aes128-cbc", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)) }, | ||
{ "aes192-cbc", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)) }, | ||
{ "aes256-cbc", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)) }, | ||
{ "aes128-cbc", new CipherInfo(128, (key, iv) => new AesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)) }, | ||
{ "aes192-cbc", new CipherInfo(192, (key, iv) => new AesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)) }, | ||
{ "aes256-cbc", new CipherInfo(256, (key, iv) => new AesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)) }, | ||
{ "3des-cbc", new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)) }, | ||
}; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,22 +95,22 @@ public Key Parse() | |
cipherInfo = new CipherInfo(192, (key, iv) => new TripleDesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)); | ||
break; | ||
case "aes128-cbc": | ||
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)); | ||
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)); | ||
break; | ||
case "aes192-cbc": | ||
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)); | ||
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)); | ||
break; | ||
case "aes256-cbc": | ||
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CBC, pkcs7Padding: false)); | ||
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, CipherMode.CBC, pkcs7Padding: false)); | ||
break; | ||
case "aes128-ctr": | ||
cipherInfo = new CipherInfo(128, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)); | ||
cipherInfo = new CipherInfo(128, (key, iv) => new AesCtrCipher(key, iv)); | ||
break; | ||
case "aes192-ctr": | ||
cipherInfo = new CipherInfo(192, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)); | ||
cipherInfo = new CipherInfo(192, (key, iv) => new AesCtrCipher(key, iv)); | ||
break; | ||
case "aes256-ctr": | ||
cipherInfo = new CipherInfo(256, (key, iv) => new AesCipher(key, iv, AesCipherMode.CTR, pkcs7Padding: false)); | ||
cipherInfo = new CipherInfo(256, (key, iv) => new AesCtrCipher(key, iv)); | ||
break; | ||
case "[email protected]": | ||
cipherInfo = new CipherInfo(128, (key, iv) => new AesGcmCipher(key, iv, aadLength: 0), isAead: true); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 0 additions & 115 deletions
115
src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.CtrImpl.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 0 additions & 26 deletions
26
src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipherMode.cs
This file was deleted.
Oops, something went wrong.
109 changes: 109 additions & 0 deletions
109
src/Renci.SshNet/Security/Cryptography/Ciphers/AesCtrCipher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
using System; | ||
using System.Buffers.Binary; | ||
using System.Numerics; | ||
using System.Security.Cryptography; | ||
|
||
namespace Renci.SshNet.Security.Cryptography.Ciphers | ||
{ | ||
internal sealed class AesCtrCipher : BlockCipher, IDisposable | ||
{ | ||
private readonly Aes _aes; | ||
private readonly ICryptoTransform _encryptor; | ||
|
||
private ulong _ivUpper; // The upper 64 bits of the IV | ||
private ulong _ivLower; // The lower 64 bits of the IV | ||
|
||
public AesCtrCipher(byte[] key, byte[] iv) | ||
: base(key, 16, mode: null, padding: null) | ||
{ | ||
var aes = Aes.Create(); | ||
aes.Key = key; | ||
aes.Mode = System.Security.Cryptography.CipherMode.ECB; | ||
aes.Padding = PaddingMode.None; | ||
_aes = aes; | ||
_encryptor = aes.CreateEncryptor(); | ||
|
||
_ivLower = BinaryPrimitives.ReadUInt64BigEndian(iv.AsSpan(8)); | ||
_ivUpper = BinaryPrimitives.ReadUInt64BigEndian(iv); | ||
} | ||
|
||
public override byte[] Encrypt(byte[] input, int offset, int length) | ||
{ | ||
return CTREncryptDecrypt(input, offset, length); | ||
} | ||
|
||
public override byte[] Decrypt(byte[] input, int offset, int length) | ||
{ | ||
return CTREncryptDecrypt(input, offset, length); | ||
} | ||
|
||
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) | ||
{ | ||
throw new NotImplementedException($"Invalid usage of {nameof(EncryptBlock)}."); | ||
} | ||
|
||
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) | ||
{ | ||
throw new NotImplementedException($"Invalid usage of {nameof(DecryptBlock)}."); | ||
} | ||
|
||
private byte[] CTREncryptDecrypt(byte[] data, int offset, int length) | ||
{ | ||
var count = length / BlockSize; | ||
if (length % BlockSize != 0) | ||
{ | ||
count++; | ||
} | ||
|
||
var buffer = new byte[count * BlockSize]; | ||
CTRCreateCounterArray(buffer); | ||
_ = _encryptor.TransformBlock(buffer, 0, buffer.Length, buffer, 0); | ||
ArrayXOR(buffer, data, offset, length); | ||
|
||
// adjust output for non-blocksized lengths | ||
if (buffer.Length > length) | ||
{ | ||
Array.Resize(ref buffer, length); | ||
} | ||
|
||
return buffer; | ||
} | ||
|
||
// creates the Counter array filled with incrementing copies of IV | ||
private void CTRCreateCounterArray(byte[] buffer) | ||
{ | ||
for (var i = 0; i < buffer.Length; i += 16) | ||
{ | ||
BinaryPrimitives.WriteUInt64BigEndian(buffer.AsSpan(i + 8), _ivLower); | ||
BinaryPrimitives.WriteUInt64BigEndian(buffer.AsSpan(i), _ivUpper); | ||
|
||
_ivLower += 1; | ||
_ivUpper += (_ivLower == 0) ? 1UL : 0UL; | ||
} | ||
} | ||
|
||
// XOR 2 arrays using Vector<byte> | ||
private static void ArrayXOR(byte[] buffer, byte[] data, int offset, int length) | ||
{ | ||
var i = 0; | ||
|
||
var oneVectorFromEnd = length - Vector<byte>.Count; | ||
for (; i <= oneVectorFromEnd; i += Vector<byte>.Count) | ||
{ | ||
var v = new Vector<byte>(buffer, i) ^ new Vector<byte>(data, offset + i); | ||
v.CopyTo(buffer, i); | ||
} | ||
|
||
for (; i < length; i++) | ||
{ | ||
buffer[i] ^= data[offset + i]; | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_aes.Dispose(); | ||
_encryptor.Dispose(); | ||
} | ||
} | ||
} |
Oops, something went wrong.