blob: 03e31f3403ff74812723ce1067a5dc8018ec2fae [file] [log] [blame]
Paul Kehrer1681a692014-02-11 23:43:51 -06001Test Vectors
2============
3
4Testing the correctness of the primitives implemented in each ``cryptography``
5backend requires trusted test vectors. Where possible these vectors are obtained
6from official sources such as `NIST`_ or `IETF`_ RFCs. When this is not possible
7``cryptography`` has chosen to create a set of custom vectors using an official
8vector file as input to verify consistency between implemented backends.
9
10Sources
11-------
12
13Asymmetric Ciphers
14~~~~~~~~~~~~~~~~~~
15
16* RSA PKCS1 from the RSA FTP site (ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/
17 and ftp://ftp.rsa.com/pub/rsalabs/tmp/).
18
19Hashes
20~~~~~~
21
22* MD5 from :rfc:`1321`.
23* RIPEMD160 from the `RIPEMD website`_.
24* SHA1 from `NIST CAVP`_.
25* SHA2 (224, 256, 384, 512) from `NIST CAVP`_.
26* Whirlpool from the `Whirlpool website`_.
27
28HMAC
29~~~~
30
31* HMAC-MD5 from :rfc:`2202`.
32* HMAC-SHA1 from :rfc:`2202`.
33* HMAC-RIPEMD160 from :rfc:`2286`.
34* HMAC-SHA2 (224, 256, 384, 512) from :rfc:`4231`.
35
36Key Derivation Functions
37~~~~~~~~~~~~~~~~~~~~~~~~
38
39* HKDF (SHA1, SHA256) from :rfc:`5869`.
40* PBKDF2 (HMAC-SHA1) from :rfc:`6070`.
41
42Recipes
43~~~~~~~
44
45* Fernet from its `specification repository`_.
46
47Symmetric Ciphers
48~~~~~~~~~~~~~~~~~
49
50* AES (CBC, CFB, CTR, ECB, GCM, OFB) from `NIST CAVP`_.
51* 3DES (CBC, CFB, ECB, OFB) from `NIST CAVP`_.
52* ARC4 from :rfc:`6229`.
53* Blowfish (CBC, CFB, ECB, OFB) from `Bruce Schneier's vectors`_.
54* Camellia (ECB) from NTT's `Camellia page`_ as linked by `CRYPTREC`_.
55* Camellia (CBC, CFB, OFB) from `OpenSSL's test vectors`_.
56* CAST5 (ECB) from :rfc:`2144`.
57
58
59Creating Test Vectors
60---------------------
61
62To create test vectors for a block cipher the following code may be used as a
63template:
64
65.. code-block:: python
66
67 import binascii
68
69 from cryptography.hazmat.backends.openssl.backend import backend
70 from cryptography.hazmat.primitives.ciphers import base, algorithms, modes
71
72
73 def encrypt(key, iv, plaintext):
74 cipher = base.Cipher(
75 algorithms.CAST5(binascii.unhexlify(key)),
76 modes.OFB(binascii.unhexlify(iv)),
77 backend
78 )
79 encryptor = cipher.encryptor()
80 ct = encryptor.update(binascii.unhexlify(plaintext))
81 ct += encryptor.finalize()
82 return binascii.hexlify(ct)
83
84
85 vector_file = open(
86 "tests/hazmat/primitives/vectors/ciphers/AES/OFB/OFBMMT128.rsp",
87 "r"
88 )
89
90 count = 0
91 output = []
92 key = None
93 iv = None
94 plaintext = None
95 ct = None
96 for line in vector_file:
97 line = line.strip()
98 if line.startswith("KEY"):
99 if count != 0:
100 output.append("CIPHERTEXT = {}".format(encrypt(key, iv, plaintext)))
101 output.append("\nCOUNT = {}".format(count))
102 count += 1
103 name, key = line.split(" = ")
104 output.append("KEY = {}".format(key))
105 elif line.startswith("IV"):
106 name, iv = line.split(" = ")
107 iv = iv[0:16]
108 output.append("IV = {}".format(iv))
109 elif line.startswith("PLAINTEXT"):
110 name, plaintext = line.split(" = ")
111 output.append("PLAINTEXT = {}".format(plaintext))
112
113 output.append("CIPHERTEXT = {}".format(encrypt(key, iv, plaintext)))
114 print("\n".join(output))
115
116The algorithm, mode, and vector_file loaded must be modified to fit on a case
117by case basis. Additionally, the IV must be truncated (if necessary) to the
118length of the block size.
119
120The output generated by this script **must** be verified against at least one
121other implementation. In the example above, the vectors were generated against
122OpenSSL's implementation, so they must be verified against an implementation
123such as ``CommonCrypto`` or ``Go``.
124
125Any vectors generated by this method must also be prefixed with the following
126header format (substituting the correct information):
127
128.. code-block:: python
129
130 # CAST5 CBC vectors built for https://github.com/pyca/cryptography
131 # Derived from the AESVS MMT test data for CBC
132 # Verified against the CommonCrypto and Go crypto packages
133 # Key Length : 128
134
135If official test vectors appear in the future the custom generated vectors
136should be discarded.
137
138.. _`NIST`: http://www.nist.gov/
139.. _`IETF`: https://www.ietf.org/
140.. _`NIST CAVP`: http://csrc.nist.gov/groups/STM/cavp/
141.. _`Bruce Schneier's vectors`: https://www.schneier.com/code/vectors.txt
142.. _`Camellia page`: http://info.isl.ntt.co.jp/crypt/eng/camellia/
143.. _`CRYPTREC`: http://www.cryptrec.go.jp
144.. _`OpenSSL's test vectors`: https://github.com/openssl/openssl/blob/97cf1f6c2854a3a955fd7dd3a1f113deba00c9ef/crypto/evp/evptests.txt#L232
145.. _`RIPEMD website`: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
146.. _`Whirlpool website`: http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html
147.. _`Specification repository`: https://github.com/fernet/spec