github.com/pion/dtls/v2@v2.2.12/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 package ciphersuite 5 6 import ( 7 "crypto/sha1" //nolint: gosec,gci 8 "crypto/sha256" 9 "fmt" 10 "hash" 11 "sync/atomic" 12 13 "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" 14 "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" 15 "github.com/pion/dtls/v2/pkg/crypto/prf" 16 "github.com/pion/dtls/v2/pkg/protocol/recordlayer" 17 ) 18 19 // TLSEcdheEcdsaWithAes256CbcSha represents a TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuite 20 type TLSEcdheEcdsaWithAes256CbcSha struct { 21 cbc atomic.Value // *cryptoCBC 22 } 23 24 // CertificateType returns what type of certficate this CipherSuite exchanges 25 func (c *TLSEcdheEcdsaWithAes256CbcSha) CertificateType() clientcertificate.Type { 26 return clientcertificate.ECDSASign 27 } 28 29 // KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake 30 func (c *TLSEcdheEcdsaWithAes256CbcSha) KeyExchangeAlgorithm() KeyExchangeAlgorithm { 31 return KeyExchangeAlgorithmEcdhe 32 } 33 34 // ECC uses Elliptic Curve Cryptography 35 func (c *TLSEcdheEcdsaWithAes256CbcSha) ECC() bool { 36 return true 37 } 38 39 // ID returns the ID of the CipherSuite 40 func (c *TLSEcdheEcdsaWithAes256CbcSha) ID() ID { 41 return TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 42 } 43 44 func (c *TLSEcdheEcdsaWithAes256CbcSha) String() string { 45 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" 46 } 47 48 // HashFunc returns the hashing func for this CipherSuite 49 func (c *TLSEcdheEcdsaWithAes256CbcSha) HashFunc() func() hash.Hash { 50 return sha256.New 51 } 52 53 // AuthenticationType controls what authentication method is using during the handshake 54 func (c *TLSEcdheEcdsaWithAes256CbcSha) AuthenticationType() AuthenticationType { 55 return AuthenticationTypeCertificate 56 } 57 58 // IsInitialized returns if the CipherSuite has keying material and can 59 // encrypt/decrypt packets 60 func (c *TLSEcdheEcdsaWithAes256CbcSha) IsInitialized() bool { 61 return c.cbc.Load() != nil 62 } 63 64 // Init initializes the internal Cipher with keying material 65 func (c *TLSEcdheEcdsaWithAes256CbcSha) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { 66 const ( 67 prfMacLen = 20 68 prfKeyLen = 32 69 prfIvLen = 16 70 ) 71 72 keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) 73 if err != nil { 74 return err 75 } 76 77 var cbc *ciphersuite.CBC 78 if isClient { 79 cbc, err = ciphersuite.NewCBC( 80 keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, 81 keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, 82 sha1.New, 83 ) 84 } else { 85 cbc, err = ciphersuite.NewCBC( 86 keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, 87 keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, 88 sha1.New, 89 ) 90 } 91 c.cbc.Store(cbc) 92 93 return err 94 } 95 96 // Encrypt encrypts a single TLS RecordLayer 97 func (c *TLSEcdheEcdsaWithAes256CbcSha) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { 98 cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) 99 if !ok { 100 return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) 101 } 102 103 return cipherSuite.Encrypt(pkt, raw) 104 } 105 106 // Decrypt decrypts a single TLS RecordLayer 107 func (c *TLSEcdheEcdsaWithAes256CbcSha) Decrypt(raw []byte) ([]byte, error) { 108 cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) 109 if !ok { 110 return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) 111 } 112 113 return cipherSuite.Decrypt(raw) 114 }