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