Source file src/crypto/ecdsa/ecdsa.go

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
     6  // defined in [FIPS 186-5].
     7  //
     8  // Signatures generated by this package are not deterministic, but entropy is
     9  // mixed with the private key and the message, achieving the same level of
    10  // security in case of randomness source failure.
    11  //
    12  // Operations involving private keys are implemented using constant-time
    13  // algorithms, as long as an [elliptic.Curve] returned by [elliptic.P224],
    14  // [elliptic.P256], [elliptic.P384], or [elliptic.P521] is used.
    15  //
    16  // [FIPS 186-5]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
    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  // PublicKey represents an ECDSA public key.
    42  type PublicKey struct {
    43  	elliptic.Curve
    44  
    45  	// X, Y are the coordinates of the public key point.
    46  	//
    47  	// Modifying the raw coordinates can produce invalid keys, and may
    48  	// invalidate internal optimizations; moreover, [big.Int] methods are not
    49  	// suitable for operating on cryptographic values. To encode and decode
    50  	// PublicKey values, use [PublicKey.Bytes] and [ParseUncompressedPublicKey]
    51  	// or [crypto/x509.MarshalPKIXPublicKey] and [crypto/x509.ParsePKIXPublicKey].
    52  	// For ECDH, use [crypto/ecdh]. For lower-level elliptic curve operations,
    53  	// use a third-party module like filippo.io/nistec.
    54  	//
    55  	// These fields will be deprecated in Go 1.26.
    56  	X, Y *big.Int
    57  }
    58  
    59  // Any methods implemented on PublicKey might need to also be implemented on
    60  // PrivateKey, as the latter embeds the former and will expose its methods.
    61  
    62  // ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is
    63  // invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the
    64  // Curve is not supported by crypto/ecdh.
    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  // Equal reports whether pub and x have the same value.
    77  //
    78  // Two keys are only considered to have the same value if they have the same Curve value.
    79  // Note that for example [elliptic.P256] and elliptic.P256().Params() are different
    80  // values, as the latter is a generic not constant time implementation.
    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  		// Standard library Curve implementations are singletons, so this check
    88  		// will work for those. Other Curves might be equivalent even if not
    89  		// singletons, but there is no definitive way to check for that, and
    90  		// better to err on the side of safety.
    91  		pub.Curve == xx.Curve
    92  }
    93  
    94  // ParseUncompressedPublicKey parses a public key encoded as an uncompressed
    95  // point according to SEC 1, Version 2.0, Section 2.3.3 (also known as the X9.62
    96  // uncompressed format). It returns an error if the point is not in uncompressed
    97  // form, is not on the curve, or is the point at infinity.
    98  //
    99  // curve must be one of [elliptic.P224], [elliptic.P256], [elliptic.P384], or
   100  // [elliptic.P521], or ParseUncompressedPublicKey returns an error.
   101  //
   102  // ParseUncompressedPublicKey accepts the same format as
   103  // [ecdh.Curve.NewPublicKey] does for NIST curves, but returns a [PublicKey]
   104  // instead of an [ecdh.PublicKey].
   105  //
   106  // Note that public keys are more commonly encoded in DER (or PEM) format, which
   107  // can be parsed with [crypto/x509.ParsePKIXPublicKey] (and [encoding/pem]).
   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  // Bytes encodes the public key as an uncompressed point according to SEC 1,
   135  // Version 2.0, Section 2.3.3 (also known as the X9.62 uncompressed format).
   136  // It returns an error if the public key is invalid.
   137  //
   138  // PublicKey.Curve must be one of [elliptic.P224], [elliptic.P256],
   139  // [elliptic.P384], or [elliptic.P521], or Bytes returns an error.
   140  //
   141  // Bytes returns the same format as [ecdh.PublicKey.Bytes] does for NIST curves.
   142  //
   143  // Note that public keys are more commonly encoded in DER (or PEM) format, which
   144  // can be generated with [crypto/x509.MarshalPKIXPublicKey] (and [encoding/pem]).
   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  // PrivateKey represents an ECDSA private key.
   169  type PrivateKey struct {
   170  	PublicKey
   171  
   172  	// D is the private scalar value.
   173  	//
   174  	// Modifying the raw value can produce invalid keys, and may
   175  	// invalidate internal optimizations; moreover, [big.Int] methods are not
   176  	// suitable for operating on cryptographic values. To encode and decode
   177  	// PrivateKey values, use [PrivateKey.Bytes] and [ParseRawPrivateKey] or
   178  	// [crypto/x509.MarshalPKCS8PrivateKey] and [crypto/x509.ParsePKCS8PrivateKey].
   179  	// For ECDH, use [crypto/ecdh].
   180  	//
   181  	// This field will be deprecated in Go 1.26.
   182  	D *big.Int
   183  }
   184  
   185  // ECDH returns k as a [ecdh.PrivateKey]. It returns an error if the key is
   186  // invalid according to the definition of [ecdh.Curve.NewPrivateKey], or if the
   187  // Curve is not supported by [crypto/ecdh].
   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  // Public returns the public key corresponding to priv.
   214  func (priv *PrivateKey) Public() crypto.PublicKey {
   215  	return &priv.PublicKey
   216  }
   217  
   218  // Equal reports whether priv and x have the same value.
   219  //
   220  // See [PublicKey.Equal] for details on how Curve is compared.
   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  // bigIntEqual reports whether a and b are equal leaking only their bit length
   230  // through timing side-channels.
   231  func bigIntEqual(a, b *big.Int) bool {
   232  	return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
   233  }
   234  
   235  // ParseRawPrivateKey parses a private key encoded as a fixed-length big-endian
   236  // integer, according to SEC 1, Version 2.0, Section 2.3.6 (sometimes referred
   237  // to as the raw format). It returns an error if the value is not reduced modulo
   238  // the curve's order, or if it's zero.
   239  //
   240  // curve must be one of [elliptic.P224], [elliptic.P256], [elliptic.P384], or
   241  // [elliptic.P521], or ParseRawPrivateKey returns an error.
   242  //
   243  // ParseRawPrivateKey accepts the same format as [ecdh.Curve.NewPrivateKey] does
   244  // for NIST curves, but returns a [PrivateKey] instead of an [ecdh.PrivateKey].
   245  //
   246  // Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format,
   247  // which can be parsed with [crypto/x509.ParseECPrivateKey] or
   248  // [crypto/x509.ParsePKCS8PrivateKey] (and [encoding/pem]).
   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  // Bytes encodes the private key as a fixed-length big-endian integer according
   277  // to SEC 1, Version 2.0, Section 2.3.6 (sometimes referred to as the raw
   278  // format). It returns an error if the private key is invalid.
   279  //
   280  // PrivateKey.Curve must be one of [elliptic.P224], [elliptic.P256],
   281  // [elliptic.P384], or [elliptic.P521], or Bytes returns an error.
   282  //
   283  // Bytes returns the same format as [ecdh.PrivateKey.Bytes] does for NIST curves.
   284  //
   285  // Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format,
   286  // which can be generated with [crypto/x509.MarshalECPrivateKey] or
   287  // [crypto/x509.MarshalPKCS8PrivateKey] (and [encoding/pem]).
   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  // Sign signs a hash (which should be the result of hashing a larger message
   312  // with opts.HashFunc()) using the private key, priv. If the hash is longer than
   313  // the bit-length of the private key's curve order, the hash will be truncated
   314  // to that length. It returns the ASN.1 encoded signature, like [SignASN1].
   315  //
   316  // If rand is not nil, the signature is randomized. Most applications should use
   317  // [crypto/rand.Reader] as rand. Note that the returned signature does not
   318  // depend deterministically on the bytes read from rand, and may change between
   319  // calls and/or between versions.
   320  //
   321  // If rand is nil, Sign will produce a deterministic signature according to RFC
   322  // 6979. When producing a deterministic signature, opts.HashFunc() must be the
   323  // function used to produce digest and priv.Curve must be one of
   324  // [elliptic.P224], [elliptic.P256], [elliptic.P384], or [elliptic.P521].
   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  // GenerateKey generates a new ECDSA private key for the specified curve.
   333  //
   334  // Most applications should use [crypto/rand.Reader] as rand. Note that the
   335  // returned key does not depend deterministically on the bytes read from rand,
   336  // and may change between calls and/or between versions.
   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  // errNoAsm is returned by signAsm and verifyAsm when the assembly
   375  // implementation is not available.
   376  var errNoAsm = errors.New("no assembly implementation available")
   377  
   378  // SignASN1 signs a hash (which should be the result of hashing a larger message)
   379  // using the private key, priv. If the hash is longer than the bit-length of the
   380  // private key's curve order, the hash will be truncated to that length. It
   381  // returns the ASN.1 encoded signature.
   382  //
   383  // The signature is randomized. Most applications should use [crypto/rand.Reader]
   384  // as rand. Note that the returned signature does not depend deterministically on
   385  // the bytes read from rand, and may change between calls and/or between versions.
   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  	// Always using SHA-512 instead of the hash that computed hash is
   421  	// technically a violation of draft-irtf-cfrg-det-sigs-with-noise-04 but in
   422  	// our API we don't get to know what it was, and this has no security impact.
   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  // addASN1IntBytes encodes in ASN.1 a positive integer represented as
   478  // a big-endian byte slice with zero or more leading zeroes.
   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  // VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
   496  // public key, pub. Its return value records whether the signature is valid.
   497  //
   498  // The inputs are not considered confidential, and may leak through timing side
   499  // channels, or if an attacker has control of part of the inputs.
   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 /* enough for a P-521 private key */)
   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  // pointFromAffine is used to convert the PublicKey to a nistec SetBytes input.
   605  func pointFromAffine(curve elliptic.Curve, x, y *big.Int) ([]byte, error) {
   606  	bitSize := curve.Params().BitSize
   607  	// Reject values that would not get correctly encoded.
   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  	// Encode the coordinates and let SetBytes reject invalid points.
   615  	byteLen := (bitSize + 7) / 8
   616  	buf := make([]byte, 1+2*byteLen)
   617  	buf[0] = 4 // uncompressed point
   618  	x.FillBytes(buf[1 : 1+byteLen])
   619  	y.FillBytes(buf[1+byteLen : 1+2*byteLen])
   620  	return buf, nil
   621  }
   622  
   623  // pointToAffine is used to convert a nistec Bytes encoding to a PublicKey.
   624  func pointToAffine(curve elliptic.Curve, p []byte) (x, y *big.Int, err error) {
   625  	if len(p) == 1 && p[0] == 0 {
   626  		// This is the encoding of the point at infinity.
   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