aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/rsa/rsa.go
diff options
context:
space:
mode:
authorAleks Rudzitis <arudzitis@stripe.com>2022-07-21 11:19:42 -0700
committerGopher Robot <gobot@golang.org>2022-11-09 23:51:34 +0000
commite48fc2665e2e95eddea612fa315403d50c7beb2b (patch)
tree4906a2b1fe4f7602955e272f23753fde4f02affd /src/crypto/rsa/rsa.go
parent89332e037aeaf1223de4c24805719f733e4c0977 (diff)
downloadgo-e48fc2665e2e95eddea612fa315403d50c7beb2b.tar.xz
crypto: allow hash.Hash for OAEP and MGF1 to be specified independently
crypto/rsa assumes RSA OAEP uses the same hash to be used for both the label and the mask generation function. However, implementations in other languages, such as Java and Python, allow these parameters to be specified independently. This change allows the MGF hash to be specified independently for decrypt operations in order to allow decrypting ciphertexts generated in other environments. Fixes: #19974 Change-Id: If453d628f0da354ceb3b52863f30087471670f7b Reviewed-on: https://go-review.googlesource.com/c/go/+/418874 Auto-Submit: Andrew Bonventre <andybons@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Andrew Bonventre <andybons@golang.org> Run-TryBot: Andrew Bonventre <andybons@golang.org>
Diffstat (limited to 'src/crypto/rsa/rsa.go')
-rw-r--r--src/crypto/rsa/rsa.go23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
index c941124fb2..9c57595dd1 100644
--- a/src/crypto/rsa/rsa.go
+++ b/src/crypto/rsa/rsa.go
@@ -68,6 +68,11 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
type OAEPOptions struct {
// Hash is the hash function that will be used when generating the mask.
Hash crypto.Hash
+
+ // MGFHash is the hash function used for MGF1.
+ // If zero, Hash is used instead.
+ MGFHash crypto.Hash
+
// Label is an arbitrary byte string that must be equal to the value
// used when encrypting.
Label []byte
@@ -160,7 +165,11 @@ func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.D
switch opts := opts.(type) {
case *OAEPOptions:
- return DecryptOAEP(opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+ if opts.MGFHash == 0 {
+ return decryptOAEP(opts.Hash.New(), opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+ } else {
+ return decryptOAEP(opts.Hash.New(), opts.MGFHash.New(), rand, priv, ciphertext, opts.Label)
+ }
case *PKCS1v15DecryptOptions:
if l := opts.SessionKeyLen; l > 0 {
@@ -458,7 +467,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
if err != nil {
return nil, err
}
- return boring.EncryptRSAOAEP(hash, bkey, msg, label)
+ return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label)
}
boring.UnreachableExceptTests()
@@ -651,6 +660,10 @@ func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int
// The label parameter must match the value given when encrypting. See
// EncryptOAEP for details.
func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
+ return decryptOAEP(hash, hash, random, priv, ciphertext, label)
+}
+
+func decryptOAEP(hash, mgfHash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
@@ -665,7 +678,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
if err != nil {
return nil, err
}
- out, err := boring.DecryptRSAOAEP(hash, bkey, ciphertext, label)
+ out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label)
if err != nil {
return nil, ErrDecryption
}
@@ -691,8 +704,8 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
seed := em[1 : hash.Size()+1]
db := em[hash.Size()+1:]
- mgf1XOR(seed, hash, db)
- mgf1XOR(db, hash, seed)
+ mgf1XOR(seed, mgfHash, db)
+ mgf1XOR(db, mgfHash, seed)
lHash2 := db[0:hash.Size()]