Skip to content

Commit

Permalink
Attempt to mitigate Bleichenbacher attacks on RSA decryption (pyca#5507)
Browse files Browse the repository at this point in the history
  • Loading branch information
alex authored and tiran committed Oct 26, 2020
1 parent 86b8b86 commit 66be1b2
Showing 1 changed file with 11 additions and 31 deletions.
42 changes: 11 additions & 31 deletions src/cryptography/hazmat/backends/openssl/rsa.py
Expand Up @@ -107,39 +107,19 @@ def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):

outlen = backend._ffi.new("size_t *", buf_size)
buf = backend._ffi.new("unsigned char[]", buf_size)
# Everything from this line onwards is written with the goal of being as
# constant-time as is practical given the constraints of Python and our
# API. See Bleichenbacher's '98 attack on RSA, and its many many variants.
# As such, you should not attempt to change this (particularly to "clean it
# up") without understanding why it was written this way (see
# Chesterton's Fence), and without measuring to verify you have not
# introduced observable time differences.
res = crypt(pkey_ctx, buf, outlen, data, len(data))
resbuf = backend._ffi.buffer(buf)[: outlen[0]]
backend._lib.ERR_clear_error()
if res <= 0:
_handle_rsa_enc_dec_error(backend, key)

return backend._ffi.buffer(buf)[:outlen[0]]


def _handle_rsa_enc_dec_error(backend, key):
errors = backend._consume_errors()
assert errors
assert errors[0].lib == backend._lib.ERR_LIB_RSA
if isinstance(key, _RSAPublicKey):
assert (errors[0].reason ==
backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE)
raise ValueError(
"Data too long for key size. Encrypt less data or use a "
"larger key size."
)
else:
decoding_errors = [
backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_01,
backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_02,
backend._lib.RSA_R_OAEP_DECODING_ERROR,
# Though this error looks similar to the
# RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE, this occurs on decrypts,
# rather than on encrypts
backend._lib.RSA_R_DATA_TOO_LARGE_FOR_MODULUS,
]
if backend._lib.Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR:
decoding_errors.append(backend._lib.RSA_R_PKCS_DECODING_ERROR)

assert errors[0].reason in decoding_errors
raise ValueError("Decryption failed.")
raise ValueError("Encryption/decryption failed.")
return resbuf


def _rsa_sig_determine_padding(backend, key, padding, algorithm):
Expand Down

0 comments on commit 66be1b2

Please sign in to comment.