1
2
3
4
5 package gcm
6
7 import (
8 "crypto/internal/fips140"
9 "crypto/internal/fips140/aes"
10 "crypto/internal/fips140/alias"
11 "crypto/internal/fips140/drbg"
12 "crypto/internal/fips140deps/byteorder"
13 "math"
14 )
15
16
17
18
19
20
21
22
23
24 func SealWithRandomNonce(g *GCM, nonce, out, plaintext, additionalData []byte) {
25 if uint64(len(plaintext)) > uint64((1<<32)-2)*gcmBlockSize {
26 panic("crypto/cipher: message too large for GCM")
27 }
28 if len(nonce) != gcmStandardNonceSize {
29 panic("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce")
30 }
31 if len(out) != len(plaintext)+gcmTagSize {
32 panic("crypto/cipher: incorrect output length given to GCMWithRandomNonce")
33 }
34 if alias.InexactOverlap(out, plaintext) {
35 panic("crypto/cipher: invalid buffer overlap of output and input")
36 }
37 if alias.AnyOverlap(out, additionalData) {
38 panic("crypto/cipher: invalid buffer overlap of output and additional data")
39 }
40 fips140.RecordApproved()
41 drbg.Read(nonce)
42 seal(out, g, nonce, plaintext, additionalData)
43 }
44
45
46
47
48
49
50
51 func NewGCMWithCounterNonce(cipher *aes.Block) (*GCMWithCounterNonce, error) {
52 g, err := newGCM(&GCM{}, cipher, gcmStandardNonceSize, gcmTagSize)
53 if err != nil {
54 return nil, err
55 }
56 return &GCMWithCounterNonce{g: *g}, nil
57 }
58
59 type GCMWithCounterNonce struct {
60 g GCM
61 ready bool
62 fixedName uint32
63 start uint64
64 next uint64
65 }
66
67 func (g *GCMWithCounterNonce) NonceSize() int { return gcmStandardNonceSize }
68
69 func (g *GCMWithCounterNonce) Overhead() int { return gcmTagSize }
70
71 func (g *GCMWithCounterNonce) Seal(dst, nonce, plaintext, data []byte) []byte {
72 if len(nonce) != gcmStandardNonceSize {
73 panic("crypto/cipher: incorrect nonce length given to GCM")
74 }
75
76 counter := byteorder.BEUint64(nonce[len(nonce)-8:])
77 if !g.ready {
78
79 g.ready = true
80 g.start = counter
81 g.fixedName = byteorder.BEUint32(nonce[:4])
82 }
83 if g.fixedName != byteorder.BEUint32(nonce[:4]) {
84 panic("crypto/cipher: incorrect module name given to GCMWithCounterNonce")
85 }
86 counter -= g.start
87
88
89 if counter == math.MaxUint64 {
90 panic("crypto/cipher: counter wrapped")
91 }
92 if counter < g.next {
93 panic("crypto/cipher: counter decreased")
94 }
95 g.next = counter + 1
96
97 fips140.RecordApproved()
98 return g.g.sealAfterIndicator(dst, nonce, plaintext, data)
99 }
100
101 func (g *GCMWithCounterNonce) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
102 fips140.RecordApproved()
103 return g.g.Open(dst, nonce, ciphertext, data)
104 }
105
106
107
108
109
110
111 func NewGCMForTLS12(cipher *aes.Block) (*GCMForTLS12, error) {
112 g, err := newGCM(&GCM{}, cipher, gcmStandardNonceSize, gcmTagSize)
113 if err != nil {
114 return nil, err
115 }
116 return &GCMForTLS12{g: *g}, nil
117 }
118
119 type GCMForTLS12 struct {
120 g GCM
121 next uint64
122 }
123
124 func (g *GCMForTLS12) NonceSize() int { return gcmStandardNonceSize }
125
126 func (g *GCMForTLS12) Overhead() int { return gcmTagSize }
127
128 func (g *GCMForTLS12) Seal(dst, nonce, plaintext, data []byte) []byte {
129 if len(nonce) != gcmStandardNonceSize {
130 panic("crypto/cipher: incorrect nonce length given to GCM")
131 }
132
133 counter := byteorder.BEUint64(nonce[len(nonce)-8:])
134
135
136 if counter == math.MaxUint64 {
137 panic("crypto/cipher: counter wrapped")
138 }
139 if counter < g.next {
140 panic("crypto/cipher: counter decreased")
141 }
142 g.next = counter + 1
143
144 fips140.RecordApproved()
145 return g.g.sealAfterIndicator(dst, nonce, plaintext, data)
146 }
147
148 func (g *GCMForTLS12) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
149 fips140.RecordApproved()
150 return g.g.Open(dst, nonce, ciphertext, data)
151 }
152
153
154
155 func NewGCMForTLS13(cipher *aes.Block) (*GCMForTLS13, error) {
156 g, err := newGCM(&GCM{}, cipher, gcmStandardNonceSize, gcmTagSize)
157 if err != nil {
158 return nil, err
159 }
160 return &GCMForTLS13{g: *g}, nil
161 }
162
163 type GCMForTLS13 struct {
164 g GCM
165 ready bool
166 mask uint64
167 next uint64
168 }
169
170 func (g *GCMForTLS13) NonceSize() int { return gcmStandardNonceSize }
171
172 func (g *GCMForTLS13) Overhead() int { return gcmTagSize }
173
174 func (g *GCMForTLS13) Seal(dst, nonce, plaintext, data []byte) []byte {
175 if len(nonce) != gcmStandardNonceSize {
176 panic("crypto/cipher: incorrect nonce length given to GCM")
177 }
178
179 counter := byteorder.BEUint64(nonce[len(nonce)-8:])
180 if !g.ready {
181
182 g.ready = true
183 g.mask = counter
184 }
185 counter ^= g.mask
186
187
188 if counter == math.MaxUint64 {
189 panic("crypto/cipher: counter wrapped")
190 }
191 if counter < g.next {
192 panic("crypto/cipher: counter decreased")
193 }
194 g.next = counter + 1
195
196 fips140.RecordApproved()
197 return g.g.sealAfterIndicator(dst, nonce, plaintext, data)
198 }
199
200 func (g *GCMForTLS13) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
201 fips140.RecordApproved()
202 return g.g.Open(dst, nonce, ciphertext, data)
203 }
204
205
206
207
208
209 func NewGCMForSSH(cipher *aes.Block) (*GCMForSSH, error) {
210 g, err := newGCM(&GCM{}, cipher, gcmStandardNonceSize, gcmTagSize)
211 if err != nil {
212 return nil, err
213 }
214 return &GCMForSSH{g: *g}, nil
215 }
216
217 type GCMForSSH struct {
218 g GCM
219 ready bool
220 start uint64
221 next uint64
222 }
223
224 func (g *GCMForSSH) NonceSize() int { return gcmStandardNonceSize }
225
226 func (g *GCMForSSH) Overhead() int { return gcmTagSize }
227
228 func (g *GCMForSSH) Seal(dst, nonce, plaintext, data []byte) []byte {
229 if len(nonce) != gcmStandardNonceSize {
230 panic("crypto/cipher: incorrect nonce length given to GCM")
231 }
232
233 counter := byteorder.BEUint64(nonce[len(nonce)-8:])
234 if !g.ready {
235
236 g.ready = true
237 g.start = counter
238 }
239 counter -= g.start
240
241
242 if counter == math.MaxUint64 {
243 panic("crypto/cipher: counter wrapped")
244 }
245 if counter < g.next {
246 panic("crypto/cipher: counter decreased")
247 }
248 g.next = counter + 1
249
250 fips140.RecordApproved()
251 return g.g.sealAfterIndicator(dst, nonce, plaintext, data)
252 }
253
254 func (g *GCMForSSH) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
255 fips140.RecordApproved()
256 return g.g.Open(dst, nonce, ciphertext, data)
257 }
258
View as plain text