blob: a243225651ae07deb16e71c39c67b36684c2584f [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
Paul Kehrerc421e632014-01-18 09:22:21 -060019def select_backends(names, backend_list):
20 if names is None:
21 return backend_list
22 split_names = [x.strip() for x in names.split(',')]
23 # this must be duplicated and then removed to preserve the metadata
24 # pytest associates. Appending backends to a new list doesn't seem to work
Paul Kehreraed9e172014-01-19 12:09:27 -060025 selected_backends = []
26 for backend in backend_list:
27 if backend.name in split_names:
28 selected_backends.append(backend)
Paul Kehrerc421e632014-01-18 09:22:21 -060029
Paul Kehreraed9e172014-01-19 12:09:27 -060030 if len(selected_backends) > 0:
31 return selected_backends
Paul Kehrerc421e632014-01-18 09:22:21 -060032 else:
33 raise ValueError(
34 "No backend selected. Tried to select: {0}".format(split_names)
35 )
Paul Kehrer34c075e2014-01-13 21:52:08 -050036
37
Alex Gaynor2b3f9422013-12-24 21:55:24 -080038def check_for_iface(name, iface, item):
39 if name in item.keywords and "backend" in item.funcargs:
40 if not isinstance(item.funcargs["backend"], iface):
41 pytest.skip("{0} backend does not support {1}".format(
42 item.funcargs["backend"], name
43 ))
Donald Stufft9e1a48b2013-08-09 00:32:30 -040044
45
Paul Kehrer60fc8da2013-12-26 20:19:34 -060046def check_backend_support(item):
Paul Kehrer5a8fdf82013-12-26 20:13:45 -060047 supported = item.keywords.get("supported")
48 if supported and "backend" in item.funcargs:
49 if not supported.kwargs["only_if"](item.funcargs["backend"]):
Paul Kehrerf03334e2014-01-02 23:16:14 -060050 pytest.skip("{0} ({1})".format(
51 supported.kwargs["skip_message"], item.funcargs["backend"]
52 ))
Paul Kehrer5a8fdf82013-12-26 20:13:45 -060053 elif supported:
Paul Kehrerec495502013-12-27 15:51:40 -060054 raise ValueError("This mark is only available on methods that take a "
55 "backend")
Paul Kehrer5a8fdf82013-12-26 20:13:45 -060056
57
Paul Kehrerf7f6a9f2013-11-11 20:43:52 -060058def load_vectors_from_file(filename, loader):
59 base = os.path.join(
60 os.path.dirname(__file__), "hazmat", "primitives", "vectors",
61 )
62 with open(os.path.join(base, filename), "r") as vector_file:
63 return loader(vector_file)
64
65
Alex Gaynord3ce7032013-11-11 14:46:20 -080066def load_nist_vectors(vector_data):
Paul Kehrer749ac5b2013-11-18 18:12:41 -060067 test_data = None
68 data = []
Donald Stufft9e1a48b2013-08-09 00:32:30 -040069
70 for line in vector_data:
71 line = line.strip()
72
Paul Kehrer749ac5b2013-11-18 18:12:41 -060073 # Blank lines, comments, and section headers are ignored
74 if not line or line.startswith("#") or (line.startswith("[")
75 and line.endswith("]")):
Alex Gaynor521c42d2013-11-11 14:25:59 -080076 continue
77
Paul Kehrera43b6692013-11-12 15:35:49 -060078 if line.strip() == "FAIL":
Paul Kehrer749ac5b2013-11-18 18:12:41 -060079 test_data["fail"] = True
Paul Kehrera43b6692013-11-12 15:35:49 -060080 continue
81
Donald Stufft9e1a48b2013-08-09 00:32:30 -040082 # Build our data using a simple Key = Value format
Paul Kehrera43b6692013-11-12 15:35:49 -060083 name, value = [c.strip() for c in line.split("=")]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040084
85 # COUNT is a special token that indicates a new block of data
86 if name.upper() == "COUNT":
Paul Kehrer749ac5b2013-11-18 18:12:41 -060087 test_data = {}
88 data.append(test_data)
89 continue
Donald Stufft9e1a48b2013-08-09 00:32:30 -040090 # For all other tokens we simply want the name, value stored in
91 # the dictionary
92 else:
Paul Kehrer749ac5b2013-11-18 18:12:41 -060093 test_data[name.lower()] = value.encode("ascii")
Donald Stufft9e1a48b2013-08-09 00:32:30 -040094
Paul Kehrer749ac5b2013-11-18 18:12:41 -060095 return data
Donald Stufft9e1a48b2013-08-09 00:32:30 -040096
97
Paul Kehrer1951bf62013-09-15 12:05:43 -050098def load_cryptrec_vectors(vector_data):
Paul Kehrere5805982013-09-27 11:26:01 -050099 cryptrec_list = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500100
101 for line in vector_data:
102 line = line.strip()
103
104 # Blank lines and comments are ignored
105 if not line or line.startswith("#"):
106 continue
107
108 if line.startswith("K"):
Paul Kehrere5805982013-09-27 11:26:01 -0500109 key = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -0500110 elif line.startswith("P"):
Paul Kehrere5805982013-09-27 11:26:01 -0500111 pt = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -0500112 elif line.startswith("C"):
Paul Kehrere5805982013-09-27 11:26:01 -0500113 ct = line.split(" : ")[1].replace(" ", "").encode("ascii")
114 # after a C is found the K+P+C tuple is complete
115 # there are many P+C pairs for each K
Alex Gaynor1fe70b12013-10-16 11:59:17 -0700116 cryptrec_list.append({
117 "key": key,
118 "plaintext": pt,
119 "ciphertext": ct
120 })
Donald Stufft3359d7e2013-10-19 19:33:06 -0400121 else:
122 raise ValueError("Invalid line in file '{}'".format(line))
Paul Kehrer1951bf62013-09-15 12:05:43 -0500123 return cryptrec_list
124
125
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500126def load_openssl_vectors(vector_data):
127 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500128
129 for line in vector_data:
130 line = line.strip()
131
132 # Blank lines and comments are ignored
133 if not line or line.startswith("#"):
134 continue
135
136 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700137 vectors.append({
138 "key": vector[1].encode("ascii"),
139 "iv": vector[2].encode("ascii"),
140 "plaintext": vector[3].encode("ascii"),
141 "ciphertext": vector[4].encode("ascii"),
142 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500143 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500144
145
146def load_hash_vectors(vector_data):
147 vectors = []
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500148 key = None
149 msg = None
150 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500151
152 for line in vector_data:
153 line = line.strip()
154
Paul Kehrer87cd0db2013-10-18 18:01:26 -0500155 if not line or line.startswith("#") or line.startswith("["):
Paul Kehrer69e06522013-10-18 17:28:39 -0500156 continue
157
158 if line.startswith("Len"):
159 length = int(line.split(" = ")[1])
Paul Kehrer0317b042013-10-28 17:34:27 -0500160 elif line.startswith("Key"):
161 """
162 HMAC vectors contain a key attribute. Hash vectors do not.
163 """
164 key = line.split(" = ")[1].encode("ascii")
Paul Kehrer69e06522013-10-18 17:28:39 -0500165 elif line.startswith("Msg"):
166 """
167 In the NIST vectors they have chosen to represent an empty
168 string as hex 00, which is of course not actually an empty
169 string. So we parse the provided length and catch this edge case.
170 """
171 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
172 elif line.startswith("MD"):
173 md = line.split(" = ")[1]
Paul Kehrer0317b042013-10-28 17:34:27 -0500174 # after MD is found the Msg+MD (+ potential key) tuple is complete
Paul Kehrer00dd5092013-10-23 09:41:49 -0500175 if key is not None:
Paul Kehrer0317b042013-10-28 17:34:27 -0500176 vectors.append((msg, md, key))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500177 key = None
178 msg = None
179 md = None
Paul Kehrer00dd5092013-10-23 09:41:49 -0500180 else:
Paul Kehrer0317b042013-10-28 17:34:27 -0500181 vectors.append((msg, md))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500182 msg = None
183 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500184 else:
185 raise ValueError("Unknown line in hash vector")
186 return vectors