Skip to content

Commit 58494b4

Browse files
authored
Attempt to mitigate Bleichenbacher attacks on RSA decryption (#5507)
1 parent cf9bd6a commit 58494b4

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

CHANGELOG.rst

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ Changelog
88

99
.. note:: This version is not yet released and is under active development.
1010

11+
* **SECURITY ISSUE:** Attempted to make RSA PKCS#1v1.5 decryption more constant
12+
time, to protect against Bleichenbacher vulnerabilities. Due to limitations
13+
imposed by our API, we cannot completely mitigate this vulnerability and a
14+
future release will contain a new API which is designed to be resilient to
15+
these for contexts where it is required. Credit to **Hubert Kario** for
16+
reporting the issue. *CVE-2020-25659*
1117
* Support for OpenSSL 1.0.2 has been removed. Users on older version of OpenSSL
1218
will need to upgrade.
1319
* Added basic support for PKCS7 signing (including SMIME) via

docs/spelling_wordlist.txt

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ backend
77
Backends
88
backends
99
bcrypt
10+
Bleichenbacher
1011
Blowfish
1112
boolean
1213
Botan

src/cryptography/hazmat/backends/openssl/rsa.py

+11-15
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,19 @@ def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):
119119

120120
outlen = backend._ffi.new("size_t *", buf_size)
121121
buf = backend._ffi.new("unsigned char[]", buf_size)
122+
# Everything from this line onwards is written with the goal of being as
123+
# constant-time as is practical given the constraints of Python and our
124+
# API. See Bleichenbacher's '98 attack on RSA, and its many many variants.
125+
# As such, you should not attempt to change this (particularly to "clean it
126+
# up") without understanding why it was written this way (see
127+
# Chesterton's Fence), and without measuring to verify you have not
128+
# introduced observable time differences.
122129
res = crypt(pkey_ctx, buf, outlen, data, len(data))
130+
resbuf = backend._ffi.buffer(buf)[: outlen[0]]
131+
backend._lib.ERR_clear_error()
123132
if res <= 0:
124-
_handle_rsa_enc_dec_error(backend, key)
125-
126-
return backend._ffi.buffer(buf)[: outlen[0]]
127-
128-
129-
def _handle_rsa_enc_dec_error(backend, key):
130-
errors = backend._consume_errors_with_text()
131-
if isinstance(key, _RSAPublicKey):
132-
raise ValueError(
133-
"Data too long for key size. Encrypt less data or use a "
134-
"larger key size.",
135-
errors,
136-
)
137-
else:
138-
raise ValueError("Decryption failed.", errors)
133+
raise ValueError("Encryption/decryption failed.")
134+
return resbuf
139135

140136

141137
def _rsa_sig_determine_padding(backend, key, padding, algorithm):

0 commit comments

Comments
 (0)