Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Basic 3DES functionality
  • Loading branch information
vcsjones authored Jul 9, 2021
commit 07ab4705569b39964906573d7418a0b8ef34132e
Original file line number Diff line number Diff line change
Expand Up @@ -28,68 +28,68 @@ public class TripleDESCipherOneShotTests : SymmetricOneShotBase

[Theory]
[MemberData(nameof(TestCases))]
public void OneShotRoundtrip(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
OneShotRoundtripTest(plaintext, ciphertext, padding, mode);
public void OneShotRoundtrip(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
OneShotRoundtripTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryDecryptOneShot_DestinationTooSmall(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryDecryptOneShot_DestinationTooSmallTest(plaintext, ciphertext, padding, mode);
public void TryDecryptOneShot_DestinationTooSmall(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryDecryptOneShot_DestinationTooSmallTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryEncryptOneShot_DestinationTooSmall(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryEncryptOneShot_DestinationTooSmallTest(plaintext, ciphertext, padding, mode);
public void TryEncryptOneShot_DestinationTooSmall(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryEncryptOneShot_DestinationTooSmallTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryDecryptOneShot_DestinationJustRight(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryDecryptOneShot_DestinationJustRightTest(plaintext, ciphertext, padding, mode);
public void TryDecryptOneShot_DestinationJustRight(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryDecryptOneShot_DestinationJustRightTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryEncryptOneShot_DestinationJustRight(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryEncryptOneShot_DestinationJustRightTest(plaintext, ciphertext, padding, mode);
public void TryEncryptOneShot_DestinationJustRight(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryEncryptOneShot_DestinationJustRightTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryDecryptOneShot_DestinationLarger(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryDecryptOneShot_DestinationLargerTest(plaintext, ciphertext, padding, mode);
public void TryDecryptOneShot_DestinationLarger(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryDecryptOneShot_DestinationLargerTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryEncryptOneShot_DestinationLarger(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryEncryptOneShot_DestinationLargerTest(plaintext, ciphertext, padding, mode);
public void TryEncryptOneShot_DestinationLarger(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryEncryptOneShot_DestinationLargerTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryDecryptOneShot_Overlaps(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryDecryptOneShot_OverlapsTest(plaintext, ciphertext, padding, mode);
public void TryDecryptOneShot_Overlaps(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryDecryptOneShot_OverlapsTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void TryEncryptOneShot_Overlaps(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
TryEncryptOneShot_OverlapsTest(plaintext, ciphertext, padding, mode);
public void TryEncryptOneShot_Overlaps(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
TryEncryptOneShot_OverlapsTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void DecryptOneShot_Span(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
DecryptOneShot_SpanTest(plaintext, ciphertext, padding, mode);
public void DecryptOneShot_Span(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
DecryptOneShot_SpanTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void EncryptOneShot_Span(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
EncryptOneShot_SpanTest(plaintext, ciphertext, padding, mode);
public void EncryptOneShot_Span(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
EncryptOneShot_SpanTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void DecryptOneShot_Array(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
DecryptOneShot_ArrayTest(plaintext, ciphertext, padding, mode);
public void DecryptOneShot_Array(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
DecryptOneShot_ArrayTest(plaintext, ciphertext, padding, mode, feedbackSize);

[Theory]
[MemberData(nameof(TestCases))]
public void EncryptOneShot_Array(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode) =>
EncryptOneShot_ArrayTest(plaintext, ciphertext, padding, mode);
public void EncryptOneShot_Array(byte[] plaintext, byte[] ciphertext, PaddingMode padding, CipherMode mode, int feedbackSize = 0) =>
EncryptOneShot_ArrayTest(plaintext, ciphertext, padding, mode, feedbackSize);

public static IEnumerable<object[]> TestCases
{
Expand Down Expand Up @@ -557,6 +557,28 @@ public static IEnumerable<object[]> TestCases
PaddingMode.PKCS7,
CipherMode.ECB,
};

yield return new object[]
{
// plaintext
new byte[]
{
0x50, 0x68, 0x12, 0xA4, 0x5F, 0x08, 0xC8, 0x89,
0xB9, 0x7F, 0x59, 0x80, 0x03, 0x8B, 0x83, 0x59,
},

// ciphertext
new byte[]
{
0x46, 0x85, 0x45, 0x43, 0x3E, 0xD9, 0x40, 0xAF,
0x16, 0xBE, 0xC5, 0xEF, 0xD9, 0x12, 0xFE, 0x07,
0x66,
},

PaddingMode.PKCS7,
CipherMode.CFB,
8
};
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,58 @@ protected override bool TryDecryptCbcCore(
}
}

protected override bool TryDecryptCfbCore(
ReadOnlySpan<byte> ciphertext,
ReadOnlySpan<byte> iv,
Span<byte> destination,
PaddingMode paddingMode,
int feedbackSizeInBits,
out int bytesWritten)
{
ValidateCFBFeedbackSize(feedbackSizeInBits);

UniversalCryptoTransform transform = CreateTransformCore(
CipherMode.CFB,
paddingMode,
Key,
iv: iv.ToArray(),
blockSize: BlockSize / BitsPerByte,
paddingSize: feedbackSizeInBits / BitsPerByte,
feedbackSizeInBits / BitsPerByte,
encrypting: false);

using (transform)
{
return transform.TransformOneShot(ciphertext, destination, out bytesWritten);
}
}

protected override bool TryEncryptCfbCore(
ReadOnlySpan<byte> plaintext,
ReadOnlySpan<byte> iv,
Span<byte> destination,
PaddingMode paddingMode,
int feedbackSizeInBits,
out int bytesWritten)
{
ValidateCFBFeedbackSize(feedbackSizeInBits);

UniversalCryptoTransform transform = CreateTransformCore(
CipherMode.CFB,
paddingMode,
Key,
iv: iv.ToArray(),
blockSize: BlockSize / BitsPerByte,
paddingSize: feedbackSizeInBits / BitsPerByte,
feedbackSizeInBits / BitsPerByte,
encrypting: true);

using (transform)
{
return transform.TransformOneShot(plaintext, destination, out bytesWritten);
}
}

private static void ValidateCFBFeedbackSize(int feedback)
{
// only 8bits/64bits feedback would be valid.
Expand Down