Skip to content

Commit

Permalink
Avoid changing signature of RSA._decrypt() method if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Dec 25, 2023
1 parent 1aa9dca commit 519e7ae
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 9 deletions.
2 changes: 1 addition & 1 deletion lib/Crypto/Cipher/PKCS1_OAEP.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def decrypt(self, ciphertext):
# Step 2a (O2SIP)
ct_int = bytes_to_long(ciphertext)
# Step 2b (RSADP) and step 2c (I2OSP)
em = self._key._decrypt(ct_int)
em = self._key._decrypt_to_bytes(ct_int)
# Step 3a
lHash = self._hashObj.new(self._label).digest()
# Step 3b
Expand Down
2 changes: 1 addition & 1 deletion lib/Crypto/Cipher/PKCS1_v1_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def decrypt(self, ciphertext, sentinel, expected_pt_len=0):
ct_int = bytes_to_long(ciphertext)

# Step 2b (RSADP) and Step 2c (I2OSP)
em = self._key._decrypt(ct_int)
em = self._key._decrypt_to_bytes(ct_int)

# Step 3 (not constant time when the sentinel is not a byte string)
output = bytes(bytearray(k))
Expand Down
7 changes: 6 additions & 1 deletion lib/Crypto/PublicKey/RSA.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def _encrypt(self, plaintext):
raise ValueError("Plaintext too large")
return int(pow(Integer(plaintext), self._e, self._n))

def _decrypt(self, ciphertext):
def _decrypt_to_bytes(self, ciphertext):
if not 0 <= ciphertext < self._n:
raise ValueError("Ciphertext too large")
if not self.has_private():
Expand All @@ -206,6 +206,11 @@ def _decrypt(self, ciphertext):
self._n)
return result

def _decrypt(self, ciphertext):
"""Legacy private method"""

return bytes_to_long(self._decrypt_to_bytes(ciphertext))

def has_private(self):
"""Whether this is an RSA private key"""

Expand Down
8 changes: 6 additions & 2 deletions lib/Crypto/SelfTest/PublicKey/test_RSA.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,11 @@ def test_raw_rsa_boundary(self):
rsa_obj = self.rsa.generate(1024)

self.assertRaises(ValueError, rsa_obj._decrypt, rsa_obj.n)
self.assertRaises(ValueError, rsa_obj._decrypt_to_bytes, rsa_obj.n)
self.assertRaises(ValueError, rsa_obj._encrypt, rsa_obj.n)

self.assertRaises(ValueError, rsa_obj._decrypt, -1)
self.assertRaises(ValueError, rsa_obj._decrypt_to_bytes, -1)
self.assertRaises(ValueError, rsa_obj._encrypt, -1)

def test_size(self):
Expand Down Expand Up @@ -265,6 +267,8 @@ def _check_public_key(self, rsaObj):
# Public keys should not be able to sign or decrypt
self.assertRaises(TypeError, rsaObj._decrypt,
bytes_to_long(ciphertext))
self.assertRaises(TypeError, rsaObj._decrypt_to_bytes,
bytes_to_long(ciphertext))

# Check __eq__ and __ne__
self.assertEqual(rsaObj.public_key() == rsaObj.public_key(),True) # assert_
Expand All @@ -279,7 +283,7 @@ def _exercise_primitive(self, rsaObj):
ciphertext = bytes_to_long(a2b_hex(self.ciphertext))

# Test decryption
plaintext = bytes_to_long(rsaObj._decrypt(ciphertext))
plaintext = rsaObj._decrypt(ciphertext)

# Test encryption (2 arguments)
new_ciphertext2 = rsaObj._encrypt(plaintext)
Expand All @@ -304,7 +308,7 @@ def _check_decryption(self, rsaObj):
ciphertext = bytes_to_long(a2b_hex(self.ciphertext))

# Test plain decryption
new_plaintext = bytes_to_long(rsaObj._decrypt(ciphertext))
new_plaintext = rsaObj._decrypt(ciphertext)
self.assertEqual(plaintext, new_plaintext)


Expand Down
4 changes: 2 additions & 2 deletions lib/Crypto/SelfTest/PublicKey/test_import_RSA.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,13 @@ def testImportKey4bytes(self):
def testImportKey5(self):
"""Verifies that the imported key is still a valid RSA pair"""
key = RSA.importKey(self.rsaKeyPEM)
idem = key._encrypt(bytes_to_long(key._decrypt(89)))
idem = key._encrypt(key._decrypt(89))
self.assertEqual(idem, 89)

def testImportKey6(self):
"""Verifies that the imported key is still a valid RSA pair"""
key = RSA.importKey(self.rsaKeyDER)
idem = key._encrypt(bytes_to_long(key._decrypt(65)))
idem = key._encrypt(key._decrypt(65))
self.assertEqual(idem, 65)

def testImportKey7(self):
Expand Down
2 changes: 1 addition & 1 deletion lib/Crypto/Signature/pkcs1_15.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def sign(self, msg_hash):
# Step 2a (OS2IP)
em_int = bytes_to_long(em)
# Step 2b (RSASP1) and Step 2c (I2OSP)
signature = self._key._decrypt(em_int)
signature = self._key._decrypt_to_bytes(em_int)
# Verify no faults occurred
if em_int != pow(bytes_to_long(signature), self._key.e, self._key.n):
raise ValueError("Fault detected in RSA private key operation")
Expand Down
2 changes: 1 addition & 1 deletion lib/Crypto/Signature/pss.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def sign(self, msg_hash):
# Step 2a (OS2IP)
em_int = bytes_to_long(em)
# Step 2b (RSASP1) and Step 2c (I2OSP)
signature = self._key._decrypt(em_int)
signature = self._key._decrypt_to_bytes(em_int)
# Verify no faults occurred
if em_int != pow(bytes_to_long(signature), self._key.e, self._key.n):
raise ValueError("Fault detected in RSA private key operation")
Expand Down

0 comments on commit 519e7ae

Please sign in to comment.