import (
"crypto/internal/fips140/hkdf"
+ "crypto/internal/fips140hash"
"crypto/internal/fips140only"
"errors"
"hash"
// Expand invocations and different context values. Most common scenarios,
// including the generation of multiple keys, should use [Key] instead.
func Extract[H hash.Hash](h func() H, secret, salt []byte) ([]byte, error) {
- if err := checkFIPS140Only(h, secret); err != nil {
+ fh := fips140hash.UnwrapNew(h)
+ if err := checkFIPS140Only(fh, secret); err != nil {
return nil, err
}
- return hkdf.Extract(h, secret, salt), nil
+ return hkdf.Extract(fh, secret, salt), nil
}
// Expand derives a key from the given hash, key, and optional context info,
// random or pseudorandom cryptographically strong key. See RFC 5869, Section
// 3.3. Most common scenarios will want to use [Key] instead.
func Expand[H hash.Hash](h func() H, pseudorandomKey []byte, info string, keyLength int) ([]byte, error) {
- if err := checkFIPS140Only(h, pseudorandomKey); err != nil {
+ fh := fips140hash.UnwrapNew(h)
+ if err := checkFIPS140Only(fh, pseudorandomKey); err != nil {
return nil, err
}
- limit := h().Size() * 255
+ limit := fh().Size() * 255
if keyLength > limit {
return nil, errors.New("hkdf: requested key length too large")
}
- return hkdf.Expand(h, pseudorandomKey, info, keyLength), nil
+ return hkdf.Expand(fh, pseudorandomKey, info, keyLength), nil
}
// Key derives a key from the given hash, secret, salt and context info,
// returning a []byte of length keyLength that can be used as cryptographic key.
// Salt and info can be nil.
func Key[Hash hash.Hash](h func() Hash, secret, salt []byte, info string, keyLength int) ([]byte, error) {
- if err := checkFIPS140Only(h, secret); err != nil {
+ fh := fips140hash.UnwrapNew(h)
+ if err := checkFIPS140Only(fh, secret); err != nil {
return nil, err
}
- limit := h().Size() * 255
+ limit := fh().Size() * 255
if keyLength > limit {
return nil, errors.New("hkdf: requested key length too large")
}
- return hkdf.Key(h, secret, salt, info, keyLength), nil
+ return hkdf.Key(fh, secret, salt, info, keyLength), nil
}
-func checkFIPS140Only[H hash.Hash](h func() H, key []byte) error {
+func checkFIPS140Only[Hash hash.Hash](h func() Hash, key []byte) error {
if !fips140only.Enabled {
return nil
}
"crypto"
"crypto/internal/boring"
"crypto/internal/fips140/rsa"
+ "crypto/internal/fips140hash"
"crypto/internal/fips140only"
"errors"
"hash"
if err := checkPublicKeySize(&priv.PublicKey); err != nil {
return nil, err
}
- if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
- return nil, err
- }
if opts != nil && opts.Hash != 0 {
hash = opts.Hash
}
- if fips140only.Enabled && !fips140only.ApprovedHash(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.Enabled && !fips140only.ApprovedRandomReader(rand) {
- return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
- }
-
if boring.Enabled && rand == boring.RandReader {
bkey, err := boringPrivateKey(priv)
if err != nil {
}
boring.UnreachableExceptTests()
+ h := fips140hash.Unwrap(hash.New())
+
+ if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
+ return nil, err
+ }
+ if fips140only.Enabled && !fips140only.ApprovedHash(h) {
+ 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.Enabled && !fips140only.ApprovedRandomReader(rand) {
+ return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
+ }
+
k, err := fipsPrivateKey(priv)
if err != nil {
return nil, err
}
- h := hash.New()
saltLength := opts.saltLength()
- if fips140only.Enabled && saltLength > hash.Size() {
+ if fips140only.Enabled && saltLength > h.Size() {
return nil, errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
}
switch saltLength {
return nil, fipsError(err)
}
case PSSSaltLengthEqualsHash:
- saltLength = hash.Size()
+ saltLength = h.Size()
default:
// If we get here saltLength is either > 0 or < -1, in the
// latter case we fail out.
if err := checkPublicKeySize(pub); err != nil {
return err
}
- if err := checkFIPS140OnlyPublicKey(pub); err != nil {
- return err
- }
- if fips140only.Enabled && !fips140only.ApprovedHash(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 boring.Enabled {
bkey, err := boringPublicKey(pub)
return nil
}
+ h := fips140hash.Unwrap(hash.New())
+
+ if err := checkFIPS140OnlyPublicKey(pub); err != nil {
+ return err
+ }
+ if fips140only.Enabled && !fips140only.ApprovedHash(h) {
+ 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)
if err != nil {
return err
}
saltLength := opts.saltLength()
- if fips140only.Enabled && saltLength > hash.Size() {
+ if fips140only.Enabled && saltLength > h.Size() {
return errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
}
switch saltLength {
case PSSSaltLengthAuto:
- return fipsError(rsa.VerifyPSS(k, hash.New(), digest, sig))
+ return fipsError(rsa.VerifyPSS(k, h, digest, sig))
case PSSSaltLengthEqualsHash:
- return fipsError(rsa.VerifyPSSWithSaltLength(k, hash.New(), digest, sig, hash.Size()))
+ return fipsError(rsa.VerifyPSSWithSaltLength(k, h, digest, sig, h.Size()))
default:
- return fipsError(rsa.VerifyPSSWithSaltLength(k, hash.New(), digest, sig, saltLength))
+ return fipsError(rsa.VerifyPSSWithSaltLength(k, h, digest, sig, saltLength))
}
}
if err := checkPublicKeySize(pub); err != nil {
return nil, err
}
- if err := checkFIPS140OnlyPublicKey(pub); err != nil {
- return nil, err
- }
- if fips140only.Enabled && !fips140only.ApprovedHash(hash) {
- 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.Enabled && !fips140only.ApprovedRandomReader(random) {
- return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
- }
defer hash.Reset()
}
boring.UnreachableExceptTests()
+ hash = fips140hash.Unwrap(hash)
+
+ if err := checkFIPS140OnlyPublicKey(pub); err != nil {
+ return nil, err
+ }
+ if fips140only.Enabled && !fips140only.ApprovedHash(hash) {
+ 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.Enabled && !fips140only.ApprovedRandomReader(random) {
+ return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
+ }
+
k, err := fipsPublicKey(pub)
if err != nil {
return nil, err
if err := checkPublicKeySize(&priv.PublicKey); err != nil {
return nil, err
}
- if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
- return nil, err
- }
- if fips140only.Enabled {
- if !fips140only.ApprovedHash(hash) || !fips140only.ApprovedHash(mgfHash) {
- 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 boring.Enabled {
k := priv.Size()
return out, nil
}
+ hash = fips140hash.Unwrap(hash)
+ mgfHash = fips140hash.Unwrap(mgfHash)
+
+ if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
+ return nil, err
+ }
+ if fips140only.Enabled {
+ if !fips140only.ApprovedHash(hash) || !fips140only.ApprovedHash(mgfHash) {
+ 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)
if err != nil {
return nil, err
if err := checkPublicKeySize(&priv.PublicKey); err != nil {
return nil, err
}
- if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
- return nil, err
- }
- if fips140only.Enabled && !fips140only.ApprovedHash(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 boring.Enabled {
bkey, err := boringPrivateKey(priv)
return boring.SignRSAPKCS1v15(bkey, hash, hashed)
}
+ if err := checkFIPS140OnlyPrivateKey(priv); err != nil {
+ return nil, err
+ }
+ if fips140only.Enabled && !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)
if err != nil {
return nil, err
// The inputs are not considered confidential, and may leak through timing side
// channels, or if an attacker has control of part of the inputs.
func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
- if err := checkPublicKeySize(pub); err != nil {
- return err
+ var hashName string
+ if hash != crypto.Hash(0) {
+ if len(hashed) != hash.Size() {
+ return errors.New("crypto/rsa: input must be hashed message")
+ }
+ hashName = hash.String()
}
- if err := checkFIPS140OnlyPublicKey(pub); err != nil {
+
+ if err := checkPublicKeySize(pub); err != nil {
return err
}
- if fips140only.Enabled && !fips140only.ApprovedHash(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 boring.Enabled {
bkey, err := boringPublicKey(pub)
return nil
}
+ if err := checkFIPS140OnlyPublicKey(pub); err != nil {
+ return err
+ }
+ if fips140only.Enabled && !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)
if err != nil {
return err
}
- var hashName string
- if hash != crypto.Hash(0) {
- if len(hashed) != hash.Size() {
- return errors.New("crypto/rsa: input must be hashed message")
- }
- hashName = hash.String()
- }
return fipsError(rsa.VerifyPKCS1v15(k, hashName, hashed, sig))
}