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