aboutsummaryrefslogtreecommitdiff
path: root/rsa/pkcs1.py
diff options
context:
space:
mode:
Diffstat (limited to 'rsa/pkcs1.py')
-rw-r--r--rsa/pkcs1.py19
1 files changed, 14 insertions, 5 deletions
diff --git a/rsa/pkcs1.py b/rsa/pkcs1.py
index 57b0276..07cf85b 100644
--- a/rsa/pkcs1.py
+++ b/rsa/pkcs1.py
@@ -30,6 +30,7 @@ import hashlib
import os
import sys
import typing
+from hmac import compare_digest
from . import common, transform, core, key
@@ -252,16 +253,24 @@ def decrypt(crypto: bytes, priv_key: key.PrivateKey) -> bytes:
# encrypted value (as leading zeroes do not influence the value of an
# integer). This fixes CVE-2020-13757.
if len(crypto) > blocksize:
+ # This is operating on public information, so doesn't need to be constant-time.
raise DecryptionError('Decryption failed')
# If we can't find the cleartext marker, decryption failed.
- if cleartext[0:2] != b'\x00\x02':
- raise DecryptionError('Decryption failed')
+ cleartext_marker_bad = not compare_digest(cleartext[:2], b'\x00\x02')
# Find the 00 separator between the padding and the message
- try:
- sep_idx = cleartext.index(b'\x00', 2)
- except ValueError:
+ sep_idx = cleartext.find(b'\x00', 2)
+
+ # sep_idx indicates the position of the `\x00` separator that separates the
+ # padding from the actual message. The padding should be at least 8 bytes
+ # long (see https://tools.ietf.org/html/rfc8017#section-7.2.2 step 3), which
+ # means the separator should be at least at index 10 (because of the
+ # `\x00\x02` marker that preceeds it).
+ sep_idx_bad = sep_idx < 10
+
+ anything_bad = cleartext_marker_bad | sep_idx_bad
+ if anything_bad:
raise DecryptionError('Decryption failed')
return cleartext[sep_idx + 1:]