1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ecdsa
18
19 import (
20 "crypto"
21 "crypto/ecdh"
22 "crypto/elliptic"
23 "crypto/internal/boring"
24 "crypto/internal/boring/bbig"
25 "crypto/internal/fips140/ecdsa"
26 "crypto/internal/fips140/nistec"
27 "crypto/internal/fips140cache"
28 "crypto/internal/fips140hash"
29 "crypto/internal/fips140only"
30 "crypto/internal/rand"
31 "crypto/sha512"
32 "crypto/subtle"
33 "errors"
34 "io"
35 "math/big"
36
37 "golang.org/x/crypto/cryptobyte"
38 "golang.org/x/crypto/cryptobyte/asn1"
39 )
40
41
42 type PublicKey struct {
43 elliptic.Curve
44
45
46
47
48
49
50
51
52
53
54 X, Y *big.Int
55 }
56
57
58
59
60
61
62
63 func (pub *PublicKey) ECDH() (*ecdh.PublicKey, error) {
64 c := curveToECDH(pub.Curve)
65 if c == nil {
66 return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
67 }
68 k, err := pub.Bytes()
69 if err != nil {
70 return nil, err
71 }
72 return c.NewPublicKey(k)
73 }
74
75
76
77
78
79
80 func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
81 xx, ok := x.(*PublicKey)
82 if !ok {
83 return false
84 }
85 return bigIntEqual(pub.X, xx.X) && bigIntEqual(pub.Y, xx.Y) &&
86
87
88
89
90 pub.Curve == xx.Curve
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 func ParseUncompressedPublicKey(curve elliptic.Curve, data []byte) (*PublicKey, error) {
108 if len(data) < 1 || data[0] != 4 {
109 return nil, errors.New("ecdsa: invalid uncompressed public key")
110 }
111 switch curve {
112 case elliptic.P224():
113 return parseUncompressedPublicKey(ecdsa.P224(), curve, data)
114 case elliptic.P256():
115 return parseUncompressedPublicKey(ecdsa.P256(), curve, data)
116 case elliptic.P384():
117 return parseUncompressedPublicKey(ecdsa.P384(), curve, data)
118 case elliptic.P521():
119 return parseUncompressedPublicKey(ecdsa.P521(), curve, data)
120 default:
121 return nil, errors.New("ecdsa: curve not supported by ParseUncompressedPublicKey")
122 }
123 }
124
125 func parseUncompressedPublicKey[P ecdsa.Point[P]](c *ecdsa.Curve[P], curve elliptic.Curve, data []byte) (*PublicKey, error) {
126 k, err := ecdsa.NewPublicKey(c, data)
127 if err != nil {
128 return nil, err
129 }
130 return publicKeyFromFIPS(curve, k)
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144 func (pub *PublicKey) Bytes() ([]byte, error) {
145 switch pub.Curve {
146 case elliptic.P224():
147 return publicKeyBytes(ecdsa.P224(), pub)
148 case elliptic.P256():
149 return publicKeyBytes(ecdsa.P256(), pub)
150 case elliptic.P384():
151 return publicKeyBytes(ecdsa.P384(), pub)
152 case elliptic.P521():
153 return publicKeyBytes(ecdsa.P521(), pub)
154 default:
155 return nil, errors.New("ecdsa: curve not supported by PublicKey.Bytes")
156 }
157 }
158
159 func publicKeyBytes[P ecdsa.Point[P]](c *ecdsa.Curve[P], pub *PublicKey) ([]byte, error) {
160 k, err := publicKeyToFIPS(c, pub)
161 if err != nil {
162 return nil, err
163 }
164 return k.Bytes(), nil
165 }
166
167
168 type PrivateKey struct {
169 PublicKey
170
171
172
173
174
175
176
177
178
179 D *big.Int
180 }
181
182
183
184
185 func (priv *PrivateKey) ECDH() (*ecdh.PrivateKey, error) {
186 c := curveToECDH(priv.Curve)
187 if c == nil {
188 return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
189 }
190 k, err := priv.Bytes()
191 if err != nil {
192 return nil, err
193 }
194 return c.NewPrivateKey(k)
195 }
196
197 func curveToECDH(c elliptic.Curve) ecdh.Curve {
198 switch c {
199 case elliptic.P256():
200 return ecdh.P256()
201 case elliptic.P384():
202 return ecdh.P384()
203 case elliptic.P521():
204 return ecdh.P521()
205 default:
206 return nil
207 }
208 }
209
210
211 func (priv *PrivateKey) Public() crypto.PublicKey {
212 return &priv.PublicKey
213 }
214
215
216
217
218 func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
219 xx, ok := x.(*PrivateKey)
220 if !ok {
221 return false
222 }
223 return priv.PublicKey.Equal(&xx.PublicKey) && bigIntEqual(priv.D, xx.D)
224 }
225
226
227
228 func bigIntEqual(a, b *big.Int) bool {
229 return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 func ParseRawPrivateKey(curve elliptic.Curve, data []byte) (*PrivateKey, error) {
247 switch curve {
248 case elliptic.P224():
249 return parseRawPrivateKey(ecdsa.P224(), nistec.NewP224Point, curve, data)
250 case elliptic.P256():
251 return parseRawPrivateKey(ecdsa.P256(), nistec.NewP256Point, curve, data)
252 case elliptic.P384():
253 return parseRawPrivateKey(ecdsa.P384(), nistec.NewP384Point, curve, data)
254 case elliptic.P521():
255 return parseRawPrivateKey(ecdsa.P521(), nistec.NewP521Point, curve, data)
256 default:
257 return nil, errors.New("ecdsa: curve not supported by ParseRawPrivateKey")
258 }
259 }
260
261 func parseRawPrivateKey[P ecdsa.Point[P]](c *ecdsa.Curve[P], newPoint func() P, curve elliptic.Curve, data []byte) (*PrivateKey, error) {
262 q, err := newPoint().ScalarBaseMult(data)
263 if err != nil {
264 return nil, err
265 }
266 k, err := ecdsa.NewPrivateKey(c, data, q.Bytes())
267 if err != nil {
268 return nil, err
269 }
270 return privateKeyFromFIPS(curve, k)
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285 func (priv *PrivateKey) Bytes() ([]byte, error) {
286 switch priv.Curve {
287 case elliptic.P224():
288 return privateKeyBytes(ecdsa.P224(), priv)
289 case elliptic.P256():
290 return privateKeyBytes(ecdsa.P256(), priv)
291 case elliptic.P384():
292 return privateKeyBytes(ecdsa.P384(), priv)
293 case elliptic.P521():
294 return privateKeyBytes(ecdsa.P521(), priv)
295 default:
296 return nil, errors.New("ecdsa: curve not supported by PrivateKey.Bytes")
297 }
298 }
299
300 func privateKeyBytes[P ecdsa.Point[P]](c *ecdsa.Curve[P], priv *PrivateKey) ([]byte, error) {
301 k, err := privateKeyToFIPS(c, priv)
302 if err != nil {
303 return nil, err
304 }
305 return k.Bytes(), nil
306 }
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323 func (priv *PrivateKey) Sign(random io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
324 if opts != nil {
325 h := opts.HashFunc()
326 if h == 0 {
327 return nil, errors.New("ecdsa: Sign must be called with a hash, not with crypto.Hash(0)")
328 }
329 if h.Size() != len(digest) {
330 return nil, errors.New("ecdsa: hash length does not match hash function")
331 }
332 }
333 if random == nil {
334 return signRFC6979(priv, digest, opts)
335 }
336 random = rand.CustomReader(random)
337 return SignASN1(random, priv, digest)
338 }
339
340
341
342
343
344
345 func GenerateKey(c elliptic.Curve, r io.Reader) (*PrivateKey, error) {
346 if boring.Enabled && rand.IsDefaultReader(r) {
347 x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
348 if err != nil {
349 return nil, err
350 }
351 return &PrivateKey{PublicKey: PublicKey{Curve: c, X: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil
352 }
353 boring.UnreachableExceptTests()
354
355 r = rand.CustomReader(r)
356
357 switch c.Params() {
358 case elliptic.P224().Params():
359 return generateFIPS(c, ecdsa.P224(), r)
360 case elliptic.P256().Params():
361 return generateFIPS(c, ecdsa.P256(), r)
362 case elliptic.P384().Params():
363 return generateFIPS(c, ecdsa.P384(), r)
364 case elliptic.P521().Params():
365 return generateFIPS(c, ecdsa.P521(), r)
366 default:
367 return generateLegacy(c, r)
368 }
369 }
370
371 func generateFIPS[P ecdsa.Point[P]](curve elliptic.Curve, c *ecdsa.Curve[P], rand io.Reader) (*PrivateKey, error) {
372 if fips140only.Enforced() && !fips140only.ApprovedRandomReader(rand) {
373 return nil, errors.New("crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
374 }
375 privateKey, err := ecdsa.GenerateKey(c, rand)
376 if err != nil {
377 return nil, err
378 }
379 return privateKeyFromFIPS(curve, privateKey)
380 }
381
382
383
384
385
386
387
388
389
390
391 func SignASN1(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
392 if len(hash) == 0 {
393 return nil, errors.New("ecdsa: hash cannot be empty")
394 }
395
396 if boring.Enabled && rand.IsDefaultReader(r) {
397 b, err := boringPrivateKey(priv)
398 if err != nil {
399 return nil, err
400 }
401 return boring.SignMarshalECDSA(b, hash)
402 }
403 boring.UnreachableExceptTests()
404
405 r = rand.CustomReader(r)
406
407 switch priv.Curve.Params() {
408 case elliptic.P224().Params():
409 return signFIPS(ecdsa.P224(), priv, r, hash)
410 case elliptic.P256().Params():
411 return signFIPS(ecdsa.P256(), priv, r, hash)
412 case elliptic.P384().Params():
413 return signFIPS(ecdsa.P384(), priv, r, hash)
414 case elliptic.P521().Params():
415 return signFIPS(ecdsa.P521(), priv, r, hash)
416 default:
417 return signLegacy(priv, r, hash)
418 }
419 }
420
421 func signFIPS[P ecdsa.Point[P]](c *ecdsa.Curve[P], priv *PrivateKey, rand io.Reader, hash []byte) ([]byte, error) {
422 if fips140only.Enforced() && !fips140only.ApprovedRandomReader(rand) {
423 return nil, errors.New("crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
424 }
425 k, err := privateKeyToFIPS(c, priv)
426 if err != nil {
427 return nil, err
428 }
429
430
431
432 sig, err := ecdsa.Sign(c, sha512.New, k, rand, hash)
433 if err != nil {
434 return nil, err
435 }
436 return encodeSignature(sig.R, sig.S)
437 }
438
439 func signRFC6979(priv *PrivateKey, hash []byte, opts crypto.SignerOpts) ([]byte, error) {
440 if opts == nil {
441 return nil, errors.New("ecdsa: Sign called with nil random and nil opts")
442 }
443 h := opts.HashFunc()
444 switch priv.Curve.Params() {
445 case elliptic.P224().Params():
446 return signFIPSDeterministic(ecdsa.P224(), h, priv, hash)
447 case elliptic.P256().Params():
448 return signFIPSDeterministic(ecdsa.P256(), h, priv, hash)
449 case elliptic.P384().Params():
450 return signFIPSDeterministic(ecdsa.P384(), h, priv, hash)
451 case elliptic.P521().Params():
452 return signFIPSDeterministic(ecdsa.P521(), h, priv, hash)
453 default:
454 return nil, errors.New("ecdsa: curve not supported by deterministic signatures")
455 }
456 }
457
458 func signFIPSDeterministic[P ecdsa.Point[P]](c *ecdsa.Curve[P], hashFunc crypto.Hash, priv *PrivateKey, hash []byte) ([]byte, error) {
459 k, err := privateKeyToFIPS(c, priv)
460 if err != nil {
461 return nil, err
462 }
463 if !hashFunc.Available() {
464 return nil, errors.New("ecdsa: requested hash function unavailable: " + hashFunc.String())
465 }
466 h := fips140hash.UnwrapNew(hashFunc.New)
467 if fips140only.Enforced() && !fips140only.ApprovedHash(h()) {
468 return nil, errors.New("crypto/ecdsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
469 }
470 sig, err := ecdsa.SignDeterministic(c, h, k, hash)
471 if err != nil {
472 return nil, err
473 }
474 return encodeSignature(sig.R, sig.S)
475 }
476
477 func encodeSignature(r, s []byte) ([]byte, error) {
478 var b cryptobyte.Builder
479 b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
480 addASN1IntBytes(b, r)
481 addASN1IntBytes(b, s)
482 })
483 return b.Bytes()
484 }
485
486
487
488 func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
489 for len(bytes) > 0 && bytes[0] == 0 {
490 bytes = bytes[1:]
491 }
492 if len(bytes) == 0 {
493 b.SetError(errors.New("invalid integer"))
494 return
495 }
496 b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
497 if bytes[0]&0x80 != 0 {
498 c.AddUint8(0)
499 }
500 c.AddBytes(bytes)
501 })
502 }
503
504
505
506
507
508
509 func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
510 if len(hash) == 0 {
511 return false
512 }
513
514 if boring.Enabled {
515 key, err := boringPublicKey(pub)
516 if err != nil {
517 return false
518 }
519 return boring.VerifyECDSA(key, hash, sig)
520 }
521 boring.UnreachableExceptTests()
522
523 switch pub.Curve.Params() {
524 case elliptic.P224().Params():
525 return verifyFIPS(ecdsa.P224(), pub, hash, sig)
526 case elliptic.P256().Params():
527 return verifyFIPS(ecdsa.P256(), pub, hash, sig)
528 case elliptic.P384().Params():
529 return verifyFIPS(ecdsa.P384(), pub, hash, sig)
530 case elliptic.P521().Params():
531 return verifyFIPS(ecdsa.P521(), pub, hash, sig)
532 default:
533 return verifyLegacy(pub, hash, sig)
534 }
535 }
536
537 func verifyFIPS[P ecdsa.Point[P]](c *ecdsa.Curve[P], pub *PublicKey, hash, sig []byte) bool {
538 r, s, err := parseSignature(sig)
539 if err != nil {
540 return false
541 }
542 k, err := publicKeyToFIPS(c, pub)
543 if err != nil {
544 return false
545 }
546 if err := ecdsa.Verify(c, k, hash, &ecdsa.Signature{R: r, S: s}); err != nil {
547 return false
548 }
549 return true
550 }
551
552 func parseSignature(sig []byte) (r, s []byte, err error) {
553 var inner cryptobyte.String
554 input := cryptobyte.String(sig)
555 if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
556 !input.Empty() ||
557 !inner.ReadASN1Integer(&r) ||
558 !inner.ReadASN1Integer(&s) ||
559 !inner.Empty() {
560 return nil, nil, errors.New("invalid ASN.1")
561 }
562 return r, s, nil
563 }
564
565 func publicKeyFromFIPS(curve elliptic.Curve, pub *ecdsa.PublicKey) (*PublicKey, error) {
566 x, y, err := pointToAffine(curve, pub.Bytes())
567 if err != nil {
568 return nil, err
569 }
570 return &PublicKey{Curve: curve, X: x, Y: y}, nil
571 }
572
573 func privateKeyFromFIPS(curve elliptic.Curve, priv *ecdsa.PrivateKey) (*PrivateKey, error) {
574 pub, err := publicKeyFromFIPS(curve, priv.PublicKey())
575 if err != nil {
576 return nil, err
577 }
578 return &PrivateKey{PublicKey: *pub, D: new(big.Int).SetBytes(priv.Bytes())}, nil
579 }
580
581 func publicKeyToFIPS[P ecdsa.Point[P]](c *ecdsa.Curve[P], pub *PublicKey) (*ecdsa.PublicKey, error) {
582 Q, err := pointFromAffine(pub.Curve, pub.X, pub.Y)
583 if err != nil {
584 return nil, err
585 }
586 return ecdsa.NewPublicKey(c, Q)
587 }
588
589 var privateKeyCache fips140cache.Cache[PrivateKey, ecdsa.PrivateKey]
590
591 func privateKeyToFIPS[P ecdsa.Point[P]](c *ecdsa.Curve[P], priv *PrivateKey) (*ecdsa.PrivateKey, error) {
592 Q, err := pointFromAffine(priv.Curve, priv.X, priv.Y)
593 if err != nil {
594 return nil, err
595 }
596
597
598 if priv.D.BitLen() > priv.Curve.Params().N.BitLen() {
599 return nil, errors.New("ecdsa: private key scalar too large")
600 }
601 if priv.D.Sign() <= 0 {
602 return nil, errors.New("ecdsa: private key scalar is zero or negative")
603 }
604
605 size := (priv.Curve.Params().N.BitLen() + 7) / 8
606 const maxScalarSize = 66
607 if size > maxScalarSize {
608 return nil, errors.New("ecdsa: internal error: curve size too large")
609 }
610 D := priv.D.FillBytes(make([]byte, size, maxScalarSize))
611
612 return privateKeyCache.Get(priv, func() (*ecdsa.PrivateKey, error) {
613 return ecdsa.NewPrivateKey(c, D, Q)
614 }, func(k *ecdsa.PrivateKey) bool {
615 return subtle.ConstantTimeCompare(k.PublicKey().Bytes(), Q) == 1 &&
616 subtle.ConstantTimeCompare(k.Bytes(), D) == 1
617 })
618 }
619
620
621 func pointFromAffine(curve elliptic.Curve, x, y *big.Int) ([]byte, error) {
622 bitSize := curve.Params().BitSize
623
624 if x.Sign() < 0 || y.Sign() < 0 {
625 return nil, errors.New("negative coordinate")
626 }
627 if x.BitLen() > bitSize || y.BitLen() > bitSize {
628 return nil, errors.New("overflowing coordinate")
629 }
630
631 byteLen := (bitSize + 7) / 8
632 buf := make([]byte, 1+2*byteLen)
633 buf[0] = 4
634 x.FillBytes(buf[1 : 1+byteLen])
635 y.FillBytes(buf[1+byteLen : 1+2*byteLen])
636 return buf, nil
637 }
638
639
640 func pointToAffine(curve elliptic.Curve, p []byte) (x, y *big.Int, err error) {
641 if len(p) == 1 && p[0] == 0 {
642
643 return nil, nil, errors.New("ecdsa: public key point is the infinity")
644 }
645 byteLen := (curve.Params().BitSize + 7) / 8
646 x = new(big.Int).SetBytes(p[1 : 1+byteLen])
647 y = new(big.Int).SetBytes(p[1+byteLen:])
648 return x, y, nil
649 }
650
View as plain text