diff options
Diffstat (limited to 'llgo/third_party/gofrontend/libgo/go/crypto/rsa')
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 { |

