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 mgfHash = fips140hash.Unwrap(mgfHash)
249
250 if err := checkFIPS140OnlyPublicKey(pub); err != nil {
251 return nil, err
252 }
253 if fips140only.Enforced() {
254 if !fips140only.ApprovedHash(hash) || !fips140only.ApprovedHash(mgfHash) {
255 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")
256 }
257 if !fips140only.ApprovedRandomReader(random) {
258 return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
259 }
260 }
261
262 k, err := fipsPublicKey(pub)
263 if err != nil {
264 return nil, err
265 }
266 return fipsError2(rsa.EncryptOAEP(hash, mgfHash, random, k, msg, label))
267 }
268
269
270
271
272
273
274
275
276
277
278
279 func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
280 defer hash.Reset()
281 return decryptOAEP(hash, hash, priv, ciphertext, label)
282 }
283
284 func decryptOAEP(hash, mgfHash hash.Hash, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
285 if err := checkPublicKeySize(&priv.PublicKey); err != nil {
286 return nil, err
287 }
288
289 if boring.Enabled && priv.N.BitLen() >= 1024 {
290 k := priv.Size()
291 if len(ciphertext) > k ||
292 k < hash.Size()*2+2 {
293 return nil, ErrDecryption
294 }
295 bkey, err := boringPrivateKey(priv)
296 if err != nil {
297 return nil, err
298 }
299 out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label)
300 if err != nil {
301 return nil, ErrDecryption
302 }
303 return out, nil
304 }
305
306 hash = fips140hash.Unwrap(hash)
307 mgfHash = fips140hash.Unwrap(mgfHash)
308
309 if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
310 return nil, err
311 }
312 if fips140only.Enforced() {
313 if !fips140only.ApprovedHash(hash) || !fips140only.ApprovedHash(mgfHash) {
314 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")
315 }
316 }
317
318 k, err := fipsPrivateKey(priv)
319 if err != nil {
320 return nil, err
321 }
322
323 return fipsError2(rsa.DecryptOAEP(hash, mgfHash, k, ciphertext, label))
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338 func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
339 var hashName string
340 if hash != crypto.Hash(0) {
341 if len(hashed) != hash.Size() {
342 return nil, errors.New("crypto/rsa: input must be hashed message")
343 }
344 hashName = hash.String()
345 }
346
347 if err := checkPublicKeySize(&priv.PublicKey); err != nil {
348 return nil, err
349 }
350
351 if boring.Enabled && priv.N.BitLen() >= 1024 {
352 bkey, err := boringPrivateKey(priv)
353 if err != nil {
354 return nil, err
355 }
356 return boring.SignRSAPKCS1v15(bkey, hash, hashed)
357 }
358
359 if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
360 return nil, err
361 }
362 if fips140only.Enforced() {
363 if !hash.Available() || !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
364 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")
365 }
366 }
367
368 k, err := fipsPrivateKey(priv)
369 if err != nil {
370 return nil, err
371 }
372 return fipsError2(rsa.SignPKCS1v15(k, hashName, hashed))
373 }
374
375
376
377
378
379
380
381
382
383 func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
384 var hashName string
385 if hash != crypto.Hash(0) {
386 if len(hashed) != hash.Size() {
387 return errors.New("crypto/rsa: input must be hashed message")
388 }
389 hashName = hash.String()
390 }
391
392 if err := checkPublicKeySize(pub); err != nil {
393 return err
394 }
395
396 if boring.Enabled {
397 bkey, err := boringPublicKey(pub)
398 if err != nil {
399 return err
400 }
401 if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
402 return ErrVerification
403 }
404 return nil
405 }
406
407 if err := checkFIPS140OnlyPublicKey(pub); err != nil {
408 return err
409 }
410 if fips140only.Enforced() {
411 if !hash.Available() || !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
412 return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
413 }
414 }
415
416 k, err := fipsPublicKey(pub)
417 if err != nil {
418 return err
419 }
420 return fipsError(rsa.VerifyPKCS1v15(k, hashName, hashed, sig))
421 }
422
423 func fipsError(err error) error {
424 switch err {
425 case rsa.ErrDecryption:
426 return ErrDecryption
427 case rsa.ErrVerification:
428 return ErrVerification
429 case rsa.ErrMessageTooLong:
430 return ErrMessageTooLong
431 }
432 return err
433 }
434
435 func fipsError2[T any](x T, err error) (T, error) {
436 return x, fipsError(err)
437 }
438
439 func checkFIPS140OnlyPublicKey(pub *PublicKey) error {
440 if !fips140only.Enforced() {
441 return nil
442 }
443 if pub.N == nil {
444 return errors.New("crypto/rsa: public key missing N")
445 }
446 if pub.N.BitLen() < 2048 {
447 return errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode")
448 }
449 if pub.N.BitLen()%2 == 1 {
450 return errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode")
451 }
452 if pub.E <= 1<<16 {
453 return errors.New("crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode")
454 }
455 if pub.E&1 == 0 {
456 return errors.New("crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode")
457 }
458 return nil
459 }
460
461 func checkFIPS140OnlyPrivateKey(priv *PrivateKey) error {
462 if !fips140only.Enforced() {
463 return nil
464 }
465 if err := checkFIPS140OnlyPublicKey(&priv.PublicKey); err != nil {
466 return err
467 }
468 if len(priv.Primes) != 2 {
469 return errors.New("crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode")
470 }
471 if priv.Primes[0] == nil || priv.Primes[1] == nil || priv.Primes[0].BitLen() != priv.Primes[1].BitLen() {
472 return errors.New("crypto/rsa: use of primes of different sizes is not allowed in FIPS 140-only mode")
473 }
474 return nil
475 }
476
View as plain text