Skip to content

Commit 204c5d0

Browse files
committed
Manually pad/unpad for Aes CFB/OFB mode
1 parent 629a3d1 commit 204c5d0

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,31 @@ public override byte[] Encrypt(byte[] input, int offset, int length)
4747
return _encryptor.TransformFinalBlock(input, offset, length);
4848
}
4949

50+
var paddingLength = 0;
51+
if (length % BlockSize > 0)
52+
{
53+
if (_aes.Mode is System.Security.Cryptography.CipherMode.CFB or System.Security.Cryptography.CipherMode.OFB)
54+
{
55+
paddingLength = BlockSize - (length % BlockSize);
56+
input = input.Take(offset, length);
57+
length += paddingLength;
58+
Array.Resize(ref input, length);
59+
offset = 0;
60+
}
61+
}
62+
5063
// Otherwise, (the most important case) assume this instance is
5164
// used for one direction of an SSH connection, whereby the
5265
// encrypted data in all packets are considered a single data
5366
// stream i.e. we do not want to reset the state between calls to Encrypt.
5467
var output = new byte[length];
5568
_ = _encryptor.TransformBlock(input, offset, length, output, 0);
69+
70+
if (paddingLength > 0)
71+
{
72+
Array.Resize(ref output, output.Length - paddingLength);
73+
}
74+
5675
return output;
5776
}
5877

@@ -65,12 +84,32 @@ public override byte[] Decrypt(byte[] input, int offset, int length)
6584
return _decryptor.TransformFinalBlock(input, offset, length);
6685
}
6786

87+
var paddingLength = 0;
88+
if (length % BlockSize > 0)
89+
{
90+
if (_aes.Mode is System.Security.Cryptography.CipherMode.CFB or System.Security.Cryptography.CipherMode.OFB)
91+
{
92+
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;
97+
offset = 0;
98+
}
99+
}
100+
68101
// Otherwise, (the most important case) assume this instance is
69102
// used for one direction of an SSH connection, whereby the
70103
// encrypted data in all packets are considered a single data
71104
// stream i.e. we do not want to reset the state between calls to Decrypt.
72105
var output = new byte[length];
73106
_ = _decryptor.TransformBlock(input, offset, length, output, 0);
107+
108+
if (paddingLength > 0)
109+
{
110+
Array.Resize(ref output, output.Length - paddingLength);
111+
}
112+
74113
return output;
75114
}
76115

0 commit comments

Comments
 (0)