mirror of
https://github.com/golang/go.git
synced 2026-06-27 03:11:23 +00:00
crypto: return an error if a hash function is not available
Calling New otherwise panics, which is unnecessary, especially in crypto.SignMessage and especially if we add a new not-implemented hash value for ML-DSA external Mu. Change-Id: I9f8d29d01e126838d7d2585133e562536a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/745660 Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
3825609217
commit
6de59e2070
7 changed files with 46 additions and 6 deletions
|
|
@ -246,14 +246,23 @@ func SignMessage(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (si
|
|||
if ms, ok := signer.(MessageSigner); ok {
|
||||
return ms.SignMessage(rand, msg, opts)
|
||||
}
|
||||
if opts.HashFunc() != 0 {
|
||||
h := opts.HashFunc().New()
|
||||
if hash := opts.HashFunc(); hash != 0 {
|
||||
if !hash.Available() {
|
||||
return nil, hashUnavailableError(hash)
|
||||
}
|
||||
h := hash.New()
|
||||
h.Write(msg)
|
||||
msg = h.Sum(nil)
|
||||
}
|
||||
return signer.Sign(rand, msg, opts)
|
||||
}
|
||||
|
||||
type hashUnavailableError Hash
|
||||
|
||||
func (h hashUnavailableError) Error() string {
|
||||
return "crypto: requested hash function unavailable: " + Hash(h).String()
|
||||
}
|
||||
|
||||
// Decapsulator is an interface for an opaque private KEM key that can be used for
|
||||
// decapsulation operations. For example, an ML-KEM key kept in a hardware module.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -450,6 +450,9 @@ func signFIPSDeterministic[P ecdsa.Point[P]](c *ecdsa.Curve[P], hashFunc crypto.
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !hashFunc.Available() {
|
||||
return nil, errors.New("ecdsa: requested hash function unavailable: " + hashFunc.String())
|
||||
}
|
||||
h := fips140hash.UnwrapNew(hashFunc.New)
|
||||
if fips140only.Enforced() && !fips140only.ApprovedHash(h()) {
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -247,10 +247,12 @@ bXVL8iKLrG91IYQByUHZIn3WVAd2bfi4MfKagRt0ggd4
|
|||
expectErr(t, errRet2(rsa.SignPKCS1v15(rand.Reader, rsaKey, crypto.SHA1, make([]byte, 20))))
|
||||
// rand is always ignored for PKCS1v15 signing
|
||||
expectNoErr(t, errRet2(rsa.SignPKCS1v15(readerWrap{rand.Reader}, rsaKey, crypto.SHA256, make([]byte, 32))))
|
||||
expectErr(t, errRet2(rsa.SignPKCS1v15(rand.Reader, rsaKey, crypto.Hash(0), make([]byte, 32))))
|
||||
|
||||
expectNoErr(t, rsa.VerifyPKCS1v15(&rsaKey.PublicKey, crypto.SHA256, make([]byte, 32), sigPKCS1v15))
|
||||
expectErr(t, rsa.VerifyPKCS1v15(&smallKey.PublicKey, crypto.SHA256, make([]byte, 32), sigPKCS1v15))
|
||||
expectErr(t, rsa.VerifyPKCS1v15(&rsaKey.PublicKey, crypto.SHA1, make([]byte, 20), sigPKCS1v15))
|
||||
expectErr(t, rsa.VerifyPKCS1v15(&rsaKey.PublicKey, crypto.Hash(0), make([]byte, 32), sigPKCS1v15))
|
||||
|
||||
sigPSS, err := rsa.SignPSS(rand.Reader, rsaKey, crypto.SHA256, make([]byte, 32), nil)
|
||||
expectNoErr(t, err)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ func SignPSS(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte
|
|||
}
|
||||
boring.UnreachableExceptTests()
|
||||
|
||||
if !hash.Available() {
|
||||
return nil, errors.New("crypto/rsa: requested hash function unavailable: " + hash.String())
|
||||
}
|
||||
h := fips140hash.Unwrap(hash.New())
|
||||
|
||||
if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
|
||||
|
|
@ -145,6 +148,9 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts
|
|||
return nil
|
||||
}
|
||||
|
||||
if !hash.Available() {
|
||||
return errors.New("crypto/rsa: requested hash function unavailable: " + hash.String())
|
||||
}
|
||||
h := fips140hash.Unwrap(hash.New())
|
||||
|
||||
if err := checkFIPS140OnlyPublicKey(pub); err != nil {
|
||||
|
|
@ -203,6 +209,12 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
|
|||
//
|
||||
// See [EncryptOAEP] for additional details.
|
||||
func EncryptOAEPWithOptions(random io.Reader, pub *PublicKey, msg []byte, opts *OAEPOptions) ([]byte, error) {
|
||||
if !opts.Hash.Available() {
|
||||
return nil, errors.New("crypto/rsa: requested hash function unavailable: " + opts.Hash.String())
|
||||
}
|
||||
if opts.MGFHash != 0 && !opts.MGFHash.Available() {
|
||||
return nil, errors.New("crypto/rsa: requested hash function unavailable: " + opts.MGFHash.String())
|
||||
}
|
||||
if opts.MGFHash == 0 {
|
||||
return encryptOAEP(opts.Hash.New(), opts.Hash.New(), random, pub, msg, opts.Label)
|
||||
}
|
||||
|
|
@ -342,8 +354,10 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [
|
|||
if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fips140only.Enforced() && !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
|
||||
return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
|
||||
if fips140only.Enforced() {
|
||||
if !hash.Available() || !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
|
||||
return nil, errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
|
||||
}
|
||||
}
|
||||
|
||||
k, err := fipsPrivateKey(priv)
|
||||
|
|
@ -388,8 +402,10 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte)
|
|||
if err := checkFIPS140OnlyPublicKey(pub); err != nil {
|
||||
return err
|
||||
}
|
||||
if fips140only.Enforced() && !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
|
||||
return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
|
||||
if fips140only.Enforced() {
|
||||
if !hash.Available() || !fips140only.ApprovedHash(fips140hash.Unwrap(hash.New())) {
|
||||
return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
|
||||
}
|
||||
}
|
||||
|
||||
k, err := fipsPublicKey(pub)
|
||||
|
|
|
|||
|
|
@ -176,6 +176,12 @@ func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.D
|
|||
|
||||
switch opts := opts.(type) {
|
||||
case *OAEPOptions:
|
||||
if !opts.Hash.Available() {
|
||||
return nil, errors.New("rsa: requested hash function unavailable: " + opts.Hash.String())
|
||||
}
|
||||
if opts.MGFHash != 0 && !opts.MGFHash.Available() {
|
||||
return nil, errors.New("rsa: requested hash function unavailable: " + opts.MGFHash.String())
|
||||
}
|
||||
if opts.MGFHash == 0 {
|
||||
return decryptOAEP(opts.Hash.New(), opts.Hash.New(), priv, ciphertext, opts.Label)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ import (
|
|||
// verifyHandshakeSignature verifies a signature against unhashed handshake contents.
|
||||
func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {
|
||||
if hashFunc != directSigning {
|
||||
if !hashFunc.Available() {
|
||||
return fmt.Errorf("hash function unavailable: %v", hashFunc)
|
||||
}
|
||||
h := hashFunc.New()
|
||||
h.Write(signed)
|
||||
signed = h.Sum(nil)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"crypto/rc4"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
_ "crypto/sha512" // for crypto.SHA384
|
||||
"fmt"
|
||||
"hash"
|
||||
"internal/cpu"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue