github.com/pion/dtls/v2@v2.2.12/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_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 // TLSEcdhePskWithAes128CbcSha256 implements the TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 CipherSuite 19 type TLSEcdhePskWithAes128CbcSha256 struct { 20 cbc atomic.Value // *cryptoCBC 21 } 22 23 // NewTLSEcdhePskWithAes128CbcSha256 creates TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher. 24 func NewTLSEcdhePskWithAes128CbcSha256() *TLSEcdhePskWithAes128CbcSha256 { 25 return &TLSEcdhePskWithAes128CbcSha256{} 26 } 27 28 // CertificateType returns what type of certificate this CipherSuite exchanges 29 func (c *TLSEcdhePskWithAes128CbcSha256) CertificateType() clientcertificate.Type { 30 return clientcertificate.Type(0) 31 } 32 33 // KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake 34 func (c *TLSEcdhePskWithAes128CbcSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm { 35 return (KeyExchangeAlgorithmPsk | KeyExchangeAlgorithmEcdhe) 36 } 37 38 // ECC uses Elliptic Curve Cryptography 39 func (c *TLSEcdhePskWithAes128CbcSha256) ECC() bool { 40 return true 41 } 42 43 // ID returns the ID of the CipherSuite 44 func (c *TLSEcdhePskWithAes128CbcSha256) ID() ID { 45 return TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 46 } 47 48 func (c *TLSEcdhePskWithAes128CbcSha256) String() string { 49 return "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256" 50 } 51 52 // HashFunc returns the hashing func for this CipherSuite 53 func (c *TLSEcdhePskWithAes128CbcSha256) HashFunc() func() hash.Hash { 54 return sha256.New 55 } 56 57 // AuthenticationType controls what authentication method is using during the handshake 58 func (c *TLSEcdhePskWithAes128CbcSha256) AuthenticationType() AuthenticationType { 59 return AuthenticationTypePreSharedKey 60 } 61 62 // IsInitialized returns if the CipherSuite has keying material and can 63 // encrypt/decrypt packets 64 func (c *TLSEcdhePskWithAes128CbcSha256) IsInitialized() bool { 65 return c.cbc.Load() != nil 66 } 67 68 // Init initializes the internal Cipher with keying material 69 func (c *TLSEcdhePskWithAes128CbcSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { 70 const ( 71 prfMacLen = 32 72 prfKeyLen = 16 73 prfIvLen = 16 74 ) 75 76 keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) 77 if err != nil { 78 return err 79 } 80 81 var cbc *ciphersuite.CBC 82 if isClient { 83 cbc, err = ciphersuite.NewCBC( 84 keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, 85 keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, 86 c.HashFunc(), 87 ) 88 } else { 89 cbc, err = ciphersuite.NewCBC( 90 keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, 91 keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, 92 c.HashFunc(), 93 ) 94 } 95 c.cbc.Store(cbc) 96 97 return err 98 } 99 100 // Encrypt encrypts a single TLS RecordLayer 101 func (c *TLSEcdhePskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { 102 cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) 103 if !ok { // !c.isInitialized() 104 return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) 105 } 106 107 return cipherSuite.Encrypt(pkt, raw) 108 } 109 110 // Decrypt decrypts a single TLS RecordLayer 111 func (c *TLSEcdhePskWithAes128CbcSha256) Decrypt(raw []byte) ([]byte, error) { 112 cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) 113 if !ok { // !c.isInitialized() 114 return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) 115 } 116 117 return cipherSuite.Decrypt(raw) 118 }