ClientSideDecryptor
                    class ClientSideDecryptor
                
                using Azure.Core.Cryptography;
using Azure.Storage.Cryptography.Models;
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
namespace Azure.Storage.Cryptography
{
    internal class ClientSideDecryptor
    {
        internal class ContentEncryptionKeyCache
        {
            public Memory<byte>? Key { get; set; }
        }
        private static readonly AsyncLocal<ContentEncryptionKeyCache> s_contentEncryptionKeyCache = new AsyncLocal<ContentEncryptionKeyCache>();
        private readonly IKeyEncryptionKey _potentialCachedIKeyEncryptionKey;
        private readonly IKeyEncryptionKeyResolver _keyResolver;
        public ClientSideDecryptor(ClientSideEncryptionOptions options)
        {
            _potentialCachedIKeyEncryptionKey = options.get_KeyEncryptionKey();
            _keyResolver = options.get_KeyResolver();
        }
        [AsyncStateMachine(typeof(<DecryptReadInternal>d__4))]
        public Task<Stream> DecryptReadInternal(Stream ciphertext, EncryptionData encryptionData, bool ivInStream, bool noPadding, bool async, CancellationToken cancellationToken)
        {
            <DecryptReadInternal>d__4 stateMachine = default(<DecryptReadInternal>d__4);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
            stateMachine.<>4__this = this;
            stateMachine.ciphertext = ciphertext;
            stateMachine.encryptionData = encryptionData;
            stateMachine.ivInStream = ivInStream;
            stateMachine.noPadding = noPadding;
            stateMachine.async = async;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        [AsyncStateMachine(typeof(<DecryptWholeContentWriteInternal>d__5))]
        public Task<Stream> DecryptWholeContentWriteInternal(Stream plaintextDestination, EncryptionData encryptionData, bool async, CancellationToken cancellationToken)
        {
            <DecryptWholeContentWriteInternal>d__5 stateMachine = default(<DecryptWholeContentWriteInternal>d__5);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
            stateMachine.<>4__this = this;
            stateMachine.plaintextDestination = plaintextDestination;
            stateMachine.encryptionData = encryptionData;
            stateMachine.async = async;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        [AsyncStateMachine(typeof(<DecryptInternalV2_0>d__6))]
        private Task<Stream> DecryptInternalV2_0(Stream ciphertext, EncryptionData encryptionData, CryptoStreamMode mode, bool async, CancellationToken cancellationToken)
        {
            <DecryptInternalV2_0>d__6 stateMachine = default(<DecryptInternalV2_0>d__6);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
            stateMachine.<>4__this = this;
            stateMachine.ciphertext = ciphertext;
            stateMachine.encryptionData = encryptionData;
            stateMachine.mode = mode;
            stateMachine.async = async;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        private static Stream WrapStreamV2_0(Stream contentStream, CryptoStreamMode mode, byte[] contentEncryptionKey, int authRegionPlaintextSize)
        {
            GcmAuthenticatedCryptographicTransform transform = new GcmAuthenticatedCryptographicTransform(contentEncryptionKey, TransformMode.Decrypt);
            return new AuthenticatedRegionCryptoStream(contentStream, transform, authRegionPlaintextSize, mode);
        }
        [AsyncStateMachine(typeof(<DecryptReadInternalV1_0>d__8))]
        private Task<Stream> DecryptReadInternalV1_0(Stream ciphertext, EncryptionData encryptionData, bool ivInStream, bool noPadding, bool async, CancellationToken cancellationToken)
        {
            <DecryptReadInternalV1_0>d__8 stateMachine = default(<DecryptReadInternalV1_0>d__8);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
            stateMachine.<>4__this = this;
            stateMachine.ciphertext = ciphertext;
            stateMachine.encryptionData = encryptionData;
            stateMachine.ivInStream = ivInStream;
            stateMachine.noPadding = noPadding;
            stateMachine.async = async;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        [AsyncStateMachine(typeof(<DecryptWholeContentWriteInternalV1_0>d__9))]
        private Task<Stream> DecryptWholeContentWriteInternalV1_0(Stream plaintextDestination, EncryptionData encryptionData, bool async, CancellationToken cancellationToken)
        {
            <DecryptWholeContentWriteInternalV1_0>d__9 stateMachine = default(<DecryptWholeContentWriteInternalV1_0>d__9);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<Stream>.Create();
            stateMachine.<>4__this = this;
            stateMachine.plaintextDestination = plaintextDestination;
            stateMachine.encryptionData = encryptionData;
            stateMachine.async = async;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        private static Stream WrapStreamV1_0(Stream contentStream, byte[] contentEncryptionKey, EncryptionData encryptionData, byte[] iv, bool noPadding, CryptoStreamMode mode)
        {
            if (encryptionData.EncryptionAgent.EncryptionAlgorithm == ClientSideEncryptionAlgorithm.AesCbc256) {
                using (Aes aes = new AesCryptoServiceProvider()) {
                    aes.IV = (iv ?? encryptionData.ContentEncryptionIV);
                    aes.Key = contentEncryptionKey;
                    if (noPadding)
                        aes.Padding = PaddingMode.None;
                    return new CryptoStream(new BufferedStream(contentStream), aes.CreateDecryptor(), mode);
                }
            }
            throw Errors.ClientSideEncryption.BadEncryptionAlgorithm(encryptionData.EncryptionAgent.EncryptionAlgorithm.ToString());
        }
        [AsyncStateMachine(typeof(<GetContentEncryptionKeyAsync>d__11))]
        internal Task<Memory<byte>> GetContentEncryptionKeyAsync(EncryptionData encryptionData, bool async, CancellationToken cancellationToken)
        {
            <GetContentEncryptionKeyAsync>d__11 stateMachine = default(<GetContentEncryptionKeyAsync>d__11);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<Memory<byte>>.Create();
            stateMachine.<>4__this = this;
            stateMachine.encryptionData = encryptionData;
            stateMachine.async = async;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        internal static void BeginContentEncryptionKeyCaching(ContentEncryptionKeyCache cache = null)
        {
            s_contentEncryptionKeyCache.Value = (cache ?? new ContentEncryptionKeyCache());
        }
    }
}