internal SymmetricAlgorithmVerifier(SymmetricAlgorithm verificationAlgorithm, SymmetricEncryptionState encryptionState, Predicate <CryptographyLockContext <SymmetricAlgorithm> > lockCheckCallback, object lockCheckParameter) : base(verificationAlgorithm, lockCheckCallback, lockCheckParameter) { Debug.Assert(encryptionState != null, "encryptionState != null"); m_encryptionState = encryptionState; }
protected override void OnDecryptorCreated(byte[] key, byte[] iv) { base.OnDecryptorCreated(key, iv); using (SymmetricEncryptionState decryptionState = new SymmetricEncryptionState(key, iv, WrappedAlgorithm)) { m_encryptionState.VerifyDecryptionState(decryptionState); } }
/// <summary> /// Create a SymmetricAlgorithm which verifies the decryption operations done on it have state /// which matches captured encryption state. This overload does not monitor for thread safe /// access to the object. /// </summary> public static SymmetricAlgorithm EnableDecryptionVerification(this SymmetricAlgorithm loggedAlgorithm, SymmetricEncryptionState encryptionState) { if (encryptionState == null) { throw new ArgumentNullException("encryptionState"); } return(loggedAlgorithm.EnableDecryptionVerification(encryptionState, new SymmetricAlgorithmDiagnosticOptions() { CheckThreadSafety = false })); }
/// <summary> /// Verify that the input decryption state matches our encryption state, throwing an error if /// they do not. /// </summary> internal override void VerifyDecryptionState(SymmetricEncryptionState decryptionState) { Debug.Assert(decryptionState != null, "decryptionState != null"); // All of the symmetric algorithm comparisons need to match base.VerifyDecryptionState(decryptionState); AuthenticatedSymmetricEncryptionState authenticatedDecryptionState = decryptionState as AuthenticatedSymmetricEncryptionState; // The base verify decryption state should have caught an algorithm mismatch, which would be the // only way that we could be encrypting with an authenticated symmetric algortihm but decrypting // with an unauthenticated algorithm. Debug.Assert(authenticatedDecryptionState != null, "authenticatedDecryptionState != null"); // If we have authenticated data, make sure it matches if (m_authenticatedData != null) { // If we have authenticated data, then the decryption state also needs to have authenticated // data, and that data needs to match. if (authenticatedDecryptionState.m_authenticatedData == null || !CompareBytes(m_authenticatedData, authenticatedDecryptionState.m_authenticatedData)) { ThrowDiagnosticException(Resources.AuthenticatedDataMismatch, m_authenticatedData.Length * 8, HexString(m_authenticatedData), authenticatedDecryptionState.m_authenticatedData != null ? authenticatedDecryptionState.m_authenticatedData.Length * 8 : 0, HexString(authenticatedDecryptionState.m_authenticatedData)); } } else if (authenticatedDecryptionState.m_authenticatedData != null) { // We had no authenticated data during encryption, but we have some during decryption, so we // have a mismatch. ThrowDiagnosticException(Resources.AuthenticatedDataMismatch, 0, HexString(null), authenticatedDecryptionState.m_authenticatedData.Length * 8, HexString(authenticatedDecryptionState.m_authenticatedData)); } // Make sure the CNG chaining modes match if (m_cngChainingMode != authenticatedDecryptionState.m_cngChainingMode) { ThrowDiagnosticException(Resources.CngChainingModeMismatch, m_cngChainingMode, authenticatedDecryptionState.m_cngChainingMode); } }
protected override void OnEncryptorCreated(byte[] key, byte[] iv) { base.OnEncryptorCreated(key, iv); // An encryptor is being created, which means that all of the encryption parameters must be set at // this point. Capture them so that they can be extracted for later verification. if (m_lastCapturedEncryptionState != null) { m_lastCapturedEncryptionState.Dispose(); } m_lastCapturedEncryptionState = new SymmetricEncryptionState(key, iv, WrappedAlgorithm); }
/// <summary> /// Create a SymmetricAlgorithm which verifies the decryption operations done on it have state /// which matches captured encryption state. /// </summary> public static SymmetricAlgorithm EnableDecryptionVerification(this SymmetricAlgorithm loggedAlgorithm, SymmetricEncryptionState encryptionState, SymmetricAlgorithmDiagnosticOptions options) { if (encryptionState == null) { throw new ArgumentNullException("encryptionState"); } if (options == null) { throw new ArgumentNullException("options"); } #if !FXONLY_BUILD AuthenticatedSymmetricAlgorithm authenticatedLoggedAlgorithm = loggedAlgorithm as AuthenticatedSymmetricAlgorithm; if (authenticatedLoggedAlgorithm != null) { AuthenticatedSymmetricEncryptionState authenticatedEncryptionState = encryptionState as AuthenticatedSymmetricEncryptionState; if (authenticatedEncryptionState == null) { throw new ArgumentException(Resources.NeedAuthenticatedEncryptionState, "encryptionState"); } return(new AuthenticatedSymmetricAlgorithmVerifier(authenticatedLoggedAlgorithm, authenticatedEncryptionState, options.CheckThreadSafety ? options.LockCheckCallback : null, options.CheckThreadSafety ? options.LockCheckParameter : null)); } else #endif // !FXONLY_BUILD { return(new SymmetricAlgorithmVerifier(loggedAlgorithm, encryptionState, options.CheckThreadSafety ? options.LockCheckCallback : null, options.CheckThreadSafety ? options.LockCheckParameter : null)); } }
/// <summary> /// Perform a deep copy of another symmetric encryption state /// </summary> protected SymmetricEncryptionState(SymmetricEncryptionState other) { if (other == null) { throw new ArgumentNullException("other"); } m_baseAlgorithmType = other.m_baseAlgorithmType; m_compareCipherModes = other.m_compareCipherModes; m_blockSize = other.m_blockSize; m_cipherMode = other.m_cipherMode; m_feedbackSize = other.m_feedbackSize; m_paddingMode = other.m_paddingMode; m_algorithm = other.m_algorithm; m_iv = new byte[other.m_iv.Length]; Array.Copy(other.m_iv, m_iv, m_iv.Length); m_key = new byte[other.m_key.Length]; Array.Copy(other.m_key, m_key, m_key.Length); }
/// <summary> /// Verify that the input decryption state matches our encryption state, throwing an error if /// they do not. /// </summary> internal virtual void VerifyDecryptionState(SymmetricEncryptionState decryptionState) { Debug.Assert(decryptionState != null, "decryptionState != null"); // Make sure the algorithms match if (m_algorithm != decryptionState.m_algorithm) { ThrowDiagnosticException(Properties.Resources.AlgorithmMismatch, m_algorithm, decryptionState.m_algorithm); } // Check the block sizes if (m_blockSize != decryptionState.m_blockSize) { ThrowDiagnosticException(Properties.Resources.BlockSizeMismatch, m_blockSize, decryptionState.m_blockSize); } // Check the ciper modes if (m_compareCipherModes && m_cipherMode != decryptionState.m_cipherMode) { ThrowDiagnosticException(Properties.Resources.CipherModeMismatch, m_cipherMode, decryptionState.m_cipherMode); } // Check the feedback if (CipherModeUsesFeedback(m_cipherMode) && m_feedbackSize != decryptionState.m_feedbackSize) { ThrowDiagnosticException(Properties.Resources.FeedbackSizeMismatch, m_feedbackSize, decryptionState.m_feedbackSize); } // Check the IVs if (!CompareBytes(m_iv, decryptionState.m_iv)) { ThrowDiagnosticException(Properties.Resources.IVMismatch, m_iv.Length * 8, HexString(m_iv), decryptionState.m_iv.Length * 8, HexString(decryptionState.m_iv)); } // Check the keys if (!CompareBytes(m_key, decryptionState.m_key)) { ThrowDiagnosticException(Properties.Resources.KeyMismatch, m_key.Length * 8, HexString(m_key), decryptionState.m_key.Length * 8, HexString(decryptionState.m_key)); } // Check the padding modes if (m_paddingMode != decryptionState.m_paddingMode) { ThrowDiagnosticException(Properties.Resources.PaddingModeMismatch, m_paddingMode, decryptionState.m_paddingMode); } }