blob: 113488d345ea488f01d3649aa2375b5a5e09247a [file] [log] [blame]
Alex Gaynorf312a5c2013-08-10 15:23:38 -04001# Licensed under the Apache License, Version 2.0 (the "License");
2# you may not use this file except in compliance with the License.
3# You may obtain a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS,
9# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10# implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
Alex Gaynor2b3f9422013-12-24 21:55:24 -080014import os
15
16import pytest
17
18
19def check_for_iface(name, iface, item):
20 if name in item.keywords and "backend" in item.funcargs:
21 if not isinstance(item.funcargs["backend"], iface):
22 pytest.skip("{0} backend does not support {1}".format(
23 item.funcargs["backend"], name
24 ))
Donald Stufft9e1a48b2013-08-09 00:32:30 -040025
26
Paul Kehrer5a8fdf82013-12-26 20:13:45 -060027def supported_by_backend_skip(item):
28 supported = item.keywords.get("supported")
29 if supported and "backend" in item.funcargs:
30 if not supported.kwargs["only_if"](item.funcargs["backend"]):
31 pytest.skip(supported.kwargs["skip_message"])
32 elif supported:
33 raise TypeError("This mark is only available on methods that take a "
34 "backend")
35
36
Paul Kehrerf7f6a9f2013-11-11 20:43:52 -060037def load_vectors_from_file(filename, loader):
38 base = os.path.join(
39 os.path.dirname(__file__), "hazmat", "primitives", "vectors",
40 )
41 with open(os.path.join(base, filename), "r") as vector_file:
42 return loader(vector_file)
43
44
Alex Gaynord3ce7032013-11-11 14:46:20 -080045def load_nist_vectors(vector_data):
Paul Kehrer749ac5b2013-11-18 18:12:41 -060046 test_data = None
47 data = []
Donald Stufft9e1a48b2013-08-09 00:32:30 -040048
49 for line in vector_data:
50 line = line.strip()
51
Paul Kehrer749ac5b2013-11-18 18:12:41 -060052 # Blank lines, comments, and section headers are ignored
53 if not line or line.startswith("#") or (line.startswith("[")
54 and line.endswith("]")):
Alex Gaynor521c42d2013-11-11 14:25:59 -080055 continue
56
Paul Kehrera43b6692013-11-12 15:35:49 -060057 if line.strip() == "FAIL":
Paul Kehrer749ac5b2013-11-18 18:12:41 -060058 test_data["fail"] = True
Paul Kehrera43b6692013-11-12 15:35:49 -060059 continue
60
Donald Stufft9e1a48b2013-08-09 00:32:30 -040061 # Build our data using a simple Key = Value format
Paul Kehrera43b6692013-11-12 15:35:49 -060062 name, value = [c.strip() for c in line.split("=")]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040063
64 # COUNT is a special token that indicates a new block of data
65 if name.upper() == "COUNT":
Paul Kehrer749ac5b2013-11-18 18:12:41 -060066 test_data = {}
67 data.append(test_data)
68 continue
Donald Stufft9e1a48b2013-08-09 00:32:30 -040069 # For all other tokens we simply want the name, value stored in
70 # the dictionary
71 else:
Paul Kehrer749ac5b2013-11-18 18:12:41 -060072 test_data[name.lower()] = value.encode("ascii")
Donald Stufft9e1a48b2013-08-09 00:32:30 -040073
Paul Kehrer749ac5b2013-11-18 18:12:41 -060074 return data
Donald Stufft9e1a48b2013-08-09 00:32:30 -040075
76
Paul Kehrer1951bf62013-09-15 12:05:43 -050077def load_cryptrec_vectors(vector_data):
Paul Kehrere5805982013-09-27 11:26:01 -050078 cryptrec_list = []
Paul Kehrer1951bf62013-09-15 12:05:43 -050079
80 for line in vector_data:
81 line = line.strip()
82
83 # Blank lines and comments are ignored
84 if not line or line.startswith("#"):
85 continue
86
87 if line.startswith("K"):
Paul Kehrere5805982013-09-27 11:26:01 -050088 key = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050089 elif line.startswith("P"):
Paul Kehrere5805982013-09-27 11:26:01 -050090 pt = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050091 elif line.startswith("C"):
Paul Kehrere5805982013-09-27 11:26:01 -050092 ct = line.split(" : ")[1].replace(" ", "").encode("ascii")
93 # after a C is found the K+P+C tuple is complete
94 # there are many P+C pairs for each K
Alex Gaynor1fe70b12013-10-16 11:59:17 -070095 cryptrec_list.append({
96 "key": key,
97 "plaintext": pt,
98 "ciphertext": ct
99 })
Donald Stufft3359d7e2013-10-19 19:33:06 -0400100 else:
101 raise ValueError("Invalid line in file '{}'".format(line))
Paul Kehrer1951bf62013-09-15 12:05:43 -0500102 return cryptrec_list
103
104
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500105def load_openssl_vectors(vector_data):
106 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500107
108 for line in vector_data:
109 line = line.strip()
110
111 # Blank lines and comments are ignored
112 if not line or line.startswith("#"):
113 continue
114
115 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700116 vectors.append({
117 "key": vector[1].encode("ascii"),
118 "iv": vector[2].encode("ascii"),
119 "plaintext": vector[3].encode("ascii"),
120 "ciphertext": vector[4].encode("ascii"),
121 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500122 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500123
124
125def load_hash_vectors(vector_data):
126 vectors = []
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500127 key = None
128 msg = None
129 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500130
131 for line in vector_data:
132 line = line.strip()
133
Paul Kehrer87cd0db2013-10-18 18:01:26 -0500134 if not line or line.startswith("#") or line.startswith("["):
Paul Kehrer69e06522013-10-18 17:28:39 -0500135 continue
136
137 if line.startswith("Len"):
138 length = int(line.split(" = ")[1])
Paul Kehrer0317b042013-10-28 17:34:27 -0500139 elif line.startswith("Key"):
140 """
141 HMAC vectors contain a key attribute. Hash vectors do not.
142 """
143 key = line.split(" = ")[1].encode("ascii")
Paul Kehrer69e06522013-10-18 17:28:39 -0500144 elif line.startswith("Msg"):
145 """
146 In the NIST vectors they have chosen to represent an empty
147 string as hex 00, which is of course not actually an empty
148 string. So we parse the provided length and catch this edge case.
149 """
150 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
151 elif line.startswith("MD"):
152 md = line.split(" = ")[1]
Paul Kehrer0317b042013-10-28 17:34:27 -0500153 # after MD is found the Msg+MD (+ potential key) tuple is complete
Paul Kehrer00dd5092013-10-23 09:41:49 -0500154 if key is not None:
Paul Kehrer0317b042013-10-28 17:34:27 -0500155 vectors.append((msg, md, key))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500156 key = None
157 msg = None
158 md = None
Paul Kehrer00dd5092013-10-23 09:41:49 -0500159 else:
Paul Kehrer0317b042013-10-28 17:34:27 -0500160 vectors.append((msg, md))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500161 msg = None
162 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500163 else:
164 raise ValueError("Unknown line in hash vector")
165 return vectors