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