/// <summary> /// Creates an instance of SqlAes256CbcAlgorithm class with a given key /// </summary> /// <param name="encryptionKey">Root key</param> /// <param name="encryptionType">Encryption Type. Expected values are either Determinitic or Randomized.</param> /// <param name="encryptionAlgorithm">Encryption Algorithm.</param> /// <returns></returns> internal override SqlClientEncryptionAlgorithm Create(SqlClientSymmetricKey encryptionKey, SqlClientEncryptionType encryptionType, string encryptionAlgorithm) { // Callers should have validated the encryption algorithm and the encryption key Debug.Assert(encryptionKey != null); Debug.Assert(string.Equals(encryptionAlgorithm, SqlAes256CbcAlgorithm.AlgorithmName, StringComparison.OrdinalIgnoreCase) == true); // Validate encryption type if (!((encryptionType == SqlClientEncryptionType.Deterministic) || (encryptionType == SqlClientEncryptionType.Randomized))) { throw SQL.InvalidEncryptionType(SqlAes256CbcAlgorithm.AlgorithmName, encryptionType, SqlClientEncryptionType.Deterministic, SqlClientEncryptionType.Randomized); } // Get the cached encryption algorithm if one exists or create a new one, add it to cache and use it // // For now, we only have one version. In future, we may need to parse the algorithm names to derive the version byte. const byte algorithmVersion = 0x1; StringBuilder algorithmKeyBuilder = new StringBuilder(Convert.ToBase64String(encryptionKey.RootKey), SqlSecurityUtility.GetBase64LengthFromByteLength(encryptionKey.RootKey.Length) + 4/*separators, type and version*/); #if DEBUG int capacity = algorithmKeyBuilder.Capacity; #endif //DEBUG algorithmKeyBuilder.Append(":"); algorithmKeyBuilder.Append((int)encryptionType); algorithmKeyBuilder.Append(":"); algorithmKeyBuilder.Append(algorithmVersion); string algorithmKey = algorithmKeyBuilder.ToString(); #if DEBUG Debug.Assert(algorithmKey.Length <= capacity, "We needed to allocate a larger array"); #endif //DEBUG SqlAes256CbcAlgorithm aesAlgorithm; if (!_encryptionAlgorithms.TryGetValue(algorithmKey, out aesAlgorithm)) { SqlAeadAes256CbcHmac256EncryptionKey encryptedKey = new SqlAeadAes256CbcHmac256EncryptionKey(encryptionKey.RootKey, SqlAes256CbcAlgorithm.AlgorithmName); aesAlgorithm = new SqlAes256CbcAlgorithm(encryptedKey, encryptionType, algorithmVersion); // In case multiple threads reach here at the same time, the first one adds the value // the second one will be a no-op, the allocated memory will be claimed by Garbage Collector. _encryptionAlgorithms.TryAdd(algorithmKey, aesAlgorithm); } return aesAlgorithm; }
/// <summary> /// Creates an encrytion algorithm with a given key. /// </summary> /// <param name="rootKey">encryption key that should be passed to the encryption algorithm to be created</param> /// <param name="encryptionType">Encryption Type, some algorithms will need this</param> /// <param name="encryptionAlgorithm">Encryption algorithm name. Needed for extracting version bits</param> /// <returns>Return a newly created SqlClientEncryptionAlgorithm instance</returns> internal abstract SqlClientEncryptionAlgorithm Create(SqlClientSymmetricKey encryptionKey, SqlClientEncryptionType encryptionType, string encryptionAlgorithm);
/// <summary> /// Initializes a new instance of SqlAeadAes256CbcHmac256Algorithm algorithm with a given key and encryption type /// </summary> /// <param name="encryptionKey"> /// Root encryption key from which three other keys will be derived /// </param> /// <param name="encryptionType">Encryption Type, accepted values are Deterministic and Randomized. /// For Deterministic encryption, a synthetic IV will be genenrated during encryption /// For Randomized encryption, a random IV will be generated during encryption. /// </param> /// <param name="algorithmVersion"> /// Algorithm version /// </param> internal SqlAeadAes256CbcHmac256Algorithm(SqlAeadAes256CbcHmac256EncryptionKey encryptionKey, SqlClientEncryptionType encryptionType, byte algorithmVersion) { _columnEncryptionKey = encryptionKey; _algorithmVersion = algorithmVersion; _version[0] = algorithmVersion; Debug.Assert(null != encryptionKey, "Null encryption key detected in AeadAes256CbcHmac256 algorithm"); Debug.Assert(0x01 == algorithmVersion, "Unknown algorithm version passed to AeadAes256CbcHmac256"); // Validate encryption type for this algorithm // This algorithm can only provide randomized or deterministic encryption types. if (encryptionType == SqlClientEncryptionType.Deterministic) { _isDeterministic = true; } else { Debug.Assert(SqlClientEncryptionType.Randomized == encryptionType, "Invalid Encryption Type detected in SqlAeadAes256CbcHmac256Algorithm, this should've been caught in factory class"); } _cryptoProviderPool = new ConcurrentQueue <AesCryptoServiceProvider>(); }
/// <summary> /// Creates an instance of SqlAes256CbcAlgorithm class with a given key /// </summary> /// <param name="encryptionKey">Root key</param> /// <param name="encryptionType">Encryption Type. Expected values are either Determinitic or Randomized.</param> /// <param name="encryptionAlgorithm">Encryption Algorithm.</param> /// <returns></returns> internal override SqlClientEncryptionAlgorithm Create(SqlClientSymmetricKey encryptionKey, SqlClientEncryptionType encryptionType, string encryptionAlgorithm) { // Callers should have validated the encryption algorithm and the encryption key Debug.Assert(encryptionKey != null); Debug.Assert(string.Equals(encryptionAlgorithm, SqlAes256CbcAlgorithm.AlgorithmName, StringComparison.OrdinalIgnoreCase) == true); // Validate encryption type if (!((encryptionType == SqlClientEncryptionType.Deterministic) || (encryptionType == SqlClientEncryptionType.Randomized))) { throw SQL.InvalidEncryptionType(SqlAes256CbcAlgorithm.AlgorithmName, encryptionType, SqlClientEncryptionType.Deterministic, SqlClientEncryptionType.Randomized); } // Get the cached encryption algorithm if one exists or create a new one, add it to cache and use it // // For now, we only have one version. In future, we may need to parse the algorithm names to derive the version byte. const byte algorithmVersion = 0x1; StringBuilder algorithmKeyBuilder = new StringBuilder(Convert.ToBase64String(encryptionKey.RootKey), SqlSecurityUtility.GetBase64LengthFromByteLength(encryptionKey.RootKey.Length) + 4 /*separators, type and version*/); #if DEBUG int capacity = algorithmKeyBuilder.Capacity; #endif //DEBUG algorithmKeyBuilder.Append(":"); algorithmKeyBuilder.Append((int)encryptionType); algorithmKeyBuilder.Append(":"); algorithmKeyBuilder.Append(algorithmVersion); string algorithmKey = algorithmKeyBuilder.ToString(); #if DEBUG Debug.Assert(algorithmKey.Length <= capacity, "We needed to allocate a larger array"); #endif //DEBUG SqlAes256CbcAlgorithm aesAlgorithm; if (!_encryptionAlgorithms.TryGetValue(algorithmKey, out aesAlgorithm)) { SqlAeadAes256CbcHmac256EncryptionKey encryptedKey = new SqlAeadAes256CbcHmac256EncryptionKey(encryptionKey.RootKey, SqlAes256CbcAlgorithm.AlgorithmName); aesAlgorithm = new SqlAes256CbcAlgorithm(encryptedKey, encryptionType, algorithmVersion); // In case multiple threads reach here at the same time, the first one adds the value // the second one will be a no-op, the allocated memory will be claimed by Garbage Collector. _encryptionAlgorithms.TryAdd(algorithmKey, aesAlgorithm); } return(aesAlgorithm); }
/// <summary> /// Initializes a new instance of SqlAes256CbcAlgorithm algorithm with a given key and encryption type /// </summary> /// <param name="encryptionKey"> /// Root encryption key from which three other keys will be derived /// </param> /// <param name="encryptionType">Encryption Type, accepted values are Deterministic and Randomized. /// For Deterministic encryption, a synthetic IV will be generated during encryption /// For Randomized encryption, a random IV will be generated during encryption. /// </param> /// <param name="algorithmVersion"> /// Algorithm version /// </param> internal SqlAes256CbcAlgorithm(SqlAeadAes256CbcHmac256EncryptionKey encryptionKey, SqlClientEncryptionType encryptionType, byte algorithmVersion) : base(encryptionKey, encryptionType, algorithmVersion) { }
/// <summary> /// Initializes a new instance of SqlAeadAes256CbcHmac256Algorithm algorithm with a given key and encryption type /// </summary> /// <param name="encryptionKey"> /// Root encryption key from which three other keys will be derived /// </param> /// <param name="encryptionType">Encryption Type, accepted values are Deterministic and Randomized. /// For Deterministic encryption, a synthetic IV will be genenrated during encryption /// For Randomized encryption, a random IV will be generated during encryption. /// </param> /// <param name="algorithmVersion"> /// Algorithm version /// </param> internal SqlAeadAes256CbcHmac256Algorithm(SqlAeadAes256CbcHmac256EncryptionKey encryptionKey, SqlClientEncryptionType encryptionType, byte algorithmVersion) { _columnEncryptionKey = encryptionKey; _algorithmVersion = algorithmVersion; _version[0] = algorithmVersion; Debug.Assert (null != encryptionKey, "Null encryption key detected in AeadAes256CbcHmac256 algorithm"); Debug.Assert (0x01 == algorithmVersion, "Unknown algorithm version passed to AeadAes256CbcHmac256"); // Validate encryption type for this algorithm // This algorithm can only provide randomized or deterministic encryption types. if (encryptionType == SqlClientEncryptionType.Deterministic) { _isDeterministic = true; } else { Debug.Assert (SqlClientEncryptionType.Randomized == encryptionType, "Invalid Encryption Type detected in SqlAeadAes256CbcHmac256Algorithm, this should've been caught in factory class"); } _cryptoProviderPool = new ConcurrentQueue<AesCryptoServiceProvider>(); }