1
2
3
4
5 package rsa
6
7
8
9
10 import (
11 "bytes"
12 "crypto/internal/fips140"
13 "crypto/internal/fips140/drbg"
14 "crypto/internal/fips140/sha256"
15 "crypto/internal/fips140/sha3"
16 "crypto/internal/fips140/sha512"
17 "crypto/internal/fips140/subtle"
18 "errors"
19 "io"
20 )
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 func incCounter(c *[4]byte) {
37 if c[3]++; c[3] != 0 {
38 return
39 }
40 if c[2]++; c[2] != 0 {
41 return
42 }
43 if c[1]++; c[1] != 0 {
44 return
45 }
46 c[0]++
47 }
48
49
50
51 func mgf1XOR(out []byte, hash fips140.Hash, seed []byte) {
52 var counter [4]byte
53 var digest []byte
54
55 done := 0
56 for done < len(out) {
57 hash.Reset()
58 hash.Write(seed)
59 hash.Write(counter[0:4])
60 digest = hash.Sum(digest[:0])
61
62 for i := 0; i < len(digest) && done < len(out); i++ {
63 out[done] ^= digest[i]
64 done++
65 }
66 incCounter(&counter)
67 }
68 }
69
70 func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash fips140.Hash) ([]byte, error) {
71
72
73 hLen := hash.Size()
74 sLen := len(salt)
75 emLen := (emBits + 7) / 8
76
77
78
79
80
81
82
83 if len(mHash) != hLen {
84 return nil, errors.New("crypto/rsa: input must be hashed with given hash")
85 }
86
87
88
89 if emLen < hLen+sLen+2 {
90 return nil, ErrMessageTooLong
91 }
92
93 em := make([]byte, emLen)
94 psLen := emLen - sLen - hLen - 2
95 db := em[:psLen+1+sLen]
96 h := em[psLen+1+sLen : emLen-1]
97
98
99
100
101
102
103
104
105
106
107
108
109 var prefix [8]byte
110
111 hash.Reset()
112 hash.Write(prefix[:])
113 hash.Write(mHash)
114 hash.Write(salt)
115
116 h = hash.Sum(h[:0])
117
118
119
120
121
122
123
124 db[psLen] = 0x01
125 copy(db[psLen+1:], salt)
126
127
128
129
130
131 mgf1XOR(db, hash, h)
132
133
134
135
136 db[0] &= 0xff >> (8*emLen - emBits)
137
138
139 em[emLen-1] = 0xbc
140
141
142 return em, nil
143 }
144
145 const pssSaltLengthAutodetect = -1
146
147 func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash fips140.Hash) error {
148
149
150 hLen := hash.Size()
151 emLen := (emBits + 7) / 8
152 if emLen != len(em) {
153 return errors.New("rsa: internal error: inconsistent length")
154 }
155
156
157
158
159
160
161 if hLen != len(mHash) {
162 return ErrVerification
163 }
164
165
166 if emLen < hLen+sLen+2 {
167 return ErrVerification
168 }
169
170
171
172 if em[emLen-1] != 0xbc {
173 return ErrVerification
174 }
175
176
177
178 db := em[:emLen-hLen-1]
179 h := em[emLen-hLen-1 : emLen-1]
180
181
182
183
184 var bitMask byte = 0xff >> (8*emLen - emBits)
185 if em[0] & ^bitMask != 0 {
186 return ErrVerification
187 }
188
189
190
191
192 mgf1XOR(db, hash, h)
193
194
195
196 db[0] &= bitMask
197
198
199 if sLen == pssSaltLengthAutodetect {
200 psLen := bytes.IndexByte(db, 0x01)
201 if psLen < 0 {
202 return ErrVerification
203 }
204 sLen = len(db) - psLen - 1
205 }
206
207
208
209 if sLen > hLen {
210 fips140.RecordNonApproved()
211 }
212
213
214
215
216
217 psLen := emLen - hLen - sLen - 2
218 for _, e := range db[:psLen] {
219 if e != 0x00 {
220 return ErrVerification
221 }
222 }
223 if db[psLen] != 0x01 {
224 return ErrVerification
225 }
226
227
228 salt := db[len(db)-sLen:]
229
230
231
232
233
234
235
236 hash.Reset()
237 var prefix [8]byte
238 hash.Write(prefix[:])
239 hash.Write(mHash)
240 hash.Write(salt)
241
242 h0 := hash.Sum(nil)
243
244
245 if !bytes.Equal(h0, h) {
246 return ErrVerification
247 }
248 return nil
249 }
250
251
252
253 func PSSMaxSaltLength(pub *PublicKey, hash fips140.Hash) (int, error) {
254 saltLength := (pub.N.BitLen()-1+7)/8 - 2 - hash.Size()
255 if saltLength < 0 {
256 return 0, ErrMessageTooLong
257 }
258
259
260 if fips140.Enabled && saltLength > hash.Size() {
261 return hash.Size(), nil
262 }
263 return saltLength, nil
264 }
265
266
267 func SignPSS(rand io.Reader, priv *PrivateKey, hash fips140.Hash, hashed []byte, saltLength int) ([]byte, error) {
268 fipsSelfTest()
269 fips140.RecordApproved()
270 checkApprovedHash(hash)
271
272
273
274
275
276
277
278 if saltLength < 0 {
279 return nil, errors.New("crypto/rsa: salt length cannot be negative")
280 }
281
282
283 if saltLength > hash.Size() {
284 fips140.RecordNonApproved()
285 }
286 salt := make([]byte, saltLength)
287 if err := drbg.ReadWithReaderDeterministic(rand, salt); err != nil {
288 return nil, err
289 }
290
291 emBits := priv.pub.N.BitLen() - 1
292 em, err := emsaPSSEncode(hashed, emBits, salt, hash)
293 if err != nil {
294 return nil, err
295 }
296
297
298
299
300
301
302
303
304 if emLen, k := len(em), priv.pub.Size(); emLen < k {
305 emNew := make([]byte, k)
306 copy(emNew[k-emLen:], em)
307 em = emNew
308 }
309
310 return decrypt(priv, em, withCheck)
311 }
312
313
314 func VerifyPSS(pub *PublicKey, hash fips140.Hash, digest []byte, sig []byte) error {
315 return verifyPSS(pub, hash, digest, sig, pssSaltLengthAutodetect)
316 }
317
318
319 func VerifyPSSWithSaltLength(pub *PublicKey, hash fips140.Hash, digest []byte, sig []byte, saltLength int) error {
320 if saltLength < 0 {
321 return errors.New("crypto/rsa: salt length cannot be negative")
322 }
323 return verifyPSS(pub, hash, digest, sig, saltLength)
324 }
325
326 func verifyPSS(pub *PublicKey, hash fips140.Hash, digest []byte, sig []byte, saltLength int) error {
327 fipsSelfTest()
328 fips140.RecordApproved()
329 checkApprovedHash(hash)
330 if fipsApproved, err := checkPublicKey(pub); err != nil {
331 return err
332 } else if !fipsApproved {
333 fips140.RecordNonApproved()
334 }
335
336 if len(sig) != pub.Size() {
337 return ErrVerification
338 }
339
340 emBits := pub.N.BitLen() - 1
341 emLen := (emBits + 7) / 8
342 em, err := encrypt(pub, sig)
343 if err != nil {
344 return ErrVerification
345 }
346
347
348
349
350
351
352 for len(em) > emLen && len(em) > 0 {
353 if em[0] != 0 {
354 return ErrVerification
355 }
356 em = em[1:]
357 }
358
359 return emsaPSSVerify(digest, em, emBits, saltLength, hash)
360 }
361
362 func checkApprovedHash(hash fips140.Hash) {
363 switch hash.(type) {
364 case *sha256.Digest, *sha512.Digest, *sha3.Digest:
365 default:
366 fips140.RecordNonApproved()
367 }
368 }
369
370
371 func EncryptOAEP(hash, mgfHash fips140.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
372
373
374
375
376
377
378 fipsSelfTest()
379 fips140.RecordApproved()
380 checkApprovedHash(hash)
381 if fipsApproved, err := checkPublicKey(pub); err != nil {
382 return nil, err
383 } else if !fipsApproved {
384 fips140.RecordNonApproved()
385 }
386 k := pub.Size()
387 if len(msg) > k-2*hash.Size()-2 {
388 return nil, ErrMessageTooLong
389 }
390
391 hash.Reset()
392 hash.Write(label)
393 lHash := hash.Sum(nil)
394
395 em := make([]byte, k)
396 seed := em[1 : 1+hash.Size()]
397 db := em[1+hash.Size():]
398
399 copy(db[0:hash.Size()], lHash)
400 db[len(db)-len(msg)-1] = 1
401 copy(db[len(db)-len(msg):], msg)
402
403 if err := drbg.ReadWithReaderDeterministic(random, seed); err != nil {
404 return nil, err
405 }
406
407 mgf1XOR(db, mgfHash, seed)
408 mgf1XOR(seed, mgfHash, db)
409
410 return encrypt(pub, em)
411 }
412
413
414 func DecryptOAEP(hash, mgfHash fips140.Hash, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
415 fipsSelfTest()
416 fips140.RecordApproved()
417 checkApprovedHash(hash)
418
419 k := priv.pub.Size()
420 if len(ciphertext) > k ||
421 k < hash.Size()*2+2 {
422 return nil, ErrDecryption
423 }
424
425 em, err := decrypt(priv, ciphertext, noCheck)
426 if err != nil {
427 return nil, err
428 }
429
430 hash.Reset()
431 hash.Write(label)
432 lHash := hash.Sum(nil)
433
434 firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
435
436 seed := em[1 : hash.Size()+1]
437 db := em[hash.Size()+1:]
438
439 mgf1XOR(seed, mgfHash, db)
440 mgf1XOR(db, mgfHash, seed)
441
442 lHash2 := db[0:hash.Size()]
443
444
445
446
447
448 lHash2Good := subtle.ConstantTimeCompare(lHash, lHash2)
449
450
451
452
453
454
455 var lookingForIndex, index, invalid int
456 lookingForIndex = 1
457 rest := db[hash.Size():]
458
459 for i := 0; i < len(rest); i++ {
460 equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
461 equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
462 index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
463 lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
464 invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
465 }
466
467 if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
468 return nil, ErrDecryption
469 }
470
471 return rest[index+1:], nil
472 }
473
View as plain text