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