1
2
3
4
5 package rsa
6
7 import (
8 "bytes"
9 "crypto/internal/fips140"
10 "crypto/internal/fips140/bigmod"
11 "errors"
12 )
13
14 type PublicKey struct {
15 N *bigmod.Modulus
16 E int
17 }
18
19
20
21 func (pub *PublicKey) Size() int {
22 return (pub.N.BitLen() + 7) / 8
23 }
24
25 type PrivateKey struct {
26
27 pub PublicKey
28 d *bigmod.Nat
29
30
31
32
33 p, q *bigmod.Modulus
34
35
36 dP []byte
37 dQ []byte
38 qInv *bigmod.Nat
39
40
41 fipsApproved bool
42 }
43
44 func (priv *PrivateKey) PublicKey() *PublicKey {
45 return &priv.pub
46 }
47
48
49
50
51
52 func NewPrivateKey(N []byte, e int, d, P, Q []byte) (*PrivateKey, error) {
53 fipsSelfTest()
54 n, err := bigmod.NewModulus(N)
55 if err != nil {
56 return nil, err
57 }
58 p, err := bigmod.NewModulus(P)
59 if err != nil {
60 return nil, err
61 }
62 q, err := bigmod.NewModulus(Q)
63 if err != nil {
64 return nil, err
65 }
66 dN, err := bigmod.NewNat().SetBytes(d, n)
67 if err != nil {
68 return nil, err
69 }
70 return newPrivateKey(n, e, dN, p, q)
71 }
72
73 func newPrivateKey(n *bigmod.Modulus, e int, d *bigmod.Nat, p, q *bigmod.Modulus) (*PrivateKey, error) {
74 pMinusOne := p.Nat().SubOne(p)
75 pMinusOneMod, err := bigmod.NewModulus(pMinusOne.Bytes(p))
76 if err != nil {
77 return nil, err
78 }
79 dP := bigmod.NewNat().Mod(d, pMinusOneMod).Bytes(pMinusOneMod)
80
81 qMinusOne := q.Nat().SubOne(q)
82 qMinusOneMod, err := bigmod.NewModulus(qMinusOne.Bytes(q))
83 if err != nil {
84 return nil, err
85 }
86 dQ := bigmod.NewNat().Mod(d, qMinusOneMod).Bytes(qMinusOneMod)
87
88
89
90 if p.Nat().IsOdd() == 0 {
91
92 return nil, errors.New("crypto/rsa: p is even")
93 }
94 pMinusTwo := p.Nat().SubOne(p).SubOne(p).Bytes(p)
95 qInv := bigmod.NewNat().Mod(q.Nat(), p)
96 qInv.Exp(qInv, pMinusTwo, p)
97
98 pk := &PrivateKey{
99 pub: PublicKey{
100 N: n, E: e,
101 },
102 d: d, p: p, q: q,
103 dP: dP, dQ: dQ, qInv: qInv,
104 }
105 if err := checkPrivateKey(pk); err != nil {
106 return nil, err
107 }
108 return pk, nil
109 }
110
111
112
113 func NewPrivateKeyWithPrecomputation(N []byte, e int, d, P, Q, dP, dQ, qInv []byte) (*PrivateKey, error) {
114 fipsSelfTest()
115
116 n, err := bigmod.NewModulus(N)
117 if err != nil {
118 return nil, err
119 }
120 p, err := bigmod.NewModulus(P)
121 if err != nil {
122 return nil, err
123 }
124 q, err := bigmod.NewModulus(Q)
125 if err != nil {
126 return nil, err
127 }
128 dN, err := bigmod.NewNat().SetBytes(d, n)
129 if err != nil {
130 return nil, err
131 }
132 qInvNat, err := bigmod.NewNat().SetBytes(qInv, p)
133 if err != nil {
134 return nil, err
135 }
136
137 pk := &PrivateKey{
138 pub: PublicKey{
139 N: n, E: e,
140 },
141 d: dN, p: p, q: q,
142 dP: dP, dQ: dQ, qInv: qInvNat,
143 }
144 if err := checkPrivateKey(pk); err != nil {
145 return nil, err
146 }
147 return pk, nil
148 }
149
150
151
152
153 func NewPrivateKeyWithoutCRT(N []byte, e int, d []byte) (*PrivateKey, error) {
154 n, err := bigmod.NewModulus(N)
155 if err != nil {
156 return nil, err
157 }
158 dN, err := bigmod.NewNat().SetBytes(d, n)
159 if err != nil {
160 return nil, err
161 }
162 pk := &PrivateKey{
163 pub: PublicKey{
164 N: n, E: e,
165 },
166 d: dN,
167 }
168 if err := checkPrivateKey(pk); err != nil {
169 return nil, err
170 }
171 return pk, nil
172 }
173
174
175
176
177
178 func (priv *PrivateKey) Export() (N []byte, e int, d, P, Q, dP, dQ, qInv []byte) {
179 N = priv.pub.N.Nat().Bytes(priv.pub.N)
180 e = priv.pub.E
181 d = priv.d.Bytes(priv.pub.N)
182 if priv.dP == nil {
183 return
184 }
185 P = priv.p.Nat().Bytes(priv.p)
186 Q = priv.q.Nat().Bytes(priv.q)
187 dP = bytes.Clone(priv.dP)
188 dQ = bytes.Clone(priv.dQ)
189 qInv = priv.qInv.Bytes(priv.p)
190 return
191 }
192
193
194
195 func checkPrivateKey(priv *PrivateKey) error {
196 priv.fipsApproved = true
197
198 if fipsApproved, err := checkPublicKey(&priv.pub); err != nil {
199 return err
200 } else if !fipsApproved {
201 priv.fipsApproved = false
202 }
203
204 if priv.dP == nil {
205
206 priv.fipsApproved = false
207 return nil
208 }
209
210 N := priv.pub.N
211 p := priv.p
212 q := priv.q
213
214
215 if p.BitLen() != q.BitLen() {
216 priv.fipsApproved = false
217 }
218
219
220 pN := bigmod.NewNat().ExpandFor(N)
221 if _, err := pN.SetBytes(p.Nat().Bytes(p), N); err != nil {
222 return errors.New("crypto/rsa: invalid prime")
223 }
224 qN := bigmod.NewNat().ExpandFor(N)
225 if _, err := qN.SetBytes(q.Nat().Bytes(q), N); err != nil {
226 return errors.New("crypto/rsa: invalid prime")
227 }
228 if pN.Mul(qN, N).IsZero() != 1 {
229 return errors.New("crypto/rsa: p * q != n")
230 }
231
232
233
234
235
236
237
238
239
240 pMinus1, err := bigmod.NewModulus(p.Nat().SubOne(p).Bytes(p))
241 if err != nil {
242 return errors.New("crypto/rsa: invalid prime")
243 }
244 dP, err := bigmod.NewNat().SetBytes(priv.dP, pMinus1)
245 if err != nil {
246 return errors.New("crypto/rsa: invalid CRT exponent")
247 }
248 de := bigmod.NewNat()
249 de.SetUint(uint(priv.pub.E)).ExpandFor(pMinus1)
250 de.Mul(dP, pMinus1)
251 if de.IsOne() != 1 {
252 return errors.New("crypto/rsa: invalid CRT exponent")
253 }
254
255 qMinus1, err := bigmod.NewModulus(q.Nat().SubOne(q).Bytes(q))
256 if err != nil {
257 return errors.New("crypto/rsa: invalid prime")
258 }
259 dQ, err := bigmod.NewNat().SetBytes(priv.dQ, qMinus1)
260 if err != nil {
261 return errors.New("crypto/rsa: invalid CRT exponent")
262 }
263 de.SetUint(uint(priv.pub.E)).ExpandFor(qMinus1)
264 de.Mul(dQ, qMinus1)
265 if de.IsOne() != 1 {
266 return errors.New("crypto/rsa: invalid CRT exponent")
267 }
268
269
270 qP, err := bigmod.NewNat().SetOverflowingBytes(q.Nat().Bytes(q), p)
271 if err != nil {
272
273 qP = bigmod.NewNat().Mod(q.Nat(), p)
274 }
275 if qP.Mul(priv.qInv, p).IsOne() != 1 {
276 return errors.New("crypto/rsa: invalid CRT coefficient")
277 }
278
279
280
281 dP1 := bigmod.NewNat().Mod(priv.d, pMinus1)
282 if dP1.Equal(dP) != 1 {
283 return errors.New("crypto/rsa: d does not match dP")
284 }
285 dQ1 := bigmod.NewNat().Mod(priv.d, qMinus1)
286 if dQ1.Equal(dQ) != 1 {
287 return errors.New("crypto/rsa: d does not match dQ")
288 }
289
290
291
292
293
294
295
296 diff := bigmod.NewNat()
297 if qP, err := bigmod.NewNat().SetBytes(q.Nat().Bytes(q), p); err != nil {
298
299 pQ, err := bigmod.NewNat().SetBytes(p.Nat().Bytes(p), q)
300 if err != nil {
301 return errors.New("crypto/rsa: p == q")
302 }
303
304 diff.ExpandFor(q).Sub(pQ, q)
305 } else {
306
307
308 diff.ExpandFor(p).Sub(qP, p)
309 }
310
311
312 if diff.BitLenVarTime() <= N.BitLen()/2-100 {
313 return errors.New("crypto/rsa: |p - q| too small")
314 }
315
316
317
318
319
320
321
322 if priv.d.BitLenVarTime() <= N.BitLen()/2 {
323 return errors.New("crypto/rsa: d too small")
324 }
325
326 return nil
327 }
328
329 func checkPublicKey(pub *PublicKey) (fipsApproved bool, err error) {
330 fipsApproved = true
331 if pub.N == nil {
332 return false, errors.New("crypto/rsa: missing public modulus")
333 }
334 if pub.N.Nat().IsOdd() == 0 {
335 return false, errors.New("crypto/rsa: public modulus is even")
336 }
337
338
339
340 if pub.N.BitLen() < 2048 {
341 fipsApproved = false
342 }
343 if pub.N.BitLen()%2 == 1 {
344 fipsApproved = false
345 }
346 if pub.E < 2 {
347 return false, errors.New("crypto/rsa: public exponent too small or negative")
348 }
349
350
351 if pub.E&1 == 0 {
352 return false, errors.New("crypto/rsa: public exponent is even")
353 }
354
355
356 if pub.E <= 1<<16 {
357 fipsApproved = false
358 }
359
360
361
362
363 if pub.E > 1<<31-1 {
364 return false, errors.New("crypto/rsa: public exponent too large")
365 }
366 return fipsApproved, nil
367 }
368
369
370 func Encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
371 fips140.RecordNonApproved()
372 if _, err := checkPublicKey(pub); err != nil {
373 return nil, err
374 }
375 return encrypt(pub, plaintext)
376 }
377
378 func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
379 m, err := bigmod.NewNat().SetBytes(plaintext, pub.N)
380 if err != nil {
381 return nil, err
382 }
383 return bigmod.NewNat().ExpShortVarTime(m, uint(pub.E), pub.N).Bytes(pub.N), nil
384 }
385
386 var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA key size")
387 var ErrDecryption = errors.New("crypto/rsa: decryption error")
388 var ErrVerification = errors.New("crypto/rsa: verification error")
389
390 const withCheck = true
391 const noCheck = false
392
393
394 func DecryptWithoutCheck(priv *PrivateKey, ciphertext []byte) ([]byte, error) {
395 fips140.RecordNonApproved()
396 return decrypt(priv, ciphertext, noCheck)
397 }
398
399
400
401 func DecryptWithCheck(priv *PrivateKey, ciphertext []byte) ([]byte, error) {
402 fips140.RecordNonApproved()
403 return decrypt(priv, ciphertext, withCheck)
404 }
405
406
407
408
409 func decrypt(priv *PrivateKey, ciphertext []byte, check bool) ([]byte, error) {
410 if !priv.fipsApproved {
411 fips140.RecordNonApproved()
412 }
413
414 var m *bigmod.Nat
415 N, E := priv.pub.N, priv.pub.E
416
417 c, err := bigmod.NewNat().SetBytes(ciphertext, N)
418 if err != nil {
419 return nil, ErrDecryption
420 }
421
422 if priv.dP == nil {
423
424 fips140.RecordNonApproved()
425 m = bigmod.NewNat().Exp(c, priv.d.Bytes(N), N)
426
427 } else {
428 P, Q := priv.p, priv.q
429 t0 := bigmod.NewNat()
430
431 m = bigmod.NewNat().Exp(t0.Mod(c, P), priv.dP, P)
432
433 m2 := bigmod.NewNat().Exp(t0.Mod(c, Q), priv.dQ, Q)
434
435 m.Sub(t0.Mod(m2, P), P)
436
437 m.Mul(priv.qInv, P)
438
439 m.ExpandFor(N).Mul(t0.Mod(Q.Nat(), N), N)
440
441 m.Add(m2.ExpandFor(N), N)
442 }
443
444 if check {
445 c1 := bigmod.NewNat().ExpShortVarTime(m, uint(E), N)
446 if c1.Equal(c) != 1 {
447 return nil, ErrDecryption
448 }
449 }
450
451 return m.Bytes(N), nil
452 }
453
View as plain text