Skip to content

Commit f49fd0e

Browse files
Legrandindlitz
authored andcommitted
Extended fix for the RSA boundary check
1 parent 58de28a commit f49fd0e

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

lib/Crypto/PublicKey/RSA.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ def verify(self, M, signature):
229229
return pubkey.pubkey.verify(self, M, signature)
230230

231231
def _encrypt(self, c, K):
232+
if not 0 < c < self.n:
233+
raise ValueError("Plaintext too large")
232234
return (self.key._encrypt(c),)
233235

234236
def _decrypt(self, c):
@@ -238,6 +240,9 @@ def _decrypt(self, c):
238240
# going to replace the Crypto.PublicKey API soon
239241
# anyway.
240242

243+
if not 0 < ciphertext < self.n:
244+
raise ValueError("Ciphertext too large")
245+
241246
# Blinded RSA decryption (to prevent timing attacks):
242247
# Step 1: Generate random secret blinding factor r, such that 0 < r < n-1
243248
r = getRandomRange(1, self.key.n-1, randfunc=self._randfunc)

lib/Crypto/PublicKey/_slowmath.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class error(Exception):
4040
class _RSAKey(object):
4141
def _blind(self, m, r):
4242
# compute r**e * m (mod n)
43-
return m * pow(r, self.e, self.n)
43+
return (m * pow(r, self.e, self.n)) % self.n
4444

4545
def _unblind(self, m, r):
4646
# compute m / r (mod n)

lib/Crypto/SelfTest/PublicKey/test_RSA.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ def test_serialization_compat(self):
219219
ciphertext_result = rsaObj.encrypt(plaintext, b(""))[0]
220220
self.assertEqual(ciphertext_result, ciphertext)
221221

222+
def test_raw_rsa_boundary(self):
223+
# The argument of every RSA raw operation (encrypt/decrypt) must be positive
224+
# and no larger than the modulus
225+
rsa_obj = self.rsa.generate(1024)
226+
227+
self.assertRaises(ValueError, rsa_obj.decrypt, (rsa_obj.n,))
228+
self.assertRaises(ValueError, rsa_obj.encrypt, rsa_obj.n, b(""))
229+
230+
self.assertRaises(ValueError, rsa_obj.decrypt, (0,))
231+
self.assertRaises(ValueError, rsa_obj.encrypt, 0, b(""))
232+
222233
def _check_private_key(self, rsaObj):
223234
# Check capabilities
224235
self.assertEqual(1, rsaObj.has_private())

0 commit comments

Comments
 (0)