summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLegrandin <helderijs@gmail.com>2014-05-07 12:20:46 +0200
committerDwayne Litzenberger <dlitz@dlitz.net>2014-06-22 21:28:37 -0700
commitf49fd0e1b57071e52200806d095679753fe36e17 (patch)
treea908ae9a87dedeb3663dbb0a625345a228f8c4e3
parent58de28a5d32bc10e15766e5a59f41b07397cc6cb (diff)
downloadpycrypto-f49fd0e1b57071e52200806d095679753fe36e17.tar.gz
Extended fix for the RSA boundary check
-rw-r--r--lib/Crypto/PublicKey/RSA.py5
-rw-r--r--lib/Crypto/PublicKey/_slowmath.py2
-rw-r--r--lib/Crypto/SelfTest/PublicKey/test_RSA.py11
3 files changed, 17 insertions, 1 deletions
diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py
index a5afeb9..c323295 100644
--- a/lib/Crypto/PublicKey/RSA.py
+++ b/lib/Crypto/PublicKey/RSA.py
@@ -229,6 +229,8 @@ class _RSAobj(pubkey.pubkey):
return pubkey.pubkey.verify(self, M, signature)
def _encrypt(self, c, K):
+ if not 0 < c < self.n:
+ raise ValueError("Plaintext too large")
return (self.key._encrypt(c),)
def _decrypt(self, c):
@@ -238,6 +240,9 @@ class _RSAobj(pubkey.pubkey):
# going to replace the Crypto.PublicKey API soon
# anyway.
+ if not 0 < ciphertext < self.n:
+ raise ValueError("Ciphertext too large")
+
# Blinded RSA decryption (to prevent timing attacks):
# Step 1: Generate random secret blinding factor r, such that 0 < r < n-1
r = getRandomRange(1, self.key.n-1, randfunc=self._randfunc)
diff --git a/lib/Crypto/PublicKey/_slowmath.py b/lib/Crypto/PublicKey/_slowmath.py
index d926596..f28ea4c 100644
--- a/lib/Crypto/PublicKey/_slowmath.py
+++ b/lib/Crypto/PublicKey/_slowmath.py
@@ -40,7 +40,7 @@ class error(Exception):
class _RSAKey(object):
def _blind(self, m, r):
# compute r**e * m (mod n)
- return m * pow(r, self.e, self.n)
+ return (m * pow(r, self.e, self.n)) % self.n
def _unblind(self, m, r):
# compute m / r (mod n)
diff --git a/lib/Crypto/SelfTest/PublicKey/test_RSA.py b/lib/Crypto/SelfTest/PublicKey/test_RSA.py
index 32bed88..16310f7 100644
--- a/lib/Crypto/SelfTest/PublicKey/test_RSA.py
+++ b/lib/Crypto/SelfTest/PublicKey/test_RSA.py
@@ -219,6 +219,17 @@ class RSATest(unittest.TestCase):
ciphertext_result = rsaObj.encrypt(plaintext, b(""))[0]
self.assertEqual(ciphertext_result, ciphertext)
+ def test_raw_rsa_boundary(self):
+ # The argument of every RSA raw operation (encrypt/decrypt) must be positive
+ # and no larger than the modulus
+ rsa_obj = self.rsa.generate(1024)
+
+ self.assertRaises(ValueError, rsa_obj.decrypt, (rsa_obj.n,))
+ self.assertRaises(ValueError, rsa_obj.encrypt, rsa_obj.n, b(""))
+
+ self.assertRaises(ValueError, rsa_obj.decrypt, (0,))
+ self.assertRaises(ValueError, rsa_obj.encrypt, 0, b(""))
+
def _check_private_key(self, rsaObj):
# Check capabilities
self.assertEqual(1, rsaObj.has_private())