// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

package ciphersuite

import (
	 //nolint: gosec,gci
	
	
	
	

	
	
	
	
)

// TLSEcdheEcdsaWithAes256CbcSha represents a TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuite
type TLSEcdheEcdsaWithAes256CbcSha struct {
	cbc atomic.Value // *cryptoCBC
}

// CertificateType returns what type of certficate this CipherSuite exchanges
func ( *TLSEcdheEcdsaWithAes256CbcSha) () clientcertificate.Type {
	return clientcertificate.ECDSASign
}

// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake
func ( *TLSEcdheEcdsaWithAes256CbcSha) () KeyExchangeAlgorithm {
	return KeyExchangeAlgorithmEcdhe
}

// ECC uses Elliptic Curve Cryptography
func ( *TLSEcdheEcdsaWithAes256CbcSha) () bool {
	return true
}

// ID returns the ID of the CipherSuite
func ( *TLSEcdheEcdsaWithAes256CbcSha) () ID {
	return TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
}

func ( *TLSEcdheEcdsaWithAes256CbcSha) () string {
	return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
}

// HashFunc returns the hashing func for this CipherSuite
func ( *TLSEcdheEcdsaWithAes256CbcSha) () func() hash.Hash {
	return sha256.New
}

// AuthenticationType controls what authentication method is using during the handshake
func ( *TLSEcdheEcdsaWithAes256CbcSha) () AuthenticationType {
	return AuthenticationTypeCertificate
}

// IsInitialized returns if the CipherSuite has keying material and can
// encrypt/decrypt packets
func ( *TLSEcdheEcdsaWithAes256CbcSha) () bool {
	return .cbc.Load() != nil
}

// Init initializes the internal Cipher with keying material
func ( *TLSEcdheEcdsaWithAes256CbcSha) (, ,  []byte,  bool) error {
	const (
		 = 20
		 = 32
		  = 16
	)

	,  := prf.GenerateEncryptionKeys(, , , , , , .HashFunc())
	if  != nil {
		return 
	}

	var  *ciphersuite.CBC
	if  {
		,  = ciphersuite.NewCBC(
			.ClientWriteKey, .ClientWriteIV, .ClientMACKey,
			.ServerWriteKey, .ServerWriteIV, .ServerMACKey,
			sha1.New,
		)
	} else {
		,  = ciphersuite.NewCBC(
			.ServerWriteKey, .ServerWriteIV, .ServerMACKey,
			.ClientWriteKey, .ClientWriteIV, .ClientMACKey,
			sha1.New,
		)
	}
	.cbc.Store()

	return 
}

// Encrypt encrypts a single TLS RecordLayer
func ( *TLSEcdheEcdsaWithAes256CbcSha) ( *recordlayer.RecordLayer,  []byte) ([]byte, error) {
	,  := .cbc.Load().(*ciphersuite.CBC)
	if ! {
		return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit)
	}

	return .Encrypt(, )
}

// Decrypt decrypts a single TLS RecordLayer
func ( *TLSEcdheEcdsaWithAes256CbcSha) ( []byte) ([]byte, error) {
	,  := .cbc.Load().(*ciphersuite.CBC)
	if ! {
		return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit)
	}

	return .Decrypt()
}