diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go index 34037b0d67..37eaf1ab3e 100644 --- a/src/crypto/rsa/pkcs1v15.go +++ b/src/crypto/rsa/pkcs1v15.go @@ -223,7 +223,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b copy(em[k-hashLen:k], hashed) m := new(big.Int).SetBytes(em) - c, err := decrypt(rand, priv, m) + c, err := decryptAndCheck(rand, priv, m) if err != nil { return } diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go index 0a41814a4b..8a94589b1c 100644 --- a/src/crypto/rsa/pss.go +++ b/src/crypto/rsa/pss.go @@ -198,7 +198,7 @@ func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, return } m := new(big.Int).SetBytes(em) - c, err := decrypt(rand, priv, m) + c, err := decryptAndCheck(rand, priv, m) if err != nil { return } diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go index 1293b78367..0a3e6acee9 100644 --- a/src/crypto/rsa/rsa.go +++ b/src/crypto/rsa/rsa.go @@ -506,6 +506,21 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er return } +func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) { + m, err = decrypt(random, priv, c) + if err != nil { + return nil, err + } + + // In order to defend against errors in the CRT computation, m^e is + // calculated, which should match the original ciphertext. + check := encrypt(new(big.Int), &priv.PublicKey, m) + if c.Cmp(check) != 0 { + return nil, errors.New("rsa: internal error") + } + return m, nil +} + // DecryptOAEP decrypts ciphertext using RSA-OAEP. // If random != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks. func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err error) { diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go index 4ee1c3a8b2..6902f9a867 100644 --- a/src/crypto/rsa/rsa_test.go +++ b/src/crypto/rsa/rsa_test.go @@ -6,8 +6,10 @@ package rsa import ( "bytes" + "crypto" "crypto/rand" "crypto/sha1" + "crypto/sha256" "math/big" "testing" ) @@ -127,9 +129,10 @@ func fromBase10(base10 string) *big.Int { return i } -func BenchmarkRSA2048Decrypt(b *testing.B) { - b.StopTimer() - priv := &PrivateKey{ +var test2048Key *PrivateKey + +func init() { + test2048Key = &PrivateKey{ PublicKey: PublicKey{ N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"), E: 3, @@ -140,14 +143,28 @@ func BenchmarkRSA2048Decrypt(b *testing.B) { fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"), }, } - priv.Precompute() + test2048Key.Precompute() +} + +func BenchmarkRSA2048Decrypt(b *testing.B) { + b.StopTimer() c := fromBase10("8472002792838218989464636159316973636630013835787202418124758118372358261975764365740026024610403138425986214991379012696600761514742817632790916315594342398720903716529235119816755589383377471752116975374952783629225022962092351886861518911824745188989071172097120352727368980275252089141512321893536744324822590480751098257559766328893767334861211872318961900897793874075248286439689249972315699410830094164386544311554704755110361048571142336148077772023880664786019636334369759624917224888206329520528064315309519262325023881707530002540634660750469137117568199824615333883758410040459705787022909848740188613313") b.StartTimer() for i := 0; i < b.N; i++ { - decrypt(nil, priv, c) + decrypt(nil, test2048Key, c) + } +} + +func BenchmarkRSA2048Sign(b *testing.B) { + b.StopTimer() + hashed := sha256.Sum256([]byte("testing")) + b.StartTimer() + + for i := 0; i < b.N; i++ { + SignPKCS1v15(rand.Reader, test2048Key, crypto.SHA256, hashed[:]) } }