Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop explicitly enabling RSA blinding #9143

Merged
merged 1 commit into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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