summaryrefslogtreecommitdiffstats
path: root/llgo/third_party/gofrontend/libgo/go/crypto/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'llgo/third_party/gofrontend/libgo/go/crypto/rsa')
-rw-r--r--llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go10
-rw-r--r--llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go43
-rw-r--r--llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss.go2
-rw-r--r--llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go9
-rw-r--r--llgo/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go57
5 files changed, 101 insertions, 20 deletions
diff --git a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go
index 59e8bb5b7ba..34037b0d674 100644
--- a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go
+++ b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15.go
@@ -14,6 +14,16 @@ import (
// This file implements encryption and decryption using PKCS#1 v1.5 padding.
+// PKCS1v15DecrypterOpts is for passing options to PKCS#1 v1.5 decryption using
+// the crypto.Decrypter interface.
+type PKCS1v15DecryptOptions struct {
+ // SessionKeyLen is the length of the session key that is being
+ // decrypted. If not zero, then a padding error during decryption will
+ // cause a random plaintext of this length to be returned rather than
+ // an error. These alternatives happen in constant time.
+ SessionKeyLen int
+}
+
// EncryptPKCS1v15 encrypts the given message with RSA and the padding scheme from PKCS#1 v1.5.
// The message must be no longer than the length of the public modulus minus 11 bytes.
// WARNING: use of this function to encrypt plaintexts other than session keys
diff --git a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go
index 2dc5dbc2c85..89253751ec2 100644
--- a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go
+++ b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pkcs1v15_test.go
@@ -51,14 +51,25 @@ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{
}
func TestDecryptPKCS1v15(t *testing.T) {
- for i, test := range decryptPKCS1v15Tests {
- out, err := DecryptPKCS1v15(nil, rsaPrivateKey, decodeBase64(test.in))
- if err != nil {
- t.Errorf("#%d error decrypting", i)
- }
- want := []byte(test.out)
- if !bytes.Equal(out, want) {
- t.Errorf("#%d got:%#v want:%#v", i, out, want)
+ decryptionFuncs := []func([]byte) ([]byte, error){
+ func(ciphertext []byte) (plaintext []byte, err error) {
+ return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext)
+ },
+ func(ciphertext []byte) (plaintext []byte, err error) {
+ return rsaPrivateKey.Decrypt(nil, ciphertext, nil)
+ },
+ }
+
+ for _, decryptFunc := range decryptionFuncs {
+ for i, test := range decryptPKCS1v15Tests {
+ out, err := decryptFunc(decodeBase64(test.in))
+ if err != nil {
+ t.Errorf("#%d error decrypting", i)
+ }
+ want := []byte(test.out)
+ if !bytes.Equal(out, want) {
+ t.Errorf("#%d got:%#v want:%#v", i, out, want)
+ }
}
}
}
@@ -138,6 +149,22 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) {
}
}
+func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) {
+ for i, test := range decryptPKCS1v15SessionKeyTests {
+ plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4})
+ if err != nil {
+ t.Fatalf("#%d: error decrypting: %s", i, err)
+ }
+ if len(plaintext) != 4 {
+ t.Fatalf("#%d: incorrect length plaintext: got %d, want 4", i, len(plaintext))
+ }
+
+ if test.out != "FAIL" && !bytes.Equal(plaintext, []byte(test.out)) {
+ t.Errorf("#%d: incorrect plaintext: got %x, want %x", plaintext, test.out)
+ }
+ }
+}
+
func TestNonZeroRandomBytes(t *testing.T) {
random := rand.Reader
diff --git a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss.go b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss.go
index e9f2908250c..0a41814a4b1 100644
--- a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss.go
+++ b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss.go
@@ -255,7 +255,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte,
saltLength = hash.Size()
}
- if opts.Hash != 0 {
+ if opts != nil && opts.Hash != 0 {
hash = opts.Hash
}
diff --git a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go
index 32e6fc39d29..cae24e58c67 100644
--- a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go
+++ b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/pss_test.go
@@ -189,6 +189,15 @@ func TestPSSOpenSSL(t *testing.T) {
}
}
+func TestPSSNilOpts(t *testing.T) {
+ hash := crypto.SHA256
+ h := hash.New()
+ h.Write([]byte("testing"))
+ hashed := h.Sum(nil)
+
+ SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, nil)
+}
+
func TestPSSSigning(t *testing.T) {
var saltLengthCombinations = []struct {
signSaltLength, verifySaltLength int
diff --git a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go
index 2702311281c..1293b783679 100644
--- a/llgo/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go
+++ b/llgo/third_party/gofrontend/libgo/go/crypto/rsa/rsa.go
@@ -24,6 +24,16 @@ type PublicKey struct {
E int // public exponent
}
+// OAEPOptions is an interface for passing options to OAEP decryption using the
+// crypto.Decrypter interface.
+type OAEPOptions struct {
+ // Hash is the hash function that will be used when generating the mask.
+ Hash crypto.Hash
+ // Label is an arbitrary byte string that must be equal to the value
+ // used when encrypting.
+ Label []byte
+}
+
var (
errPublicModulus = errors.New("crypto/rsa: missing public modulus")
errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
@@ -77,6 +87,37 @@ func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts)
return SignPKCS1v15(rand, priv, opts.HashFunc(), msg)
}
+// Decrypt decrypts ciphertext with priv. If opts is nil or of type
+// *PKCS1v15DecryptOptions then PKCS#1 v1.5 decryption is performed. Otherwise
+// opts must have type *OAEPOptions and OAEP decryption is done.
+func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) {
+ if opts == nil {
+ return DecryptPKCS1v15(rand, priv, ciphertext)
+ }
+
+ switch opts := opts.(type) {
+ case *OAEPOptions:
+ return DecryptOAEP(opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+
+ case *PKCS1v15DecryptOptions:
+ if l := opts.SessionKeyLen; l > 0 {
+ plaintext = make([]byte, l)
+ if _, err := io.ReadFull(rand, plaintext); err != nil {
+ return nil, err
+ }
+ if err := DecryptPKCS1v15SessionKey(rand, priv, ciphertext, plaintext); err != nil {
+ return nil, err
+ }
+ return plaintext, nil
+ } else {
+ return DecryptPKCS1v15(rand, priv, ciphertext)
+ }
+
+ default:
+ return nil, errors.New("crypto/rsa: invalid options for Decrypt")
+ }
+}
+
type PrecomputedValues struct {
Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
Qinv *big.Int // Q^-1 mod P
@@ -88,7 +129,7 @@ type PrecomputedValues struct {
CRTValues []CRTValue
}
-// CRTValue contains the precomputed chinese remainder theorem values.
+// CRTValue contains the precomputed Chinese remainder theorem values.
type CRTValue struct {
Exp *big.Int // D mod (prime-1).
Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
@@ -102,19 +143,13 @@ func (priv *PrivateKey) Validate() error {
return err
}
- // Check that the prime factors are actually prime. Note that this is
- // just a sanity check. Since the random witnesses chosen by
- // ProbablyPrime are deterministic, given the candidate number, it's
- // easy for an attack to generate composites that pass this test.
- for _, prime := range priv.Primes {
- if !prime.ProbablyPrime(20) {
- return errors.New("crypto/rsa: prime factor is composite")
- }
- }
-
// Check that Πprimes == n.
modulus := new(big.Int).Set(bigOne)
for _, prime := range priv.Primes {
+ // Any primes ≤ 1 will cause divide-by-zero panics later.
+ if prime.Cmp(bigOne) <= 0 {
+ return errors.New("crypto/rsa: invalid prime value")
+ }
modulus.Mul(modulus, prime)
}
if modulus.Cmp(priv.N) != 0 {
OpenPOWER on IntegriCloud