|
21 | 21 | # pylint: disable=redefined-outer-name |
22 | 22 |
|
23 | 23 | from collections import namedtuple |
| 24 | +import random |
24 | 25 | import pytest |
25 | 26 | from wolfcrypt._ffi import ffi as _ffi |
26 | 27 | from wolfcrypt._ffi import lib as _lib |
|
35 | 36 | if _lib.AES_ENABLED: |
36 | 37 | from wolfcrypt.ciphers import Aes |
37 | 38 |
|
| 39 | +if _lib.AES_SIV_ENABLED: |
| 40 | + from wolfcrypt.ciphers import AesSiv |
| 41 | + |
38 | 42 | if _lib.CHACHA_ENABLED: |
39 | 43 | from wolfcrypt.ciphers import ChaCha |
40 | 44 |
|
|
57 | 61 |
|
58 | 62 | @pytest.fixture |
59 | 63 | def vectors(): |
60 | | - TestVector = namedtuple("TestVector", """key iv plaintext ciphertext |
| 64 | + TestVector = namedtuple("TestVector", """key iv plaintext ciphertext |
61 | 65 | ciphertext_ctr raw_key |
62 | 66 | pkcs8_key pem""") |
63 | 67 | TestVector.__new__.__defaults__ = (None,) * len(TestVector._fields) |
@@ -727,3 +731,142 @@ def test_ed448_sign_verify(ed448_private, ed448_public): |
727 | 731 | # private object holds both private and public info, so it can also verify |
728 | 732 | # using the known public key. |
729 | 733 | assert ed448_private.verify(signature, plaintext) |
| 734 | + |
| 735 | + |
| 736 | +@pytest.mark.skipif(not _lib.AES_SIV_ENABLED, reason="AES-SIV not enabled") |
| 737 | +def test_aessiv_encrypt_decrypt(): |
| 738 | + key = random.randbytes(32) |
| 739 | + aessiv = AesSiv(key) |
| 740 | + associated_data = random.randbytes(16) |
| 741 | + nonce = random.randbytes(12) |
| 742 | + plaintext = random.randbytes(16) |
| 743 | + siv, ciphertext = aessiv.encrypt(associated_data, nonce, plaintext) |
| 744 | + assert aessiv.decrypt(associated_data, nonce, siv, ciphertext) == plaintext |
| 745 | + |
| 746 | + |
| 747 | +# |
| 748 | +# Test vectors copied from RFC-5297. |
| 749 | +# |
| 750 | +TEST_VECTOR_KEY_RFC5297 = bytes.fromhex( |
| 751 | + "7f7e7d7c 7b7a7978 77767574 73727170" |
| 752 | + "40414243 44454647 48494a4b 4c4d4e4f" |
| 753 | +) |
| 754 | +TEST_VECTOR_ASSOCIATED_DATA_1_RFC5297 = bytes.fromhex( |
| 755 | + "00112233 44556677 8899aabb ccddeeff" |
| 756 | + "deaddada deaddada ffeeddcc bbaa9988" |
| 757 | + "77665544 33221100" |
| 758 | +) |
| 759 | +TEST_VECTOR_ASSOCIATED_DATA_2_RFC5297 = bytes.fromhex( |
| 760 | + "10203040 50607080 90a0" |
| 761 | +) |
| 762 | +TEST_VECTOR_NONCE_RFC5297 = bytes.fromhex( |
| 763 | + "09f91102 9d74e35b d84156c5 635688c0" |
| 764 | +) |
| 765 | +TEST_VECTOR_PLAINTEXT_RFC5297 = bytes.fromhex( |
| 766 | + "74686973 20697320 736f6d65 20706c61" |
| 767 | + "696e7465 78742074 6f20656e 63727970" |
| 768 | + "74207573 696e6720 5349562d 414553" |
| 769 | +) |
| 770 | +TEST_VECTOR_SIV_RFC5297 = bytes.fromhex( |
| 771 | + "7bdb6e3b 432667eb 06f4d14b ff2fbd0f" |
| 772 | +) |
| 773 | +TEST_VECTOR_CIPHERTEXT_RFC5297 = bytes.fromhex( |
| 774 | + "cb900f2f ddbe4043 26601965 c889bf17" |
| 775 | + "dba77ceb 094fa663 b7a3f748 ba8af829" |
| 776 | + "ea64ad54 4a272e9c 485b62a3 fd5c0d" |
| 777 | +) |
| 778 | + |
| 779 | + |
| 780 | +@pytest.mark.skipif(not _lib.AES_SIV_ENABLED, reason="AES-SIV not enabled") |
| 781 | +def test_aessiv_encrypt_kat_rfc5297(): |
| 782 | + """ |
| 783 | + Known-answer test using test vectors from RFC-5297. |
| 784 | + """ |
| 785 | + aessiv = AesSiv(TEST_VECTOR_KEY_RFC5297) |
| 786 | + associated_data = [ |
| 787 | + TEST_VECTOR_ASSOCIATED_DATA_1_RFC5297, |
| 788 | + TEST_VECTOR_ASSOCIATED_DATA_2_RFC5297, |
| 789 | + ] |
| 790 | + siv, ciphertext = aessiv.encrypt( |
| 791 | + associated_data, |
| 792 | + TEST_VECTOR_NONCE_RFC5297, |
| 793 | + TEST_VECTOR_PLAINTEXT_RFC5297 |
| 794 | + ) |
| 795 | + assert siv == TEST_VECTOR_SIV_RFC5297 |
| 796 | + assert ciphertext == TEST_VECTOR_CIPHERTEXT_RFC5297 |
| 797 | + |
| 798 | + |
| 799 | +@pytest.mark.skipif(not _lib.AES_SIV_ENABLED, reason="AES-SIV not enabled") |
| 800 | +def test_aessiv_decrypt_kat_rfc5297(): |
| 801 | + """ |
| 802 | + Known-answer test using test vectors from RFC-5297. |
| 803 | + """ |
| 804 | + aessiv = AesSiv(TEST_VECTOR_KEY_RFC5297) |
| 805 | + associated_data = ( |
| 806 | + TEST_VECTOR_ASSOCIATED_DATA_1_RFC5297, |
| 807 | + TEST_VECTOR_ASSOCIATED_DATA_2_RFC5297, |
| 808 | + ) |
| 809 | + plaintext = aessiv.decrypt( |
| 810 | + associated_data, |
| 811 | + TEST_VECTOR_NONCE_RFC5297, |
| 812 | + TEST_VECTOR_SIV_RFC5297, |
| 813 | + TEST_VECTOR_CIPHERTEXT_RFC5297 |
| 814 | + ) |
| 815 | + assert plaintext == TEST_VECTOR_PLAINTEXT_RFC5297 |
| 816 | + |
| 817 | + |
| 818 | +# |
| 819 | +# Test vectors copied from OpenSSL library file evpciph_aes_siv.txt.. |
| 820 | +# |
| 821 | +TEST_VECTOR_KEY_OPENSSL = bytes.fromhex( |
| 822 | + "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" |
| 823 | +) |
| 824 | +TEST_VECTOR_ASSOCIATED_DATA_OPENSSL = bytes.fromhex( |
| 825 | + "101112131415161718191a1b1c1d1e1f2021222324252627" |
| 826 | +) |
| 827 | +TEST_VECTOR_NONCE_OPENSSL = b"" |
| 828 | +TEST_VECTOR_PLAINTEXT_OPENSSL = bytes.fromhex( |
| 829 | + "112233445566778899aabbccddee" |
| 830 | +) |
| 831 | +TEST_VECTOR_SIV_OPENSSL = bytes.fromhex( |
| 832 | + "85632d07c6e8f37f950acd320a2ecc93" |
| 833 | +) |
| 834 | +TEST_VECTOR_CIPHERTEXT_OPENSSL = bytes.fromhex( |
| 835 | + "40c02b9690c4dc04daef7f6afe5c" |
| 836 | +) |
| 837 | + |
| 838 | + |
| 839 | +@pytest.mark.skipif(not _lib.AES_SIV_ENABLED, reason="AES-SIV not enabled") |
| 840 | +def test_aessiv_encrypt_kat_openssl(): |
| 841 | + """ |
| 842 | + Known-answer test using test vectors from OpenSSL. |
| 843 | +
|
| 844 | + This also tests calling AesSiv with a single associated data block, not |
| 845 | + provided as a list of blocks. |
| 846 | + """ |
| 847 | + aessiv = AesSiv(TEST_VECTOR_KEY_OPENSSL) |
| 848 | + siv, ciphertext = aessiv.encrypt( |
| 849 | + TEST_VECTOR_ASSOCIATED_DATA_OPENSSL, |
| 850 | + TEST_VECTOR_NONCE_OPENSSL, |
| 851 | + TEST_VECTOR_PLAINTEXT_OPENSSL |
| 852 | + ) |
| 853 | + assert siv == TEST_VECTOR_SIV_OPENSSL |
| 854 | + assert ciphertext == TEST_VECTOR_CIPHERTEXT_OPENSSL |
| 855 | + |
| 856 | + |
| 857 | +@pytest.mark.skipif(not _lib.AES_SIV_ENABLED, reason="AES-SIV not enabled") |
| 858 | +def test_aessiv_decrypt_kat_openssl(): |
| 859 | + """ |
| 860 | + Known-answer test using test vectors from OpenSSL. |
| 861 | +
|
| 862 | + This also tests calling AesSiv with a single associated data block, not |
| 863 | + provided as a list of blocks. |
| 864 | + """ |
| 865 | + aessiv = AesSiv(TEST_VECTOR_KEY_OPENSSL) |
| 866 | + plaintext = aessiv.decrypt( |
| 867 | + TEST_VECTOR_ASSOCIATED_DATA_OPENSSL, |
| 868 | + TEST_VECTOR_NONCE_OPENSSL, |
| 869 | + TEST_VECTOR_SIV_OPENSSL, |
| 870 | + TEST_VECTOR_CIPHERTEXT_OPENSSL |
| 871 | + ) |
| 872 | + assert plaintext == TEST_VECTOR_PLAINTEXT_OPENSSL |
0 commit comments