Skip to content
Open
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
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ Changelog
such keys are impossible to process in a constant-time manner. We do not
believe keys with this problem are in wide use, however we may revert this
change based on the feedback we receive.
* Deprecated passing 64-bit (8-byte) and 128-bit (16-byte) keys to
:class:`~cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES`. In a
future release, only 192-bit (24-byte) keys will be accepted. Users should
expand shorter keys themselves (e.g., for single DES: ``key + key + key``,
for two-key: ``key + key[:8]``).
* Updated the minimum supported Rust version (MSRV) to 1.83.0, from 1.74.0.
* Added support for loading elliptic curve keys that contain explicit encodings
of the curves ``secp256r1``, ``secp384r1``, and ``secp521r1``.
Expand Down
9 changes: 8 additions & 1 deletion docs/hazmat/decrepit/ciphers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,16 @@ object along with the appropriate :mod:`~cryptography.hazmat.primitives.ciphers.
:param key: The secret key. This must be kept secret. Either ``64``,
``128``, or ``192`` :term:`bits` long. DES only uses ``56``, ``112``,
or ``168`` bits of the key as there is a parity byte in each component
of the key. Some writing refers to there being up to three separate
of the key. Some writing refers to there being up to three separate
keys that are each ``56`` bits long, they can simply be concatenated
to produce the full key.

.. deprecated:: 47.0.0

Passing 64-bit or 128-bit keys is deprecated. In a future release,
only 192-bit (24-byte) keys will be accepted. Users should expand
shorter keys themselves (e.g., for single DES: ``key + key + key``,
for two-key: ``key + key[:8]``).
:type key: :term:`bytes-like`

.. class:: CAST5(key)
Expand Down
21 changes: 19 additions & 2 deletions src/cryptography/hazmat/decrepit/ciphers/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

from __future__ import annotations

import warnings

from cryptography import utils
from cryptography.hazmat.primitives._cipheralgorithm import (
BlockCipherAlgorithm,
CipherAlgorithm,
Expand All @@ -30,9 +33,23 @@ class TripleDES(BlockCipherAlgorithm):

def __init__(self, key: bytes):
if len(key) == 8:
key += key + key
warnings.warn(
"Single-key TripleDES (8-byte keys) is deprecated and "
"support will be removed in a future release. Use 24-byte "
"keys instead (e.g., key + key + key).",
utils.DeprecatedIn47,
stacklevel=2,
)
key = key + key + key
elif len(key) == 16:
key += key[:8]
warnings.warn(
"Two-key TripleDES (16-byte keys) is deprecated and "
"support will be removed in a future release. Use 24-byte "
"keys instead (e.g., key + key[:8]).",
utils.DeprecatedIn47,
stacklevel=2,
)
key = key + key[:8]
self.key = _verify_key_size(self, key)

@property
Expand Down
30 changes: 20 additions & 10 deletions tests/hazmat/primitives/decrepit/test_3des.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
algorithms.TripleDES(b"\x00" * 8), modes.CBC(b"\x00" * 8)
algorithms.TripleDES(b"\x00" * 24), modes.CBC(b"\x00" * 8)
),
skip_message="Does not support TripleDES CBC",
)
Expand All @@ -36,7 +36,9 @@ class TestTripleDESModeCBC:
"TCBCvarkey.rsp",
"TCBCvartext.rsp",
],
lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
lambda keys, **kwargs: algorithms.TripleDES(
binascii.unhexlify(keys) * 3
),
lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)),
)

Expand All @@ -53,7 +55,7 @@ class TestTripleDESModeCBC:

@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
algorithms.TripleDES(b"\x00" * 8), OFB(b"\x00" * 8)
algorithms.TripleDES(b"\x00" * 24), OFB(b"\x00" * 8)
),
skip_message="Does not support TripleDES OFB",
)
Expand All @@ -68,7 +70,9 @@ class TestTripleDESModeOFB:
"TOFBvartext.rsp",
"TOFBinvperm.rsp",
],
lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
lambda keys, **kwargs: algorithms.TripleDES(
binascii.unhexlify(keys) * 3
),
lambda iv, **kwargs: OFB(binascii.unhexlify(iv)),
)

Expand All @@ -85,7 +89,7 @@ class TestTripleDESModeOFB:

@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
algorithms.TripleDES(b"\x00" * 8), CFB(b"\x00" * 8)
algorithms.TripleDES(b"\x00" * 24), CFB(b"\x00" * 8)
),
skip_message="Does not support TripleDES CFB",
)
Expand All @@ -100,7 +104,9 @@ class TestTripleDESModeCFB:
"TCFB64varkey.rsp",
"TCFB64vartext.rsp",
],
lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
lambda keys, **kwargs: algorithms.TripleDES(
binascii.unhexlify(keys) * 3
),
lambda iv, **kwargs: CFB(binascii.unhexlify(iv)),
)

Expand All @@ -117,7 +123,7 @@ class TestTripleDESModeCFB:

@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
algorithms.TripleDES(b"\x00" * 8), CFB8(b"\x00" * 8)
algorithms.TripleDES(b"\x00" * 24), CFB8(b"\x00" * 8)
),
skip_message="Does not support TripleDES CFB8",
)
Expand All @@ -132,7 +138,9 @@ class TestTripleDESModeCFB8:
"TCFB8varkey.rsp",
"TCFB8vartext.rsp",
],
lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
lambda keys, **kwargs: algorithms.TripleDES(
binascii.unhexlify(keys) * 3
),
lambda iv, **kwargs: CFB8(binascii.unhexlify(iv)),
)

Expand All @@ -149,7 +157,7 @@ class TestTripleDESModeCFB8:

@pytest.mark.supported(
only_if=lambda backend: backend.cipher_supported(
algorithms.TripleDES(b"\x00" * 8), modes.ECB()
algorithms.TripleDES(b"\x00" * 24), modes.ECB()
),
skip_message="Does not support TripleDES ECB",
)
Expand All @@ -164,7 +172,9 @@ class TestTripleDESModeECB:
"TECBvarkey.rsp",
"TECBvartext.rsp",
],
lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
lambda keys, **kwargs: algorithms.TripleDES(
binascii.unhexlify(keys) * 3
),
lambda **kwargs: modes.ECB(),
)

Expand Down
16 changes: 13 additions & 3 deletions tests/hazmat/primitives/decrepit/test_algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import pytest

from cryptography import utils
from cryptography.exceptions import _Reasons
from cryptography.hazmat.decrepit.ciphers.algorithms import (
ARC4,
Expand Down Expand Up @@ -72,9 +73,8 @@ def test_invalid_mode_algorithm():


class TestTripleDES:
@pytest.mark.parametrize("key", [b"0" * 16, b"0" * 32, b"0" * 48])
def test_key_size(self, key):
cipher = TripleDES(binascii.unhexlify(key))
def test_key_size(self):
cipher = TripleDES(binascii.unhexlify(b"0" * 48))
assert cipher.key_size == 192

def test_invalid_key_size(self):
Expand All @@ -85,6 +85,16 @@ def test_invalid_key_type(self):
with pytest.raises(TypeError, match="key must be bytes"):
TripleDES("0" * 16) # type: ignore[arg-type]

def test_single_key_deprecated(self):
with pytest.warns(utils.DeprecatedIn47):
cipher = TripleDES(binascii.unhexlify(b"0" * 16))
assert cipher.key_size == 192

def test_two_key_deprecated(self):
with pytest.warns(utils.DeprecatedIn47):
cipher = TripleDES(binascii.unhexlify(b"0" * 32))
assert cipher.key_size == 192


class TestBlowfish:
@pytest.mark.parametrize(
Expand Down
4 changes: 2 additions & 2 deletions tests/hazmat/primitives/test_cmac.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def test_aes_verify(self, backend, params):

@pytest.mark.supported(
only_if=lambda backend: backend.cmac_algorithm_supported(
TripleDES(fake_key)
TripleDES(b"\x00" * 24)
),
skip_message="Does not support CMAC.",
)
Expand All @@ -102,7 +102,7 @@ def test_3des_generate(self, backend, params):

@pytest.mark.supported(
only_if=lambda backend: backend.cmac_algorithm_supported(
TripleDES(fake_key)
TripleDES(b"\x00" * 24)
),
skip_message="Does not support CMAC.",
)
Expand Down
6 changes: 5 additions & 1 deletion tests/hazmat/primitives/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,11 @@ def _kbkdf_cmac_counter_mode_test(backend, prf, ctr_loc, brk_loc, params):
break_location=brk_loc,
)

ko = ctrkdf.derive(binascii.unhexlify(params["ki"]))
ki = binascii.unhexlify(params["ki"])
# TripleDES requires 24-byte keys. Expand 16-byte (2-key) to 24-byte.
if prf == "cmac_tdes2":
ki = ki + ki[:8]
ko = ctrkdf.derive(ki)
assert binascii.hexlify(ko) == params["ko"]


Expand Down