• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
7import binascii
8import os
9import struct
10
11import pytest
12
13from cryptography.hazmat.backends.interfaces import CipherBackend
14from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
15
16from .utils import _load_all_params
17from ...utils import load_nist_vectors
18
19
20@pytest.mark.supported(
21    only_if=lambda backend: backend.cipher_supported(
22        algorithms.ChaCha20(b"\x00" * 32, b"0" * 16), None
23    ),
24    skip_message="Does not support ChaCha20",
25)
26@pytest.mark.requires_backend_interface(interface=CipherBackend)
27class TestChaCha20(object):
28    @pytest.mark.parametrize(
29        "vector",
30        _load_all_params(
31            os.path.join("ciphers", "ChaCha20"),
32            ["rfc7539.txt"],
33            load_nist_vectors,
34        ),
35    )
36    def test_vectors(self, vector, backend):
37        key = binascii.unhexlify(vector["key"])
38        nonce = binascii.unhexlify(vector["nonce"])
39        ibc = struct.pack("<i", int(vector["initial_block_counter"]))
40        pt = binascii.unhexlify(vector["plaintext"])
41        encryptor = Cipher(
42            algorithms.ChaCha20(key, ibc + nonce), None, backend
43        ).encryptor()
44        computed_ct = encryptor.update(pt) + encryptor.finalize()
45        assert binascii.hexlify(computed_ct) == vector["ciphertext"]
46
47    def test_buffer_protocol(self, backend):
48        key = bytearray(os.urandom(32))
49        nonce = bytearray(os.urandom(16))
50        cipher = Cipher(algorithms.ChaCha20(key, nonce), None, backend)
51        enc = cipher.encryptor()
52        ct = enc.update(bytearray(b"hello")) + enc.finalize()
53        dec = cipher.decryptor()
54        pt = dec.update(ct) + dec.finalize()
55        assert pt == b"hello"
56
57    def test_key_size(self):
58        chacha = algorithms.ChaCha20(b"0" * 32, b"0" * 16)
59        assert chacha.key_size == 256
60
61    def test_invalid_key_size(self):
62        with pytest.raises(ValueError):
63            algorithms.ChaCha20(b"wrongsize", b"0" * 16)
64
65    def test_invalid_nonce(self):
66        with pytest.raises(ValueError):
67            algorithms.ChaCha20(b"0" * 32, b"0")
68
69        with pytest.raises(TypeError):
70            algorithms.ChaCha20(b"0" * 32, object())
71
72    def test_invalid_key_type(self):
73        with pytest.raises(TypeError, match="key must be bytes"):
74            algorithms.ChaCha20(u"0" * 32, b"0" * 16)
75