1
2
3
4
5 package rsa
6
7 import (
8 "crypto"
9 "crypto/internal/boring"
10 "crypto/internal/fips140/rsa"
11 "crypto/internal/fips140hash"
12 "crypto/internal/fips140only"
13 "crypto/internal/rand"
14 "errors"
15 "hash"
16 "io"
17 )
18
19 const (
20
21
22
23
24
25 PSSSaltLengthAuto = 0
26
27
28 PSSSaltLengthEqualsHash = -1
29 )
30
31
32 type PSSOptions struct {
33
34
35
36 SaltLength int
37
38
39
40
41 Hash crypto.Hash
42 }
43
44
45 func (opts *PSSOptions) HashFunc() crypto.Hash {
46 return opts.Hash
47 }
48
49 func (opts *PSSOptions) saltLength() int {
50 if opts == nil {
51 return PSSSaltLengthAuto
52 }
53 return opts.SaltLength
54 }
55
56
57
58
59
60
61
62
63
64
65 func SignPSS(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
66 if err := checkPublicKeySize(&priv.PublicKey); err != nil {
67 return nil, err
68 }
69
70 if opts != nil && opts.Hash != 0 {
71 hash = opts.Hash
72 }
73
74 if boring.Enabled && rand.IsDefaultReader(random) && priv.N.BitLen() >= 1024 {
75 bkey, err := boringPrivateKey(priv)
76 if err != nil {
77 return nil, err
78 }
79 return boring.SignRSAPSS(bkey, hash, digest, opts.saltLength())
80 }
81 if priv.N.BitLen() >= 1024 {
82 boring.UnreachableExceptTests()
83 }
84
85 if !hash.Available() {
86 return nil, errors.New("crypto/rsa: requested hash function unavailable: " + hash.String())
87 }
88 h := fips140hash.Unwrap(hash.New())
89
90 if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
91 return nil, err
92 }
93 if fips140only.Enforced() && !fips140only.ApprovedHash(h) {
94 return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
95 }
96 if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {
97 return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
98 }
99
100 k, err := fipsPrivateKey(priv)
101 if err != nil {
102 return nil, err
103 }
104
105 saltLength := opts.saltLength()
106 if fips140only.Enforced() && saltLength > h.Size() {
107 return nil, errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
108 }
109 switch saltLength {
110 case PSSSaltLengthAuto:
111 saltLength, err = rsa.PSSMaxSaltLength(k.PublicKey(), h)
112 if err != nil {
113 return nil, fipsError(err)
114 }
115 case PSSSaltLengthEqualsHash:
116 saltLength = h.Size()
117 default:
118
119
120 if saltLength <= 0 {
121 return nil, errors.New("crypto/rsa: invalid PSS salt length")
122 }
123 }
124
125 return fipsError2(rsa.SignPSS(random, k, h, digest, saltLength))
126 }
127
128
129
130
131
132
133
134
135
136
137 func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
138 if err := checkPublicKeySize(pub); err != nil {
139 return err
140 }
141
142 if boring.Enabled {
143 bkey, err := boringPublicKey(pub)
144 if err != nil {
145 return err
146 }
147 if err := boring.VerifyRSAPSS(bkey, hash, digest, sig, opts.saltLength()); err != nil {
148 return ErrVerification
149 }
150 return nil
151 }
152
153 if !hash.Available() {
154 return errors.New("crypto/rsa: requested hash function unavailable: " + hash.String())
155 }
156 h := fips140hash.Unwrap(hash.New())
157
158 if err := checkFIPS140OnlyPublicKey(pub); err != nil {
159 return err
160 }
161 if fips140only.Enforced() && !fips140only.ApprovedHash(h) {
162 return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
163 }
164
165 k, err := fipsPublicKey(pub)
166 if err != nil {
167 return err
168 }
169
170 saltLength := opts.saltLength()
171 if fips140only.Enforced() && saltLength > h.Size() {
172 return errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
173 }
174 switch saltLength {
175 case PSSSaltLengthAuto:
176 return fipsError(rsa.VerifyPSS(k, h, digest, sig))
177 case PSSSaltLengthEqualsHash:
178 return fipsError(rsa.VerifyPSSWithSaltLength(k, h, digest, sig, h.Size()))
179 default:
180 return fipsError(rsa.VerifyPSSWithSaltLength(k, h, digest, sig, saltLength))
181 }
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
203 return encryptOAEP(hash, hash, random, pub, msg, label)
204 }
205
206
207
208
209
210
211
212
213 func EncryptOAEPWithOptions(random io.Reader, pub *PublicKey, msg []byte, opts *OAEPOptions) ([]byte, error) {
214 if !opts.Hash.Available() {
215 return nil, errors.New("crypto/rsa: requested hash function unavailable: " + opts.Hash.String())
216 }
217 if opts.MGFHash != 0 && !opts.MGFHash.Available() {
218 return nil, errors.New("crypto/rsa: requested hash function unavailable: " + opts.MGFHash.String())
219 }
220 if opts.MGFHash == 0 {
221 return encryptOAEP(opts.Hash.New(), opts.Hash.New(), random, pub, msg, opts.Label)
222 }
223 return encryptOAEP(opts.Hash.New(), opts.MGFHash.New(), random, pub, msg, opts.Label)
224 }
225
226 func encryptOAEP(hash hash.Hash, mgfHash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
227 if err := checkPublicKeySize(pub); err != nil {
228 return nil, err
229 }
230
231 defer hash.Reset()
232 defer mgfHash.Reset()
233
234 if boring.Enabled && rand.IsDefaultReader(random) {
235 k := pub.Size()
236 if len(msg) > k-2*hash.Size()-2 {
237 return nil, ErrMessageTooLong
238 }
239 bkey, err := boringPublicKey(pub)
240 if err != nil {
241 return nil, err
242 }
243 return boring.EncryptRSAOAEP(hash, mgfHash, bkey, msg, label)
244 }
245 boring.UnreachableExceptTests()
246
247 hash = fips140hash.Unwrap(hash)
248
249 if err := checkFIPS140OnlyPublicKey(pub); err != nil {
250 return nil, err
251 }
252 if fips140only.Enforced() && !fips140only.ApprovedHash(hash) {
253 return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
254 }
255 if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {
256 return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
257 }
258
259 k, err := fipsPublicKey(pub)
260 if err != nil {
261 return nil, err
262 }
263 return fipsError2(rsa.EncryptOAEP(hash, mgfHash, random, k, msg, label))
264 }
265
266
267
268
269
270
271
272
273
274
275
276 func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
277 defer hash.Reset()
278 return decryptOAEP(hash, hash, priv, ciphertext, label)
279 }
280
281 func decryptOAEP(hash, mgfHash hash.Hash, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
282 if err := checkPublicKeySize(&priv.PublicKey); err != nil {
283 return nil, err
284 }
285
286 if boring.Enabled && priv.N.BitLen() >= 1024 {
287 k := priv.Size()
288 if len(ciphertext) > k ||
289 k < hash.Size()*2+2 {
290 return nil, ErrDecryption
291 }
292 bkey, err := boringPrivateKey(priv)
293 if err != nil {
294 return nil, err
295 }
296 out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label)
297 if err != nil {
298 return nil, ErrDecryption
299 }
300 return out, nil
301 }
302
303 hash = fips140hash.Unwrap(hash)
304 mgfHash = fips140hash.Unwrap(mgfHash)
305
306 if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
307 return nil, err
308 }
309 if fips140only.Enforced() {
310 if !fips140only.ApprovedHash(hash) || !fips140only.ApprovedHash(mgfHash) {
311 return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
312 }
313 }
314
315 k, err := fipsPrivateKey(priv)
316 if err != nil {
317 return nil, err
318 }
319
320 return fipsError2(rsa.DecryptOAEP(hash, mgfHash, k, ciphertext, label))
321 }
322
323
324
325
326
327
328
329
330
331
332
333
334
335 func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
336 var hashName string
337 if hash != crypto.Hash(0) {
338 if len(hashed) != hash.Size() {
339 return nil, errors.New("crypto/rsa: input must be hashed message")
340 }
341 hashName = hash.String()
342 }
343
344 if err := checkPublicKeySize(&priv.PublicKey); err != nil {
345 return nil, err
346 }
347
348 if boring.Enabled && priv.N.BitLen() >= 1024 {
349 bkey, err := boringPrivateKey(priv)
350 if err != nil {
351 return nil, err
352 }
353 return boring.SignRSAPKCS1v15(bkey, hash, hashed)
354 }
355
356 if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
357 return nil, err
358 }
359 if fips140only.Enforced() {
360 if !hash.Available() || !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
361 return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
362 }
363 }
364
365 k, err := fipsPrivateKey(priv)
366 if err != nil {
367 return nil, err
368 }
369 return fipsError2(rsa.SignPKCS1v15(k, hashName, hashed))
370 }
371
372
373
374
375
376
377
378
379
380 func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
381 var hashName string
382 if hash != crypto.Hash(0) {
383 if len(hashed) != hash.Size() {
384 return errors.New("crypto/rsa: input must be hashed message")
385 }
386 hashName = hash.String()
387 }
388
389 if err := checkPublicKeySize(pub); err != nil {
390 return err
391 }
392
393 if boring.Enabled {
394 bkey, err := boringPublicKey(pub)
395 if err != nil {
396 return err
397 }
398 if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
399 return ErrVerification
400 }
401 return nil
402 }
403
404 if err := checkFIPS140OnlyPublicKey(pub); err != nil {
405 return err
406 }
407 if fips140only.Enforced() {
408 if !hash.Available() || !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
409 return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
410 }
411 }
412
413 k, err := fipsPublicKey(pub)
414 if err != nil {
415 return err
416 }
417 return fipsError(rsa.VerifyPKCS1v15(k, hashName, hashed, sig))
418 }
419
420 func fipsError(err error) error {
421 switch err {
422 case rsa.ErrDecryption:
423 return ErrDecryption
424 case rsa.ErrVerification:
425 return ErrVerification
426 case rsa.ErrMessageTooLong:
427 return ErrMessageTooLong
428 }
429 return err
430 }
431
432 func fipsError2[T any](x T, err error) (T, error) {
433 return x, fipsError(err)
434 }
435
436 func checkFIPS140OnlyPublicKey(pub *PublicKey) error {
437 if !fips140only.Enforced() {
438 return nil
439 }
440 if pub.N == nil {
441 return errors.New("crypto/rsa: public key missing N")
442 }
443 if pub.N.BitLen() < 2048 {
444 return errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode")
445 }
446 if pub.N.BitLen()%2 == 1 {
447 return errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode")
448 }
449 if pub.E <= 1<<16 {
450 return errors.New("crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode")
451 }
452 if pub.E&1 == 0 {
453 return errors.New("crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode")
454 }
455 return nil
456 }
457
458 func checkFIPS140OnlyPrivateKey(priv *PrivateKey) error {
459 if !fips140only.Enforced() {
460 return nil
461 }
462 if err := checkFIPS140OnlyPublicKey(&priv.PublicKey); err != nil {
463 return err
464 }
465 if len(priv.Primes) != 2 {
466 return errors.New("crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode")
467 }
468 if priv.Primes[0] == nil || priv.Primes[1] == nil || priv.Primes[0].BitLen() != priv.Primes[1].BitLen() {
469 return errors.New("crypto/rsa: use of primes of different sizes is not allowed in FIPS 140-only mode")
470 }
471 return nil
472 }
473
View as plain text