]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/internal/fips140/rsa: check that e and N are odd
authorFilippo Valsorda <filippo@golang.org>
Thu, 28 Nov 2024 18:55:53 +0000 (19:55 +0100)
committerGopher Robot <gobot@golang.org>
Sat, 30 Nov 2024 01:47:06 +0000 (01:47 +0000)
N needs to be odd or we can't call Nat.Exp with it. This was previously
enforced at the Modulus level, but was relaxed in CL 630515.

While at it, also assert that e is odd. If it's even, there is no
possible corresponding private key, and we might as well error out.

Change-Id: I43a6c6e5789683854e4aece650fbf85166b6c318
Reviewed-on: https://go-review.googlesource.com/c/go/+/632475
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>

src/crypto/internal/fips140/rsa/rsa.go
src/crypto/rsa/rsa.go

index 91655142dd08eb5d3aff31ec87143ccc55d8bffc..692cd3b1ad99dcb74e9a603d0b6d3998b4c787b9 100644 (file)
@@ -115,15 +115,23 @@ func checkPublicKey(pub *PublicKey) error {
        if pub.N == nil {
                return errors.New("crypto/rsa: missing public modulus")
        }
+       if pub.N.Nat().IsOdd() == 0 {
+               return errors.New("crypto/rsa: public modulus is even")
+       }
        if pub.N.BitLen() < 2048 || pub.N.BitLen() > 16384 {
                fips140.RecordNonApproved()
        }
        if pub.E < 2 {
                return errors.New("crypto/rsa: public exponent too small or negative")
        }
+       // e needs to be coprime with p-1 and q-1, since it must be invertible
+       // modulo λ(pq). Since p and q are prime, this means e needs to be odd.
+       if pub.E&1 == 0 {
+               return errors.New("crypto/rsa: public exponent is even")
+       }
        // FIPS 186-5, Section 5.5(e): "The exponent e shall be an odd, positive
        // integer such that 2¹⁶ < e < 2²⁵⁶."
-       if pub.E <= 1<<16 || pub.E&1 == 0 {
+       if pub.E <= 1<<16 {
                fips140.RecordNonApproved()
        }
        // We require pub.E to fit into a 32-bit integer so that we
index 3c9b98eae98079011cfd7677163d254a92a66b7c..9051f176f7a9f3679d53c737257459b45227ddef 100644 (file)
@@ -228,9 +228,15 @@ func (priv *PrivateKey) Validate() error {
        if pub.N == nil {
                return errors.New("crypto/rsa: missing public modulus")
        }
+       if pub.N.Bit(0) == 0 {
+               return errors.New("crypto/rsa: public modulus is even")
+       }
        if pub.E < 2 {
                return errors.New("crypto/rsa: public exponent is less than 2")
        }
+       if pub.E&1 == 0 {
+               return errors.New("crypto/rsa: public exponent is even")
+       }
        if pub.E > 1<<31-1 {
                return errors.New("crypto/rsa: public exponent too large")
        }
@@ -544,9 +550,6 @@ func fipsPublicKey(pub *PublicKey) (*rsa.PublicKey, error) {
        if err != nil {
                return nil, err
        }
-       if pub.E < 0 {
-               return nil, errors.New("crypto/rsa: negative public exponent")
-       }
        return &rsa.PublicKey{N: N, E: pub.E}, nil
 }