Skip to content

Commit

Permalink
Fix CFB8 with Zero padding (#45009)
Browse files Browse the repository at this point in the history
  • Loading branch information
vcsjones committed Nov 24, 2020
1 parent d9a4a64 commit 2767f44
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ private int PadBlock(ReadOnlySpan<byte> block, Span<byte> destination)
//
// xx 00 00 00 00 00 00 00
case PaddingMode.Zeros:
if (padBytes == InputBlockSize)
if (padBytes == PaddingSizeBytes)
{
padBytes = 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,17 @@ public static void DecryptKnownCFB128_192()
{
byte[] encryptedBytes = new byte[]
{
0x7C, 0xC6, 0xEE, 0xD8, 0xED, 0xB5, 0x3F, 0x8A,
0x90, 0x95, 0x12, 0xD2, 0xBC, 0x9A, 0x96, 0x1E,
0x4E, 0xC4, 0xD1, 0x15, 0xA4, 0x7F, 0x32, 0xA4,
0xD1, 0xFD, 0x8E, 0x02, 0x45, 0xE8, 0x93, 0x3C,
0x3C, 0x91, 0x3F, 0xA4, 0x7F, 0x99, 0xF7, 0x3A,
0x53, 0x0C, 0x0B, 0xFD, 0x01, 0xC5, 0xBD, 0x76,
0xB7, 0xCF, 0x2B, 0x52, 0x34, 0xB1, 0xA6, 0xA4,
0x29, 0x2F, 0x7D, 0x1C, 0x97, 0x3A, 0xE2, 0x75,
0x3E, 0xEB, 0xFC, 0xB7, 0xBB, 0x7A, 0xC0, 0x66,
0x34, 0x25, 0xCF, 0x2D, 0xE2, 0x7E, 0x23, 0x06,
0x10, 0xFE, 0xEA, 0xB3, 0x0F, 0x1D, 0x2C, 0xDD,
0x7C, 0xC6, 0xEE, 0xD8, 0xED, 0xB5, 0x3F, 0x8A,
0x90, 0x95, 0x12, 0xD2, 0xBC, 0x9A, 0x96, 0x1E,
0x4E, 0xC4, 0xD1, 0x15, 0xA4, 0x7F, 0x32, 0xA4,
0xD1, 0xFD, 0x8E, 0x02, 0x45, 0xE8, 0x93, 0x3C,
0x3C, 0x91, 0x3F, 0xA4, 0x7F, 0x99, 0xF7, 0x3A,
0x53, 0x0C, 0x0B, 0xFD, 0x01, 0xC5, 0xBD, 0x76,
0xB7, 0xCF, 0x2B, 0x52, 0x34, 0xB1, 0xA6, 0xA4,
0x29, 0x2F, 0x7D, 0x1C, 0x97, 0x3A, 0xE2, 0x75,
0x3E, 0xEB, 0xFC, 0xB7, 0xBB, 0x7A, 0xC0, 0x66,
0x34, 0x25, 0xCF, 0x2D, 0xE2, 0x7E, 0x23, 0x06,
0x10, 0xFE, 0xEA, 0xB3, 0x0F, 0x1D, 0x2C, 0xDD,
0x72, 0x64, 0x51, 0x78, 0x1D, 0x75, 0xD2, 0x17
};

Expand All @@ -149,17 +149,17 @@ public static void DecryptKnownCFB128_128()
{
byte[] encryptedBytes = new byte[]
{
0x5B, 0x63, 0x3D, 0x1C, 0x0C, 0x8E, 0xD4, 0xF4,
0xE5, 0x5F, 0xA0, 0xAF, 0x2F, 0xF5, 0xAE, 0x59,
0xB9, 0xC4, 0xFA, 0x02, 0x11, 0x37, 0xEB, 0x38,
0x5B, 0x2F, 0x1D, 0xF5, 0x03, 0xD1, 0xFD, 0x85,
0x4B, 0xAA, 0x4F, 0x29, 0x94, 0x09, 0x31, 0x4C,
0x4D, 0xD6, 0x99, 0xE3, 0x4D, 0xC4, 0x3A, 0x40,
0x97, 0x58, 0xA5, 0x26, 0x80, 0xA8, 0xCA, 0xFA,
0x6D, 0x19, 0x3B, 0x6B, 0x6F, 0x75, 0x76, 0x83,
0x90, 0x31, 0x07, 0x86, 0x35, 0xD6, 0xAB, 0xB4,
0x65, 0x07, 0x0A, 0x0A, 0xA3, 0x7A, 0xD7, 0x16,
0xE2, 0xC5, 0x3B, 0xE0, 0x42, 0x5F, 0xFA, 0xEF,
0x5B, 0x63, 0x3D, 0x1C, 0x0C, 0x8E, 0xD4, 0xF4,
0xE5, 0x5F, 0xA0, 0xAF, 0x2F, 0xF5, 0xAE, 0x59,
0xB9, 0xC4, 0xFA, 0x02, 0x11, 0x37, 0xEB, 0x38,
0x5B, 0x2F, 0x1D, 0xF5, 0x03, 0xD1, 0xFD, 0x85,
0x4B, 0xAA, 0x4F, 0x29, 0x94, 0x09, 0x31, 0x4C,
0x4D, 0xD6, 0x99, 0xE3, 0x4D, 0xC4, 0x3A, 0x40,
0x97, 0x58, 0xA5, 0x26, 0x80, 0xA8, 0xCA, 0xFA,
0x6D, 0x19, 0x3B, 0x6B, 0x6F, 0x75, 0x76, 0x83,
0x90, 0x31, 0x07, 0x86, 0x35, 0xD6, 0xAB, 0xB4,
0x65, 0x07, 0x0A, 0x0A, 0xA3, 0x7A, 0xD7, 0x16,
0xE2, 0xC5, 0x3B, 0xE0, 0x42, 0x5F, 0xFA, 0xEF,
0xE1, 0x2E, 0x40, 0x84, 0x36, 0x66, 0xB1, 0xBA
};

Expand Down Expand Up @@ -655,7 +655,7 @@ public static void VerifyKnownTransform_CFB128_128_NoPadding_4_Fails()
feedbackSize: 128)
);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB128_128_PKCS7_4()
{
Expand All @@ -682,95 +682,107 @@ public static void VerifyKnownTransform_CFB8_128_PKCS7_4()
feedbackSize: 8);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB8_128_NoPadding_0_Extended()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[InlineData(PaddingMode.None)]
[InlineData(PaddingMode.Zeros)]
public static void VerifyKnownTransform_CFB8_128_NoOrZeroPadding_0_Extended(PaddingMode paddingMode)
{
// NIST CAVP AESMMT.ZIP CFB8MMT128.rsp, [ENCRYPT] COUNT=0
// plaintext zero-extended to a full block, cipherBytes extended value
// provided by .NET Framework
TestAesTransformDirectKey(
CipherMode.CFB,
PaddingMode.None,
paddingMode,
key: "c57d699d89df7cfbef71c080a6b10ac3".HexToByteArray(),
iv: "fcb2bc4c006b87483978796a2ae2c42e".HexToByteArray(),
plainBytes: ("61" + "000000000000000000000000000000").HexToByteArray(),
cipherBytes: ("24" + "D89FE413C3D37172D6B577E2F94997").HexToByteArray(),
feedbackSize: 8);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB8_128_NoPadding_9_Extended()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[InlineData(PaddingMode.None)]
[InlineData(PaddingMode.Zeros)]
public static void VerifyKnownTransform_CFB8_128_NoOrZeroPadding_9_Extended(PaddingMode paddingMode)
{
// NIST CAVP AESMMT.ZIP CFB8MMT128.rsp, [ENCRYPT] COUNT=9
// plaintext zero-extended to a full block, cipherBytes extended value
// provided by .NET Framework
TestAesTransformDirectKey(
CipherMode.CFB,
PaddingMode.None,
paddingMode,
key: "3a6f9159263fa6cef2a075caface5817".HexToByteArray(),
iv: "0fc23662b7dbf73827f0c7de321ca36e".HexToByteArray(),
plainBytes: ("87efeb8d559ed3367728" + "000000000000").HexToByteArray(),
cipherBytes: ("8e9c50425614d540ce11" + "7DD85E93D8E0").HexToByteArray(),
feedbackSize: 8);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB8_192_NoPadding_0_Extended()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[InlineData(PaddingMode.None)]
[InlineData(PaddingMode.Zeros)]
public static void VerifyKnownTransform_CFB8_192_NoOrZeroPadding_0_Extended(PaddingMode paddingMode)
{
// NIST CAVP AESMMT.ZIP CFB8MMT192.rsp, [ENCRYPT] COUNT=0
// plaintext zero-extended to a full block, cipherBytes extended value
// provided by .NET Framework
TestAesTransformDirectKey(
CipherMode.CFB,
PaddingMode.None,
paddingMode,
key: "32a1b0e3da368db563d7316b9779d3327e53d9a6d287ed97".HexToByteArray(),
iv: "3dd0e7e21f09d5842f3a699da9b57346".HexToByteArray(),
plainBytes: ("54" + "000000000000000000000000000000").HexToByteArray(),
cipherBytes: ("6d" + "B3F513638A136D73873517AF1A770F").HexToByteArray(),
feedbackSize: 8);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB8_192_NoPadding_9_Extended()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[InlineData(PaddingMode.None)]
[InlineData(PaddingMode.Zeros)]
public static void VerifyKnownTransform_CFB8_192_NoOrZeroPadding_9_Extended(PaddingMode paddingMode)
{
// NIST CAVP AESMMT.ZIP CFB8MMT192.rsp, [ENCRYPT] COUNT=9
// plaintext zero-extended to a full block, cipherBytes extended value
// provided by .NET Framework
TestAesTransformDirectKey(
CipherMode.CFB,
PaddingMode.None,
paddingMode,
key: "537e7bf661fd4024a024613f15b13690f7d0c847c1e18965".HexToByteArray(),
iv: "3a81f9d9d3c155b0caad5d73349476fc".HexToByteArray(),
plainBytes: ("d3d8b9b984adc24237ee" + "000000000000").HexToByteArray(),
cipherBytes: ("3879fea72ac99929e53a" + "39552A575D73").HexToByteArray(),
feedbackSize: 8);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB8_256_NoPadding_0_Extended()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[InlineData(PaddingMode.None)]
[InlineData(PaddingMode.Zeros)]
public static void VerifyKnownTransform_CFB8_256_NoOrZeroPadding_0_Extended(PaddingMode paddingMode)
{
// NIST CAVP AESMMT.ZIP CFB8MMT256.rsp, [ENCRYPT] COUNT=0
// plaintext zero-extended to a full block, cipherBytes extended value
// provided by .NET Framework
TestAesTransformDirectKey(
CipherMode.CFB,
PaddingMode.None,
paddingMode,
key: "34e8091cee09f1bd3ebf1e8f05f51bfbd4899ef2ae006a3a0f7875052cdd46c8".HexToByteArray(),
iv: "43eb4dcc4b04a80216a20e4a09a7abb5".HexToByteArray(),
plainBytes: ("f9" + "000000000000000000000000000000").HexToByteArray(),
cipherBytes: ("28" + "26199F76D20BE53AB4D146CFC6D281").HexToByteArray(),
feedbackSize: 8);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
public static void VerifyKnownTransform_CFB8_256_NoPadding_9_Extended()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindows7))]
[InlineData(PaddingMode.None)]
[InlineData(PaddingMode.Zeros)]
public static void VerifyKnownTransform_CFB8_256_NoOrZeroPadding_9_Extended(PaddingMode paddingMode)
{
// NIST CAVP AESMMT.ZIP CFB8MMT256.rsp, [ENCRYPT] COUNT=9
// plaintext zero-extended to a full block, cipherBytes extended value
// provided by .NET Framework
TestAesTransformDirectKey(
CipherMode.CFB,
PaddingMode.None,
paddingMode,
key: "ebbb4566b5e182e0f072466b0b311df38f9175bc0213a5530bce2ec4d74f400d".HexToByteArray(),
iv: "0956a48e01002c9e16376d6e308dbad1".HexToByteArray(),
plainBytes: ("b0fe25ac8d3d28a2f471" + "000000000000").HexToByteArray(),
Expand Down Expand Up @@ -927,18 +939,28 @@ public static void VerifyKnownTransform_CFB128_256_NoPadding_1_Extended()
feedbackSize: 128);
}

[Fact]
public static void AesZeroPad()
[Theory]
[InlineData(CipherMode.CBC)]
[InlineData(CipherMode.CFB)]
public static void AesZeroPad(CipherMode cipherMode)
{
if (cipherMode == CipherMode.CFB && PlatformDetection.IsWindows7)
{
// Windows 7 does not support CFB.
return;
}

byte[] decryptedBytes;
byte[] expectedAnswer;

using (Aes aes = AesFactory.Create())
{
aes.Mode = cipherMode;
aes.Padding = PaddingMode.Zeros;
aes.FeedbackSize = 128;

int blockBytes = aes.BlockSize / 8;
int missingBytes = blockBytes - (s_multiBlockBytes.Length % blockBytes);
int alignBytes = aes.BlockSize / 8; // Feedback size is same as block size, both are 128 bits
int missingBytes = alignBytes - (s_multiBlockBytes.Length % alignBytes);

// Zero-padding doesn't have enough information to remove the trailing zeroes.
// Therefore we expect the answer of ZeroPad(s_multiBlockBytes).
Expand Down Expand Up @@ -1049,7 +1071,7 @@ private static void RandomKeyRoundtrip(Aes aes)
{
aes.Mode = mode;
aes.Key = key;

if (feedbackSize.HasValue)
{
aes.FeedbackSize = feedbackSize.Value;
Expand Down
Loading

0 comments on commit 2767f44

Please sign in to comment.