package rsa
import (
)
const (
PSSSaltLengthAuto = 0
PSSSaltLengthEqualsHash = -1
)
type PSSOptions struct {
SaltLength int
Hash crypto.Hash
}
func ( *PSSOptions) () crypto.Hash {
return .Hash
}
func ( *PSSOptions) () int {
if == nil {
return PSSSaltLengthAuto
}
return .SaltLength
}
func ( io.Reader, *PrivateKey, crypto.Hash, []byte, *PSSOptions) ([]byte, error) {
if := checkPublicKeySize(&.PublicKey); != nil {
return nil,
}
if != nil && .Hash != 0 {
= .Hash
}
if boring.Enabled && == boring.RandReader {
, := boringPrivateKey()
if != nil {
return nil,
}
return boring.SignRSAPSS(, , , .saltLength())
}
boring.UnreachableExceptTests()
:= fips140hash.Unwrap(.New())
if := checkFIPS140OnlyPrivateKey(); != nil {
return nil,
}
if fips140only.Enabled && !fips140only.ApprovedHash() {
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() {
return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
}
, := fipsPrivateKey()
if != nil {
return nil,
}
:= .saltLength()
if fips140only.Enabled && > .Size() {
return nil, errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
}
switch {
case PSSSaltLengthAuto:
, = rsa.PSSMaxSaltLength(.PublicKey(), )
if != nil {
return nil, fipsError()
}
case PSSSaltLengthEqualsHash:
= .Size()
default:
if <= 0 {
return nil, errors.New("crypto/rsa: invalid PSS salt length")
}
}
return fipsError2(rsa.SignPSS(, , , , ))
}
func ( *PublicKey, crypto.Hash, []byte, []byte, *PSSOptions) error {
if := checkPublicKeySize(); != nil {
return
}
if boring.Enabled {
, := boringPublicKey()
if != nil {
return
}
if := boring.VerifyRSAPSS(, , , , .saltLength()); != nil {
return ErrVerification
}
return nil
}
:= fips140hash.Unwrap(.New())
if := checkFIPS140OnlyPublicKey(); != nil {
return
}
if fips140only.Enabled && !fips140only.ApprovedHash() {
return errors.New("crypto/rsa: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
}
, := fipsPublicKey()
if != nil {
return
}
:= .saltLength()
if fips140only.Enabled && > .Size() {
return errors.New("crypto/rsa: use of PSS salt longer than the hash is not allowed in FIPS 140-only mode")
}
switch {
case PSSSaltLengthAuto:
return fipsError(rsa.VerifyPSS(, , , ))
case PSSSaltLengthEqualsHash:
return fipsError(rsa.VerifyPSSWithSaltLength(, , , , .Size()))
default:
return fipsError(rsa.VerifyPSSWithSaltLength(, , , , ))
}
}
func ( hash.Hash, io.Reader, *PublicKey, []byte, []byte) ([]byte, error) {
if := checkPublicKeySize(); != nil {
return nil,
}
defer .Reset()
if boring.Enabled && == boring.RandReader {
.Reset()
:= .Size()
if len() > -2*.Size()-2 {
return nil, ErrMessageTooLong
}
, := boringPublicKey()
if != nil {
return nil,
}
return boring.EncryptRSAOAEP(, , , , )
}
boring.UnreachableExceptTests()
= fips140hash.Unwrap()
if := checkFIPS140OnlyPublicKey(); != nil {
return nil,
}
if fips140only.Enabled && !fips140only.ApprovedHash() {
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() {
return nil, errors.New("crypto/rsa: only crypto/rand.Reader is allowed in FIPS 140-only mode")
}
, := fipsPublicKey()
if != nil {
return nil,
}
return fipsError2(rsa.EncryptOAEP(, , , , , ))
}
func ( hash.Hash, io.Reader, *PrivateKey, []byte, []byte) ([]byte, error) {
defer .Reset()
return decryptOAEP(, , , , )
}
func (, hash.Hash, *PrivateKey, []byte, []byte) ([]byte, error) {
if := checkPublicKeySize(&.PublicKey); != nil {
return nil,
}
if boring.Enabled {
:= .Size()
if len() > ||
< .Size()*2+2 {
return nil, ErrDecryption
}
, := boringPrivateKey()
if != nil {
return nil,
}
, := boring.DecryptRSAOAEP(, , , , )
if != nil {
return nil, ErrDecryption
}
return , nil
}
= fips140hash.Unwrap()
= fips140hash.Unwrap()
if := checkFIPS140OnlyPrivateKey(); != nil {
return nil,
}
if fips140only.Enabled {
if !fips140only.ApprovedHash() || !fips140only.ApprovedHash() {
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")
}
}
, := fipsPrivateKey()
if != nil {
return nil,
}
return fipsError2(rsa.DecryptOAEP(, , , , ))
}
func ( io.Reader, *PrivateKey, crypto.Hash, []byte) ([]byte, error) {
var string
if != crypto.Hash(0) {
if len() != .Size() {
return nil, errors.New("crypto/rsa: input must be hashed message")
}
= .String()
}
if := checkPublicKeySize(&.PublicKey); != nil {
return nil,
}
if boring.Enabled {
, := boringPrivateKey()
if != nil {
return nil,
}
return boring.SignRSAPKCS1v15(, , )
}
if := checkFIPS140OnlyPrivateKey(); != nil {
return nil,
}
if fips140only.Enabled && !fips140only.ApprovedHash(fips140hash.Unwrap(.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")
}
, := fipsPrivateKey()
if != nil {
return nil,
}
return fipsError2(rsa.SignPKCS1v15(, , ))
}
func ( *PublicKey, crypto.Hash, []byte, []byte) error {
var string
if != crypto.Hash(0) {
if len() != .Size() {
return errors.New("crypto/rsa: input must be hashed message")
}
= .String()
}
if := checkPublicKeySize(); != nil {
return
}
if boring.Enabled {
, := boringPublicKey()
if != nil {
return
}
if := boring.VerifyRSAPKCS1v15(, , , ); != nil {
return ErrVerification
}
return nil
}
if := checkFIPS140OnlyPublicKey(); != nil {
return
}
if fips140only.Enabled && !fips140only.ApprovedHash(fips140hash.Unwrap(.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")
}
, := fipsPublicKey()
if != nil {
return
}
return fipsError(rsa.VerifyPKCS1v15(, , , ))
}
func ( error) error {
switch {
case rsa.ErrDecryption:
return ErrDecryption
case rsa.ErrVerification:
return ErrVerification
case rsa.ErrMessageTooLong:
return ErrMessageTooLong
}
return
}
func [ any]( , error) (, error) {
return , fipsError()
}
func ( *PublicKey) error {
if !fips140only.Enabled {
return nil
}
if .N == nil {
return errors.New("crypto/rsa: public key missing N")
}
if .N.BitLen() < 2048 {
return errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode")
}
if .N.BitLen()%2 == 1 {
return errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode")
}
if .E <= 1<<16 {
return errors.New("crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode")
}
if .E&1 == 0 {
return errors.New("crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode")
}
return nil
}
func ( *PrivateKey) error {
if !fips140only.Enabled {
return nil
}
if := checkFIPS140OnlyPublicKey(&.PublicKey); != nil {
return
}
if len(.Primes) != 2 {
return errors.New("crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode")
}
if .Primes[0] == nil || .Primes[1] == nil || .Primes[0].BitLen() != .Primes[1].BitLen() {
return errors.New("crypto/rsa: use of primes of different sizes is not allowed in FIPS 140-only mode")
}
return nil
}