@@ -5,13 +5,8 @@ package ciphersuite
55
66import (
77 "crypto/aes"
8- "crypto/rand"
9- "encoding/binary"
10- "fmt"
11- "sync"
128
139 "github.com/pion/dtls/v3/pkg/crypto/ccm"
14- "github.com/pion/dtls/v3/pkg/protocol"
1510 "github.com/pion/dtls/v3/pkg/protocol/recordlayer"
1611)
1712
@@ -27,12 +22,7 @@ const (
2722
2823// CCM Provides an API to Encrypt/Decrypt DTLS 1.2 Packets.
2924type CCM struct {
30- localCCM , remoteCCM ccm.CCM
31- localWriteIV , remoteWriteIV []byte
32- tagLen CCMTagLen
33-
34- // buffer pool for nonces.
35- nonceBufferPool sync.Pool
25+ aead * aead
3626}
3727
3828// NewCCM creates a DTLS GCM Cipher.
@@ -56,82 +46,23 @@ func NewCCM(tagLen CCMTagLen, localKey, localWriteIV, remoteKey, remoteWriteIV [
5646 }
5747
5848 return & CCM {
59- localCCM : localCCM ,
60- localWriteIV : localWriteIV ,
61- remoteCCM : remoteCCM ,
62- remoteWriteIV : remoteWriteIV ,
63- tagLen : tagLen ,
64-
65- nonceBufferPool : sync.Pool {
66- New : func () any {
67- b := make ([]byte , ccmNonceLength )
68- return & b // nolint:nlreturn
69- },
70- },
49+ aead : newAEAD (
50+ localCCM ,
51+ localWriteIV ,
52+ remoteCCM ,
53+ remoteWriteIV ,
54+ ccmNonceLength ,
55+ int (tagLen ),
56+ ),
7157 }, nil
7258}
7359
7460// Encrypt encrypt a DTLS RecordLayer message.
7561func (c * CCM ) Encrypt (pkt * recordlayer.RecordLayer , raw []byte ) ([]byte , error ) {
76- payload := raw [pkt .Header .Size ():]
77- raw = raw [:pkt .Header .Size ()]
78-
79- noncePtr := c .nonceBufferPool .Get ().(* []byte ) // nolint:forcetypeassert
80- nonce := * noncePtr
81- defer c .nonceBufferPool .Put (noncePtr )
82-
83- copy (nonce [:4 ], c .localWriteIV [:4 ])
84- if _ , err := rand .Read (nonce [4 :]); err != nil {
85- return nil , err
86- }
87-
88- var additionalData []byte
89- if pkt .Header .ContentType == protocol .ContentTypeConnectionID {
90- additionalData = generateAEADAdditionalDataCID (& pkt .Header , len (payload ))
91- } else {
92- additionalData = generateAEADAdditionalData (& pkt .Header , len (payload ))
93- }
94-
95- finalSize := len (raw ) + 8 + len (payload ) + int (c .tagLen )
96- result := make ([]byte , finalSize )
97- copy (result , raw )
98- copy (result [len (raw ):], nonce [4 :])
99-
100- c .localCCM .Seal (result [len (raw )+ 8 :len (raw )+ 8 ], nonce , payload , additionalData )
101-
102- // Update recordLayer size to include explicit nonce
103- binary .BigEndian .PutUint16 (result [pkt .Header .Size ()- 2 :], uint16 (len (result )- pkt .Header .Size ())) //nolint:gosec //G115
104-
105- return result , nil
62+ return c .aead .encrypt (pkt , raw )
10663}
10764
10865// Decrypt decrypts a DTLS RecordLayer message.
10966func (c * CCM ) Decrypt (header recordlayer.Header , in []byte ) ([]byte , error ) {
110- if err := header .Unmarshal (in ); err != nil {
111- return nil , err
112- }
113- switch {
114- case header .ContentType == protocol .ContentTypeChangeCipherSpec :
115- // Nothing to encrypt with ChangeCipherSpec
116- return in , nil
117- case len (in ) <= (8 + header .Size ()):
118- return nil , errNotEnoughRoomForNonce
119- }
120-
121- nonce := append (append ([]byte {}, c .remoteWriteIV [:4 ]... ), in [header .Size ():header .Size ()+ 8 ]... )
122- out := in [header .Size ()+ 8 :]
123-
124- var additionalData []byte
125- if header .ContentType == protocol .ContentTypeConnectionID {
126- additionalData = generateAEADAdditionalDataCID (& header , len (out )- int (c .tagLen ))
127- } else {
128- additionalData = generateAEADAdditionalData (& header , len (out )- int (c .tagLen ))
129- }
130- var err error
131- out , err = c .remoteCCM .Open (out [:0 ], nonce , out , additionalData )
132- if err != nil {
133- return nil , fmt .Errorf ("%w: %v" , errDecryptPacket , err ) //nolint:errorlint
134- }
135-
136- return append (in [:header .Size ()], out ... ), nil
67+ return c .aead .decrypt (header , in )
13768}
0 commit comments