// When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache.
        internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter)
        {
            ////for simulator: enclave does not send public key, and sends an empty attestation info
            //// The only non-trivial content it sends is the session setup info (DH pubkey of enclave)

            sqlEnclaveSession = null;
            counter           = 0;
            try
            {
                ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString());
                sqlEnclaveSession = GetEnclaveSessionFromCache(enclaveSessionParameters, out counter);

                if (sqlEnclaveSession == null)
                {
                    if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl))
                    {
                        ////Read AttestationInfo
                        int  attestationInfoOffset = 0;
                        uint sizeOfTrustedModuleAttestationInfoBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
                        attestationInfoOffset += sizeof(UInt32);
                        int sizeOfTrustedModuleAttestationInfoBufferInt = checked ((int)sizeOfTrustedModuleAttestationInfoBuffer);
                        Debug.Assert(sizeOfTrustedModuleAttestationInfoBuffer == 0);

                        ////read secure session info
                        uint sizeOfSecureSessionInfoResponse = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
                        attestationInfoOffset += sizeof(UInt32);

                        byte[] enclaveSessionHandle = new byte[EnclaveSessionHandleSize];
                        Buffer.BlockCopy(attestationInfo, attestationInfoOffset, enclaveSessionHandle, 0, EnclaveSessionHandleSize);
                        attestationInfoOffset += EnclaveSessionHandleSize;

                        uint sizeOfTrustedModuleDHPublicKeyBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
                        attestationInfoOffset += sizeof(UInt32);
                        uint sizeOfTrustedModuleDHPublicKeySignatureBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
                        attestationInfoOffset += sizeof(UInt32);
                        int sizeOfTrustedModuleDHPublicKeyBufferInt = checked ((int)sizeOfTrustedModuleDHPublicKeyBuffer);

                        byte[] trustedModuleDHPublicKey = new byte[sizeOfTrustedModuleDHPublicKeyBuffer];
                        Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKey, 0,
                                         sizeOfTrustedModuleDHPublicKeyBufferInt);
                        attestationInfoOffset += sizeOfTrustedModuleDHPublicKeyBufferInt;

                        byte[] trustedModuleDHPublicKeySignature = new byte[sizeOfTrustedModuleDHPublicKeySignatureBuffer];
                        Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKeySignature, 0,
                                         checked ((int)sizeOfTrustedModuleDHPublicKeySignatureBuffer));

                        byte[] sharedSecret;
                        using ECDiffieHellman ecdh = KeyConverter.CreateECDiffieHellmanFromPublicKeyBlob(trustedModuleDHPublicKey);
                        sharedSecret = KeyConverter.DeriveKey(clientDHKey, ecdh.PublicKey);
                        long sessionId = BitConverter.ToInt64(enclaveSessionHandle, 0);
                        sqlEnclaveSession = AddEnclaveSessionToCache(enclaveSessionParameters, sharedSecret, sessionId, out counter);
                    }
                    else
                    {
                        throw new AlwaysEncryptedAttestationException(Strings.FailToCreateEnclaveSession);
                    }
                }
            }
            finally
            {
                UpdateEnclaveSessionLockStatus(sqlEnclaveSession);
            }
        }
        // Gets the information that SqlClient subsequently uses to initiate the process of attesting the enclave and to establish a secure session with the enclave.
        internal override SqlEnclaveAttestationParameters GetAttestationParameters(string attestationUrl, byte[] customData, int customDataLength)
        {
            ECDiffieHellman clientDHKey = KeyConverter.CreateECDiffieHellman(DiffieHellmanKeySize);

            return(new SqlEnclaveAttestationParameters(VsmHGSProtocolId, new byte[] { }, clientDHKey));
        }