Skip to content

Commit 2d8e19f

Browse files
Change default FeedbackSize for TripleDES internal implementation to 8
In .NET Framework, TripleDESCryptoServiceProvider defaults to a feedback size of 8, and TripleDESCng defaults to a feedback size of 64. The static Create by default would return TripleDESCryptoServiceProvider, thus the TripleDES from Create would have a default feedback size of 8. This changes the default sizes of TripleDES to behave more similarly to .NET Framework to make porting CFB code from Framework easier. The internal 3DES implementation (and thus TripleDESCryptoServiceProvider, since that is a wrapper around the internal implementation) now defaults to a feedback size of 8. TripleDESCng and user-derived classes from TripleDES will continue to use a feedback size of 64. Co-authored-by: Kevin Jones <[email protected]>
1 parent 78740be commit 2d8e19f

File tree

8 files changed

+60
-1
lines changed

8 files changed

+60
-1
lines changed

src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/AES/AesContractTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static void VerifyDefaults()
1717
{
1818
Assert.Equal(128, aes.BlockSize);
1919
Assert.Equal(256, aes.KeySize);
20+
Assert.Equal(8, aes.FeedbackSize);
2021
Assert.Equal(CipherMode.CBC, aes.Mode);
2122
Assert.Equal(PaddingMode.PKCS7, aes.Padding);
2223
}

src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/TripleDES/TripleDESCipherTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,5 +827,27 @@ public static void MultipleBlockDecryptTransform(bool blockAlignedOutput)
827827
string decrypted = Encoding.ASCII.GetString(outputBytes, 0, outputOffset);
828828
Assert.Equal(ExpectedOutput, decrypted);
829829
}
830+
831+
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
832+
public static void VerifyNetFxCompat_CFB8_PKCS7Padding()
833+
{
834+
// .NET Framework would always pad to the nearest block
835+
// with CFB8 and PKCS7 padding even though the shortest possible
836+
// padding is always 1 byte. This ensures we can continue to decrypt
837+
// .NET Framework encrypted data with the excessive padding.
838+
839+
byte[] key = "531bd715cbf785c10169b6e4926562b8e1e5c4c8884ed791".HexToByteArray();
840+
byte[] iv = "dbeba40532a5304a".HexToByteArray();
841+
byte[] plaintext = "70656e6e79".HexToByteArray();
842+
byte[] ciphertext = "8798c2da055c9ea0".HexToByteArray();
843+
844+
using TripleDES tdes = TripleDESFactory.Create();
845+
tdes.Mode = CipherMode.CFB;
846+
tdes.Padding = PaddingMode.PKCS7;
847+
tdes.FeedbackSize = 8;
848+
849+
byte[] decrypted = TripleDESDecryptDirectKey(tdes, key, iv, ciphertext);
850+
Assert.Equal(plaintext, decrypted);
851+
}
830852
}
831853
}

src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/TripleDesImplementation.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ internal sealed partial class TripleDesImplementation : TripleDES
1111
{
1212
private const int BitsPerByte = 8;
1313

14+
public TripleDesImplementation()
15+
{
16+
// Default CFB to CFB8 to match .NET Framework's default for TripleDES.Create()
17+
// and TripleDESCryptoServiceProvider.
18+
FeedbackSizeValue = 8;
19+
}
20+
1421
public override ICryptoTransform CreateDecryptor()
1522
{
1623
return CreateTransform(Key, IV, encrypting: false);

src/libraries/System.Security.Cryptography.Algorithms/tests/AesTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static void AesDefaultCtor()
1515
{
1616
Assert.Equal(256, aes.KeySize);
1717
Assert.Equal(128, aes.BlockSize);
18+
Assert.Equal(8, aes.FeedbackSize);
1819
Assert.Equal(CipherMode.CBC, aes.Mode);
1920
Assert.Equal(PaddingMode.PKCS7, aes.Padding);
2021
}

src/libraries/System.Security.Cryptography.Algorithms/tests/TripleDesTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ public static void TripleDesDefaultCtor()
1919
{
2020
Assert.Equal(192, tdes.KeySize);
2121
Assert.Equal(64, tdes.BlockSize);
22+
Assert.Equal(64, tdes.FeedbackSize);
23+
Assert.Equal(CipherMode.CBC, tdes.Mode);
24+
Assert.Equal(PaddingMode.PKCS7, tdes.Padding);
25+
}
26+
}
27+
28+
[Fact]
29+
public static void TripleDesInternalDefault()
30+
{
31+
using (TripleDES tdes = TripleDES.Create())
32+
{
33+
Assert.Equal(192, tdes.KeySize);
34+
Assert.Equal(64, tdes.BlockSize);
35+
Assert.Equal(8, tdes.FeedbackSize);
2236
Assert.Equal(CipherMode.CBC, tdes.Mode);
2337
Assert.Equal(PaddingMode.PKCS7, tdes.Padding);
2438
}

src/libraries/System.Security.Cryptography.Cng/tests/TripleDESCngTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@ public static class TripleDESCngTests
1111

1212
private static readonly CngAlgorithm s_cngAlgorithm = new CngAlgorithm("3DES");
1313

14+
[Fact]
15+
public static void VerifyDefaults()
16+
{
17+
using TripleDES tdes = new TripleDESCng();
18+
Assert.Equal(64, tdes.BlockSize);
19+
Assert.Equal(192, tdes.KeySize);
20+
Assert.Equal(CipherMode.CBC, tdes.Mode);
21+
Assert.Equal(PaddingMode.PKCS7, tdes.Padding);
22+
23+
// .NET Framework Compat: The default feedback size of TripleDESCng
24+
// is 64 while TripleDESCryptoServiceProvider defaults to 8.
25+
Assert.Equal(64, tdes.FeedbackSize);
26+
}
27+
1428
[OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)]
1529
[ConditionalTheory(nameof(SupportsPersistedSymmetricKeys))]
1630
// 3DES192-ECB-NoPadding 2 blocks.

src/libraries/System.Security.Cryptography.Csp/src/System/Security/Cryptography/TripleDESCryptoServiceProvider.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public TripleDESCryptoServiceProvider()
1616
{
1717
// This class wraps TripleDES
1818
_impl = TripleDES.Create();
19-
_impl.FeedbackSize = 8;
2019
}
2120

2221
public override int FeedbackSize

src/libraries/System.Security.Cryptography.Csp/tests/TripleDESCryptoServiceProviderTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public static void VerifyDefaults()
1919
{
2020
Assert.Equal(64, alg.BlockSize);
2121
Assert.Equal(192, alg.KeySize);
22+
Assert.Equal(8, alg.FeedbackSize);
2223
Assert.Equal(CipherMode.CBC, alg.Mode);
2324
Assert.Equal(PaddingMode.PKCS7, alg.Padding);
2425
}

0 commit comments

Comments
 (0)