Skip to content

Commit 369f74a

Browse files
committed
Use Array.Resize to reduce allocation. Add more comments.
1 parent 232e446 commit 369f74a

File tree

4 files changed

+42
-9
lines changed

4 files changed

+42
-9
lines changed

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public override byte[] Encrypt(byte[] input, int offset, int length)
5252
{
5353
if (_aes.Mode is System.Security.Cryptography.CipherMode.CFB or System.Security.Cryptography.CipherMode.OFB)
5454
{
55+
// Manually pad the input for cfb and ofb cipher mode as BCL doesn't support partial block.
56+
// See https://github.com/dotnet/runtime/blob/e7d837da5b1aacd9325a8b8f2214cfaf4d3f0ff6/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SymmetricPadding.cs#L20-L21
5557
paddingLength = BlockSize - (length % BlockSize);
5658
input = input.Take(offset, length);
5759
length += paddingLength;
@@ -69,6 +71,7 @@ public override byte[] Encrypt(byte[] input, int offset, int length)
6971

7072
if (paddingLength > 0)
7173
{
74+
// Manually unpad the output.
7275
Array.Resize(ref output, output.Length - paddingLength);
7376
}
7477

@@ -89,11 +92,12 @@ public override byte[] Decrypt(byte[] input, int offset, int length)
8992
{
9093
if (_aes.Mode is System.Security.Cryptography.CipherMode.CFB or System.Security.Cryptography.CipherMode.OFB)
9194
{
95+
// Manually pad the input for cfb and ofb cipher mode as BCL doesn't support partial block.
96+
// See https://github.com/dotnet/runtime/blob/e7d837da5b1aacd9325a8b8f2214cfaf4d3f0ff6/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SymmetricPadding.cs#L20-L21
9297
paddingLength = BlockSize - (length % BlockSize);
93-
var newInput = new byte[input.Length + paddingLength];
94-
Buffer.BlockCopy(input, offset, newInput, 0, length);
95-
input = newInput;
96-
length = input.Length;
98+
input = input.Take(offset, length);
99+
length += paddingLength;
100+
Array.Resize(ref input, length);
97101
offset = 0;
98102
}
99103
}
@@ -107,6 +111,7 @@ public override byte[] Decrypt(byte[] input, int offset, int length)
107111

108112
if (paddingLength > 0)
109113
{
114+
// Manually unpad the output.
110115
Array.Resize(ref output, output.Length - paddingLength);
111116
}
112117

src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.BclImpl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@ public override byte[] Encrypt(byte[] input, int offset, int length)
3434
{
3535
if (_des.Padding != PaddingMode.None)
3636
{
37+
// If padding has been specified, call TransformFinalBlock to apply
38+
// the padding and reset the state.
3739
return _encryptor.TransformFinalBlock(input, offset, length);
3840
}
3941

42+
// Otherwise, (the most important case) assume this instance is
43+
// used for one direction of an SSH connection, whereby the
44+
// encrypted data in all packets are considered a single data
45+
// stream i.e. we do not want to reset the state between calls to Encrypt.
4046
var output = new byte[length];
4147
_ = _encryptor.TransformBlock(input, offset, length, output, 0);
4248

@@ -47,9 +53,15 @@ public override byte[] Decrypt(byte[] input, int offset, int length)
4753
{
4854
if (_des.Padding != PaddingMode.None)
4955
{
56+
// If padding has been specified, call TransformFinalBlock to apply
57+
// the padding and reset the state.
5058
return _decryptor.TransformFinalBlock(input, offset, length);
5159
}
5260

61+
// Otherwise, (the most important case) assume this instance is
62+
// used for one direction of an SSH connection, whereby the
63+
// encrypted data in all packets are considered a single data
64+
// stream i.e. we do not want to reset the state between calls to Encrypt.
5365
var output = new byte[length];
5466
_ = _decryptor.TransformBlock(input, offset, length, output, 0);
5567

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public override byte[] Encrypt(byte[] input, int offset, int length)
4343
{
4444
if (_des.Mode is System.Security.Cryptography.CipherMode.CFB or System.Security.Cryptography.CipherMode.OFB)
4545
{
46+
// Manually pad the input for cfb and ofb cipher mode as BCL doesn't support partial block.
47+
// See https://github.com/dotnet/runtime/blob/e7d837da5b1aacd9325a8b8f2214cfaf4d3f0ff6/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SymmetricPadding.cs#L20-L21
4648
paddingLength = BlockSize - (length % BlockSize);
4749
input = input.Take(offset, length);
4850
length += paddingLength;
@@ -51,11 +53,16 @@ public override byte[] Encrypt(byte[] input, int offset, int length)
5153
}
5254
}
5355

56+
// Otherwise, (the most important case) assume this instance is
57+
// used for one direction of an SSH connection, whereby the
58+
// encrypted data in all packets are considered a single data
59+
// stream i.e. we do not want to reset the state between calls to Encrypt.
5460
var output = new byte[length];
5561
_ = _encryptor.TransformBlock(input, offset, length, output, 0);
5662

5763
if (paddingLength > 0)
5864
{
65+
// Manually unpad the output.
5966
Array.Resize(ref output, output.Length - paddingLength);
6067
}
6168

@@ -66,6 +73,8 @@ public override byte[] Decrypt(byte[] input, int offset, int length)
6673
{
6774
if (_des.Padding != PaddingMode.None)
6875
{
76+
// If padding has been specified, call TransformFinalBlock to apply
77+
// the padding and reset the state.
6978
return _decryptor.TransformFinalBlock(input, offset, length);
7079
}
7180

@@ -74,20 +83,26 @@ public override byte[] Decrypt(byte[] input, int offset, int length)
7483
{
7584
if (_des.Mode is System.Security.Cryptography.CipherMode.CFB or System.Security.Cryptography.CipherMode.OFB)
7685
{
86+
// Manually pad the input for cfb and ofb cipher mode as BCL doesn't support partial block.
87+
// See https://github.com/dotnet/runtime/blob/e7d837da5b1aacd9325a8b8f2214cfaf4d3f0ff6/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SymmetricPadding.cs#L20-L21
7788
paddingLength = BlockSize - (length % BlockSize);
78-
var newInput = new byte[input.Length + paddingLength];
79-
Buffer.BlockCopy(input, offset, newInput, 0, length);
80-
input = newInput;
81-
length = input.Length;
89+
input = input.Take(offset, length);
90+
length += paddingLength;
91+
Array.Resize(ref input, length);
8292
offset = 0;
8393
}
8494
}
8595

96+
// Otherwise, (the most important case) assume this instance is
97+
// used for one direction of an SSH connection, whereby the
98+
// encrypted data in all packets are considered a single data
99+
// stream i.e. we do not want to reset the state between calls to Encrypt.
86100
var output = new byte[length];
87101
_ = _decryptor.TransformBlock(input, offset, length, output, 0);
88102

89103
if (paddingLength > 0)
90104
{
105+
// Manually unpad the output.
91106
Array.Resize(ref output, output.Length - paddingLength);
92107
}
93108

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ public TripleDesCipher(byte[] key, byte[] iv, BlockCipherMode mode, bool pkcs7Pa
3333
#if !NET6_0_OR_GREATER
3434
if (mode == BlockCipherMode.CFB)
3535
{
36-
// CFB8 not supported on .NET Framework
36+
// CFB8 not supported on .NET Framework, but supported on .NET
3737
// see https://github.com/microsoft/referencesource/blob/51cf7850defa8a17d815b4700b67116e3fa283c2/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs#L76-L78
38+
// see https://github.com/dotnet/runtime/blob/e7d837da5b1aacd9325a8b8f2214cfaf4d3f0ff6/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/TripleDesImplementation.cs#L229-L236
3839
_impl = new BouncyCastleImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new PKCS7Padding() : null);
3940
}
4041
else

0 commit comments

Comments
 (0)