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/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  // 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  	// Deprecated: 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  	X, Y *big.Int
    55  }
    56  
    57  // Any methods implemented on PublicKey might need to also be implemented on
    58  // PrivateKey, as the latter embeds the former and will expose its methods.
    59  
    60  // ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is
    61  // invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the
    62  // Curve is not supported by crypto/ecdh.
    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  // Equal reports whether pub and x have the same value.
    76  //
    77  // Two keys are only considered to have the same value if they have the same Curve value.
    78  // Note that for example [elliptic.P256] and elliptic.P256().Params() are different
    79  // values, as the latter is a generic not constant time implementation.
    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  		// Standard library Curve implementations are singletons, so this check
    87  		// will work for those. Other Curves might be equivalent even if not
    88  		// singletons, but there is no definitive way to check for that, and
    89  		// better to err on the side of safety.
    90  		pub.Curve == xx.Curve
    91  }
    92  
    93  // ParseUncompressedPublicKey parses a public key encoded as an uncompressed
    94  // point according to SEC 1, Version 2.0, Section 2.3.3 (also known as the X9.62
    95  // uncompressed format). It returns an error if the point is not in uncompressed
    96  // form, is not on the curve, or is the point at infinity.
    97  //
    98  // curve must be one of [elliptic.P224], [elliptic.P256], [elliptic.P384], or
    99  // [elliptic.P521], or ParseUncompressedPublicKey returns an error.
   100  //
   101  // ParseUncompressedPublicKey accepts the same format as
   102  // [ecdh.Curve.NewPublicKey] does for NIST curves, but returns a [PublicKey]
   103  // instead of an [ecdh.PublicKey].
   104  //
   105  // Note that public keys are more commonly encoded in DER (or PEM) format, which
   106  // can be parsed with [crypto/x509.ParsePKIXPublicKey] (and [encoding/pem]).
   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  // Bytes encodes the public key as an uncompressed point according to SEC 1,
   134  // Version 2.0, Section 2.3.3 (also known as the X9.62 uncompressed format).
   135  // It returns an error if the public key is invalid.
   136  //
   137  // PublicKey.Curve must be one of [elliptic.P224], [elliptic.P256],
   138  // [elliptic.P384], or [elliptic.P521], or Bytes returns an error.
   139  //
   140  // Bytes returns the same format as [ecdh.PublicKey.Bytes] does for NIST curves.
   141  //
   142  // Note that public keys are more commonly encoded in DER (or PEM) format, which
   143  // can be generated with [crypto/x509.MarshalPKIXPublicKey] (and [encoding/pem]).
   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  // PrivateKey represents an ECDSA private key.
   168  type PrivateKey struct {
   169  	PublicKey
   170  
   171  	// D is the private scalar value.
   172  	//
   173  	// Deprecated: modifying the raw value can produce invalid keys, and may
   174  	// invalidate internal optimizations; moreover, [big.Int] methods are not
   175  	// suitable for operating on cryptographic values. To encode and decode
   176  	// PrivateKey values, use [PrivateKey.Bytes] and [ParseRawPrivateKey] or
   177  	// [crypto/x509.MarshalPKCS8PrivateKey] and [crypto/x509.ParsePKCS8PrivateKey].
   178  	// For ECDH, use [crypto/ecdh].
   179  	D *big.Int
   180  }
   181  
   182  // ECDH returns k as a [ecdh.PrivateKey]. It returns an error if the key is
   183  // invalid according to the definition of [ecdh.Curve.NewPrivateKey], or if the
   184  // Curve is not supported by [crypto/ecdh].
   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  // Public returns the public key corresponding to priv.
   211  func (priv *PrivateKey) Public() crypto.PublicKey {
   212  	return &priv.PublicKey
   213  }
   214  
   215  // Equal reports whether priv and x have the same value.
   216  //
   217  // See [PublicKey.Equal] for details on how Curve is compared.
   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  // bigIntEqual reports whether a and b are equal leaking only their bit length
   227  // through timing side-channels.
   228  func bigIntEqual(a, b *big.Int) bool {
   229  	return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
   230  }
   231  
   232  // ParseRawPrivateKey parses a private key encoded as a fixed-length big-endian
   233  // integer, according to SEC 1, Version 2.0, Section 2.3.6 (sometimes referred
   234  // to as the raw format). It returns an error if the value is not reduced modulo
   235  // the curve's order, or if it's zero.
   236  //
   237  // curve must be one of [elliptic.P224], [elliptic.P256], [elliptic.P384], or
   238  // [elliptic.P521], or ParseRawPrivateKey returns an error.
   239  //
   240  // ParseRawPrivateKey accepts the same format as [ecdh.Curve.NewPrivateKey] does
   241  // for NIST curves, but returns a [PrivateKey] instead of an [ecdh.PrivateKey].
   242  //
   243  // Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format,
   244  // which can be parsed with [crypto/x509.ParseECPrivateKey] or
   245  // [crypto/x509.ParsePKCS8PrivateKey] (and [encoding/pem]).
   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  // Bytes encodes the private key as a fixed-length big-endian integer according
   274  // to SEC 1, Version 2.0, Section 2.3.6 (sometimes referred to as the raw
   275  // format). It returns an error if the private key is invalid.
   276  //
   277  // PrivateKey.Curve must be one of [elliptic.P224], [elliptic.P256],
   278  // [elliptic.P384], or [elliptic.P521], or Bytes returns an error.
   279  //
   280  // Bytes returns the same format as [ecdh.PrivateKey.Bytes] does for NIST curves.
   281  //
   282  // Note that private keys are more commonly encoded in ASN.1 or PKCS#8 format,
   283  // which can be generated with [crypto/x509.MarshalECPrivateKey] or
   284  // [crypto/x509.MarshalPKCS8PrivateKey] (and [encoding/pem]).
   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  // Sign signs a hash (which should be the result of hashing a larger message
   309  // with opts.HashFunc()) using the private key, priv. If the hash is longer than
   310  // the bit-length of the private key's curve order, the hash will be truncated
   311  // to that length. It returns the ASN.1 encoded signature, like [SignASN1].
   312  //
   313  // If random is not nil, the signature is randomized. Most applications should use
   314  // [crypto/rand.Reader] as random, but unless GODEBUG=cryptocustomrand=1 is set, a
   315  // secure source of random bytes is always used, and the actual Reader is ignored.
   316  // The GODEBUG setting will be removed in a future Go release. Instead, use
   317  // [testing/cryptotest.SetGlobalRandom].
   318  //
   319  // If random is nil, Sign will produce a deterministic signature according to RFC
   320  // 6979. When producing a deterministic signature, opts.HashFunc() must be the
   321  // function used to produce digest and priv.Curve must be one of
   322  // [elliptic.P224], [elliptic.P256], [elliptic.P384], or [elliptic.P521].
   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  // GenerateKey generates a new ECDSA private key for the specified curve.
   341  //
   342  // Since Go 1.26, a secure source of random bytes is always used, and the Reader is
   343  // ignored unless GODEBUG=cryptocustomrand=1 is set. This setting will be removed
   344  // in a future Go release. Instead, use [testing/cryptotest.SetGlobalRandom].
   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  // SignASN1 signs a hash (which should be the result of hashing a larger message)
   383  // using the private key, priv. If the hash is longer than the bit-length of the
   384  // private key's curve order, the hash will be truncated to that length. It
   385  // returns the ASN.1 encoded signature.
   386  //
   387  // The signature is randomized. Since Go 1.26, a secure source of random bytes
   388  // is always used, and the Reader is ignored unless GODEBUG=cryptocustomrand=1
   389  // is set. This setting will be removed in a future Go release. Instead, use
   390  // [testing/cryptotest.SetGlobalRandom].
   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  	// Always using SHA-512 instead of the hash that computed hash is
   430  	// technically a violation of draft-irtf-cfrg-det-sigs-with-noise-04 but in
   431  	// our API we don't get to know what it was, and this has no security impact.
   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  // addASN1IntBytes encodes in ASN.1 a positive integer represented as
   487  // a big-endian byte slice with zero or more leading zeroes.
   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  // VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
   505  // public key, pub. Its return value records whether the signature is valid.
   506  //
   507  // The inputs are not considered confidential, and may leak through timing side
   508  // channels, or if an attacker has control of part of the inputs.
   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  	// Reject values that would not get correctly encoded.
   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 // enough for a P-521 private key
   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  // pointFromAffine is used to convert the PublicKey to a nistec SetBytes input.
   621  func pointFromAffine(curve elliptic.Curve, x, y *big.Int) ([]byte, error) {
   622  	bitSize := curve.Params().BitSize
   623  	// Reject values that would not get correctly encoded.
   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  	// Encode the coordinates and let [ecdsa.NewPublicKey] reject invalid points.
   631  	byteLen := (bitSize + 7) / 8
   632  	buf := make([]byte, 1+2*byteLen)
   633  	buf[0] = 4 // uncompressed point
   634  	x.FillBytes(buf[1 : 1+byteLen])
   635  	y.FillBytes(buf[1+byteLen : 1+2*byteLen])
   636  	return buf, nil
   637  }
   638  
   639  // pointToAffine is used to convert a nistec Bytes encoding to a PublicKey.
   640  func pointToAffine(curve elliptic.Curve, p []byte) (x, y *big.Int, err error) {
   641  	if len(p) == 1 && p[0] == 0 {
   642  		// This is the encoding of the point at infinity.
   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