Skip to content

Commit

Permalink
Add support for ChaCha20 in LibreSSL (#9758)
Browse files Browse the repository at this point in the history
  • Loading branch information
facutuesca authored Oct 24, 2023
1 parent 724697f commit b943680
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ Changelog
:meth:`~cryptography.x509.CertificateRevocationList.next_update`,
:meth:`~cryptography.x509.CertificateRevocationList.last_update`
in favor of the new timezone-aware variants mentioned above.

* Added support for
:class:`~cryptography.hazmat.primitives.ciphers.algorithms.ChaCha20`
on LibreSSL.

.. _v41-0-4:

Expand Down
8 changes: 7 additions & 1 deletion src/cryptography/hazmat/backends/openssl/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,14 @@ def _register_default_ciphers(self) -> None:
self.register_cipher_adapter(
TripleDES, ECB, GetCipherByName("des-ede3")
)
# ChaCha20 uses the Short Name "chacha20" in OpenSSL, but in LibreSSL
# it uses "chacha"
self.register_cipher_adapter(
ChaCha20, type(None), GetCipherByName("chacha20")
ChaCha20,
type(None),
GetCipherByName(
"chacha" if self._lib.CRYPTOGRAPHY_IS_LIBRESSL else "chacha20"
),
)
self.register_cipher_adapter(AES, XTS, _get_xts_cipher)
for mode_cls in [ECB, CBC, OFB, CFB, CTR]:
Expand Down
21 changes: 21 additions & 0 deletions tests/hazmat/primitives/test_chacha20.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,24 @@ def test_invalid_nonce(self):
def test_invalid_key_type(self):
with pytest.raises(TypeError, match="key must be bytes"):
algorithms.ChaCha20("0" * 32, b"0" * 16) # type:ignore[arg-type]

def test_partial_blocks(self, backend):
# Test that partial blocks and counter increments are handled
# correctly. Successive calls to update should return the same
# as if the entire input was passed in a single call:
# update(pt[0:n]) + update(pt[n:m]) + update(pt[m:]) == update(pt)
key = bytearray(os.urandom(32))
nonce = bytearray(os.urandom(16))
cipher = Cipher(algorithms.ChaCha20(key, nonce), None, backend)
pt = bytearray(os.urandom(96 * 3))

enc_full = cipher.encryptor()
ct_full = enc_full.update(pt)

enc_partial = cipher.encryptor()
len_partial = len(pt) // 3
ct_partial_1 = enc_partial.update(pt[:len_partial])
ct_partial_2 = enc_partial.update(pt[len_partial : len_partial * 2])
ct_partial_3 = enc_partial.update(pt[len_partial * 2 :])

assert ct_full == ct_partial_1 + ct_partial_2 + ct_partial_3

0 comments on commit b943680

Please sign in to comment.