public static void InvalidCFBFeedbackSizes(int feedbackSize, bool discoverableInSetter) { using (RC2 rc2 = RC2Factory.Create()) { rc2.GenerateKey(); rc2.Mode = CipherMode.CFB; if (discoverableInSetter) { // there are some key sizes that are invalid for any of the modes, // so the exception is thrown in the setter Assert.Throws <CryptographicException>(() => { rc2.FeedbackSize = feedbackSize; }); } else { rc2.FeedbackSize = feedbackSize; // however, for CFB only few sizes are valid. Those should throw in the // actual RC2 instantiation. Assert.Throws <CryptographicException>(() => rc2.CreateDecryptor()); Assert.Throws <CryptographicException>(() => rc2.CreateEncryptor()); } } }
public static void DecryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) { // AppleCCCryptor does not allow calling Reset on CFB cipher. // this test validates that the behavior is taken into consideration. var input = "896072ab28e5fdfc".HexToByteArray(); var key = "3000000000000000".HexToByteArray(); var iv = "3000000000000000".HexToByteArray(); using (RC2 rc2 = RC2Factory.Create()) { rc2.Mode = cipherMode; rc2.Key = key; rc2.IV = iv; rc2.Padding = PaddingMode.None; if (feedbackSize > 0) { rc2.FeedbackSize = feedbackSize; } using (ICryptoTransform transform = rc2.CreateDecryptor()) { byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); Assert.Equal(output1, output2); } } }
public static void MultipleBlockDecryptTransform(bool blockAlignedOutput) { const string ExpectedOutput = "This is a test"; int outputPadding = blockAlignedOutput ? 0 : 3; byte[] key = "0123456789ABCDEF".HexToByteArray(); byte[] iv = "0123456789ABCDEF".HexToByteArray(); byte[] outputBytes = new byte[iv.Length * 2 + outputPadding]; byte[] input = "DB5400368C7E67FF5F9E1FA99641EB69".HexToByteArray(); int outputOffset = 0; using (RC2 alg = RC2Factory.Create()) using (ICryptoTransform xform = alg.CreateDecryptor(key, iv)) { Assert.Equal(2 * alg.BlockSize, (outputBytes.Length - outputPadding) * 8); outputOffset += xform.TransformBlock(input, 0, input.Length, outputBytes, outputOffset); byte[] overflow = xform.TransformFinalBlock(Array.Empty <byte>(), 0, 0); Buffer.BlockCopy(overflow, 0, outputBytes, outputOffset, overflow.Length); outputOffset += overflow.Length; } string decrypted = Encoding.ASCII.GetString(outputBytes, 0, outputOffset); Assert.Equal(ExpectedOutput, decrypted); }
public static void RC2DefaultCtor() { using (RC2 rc2 = RC2Factory.Create()) { Assert.Equal(128, rc2.KeySize); Assert.Equal(64, rc2.BlockSize); Assert.Equal(CipherMode.CBC, rc2.Mode); Assert.Equal(PaddingMode.PKCS7, rc2.Padding); } }
public static void RC2Blockize() { using (RC2 rc2 = RC2Factory.Create()) { rc2.BlockSize = 64; Assert.Equal(64, rc2.BlockSize); Assert.Throws <CryptographicException>(() => rc2.BlockSize = 64 - 1); Assert.Throws <CryptographicException>(() => rc2.BlockSize = 64 + 1); } }
public static void EcbRoundtrip(byte[] plaintext, byte[] ciphertext, PaddingMode padding) { using (RC2 rc2 = RC2Factory.Create()) { rc2.Key = s_rc2OneShotKey; byte[] encrypted = rc2.EncryptEcb(plaintext, padding); byte[] decrypted = rc2.DecryptEcb(encrypted, padding); if (padding == PaddingMode.Zeros) { Assert.Equal(plaintext, decrypted[..plaintext.Length]);
public static void RC2EffectiveKeySize() { using (RC2 rc2 = RC2Factory.Create()) { rc2.KeySize = 40; Assert.Equal(40, rc2.EffectiveKeySize); rc2.EffectiveKeySize = 40; // KeySize must equal EffectiveKeySize rc2.KeySize = 48; Assert.Throws <CryptographicUnexpectedOperationException>(() => rc2.EffectiveKeySize = 48 + 8); Assert.Throws <CryptographicUnexpectedOperationException>(() => rc2.EffectiveKeySize = 48 - 8); Assert.Throws <CryptographicUnexpectedOperationException>(() => rc2.EffectiveKeySize = 0); } }
public static void RC2ExplicitEncryptorDecryptor_NoIV() { using (RC2 alg = RC2Factory.Create()) { alg.Padding = PaddingMode.PKCS7; alg.Mode = CipherMode.ECB; using (ICryptoTransform encryptor = alg.CreateEncryptor(s_randomKey_64.HexToByteArray(), null)) { byte[] plainText1 = s_multiBlockString.HexToByteArray(); byte[] cipher1 = encryptor.Transform(plainText1); byte[] expectedCipher1 = ( "F6DF2E83811D6CB0C8A5830069D16F6A51C985D7003852539051FABC3C6EA7CF46BD3DBD5527003A789B76CBE4D40A73" + "620F04ED9F0AA1AEC7FEC90E7934F69E0568F6DF1F38B2198821D0A771D68A3F8220C8822E387721AEB21E183555CE07").HexToByteArray(); Assert.Equal <byte>(expectedCipher1, cipher1); } } }
public static void RC2ExplicitEncryptorDecryptor_WithIV() { using (RC2 alg = RC2Factory.Create()) { alg.Padding = PaddingMode.PKCS7; alg.Mode = CipherMode.CBC; using (ICryptoTransform encryptor = alg.CreateEncryptor(s_randomKey_64.HexToByteArray(), s_randomIv_64.HexToByteArray())) { byte[] plainText1 = s_multiBlockString.HexToByteArray(); byte[] cipher1 = encryptor.Transform(plainText1); byte[] expectedCipher1 = ( "85B5D998F35ECD98DB886798170F64BA2DBA4FE902791CDE900EEB0B35728FEE35FB6CADC41DF67FBB691B45D92B876A" + "13FD18229E5ACB797D21D7B257520910360E00FEECDE3433FDC6F15233AE6B5CAC01289AC8B57A9A6B5DA734C2E7E733").HexToByteArray(); Assert.Equal <byte>(expectedCipher1, cipher1); } } }
public static void TransformWithTooShortOutputBuffer(bool encrypt, bool blockAlignedOutput) { using (RC2 alg = RC2Factory.Create()) using (ICryptoTransform xform = encrypt ? alg.CreateEncryptor() : alg.CreateDecryptor()) { // 1 block, plus maybe three bytes int outputPadding = blockAlignedOutput ? 0 : 3; byte[] output = new byte[alg.BlockSize / 8 + outputPadding]; // 3 blocks of 0x00 byte[] input = new byte[3 * (alg.BlockSize / 8)]; Assert.Throws <ArgumentOutOfRangeException>( () => xform.TransformBlock(input, 0, input.Length, output, 0)); Assert.Equal(new byte[output.Length], output); } }
public static void RC2RoundTrip(CipherMode cipherMode, PaddingMode paddingMode, string key, string iv, string textHex, string expectedDecrypted, string expectedEncrypted) { byte[] expectedDecryptedBytes = expectedDecrypted == null?textHex.HexToByteArray() : expectedDecrypted.HexToByteArray(); byte[] expectedEncryptedBytes = expectedEncrypted.HexToByteArray(); byte[] keyBytes = key.HexToByteArray(); using (RC2 alg = RC2Factory.Create()) { alg.Key = keyBytes; alg.Padding = paddingMode; alg.Mode = cipherMode; if (iv != null) { alg.IV = iv.HexToByteArray(); } byte[] cipher = alg.Encrypt(textHex.HexToByteArray()); Assert.Equal <byte>(expectedEncryptedBytes, cipher); byte[] decrypted = alg.Decrypt(cipher); Assert.Equal <byte>(expectedDecryptedBytes, decrypted); if (RC2Factory.OneShotSupported) { byte[] oneShotEncrypt = cipherMode switch { CipherMode.ECB => alg.EncryptEcb(textHex.HexToByteArray(), paddingMode), CipherMode.CBC => alg.EncryptCbc(textHex.HexToByteArray(), iv.HexToByteArray(), paddingMode), _ => throw new NotImplementedException(), }; Assert.Equal(expectedEncryptedBytes, oneShotEncrypt); byte[] oneShotDecrypt = cipherMode switch { CipherMode.ECB => alg.DecryptEcb(cipher, paddingMode), CipherMode.CBC => alg.DecryptCbc(cipher, iv.HexToByteArray(), paddingMode), _ => throw new NotImplementedException(), }; Assert.Equal(expectedDecryptedBytes, oneShotDecrypt); } } }
public static void RC2ReuseEncryptorDecryptor() { using (RC2 alg = RC2Factory.Create()) { alg.Key = s_randomKey_64.HexToByteArray(); alg.IV = s_randomIv_64.HexToByteArray(); alg.Padding = PaddingMode.PKCS7; alg.Mode = CipherMode.CBC; using (ICryptoTransform encryptor = alg.CreateEncryptor()) using (ICryptoTransform decryptor = alg.CreateDecryptor()) { for (int i = 0; i < 2; i++) { byte[] plainText1 = s_multiBlockString.HexToByteArray(); byte[] cipher1 = encryptor.Transform(plainText1); byte[] expectedCipher1 = ( "85B5D998F35ECD98DB886798170F64BA2DBA4FE902791CDE900EEB0B35728FEE35FB6CADC41DF67FBB691B45D92B876A" + "13FD18229E5ACB797D21D7B257520910360E00FEECDE3433FDC6F15233AE6B5CAC01289AC8B57A9A6B5DA734C2E7E733").HexToByteArray(); Assert.Equal <byte>(expectedCipher1, cipher1); byte[] decrypted1 = decryptor.Transform(cipher1); byte[] expectedDecrypted1 = s_multiBlockString.HexToByteArray(); Assert.Equal <byte>(expectedDecrypted1, decrypted1); byte[] plainText2 = s_multiBlockString_8.HexToByteArray(); byte[] cipher2 = encryptor.Transform(plainText2); byte[] expectedCipher2 = ( "85B5D998F35ECD98DB886798170F64BA2DBA4FE902791CDE900EEB0B35728FEE35FB6CADC41DF67F6056044F15B5C7ED" + "4FAB086053D7DC458C206145AE9655F1590C590FBDE76365FA488CADBCDA67B325A35E7CCBC1B9A15E5EBE2879C7AEC2").HexToByteArray(); Assert.Equal <byte>(expectedCipher2, cipher2); byte[] decrypted2 = decryptor.Transform(cipher2); byte[] expectedDecrypted2 = s_multiBlockString_8.HexToByteArray(); Assert.Equal <byte>(expectedDecrypted2, decrypted2); } } } }
public static void EncryptWithLargeOutputBuffer(bool blockAlignedOutput) { using (RC2 alg = RC2Factory.Create()) using (ICryptoTransform xform = alg.CreateEncryptor()) { // 8 blocks, plus maybe three bytes int outputPadding = blockAlignedOutput ? 0 : 3; byte[] output = new byte[alg.BlockSize + outputPadding]; // 2 blocks of 0x00 byte[] input = new byte[alg.BlockSize / 4]; int outputOffset = 0; outputOffset += xform.TransformBlock(input, 0, input.Length, output, outputOffset); byte[] overflow = xform.TransformFinalBlock(Array.Empty <byte>(), 0, 0); Buffer.BlockCopy(overflow, 0, output, outputOffset, overflow.Length); outputOffset += overflow.Length; Assert.Equal(3 * (alg.BlockSize / 8), outputOffset); string outputAsHex = output.ByteArrayToHex(); Assert.NotEqual(new string('0', outputOffset * 2), outputAsHex.Substring(0, outputOffset * 2)); Assert.Equal(new string('0', (output.Length - outputOffset) * 2), outputAsHex.Substring(outputOffset * 2)); } }
public static void RC2RoundTrip(CipherMode cipherMode, PaddingMode paddingMode, string key, string iv, string textHex, string expectedDecrypted, string expectedEncrypted) { byte[] expectedDecryptedBytes = expectedDecrypted == null?textHex.HexToByteArray() : expectedDecrypted.HexToByteArray(); byte[] expectedEncryptedBytes = expectedEncrypted.HexToByteArray(); byte[] keyBytes = key.HexToByteArray(); using (RC2 alg = RC2Factory.Create()) { alg.Key = keyBytes; alg.Padding = paddingMode; alg.Mode = cipherMode; if (iv != null) { alg.IV = iv.HexToByteArray(); } byte[] cipher = alg.Encrypt(textHex.HexToByteArray()); Assert.Equal <byte>(expectedEncryptedBytes, cipher); byte[] decrypted = alg.Decrypt(cipher); Assert.Equal <byte>(expectedDecryptedBytes, decrypted); } }
public static void EncryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) { // AppleCCCryptor does not allow calling Reset on CFB cipher. // this test validates that the behavior is taken into consideration. var input = "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(); using (RC2 rc2 = RC2Factory.Create()) { rc2.Mode = cipherMode; if (feedbackSize > 0) { rc2.FeedbackSize = feedbackSize; } using (ICryptoTransform transform = rc2.CreateEncryptor()) { byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); Assert.Equal(output1, output2); } } }
protected override SymmetricAlgorithm CreateAlgorithm() => RC2Factory.Create();