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