# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import, division, print_function

import binascii

import pytest

from cryptography.exceptions import (
    AlreadyFinalized, InvalidSignature, _Reasons
)
from cryptography.hazmat.backends.interfaces import CMACBackend
from cryptography.hazmat.primitives.ciphers.algorithms import (
    AES, ARC4, TripleDES
)
from cryptography.hazmat.primitives.cmac import CMAC

from ...utils import (
    load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm
)


vectors_aes128 = load_vectors_from_file(
    "CMAC/nist-800-38b-aes128.txt", load_nist_vectors)

vectors_aes192 = load_vectors_from_file(
    "CMAC/nist-800-38b-aes192.txt", load_nist_vectors)

vectors_aes256 = load_vectors_from_file(
    "CMAC/nist-800-38b-aes256.txt", load_nist_vectors)

vectors_aes = vectors_aes128 + vectors_aes192 + vectors_aes256

vectors_3des = load_vectors_from_file(
    "CMAC/nist-800-38b-3des.txt", load_nist_vectors)

fake_key = b"\x00" * 16


@pytest.mark.requires_backend_interface(interface=CMACBackend)
class TestCMAC(object):
    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    @pytest.mark.parametrize("params", vectors_aes)
    def test_aes_generate(self, backend, params):
        key = params["key"]
        message = params["message"]
        output = params["output"]

        cmac = CMAC(AES(binascii.unhexlify(key)), backend)
        cmac.update(binascii.unhexlify(message))
        assert binascii.hexlify(cmac.finalize()) == output

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    @pytest.mark.parametrize("params", vectors_aes)
    def test_aes_verify(self, backend, params):
        key = params["key"]
        message = params["message"]
        output = params["output"]

        cmac = CMAC(AES(binascii.unhexlify(key)), backend)
        cmac.update(binascii.unhexlify(message))
        assert cmac.verify(binascii.unhexlify(output)) is None

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            TripleDES(fake_key)),
        skip_message="Does not support CMAC."
    )
    @pytest.mark.parametrize("params", vectors_3des)
    def test_3des_generate(self, backend, params):
        key1 = params["key1"]
        key2 = params["key2"]
        key3 = params["key3"]

        key = key1 + key2 + key3

        message = params["message"]
        output = params["output"]

        cmac = CMAC(TripleDES(binascii.unhexlify(key)), backend)
        cmac.update(binascii.unhexlify(message))
        assert binascii.hexlify(cmac.finalize()) == output

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            TripleDES(fake_key)),
        skip_message="Does not support CMAC."
    )
    @pytest.mark.parametrize("params", vectors_3des)
    def test_3des_verify(self, backend, params):
        key1 = params["key1"]
        key2 = params["key2"]
        key3 = params["key3"]

        key = key1 + key2 + key3

        message = params["message"]
        output = params["output"]

        cmac = CMAC(TripleDES(binascii.unhexlify(key)), backend)
        cmac.update(binascii.unhexlify(message))
        assert cmac.verify(binascii.unhexlify(output)) is None

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    def test_invalid_verify(self, backend):
        key = b"2b7e151628aed2a6abf7158809cf4f3c"
        cmac = CMAC(AES(key), backend)
        cmac.update(b"6bc1bee22e409f96e93d7e117393172a")

        with pytest.raises(InvalidSignature):
            cmac.verify(b"foobar")

    @pytest.mark.supported(
        only_if=lambda backend: backend.cipher_supported(
            ARC4(fake_key), None),
        skip_message="Does not support CMAC."
    )
    def test_invalid_algorithm(self, backend):
        key = b"0102030405"
        with pytest.raises(TypeError):
            CMAC(ARC4(key), backend)

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    def test_raises_after_finalize(self, backend):
        key = b"2b7e151628aed2a6abf7158809cf4f3c"
        cmac = CMAC(AES(key), backend)
        cmac.finalize()

        with pytest.raises(AlreadyFinalized):
            cmac.update(b"foo")

        with pytest.raises(AlreadyFinalized):
            cmac.copy()

        with pytest.raises(AlreadyFinalized):
            cmac.finalize()

        with pytest.raises(AlreadyFinalized):
            cmac.verify(b"")

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    def test_verify_reject_unicode(self, backend):
        key = b"2b7e151628aed2a6abf7158809cf4f3c"
        cmac = CMAC(AES(key), backend)

        with pytest.raises(TypeError):
            cmac.update(u'')

        with pytest.raises(TypeError):
            cmac.verify(u'')

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    def test_copy_with_backend(self, backend):
        key = b"2b7e151628aed2a6abf7158809cf4f3c"
        cmac = CMAC(AES(key), backend)
        cmac.update(b"6bc1bee22e409f96e93d7e117393172a")
        copy_cmac = cmac.copy()
        assert cmac.finalize() == copy_cmac.finalize()

    @pytest.mark.supported(
        only_if=lambda backend: backend.cmac_algorithm_supported(
            AES(fake_key)),
        skip_message="Does not support CMAC."
    )
    def test_buffer_protocol(self, backend):
        key = bytearray(b"2b7e151628aed2a6abf7158809cf4f3c")
        cmac = CMAC(AES(key), backend)
        cmac.update(b"6bc1bee22e409f96e93d7e117393172a")
        assert cmac.finalize() == binascii.unhexlify(
            b"a21e6e647bfeaf5ca0a5e1bcd957dfad"
        )


def test_invalid_backend():
    key = b"2b7e151628aed2a6abf7158809cf4f3c"
    pretend_backend = object()

    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
        CMAC(AES(key), pretend_backend)
