diff options
Diffstat (limited to 'vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go')
-rw-r--r-- | vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go new file mode 100644 index 0000000..dcc5379 --- /dev/null +++ b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go @@ -0,0 +1,108 @@ +package ciphersuite + +import ( + "crypto/sha256" + "fmt" + "hash" + "sync/atomic" + + "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v2/pkg/crypto/prf" + "github.com/pion/dtls/v2/pkg/protocol/recordlayer" +) + +// Aes128Ccm is a base class used by multiple AES-CCM Ciphers +type Aes128Ccm struct { + ccm atomic.Value // *cryptoCCM + clientCertificateType clientcertificate.Type + id ID + psk bool + cryptoCCMTagLen ciphersuite.CCMTagLen +} + +func newAes128Ccm(clientCertificateType clientcertificate.Type, id ID, psk bool, cryptoCCMTagLen ciphersuite.CCMTagLen) *Aes128Ccm { + return &Aes128Ccm{ + clientCertificateType: clientCertificateType, + id: id, + psk: psk, + cryptoCCMTagLen: cryptoCCMTagLen, + } +} + +// CertificateType returns what type of certificate this CipherSuite exchanges +func (c *Aes128Ccm) CertificateType() clientcertificate.Type { + return c.clientCertificateType +} + +// ID returns the ID of the CipherSuite +func (c *Aes128Ccm) ID() ID { + return c.id +} + +func (c *Aes128Ccm) String() string { + return c.id.String() +} + +// HashFunc returns the hashing func for this CipherSuite +func (c *Aes128Ccm) HashFunc() func() hash.Hash { + return sha256.New +} + +// AuthenticationType controls what authentication method is using during the handshake +func (c *Aes128Ccm) AuthenticationType() AuthenticationType { + if c.psk { + return AuthenticationTypePreSharedKey + } + return AuthenticationTypeCertificate +} + +// IsInitialized returns if the CipherSuite has keying material and can +// encrypt/decrypt packets +func (c *Aes128Ccm) IsInitialized() bool { + return c.ccm.Load() != nil +} + +// Init initializes the internal Cipher with keying material +func (c *Aes128Ccm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { + const ( + prfMacLen = 0 + prfKeyLen = 16 + prfIvLen = 4 + ) + + keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) + if err != nil { + return err + } + + var ccm *ciphersuite.CCM + if isClient { + ccm, err = ciphersuite.NewCCM(c.cryptoCCMTagLen, keys.ClientWriteKey, keys.ClientWriteIV, keys.ServerWriteKey, keys.ServerWriteIV) + } else { + ccm, err = ciphersuite.NewCCM(c.cryptoCCMTagLen, keys.ServerWriteKey, keys.ServerWriteIV, keys.ClientWriteKey, keys.ClientWriteIV) + } + c.ccm.Store(ccm) + + return err +} + +// Encrypt encrypts a single TLS RecordLayer +func (c *Aes128Ccm) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { + ccm := c.ccm.Load() + if ccm == nil { + return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) + } + + return ccm.(*ciphersuite.CCM).Encrypt(pkt, raw) +} + +// Decrypt decrypts a single TLS RecordLayer +func (c *Aes128Ccm) Decrypt(raw []byte) ([]byte, error) { + ccm := c.ccm.Load() + if ccm == nil { + return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) + } + + return ccm.(*ciphersuite.CCM).Decrypt(raw) +} |