public void AuthenticatedSymmetricAlgorithmCreateTest() { // AuthenticatedAesCng should be the default implementation using (AuthenticatedSymmetricAlgorithm alg = AuthenticatedSymmetricAlgorithm.Create()) { Assert.IsInstanceOfType(alg, typeof(AuthenticatedAesCng)); } using (AuthenticatedSymmetricAlgorithm alg = AuthenticatedSymmetricAlgorithm.Create("AuthenticatedAesCng")) { Assert.IsInstanceOfType(alg, typeof(AuthenticatedAesCng)); } Assert.IsNull(AuthenticatedAes.Create("AuthenticatedAesDoesntExist")); Assert.IsNull(AuthenticatedAes.Create("AesCng")); }
public void AuthenticatedSymmetricAlgorithmValidTagSizeTest() { using (AuthenticatedSymmetricAlgorithm alg = AuthenticatedSymmetricAlgorithm.Create()) { foreach (KeySizes tagSizeRange in alg.LegalTagSizes) { Assert.IsTrue(alg.ValidTagSize(tagSizeRange.MinSize)); Assert.IsTrue(alg.ValidTagSize(tagSizeRange.MaxSize)); if (tagSizeRange.MinSize != tagSizeRange.MaxSize) { for (int tagSize = tagSizeRange.MinSize; tagSize < tagSizeRange.MaxSize; tagSize += tagSizeRange.SkipSize) { Assert.IsTrue(alg.ValidTagSize(tagSize)); } } } Assert.IsFalse(alg.ValidTagSize(0)); Assert.IsFalse(alg.ValidTagSize(Int32.MaxValue)); } }
/// <summary> /// Utility to encapsulate round-tripping ciphertext /// </summary> private static bool RoundTripHelper <TEncryptionAlgorithm, TDecryptionAlgorithm>(Action <TEncryptionAlgorithm> encryptionSetup, Action <TDecryptionAlgorithm> decryptionSetup) where TEncryptionAlgorithm : AuthenticatedSymmetricAlgorithm, new() where TDecryptionAlgorithm : AuthenticatedSymmetricAlgorithm, new() { // Encryption parameters byte[] key = null; byte[] iv = null; byte[] authenticatedData = Encoding.UTF8.GetBytes("Additional authenticated data"); // Round tripping data byte[] plainText = Encoding.UTF8.GetBytes("Authenticated round trip message"); byte[] cipherText = null; byte[] tag = null; AuthenticatedSymmetricEncryptionState encryptionState = null; AuthenticatedSymmetricAlgorithm encryptionObject = null; try { // Setup the encryption algorithm encryptionObject = new TEncryptionAlgorithm(); encryptionObject.AuthenticatedData = authenticatedData; encryptionObject.IV = new byte[] { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; encryptionSetup(encryptionObject as TEncryptionAlgorithm); encryptionObject = encryptionObject.EnableLogging(); // Encrypt the data using (MemoryStream ms = new MemoryStream()) using (IAuthenticatedCryptoTransform encryptor = encryptionObject.CreateAuthenticatedEncryptor()) using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { cs.Write(plainText, 0, plainText.Length); cs.FlushFinalBlock(); cipherText = ms.ToArray(); tag = encryptor.GetTag(); } // Save the encryption parameters key = encryptionObject.Key; iv = encryptionObject.IV; authenticatedData = encryptionObject.AuthenticatedData; encryptionState = encryptionObject.GetLastEncryptionState(); } finally { if (encryptionObject != null) { (encryptionObject as IDisposable).Dispose(); } } byte[] roundTrip = null; // Now verify the data AuthenticatedSymmetricAlgorithm decryptionObject = null; try { decryptionObject = new TDecryptionAlgorithm(); decryptionObject.Key = key; decryptionObject.IV = iv; decryptionObject.AuthenticatedData = authenticatedData; decryptionObject.Tag = tag; decryptionSetup(decryptionObject as TDecryptionAlgorithm); decryptionObject = decryptionObject.EnableDecryptionVerification(encryptionState); using (MemoryStream ms = new MemoryStream()) using (CryptoStream cs = new CryptoStream(ms, decryptionObject.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherText, 0, cipherText.Length); cs.FlushFinalBlock(); roundTrip = ms.ToArray(); } } finally { if (decryptionObject != null) { (decryptionObject as IDisposable).Dispose(); } } if (roundTrip.Length != plainText.Length) { return(false); } for (int i = 0; i < roundTrip.Length; ++i) { if (roundTrip[i] != plainText[i]) { return(false); } } return(true); }
public void AuthenticatedSymmetricAlgorithmVerifierNegativeThreadingTest() { // Synchronization state object lockCheckParameter = new object(); AuthenticatedSymmetricAlgorithm encryptorInstance = null; bool lockChecked = false; SymmetricAlgorithmDiagnosticOptions diagnosticOptions = new SymmetricAlgorithmDiagnosticOptions { CheckThreadSafety = true, LockCheckParameter = lockCheckParameter, LockCheckCallback = delegate(CryptographyLockContext <SymmetricAlgorithm> lockCheck) { Assert.AreSame(lockCheck.Parameter, lockCheckParameter, "Unexpected lock check parameter"); Assert.AreSame(lockCheck.Algorithm, encryptorInstance, "Unexpected algorithm check parameter"); lockChecked = true; return(false); } }; // Encryption state bool encryptionSucceeded = true; Exception encryptionException = null; try { encryptorInstance = new AuthenticatedAesCng(); AuthenticatedSymmetricAlgorithm encryptor = encryptorInstance.EnableLogging(diagnosticOptions); // Thread to do the encryption Thread encryptionThread = new Thread(delegate() { try { using (MemoryStream ms = new MemoryStream()) using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) { byte[] plainText = Encoding.UTF8.GetBytes("Secret round trip message"); cs.Write(plainText, 0, plainText.Length); cs.FlushFinalBlock(); } encryptionSucceeded = true; } catch (Exception e) { encryptionException = e; encryptionSucceeded = false; } }); encryptionThread.Start(); encryptionThread.Join(); } finally { if (encryptorInstance != null) { (encryptorInstance as IDisposable).Dispose(); } } // Verify that our lock check was called, that we failed encryption, and that we got the correct exception Assert.IsTrue(lockChecked, "Lock check callback was not performed"); Assert.IsFalse(encryptionSucceeded, "Encryption should not have succeeded"); Assert.IsInstanceOfType(encryptionException, typeof(CryptographicDiagnosticException), "Did not get expected exception"); }