Skip to content

Commit

Permalink
Stop explicitly enabling RSA blinding (#9143)
Browse files Browse the repository at this point in the history
It is on by default in OpenSSL, going back at least as far 1.1.1d, and probably much farther.
  • Loading branch information
alex authored Jun 27, 2023
1 parent 16ee22f commit 1eb823a
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 64 deletions.
25 changes: 0 additions & 25 deletions src/cryptography/hazmat/backends/openssl/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from __future__ import annotations

import threading
import typing

from cryptography.exceptions import (
Expand Down Expand Up @@ -400,9 +399,6 @@ def __init__(
self._backend = backend
self._rsa_cdata = rsa_cdata
self._evp_pkey = evp_pkey
# Used for lazy blinding
self._blinded = False
self._blinding_lock = threading.Lock()

n = self._backend._ffi.new("BIGNUM **")
self._backend._lib.RSA_get0_key(
Expand All @@ -414,31 +410,11 @@ def __init__(
self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
self._key_size = self._backend._lib.BN_num_bits(n[0])

def _enable_blinding(self) -> None:
# If you call blind on an already blinded RSA key OpenSSL will turn
# it off and back on, which is a performance hit we want to avoid.
if not self._blinded:
with self._blinding_lock:
self._non_threadsafe_enable_blinding()

def _non_threadsafe_enable_blinding(self) -> None:
# This is only a separate function to allow for testing to cover both
# branches. It should never be invoked except through _enable_blinding.
# Check if it's not True again in case another thread raced past the
# first non-locked check.
if not self._blinded:
res = self._backend._lib.RSA_blinding_on(
self._rsa_cdata, self._backend._ffi.NULL
)
self._backend.openssl_assert(res == 1)
self._blinded = True

@property
def key_size(self) -> int:
return self._key_size

def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes:
self._enable_blinding()
key_size_bytes = (self.key_size + 7) // 8
if key_size_bytes != len(ciphertext):
raise ValueError("Ciphertext length must be equal to key size.")
Expand Down Expand Up @@ -508,7 +484,6 @@ def sign(
padding: AsymmetricPadding,
algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
) -> bytes:
self._enable_blinding()
data, algorithm = _calculate_digest_and_algorithm(data, algorithm)
return _rsa_sig_sign(self._backend, padding, algorithm, self, data)

Expand Down
39 changes: 0 additions & 39 deletions tests/hazmat/primitives/test_rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,45 +451,6 @@ def test_oaep_wrong_label(self, rsa_key_2048, enclabel, declabel, backend):
),
)

@pytest.mark.supported(
only_if=lambda backend: backend.rsa_encryption_supported(
padding.PKCS1v15()
),
skip_message="Does not support PKCS1v1.5.",
)
def test_lazy_blinding(self, backend):
# We don't want to reuse the rsa_key_2048 fixture here because lazy
# blinding mutates the object to add the blinding factor on
# the first call to decrypt/sign. Since we reuse rsa_key_2048 in
# many tests we can't properly test blinding, which will (likely)
# already be set on the fixture.
private_key = RSA_KEY_2048.private_key(
unsafe_skip_rsa_key_validation=True
)
public_key = private_key.public_key()
msg = b"encrypt me!"
ct = public_key.encrypt(
msg,
padding.PKCS1v15(),
)
assert private_key._blinded is False # type: ignore[attr-defined]
pt = private_key.decrypt(
ct,
padding.PKCS1v15(),
)
assert private_key._blinded is True # type: ignore[attr-defined]
# Call a second time to cover the branch where blinding
# has already occurred and we don't want to do it again.
pt2 = private_key.decrypt(
ct,
padding.PKCS1v15(),
)
assert pt == pt2
assert private_key._blinded is True
# Private method call to cover the racy branch within the lock
private_key._non_threadsafe_enable_blinding()
assert private_key._blinded is True


class TestRSASignature:
@pytest.mark.supported(
Expand Down

0 comments on commit 1eb823a

Please sign in to comment.