crypto/internal/fips140/rsa: check that e and N are odd

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>
This commit is contained in:
Filippo Valsorda 2024-11-28 19:55:53 +01:00 committed by Gopher Robot
parent f7475a0af3
commit fa38b41be9
2 changed files with 15 additions and 4 deletions

View 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

View 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
}