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 9 10import pytest 11 12from cryptography.exceptions import ( 13 AlreadyFinalized, 14 InvalidSignature, 15 _Reasons, 16) 17from cryptography.hazmat.primitives.poly1305 import Poly1305 18 19from ...utils import ( 20 load_nist_vectors, 21 load_vectors_from_file, 22 raises_unsupported_algorithm, 23) 24 25 26@pytest.mark.supported( 27 only_if=lambda backend: not backend.poly1305_supported(), 28 skip_message="Requires OpenSSL without poly1305 support", 29) 30def test_poly1305_unsupported(backend): 31 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MAC): 32 Poly1305(b"0" * 32) 33 34 35@pytest.mark.supported( 36 only_if=lambda backend: backend.poly1305_supported(), 37 skip_message="Requires OpenSSL with poly1305 support", 38) 39class TestPoly1305(object): 40 @pytest.mark.parametrize( 41 "vector", 42 load_vectors_from_file( 43 os.path.join("poly1305", "rfc7539.txt"), load_nist_vectors 44 ), 45 ) 46 def test_vectors(self, vector, backend): 47 key = binascii.unhexlify(vector["key"]) 48 msg = binascii.unhexlify(vector["msg"]) 49 tag = binascii.unhexlify(vector["tag"]) 50 poly = Poly1305(key) 51 poly.update(msg) 52 assert poly.finalize() == tag 53 54 assert Poly1305.generate_tag(key, msg) == tag 55 Poly1305.verify_tag(key, msg, tag) 56 57 def test_key_with_no_additional_references(self, backend): 58 poly = Poly1305(os.urandom(32)) 59 assert len(poly.finalize()) == 16 60 61 def test_raises_after_finalize(self, backend): 62 poly = Poly1305(b"0" * 32) 63 poly.finalize() 64 65 with pytest.raises(AlreadyFinalized): 66 poly.update(b"foo") 67 68 with pytest.raises(AlreadyFinalized): 69 poly.finalize() 70 71 def test_reject_unicode(self, backend): 72 poly = Poly1305(b"0" * 32) 73 with pytest.raises(TypeError): 74 poly.update(u"") 75 76 with pytest.raises(TypeError): 77 Poly1305.generate_tag(b"0" * 32, u"") 78 79 def test_verify(self, backend): 80 poly = Poly1305(b"0" * 32) 81 poly.update(b"msg") 82 tag = poly.finalize() 83 84 with pytest.raises(AlreadyFinalized): 85 poly.verify(b"") 86 87 poly2 = Poly1305(b"0" * 32) 88 poly2.update(b"msg") 89 poly2.verify(tag) 90 91 Poly1305.verify_tag(b"0" * 32, b"msg", tag) 92 93 def test_invalid_verify(self, backend): 94 poly = Poly1305(b"0" * 32) 95 poly.update(b"msg") 96 with pytest.raises(InvalidSignature): 97 poly.verify(b"") 98 99 p2 = Poly1305(b"0" * 32) 100 p2.update(b"msg") 101 with pytest.raises(InvalidSignature): 102 p2.verify(b"\x00" * 16) 103 104 with pytest.raises(InvalidSignature): 105 Poly1305.verify_tag(b"0" * 32, b"msg", b"\x00" * 16) 106 107 def test_verify_reject_unicode(self, backend): 108 poly = Poly1305(b"0" * 32) 109 with pytest.raises(TypeError): 110 poly.verify(u"") 111 112 with pytest.raises(TypeError): 113 Poly1305.verify_tag(b"0" * 32, b"msg", u"") 114 115 def test_invalid_key_type(self, backend): 116 with pytest.raises(TypeError): 117 Poly1305(object()) 118 119 with pytest.raises(TypeError): 120 Poly1305.generate_tag(object(), b"msg") 121 122 def test_invalid_key_length(self, backend): 123 with pytest.raises(ValueError): 124 Poly1305(b"0" * 31) 125 126 with pytest.raises(ValueError): 127 Poly1305.generate_tag(b"0" * 31, b"msg") 128 129 with pytest.raises(ValueError): 130 Poly1305(b"0" * 33) 131 132 with pytest.raises(ValueError): 133 Poly1305.generate_tag(b"0" * 33, b"msg") 134 135 def test_buffer_protocol(self, backend): 136 key = binascii.unhexlify( 137 b"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cb" 138 b"c207075c0" 139 ) 140 msg = binascii.unhexlify( 141 b"2754776173206272696c6c69672c20616e642074686520736c69746" 142 b"87920746f7665730a446964206779726520616e642067696d626c65" 143 b"20696e2074686520776162653a0a416c6c206d696d7379207765726" 144 b"52074686520626f726f676f7665732c0a416e6420746865206d6f6d" 145 b"65207261746873206f757467726162652e" 146 ) 147 key = bytearray(key) 148 poly = Poly1305(key) 149 poly.update(bytearray(msg)) 150 assert poly.finalize() == binascii.unhexlify( 151 b"4541669a7eaaee61e708dc7cbcc5eb62" 152 ) 153 154 assert Poly1305.generate_tag(key, msg) == binascii.unhexlify( 155 b"4541669a7eaaee61e708dc7cbcc5eb62" 156 ) 157