/// <summary> /// Initializes a new instance of AeadAes256CbcHmac256Algorithm 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 AeadAes256CbcHmac256Algorithm(AeadAes256CbcHmac256EncryptionKey encryptionKey, EncryptionType encryptionType, byte algorithmVersion) { this.dataEncryptionKey = encryptionKey; this.algorithmVersion = algorithmVersion; version[0] = algorithmVersion; Debug.Assert(encryptionKey != null, "Null encryption key detected in AeadAes256CbcHmac256 algorithm"); Debug.Assert(algorithmVersion == 0x01, "Unknown algorithm version passed to AeadAes256CbcHmac256"); // Validate encryption type for this algorithm // This algorithm can only provide randomized or deterministic encryption types. // Right now, we support both randomized and deterministic IV based encryption for Cosmos DB client side encryption. Debug.Assert((encryptionType == EncryptionType.Randomized) || (encryptionType == EncryptionType.Deterministic), "Invalid Encryption Type detected in AeadAes256CbcHmac256Algorithm"); if (encryptionType == EncryptionType.Deterministic) { this.isDeterministic = true; } else { this.isDeterministic = false; } this.cryptoProviderPool = new ConcurrentQueue <AesCryptoServiceProvider>(); }
/// <summary> /// Creates a new instance of data encryption key given the raw key bytes /// suitable for use with the provided encryption algorithm. /// </summary> /// <param name="rawKey">Raw key bytes.</param> /// <param name="encryptionAlgorithm">Encryption algorithm the returned key is intended to be used with.</param> /// <returns>New instance of data encryption key.</returns> public static DataEncryptionKey Create( byte[] rawKey, string encryptionAlgorithm) { if (rawKey == null) { throw new ArgumentNullException(nameof(rawKey)); } if (encryptionAlgorithm != CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) { throw new ArgumentException($"Encryption algorithm not supported: {encryptionAlgorithm}", nameof(encryptionAlgorithm)); } AeadAes256CbcHmac256EncryptionKey aeKey = new AeadAes256CbcHmac256EncryptionKey(rawKey, AeadAes256CbcHmac256Algorithm.AlgorithmNameConstant); return(new AeadAes256CbcHmac256Algorithm(aeKey, EncryptionType.Randomized, algorithmVersion: 1)); }
/// <summary> /// Creates a new instance of data encryption key given the raw key bytes /// suitable for use with the provided encryption algorithm. /// </summary> /// <param name="rawKey">Raw key bytes.</param> /// <param name="encryptionAlgorithm">Encryption algorithm the returned key is intended to be used with.</param> /// <returns>New instance of data encryption key.</returns> public static DataEncryptionKey Create( byte[] rawKey, string encryptionAlgorithm) { if (rawKey == null) { throw new ArgumentNullException(nameof(rawKey)); } switch (encryptionAlgorithm) { case CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized: AeadAes256CbcHmac256EncryptionKey aeKey = new AeadAes256CbcHmac256EncryptionKey(rawKey, AeadAes256CbcHmac256Algorithm.AlgorithmNameConstant); return(new AeadAes256CbcHmac256Algorithm(aeKey, EncryptionType.Randomized, algorithmVersion: 1)); case CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256: AeadAes256CbcHmac256EncryptionKey aedKey = new AeadAes256CbcHmac256EncryptionKey(rawKey, AeadAes256CbcHmac256Algorithm.AlgorithmNameConstant); return(new AeadAes256CbcHmac256Algorithm(aedKey, EncryptionType.Deterministic, algorithmVersion: 1)); default: throw new ArgumentException($"Encryption algorithm not supported: {encryptionAlgorithm}", nameof(encryptionAlgorithm)); } }