blob: 8fa9af924608c81e945bc8795a204f73205f61ba [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
Donald Stufft9e1a48b2013-08-09 00:32:30 -040014import os.path
15
16
Paul Kehrerf7f6a9f2013-11-11 20:43:52 -060017def load_vectors_from_file(filename, loader):
18 base = os.path.join(
19 os.path.dirname(__file__), "hazmat", "primitives", "vectors",
20 )
21 with open(os.path.join(base, filename), "r") as vector_file:
22 return loader(vector_file)
23
24
Alex Gaynord3ce7032013-11-11 14:46:20 -080025def load_nist_vectors(vector_data):
Alex Gaynor521c42d2013-11-11 14:25:59 -080026 section = None
27 count = None
28 data = {}
Donald Stufft9e1a48b2013-08-09 00:32:30 -040029
30 for line in vector_data:
31 line = line.strip()
32
33 # Blank lines are ignored
34 if not line:
35 continue
36
37 # Lines starting with # are comments
38 if line.startswith("#"):
39 continue
40
41 # Look for section headers
42 if line.startswith("[") and line.endswith("]"):
43 section = line[1:-1]
Alex Gaynor521c42d2013-11-11 14:25:59 -080044 continue
45
Paul Kehrera43b6692013-11-12 15:35:49 -060046 if line.strip() == "FAIL":
47 data[section, count]["fail"] = True
48 continue
49
Donald Stufft9e1a48b2013-08-09 00:32:30 -040050 # Build our data using a simple Key = Value format
Paul Kehrera43b6692013-11-12 15:35:49 -060051 name, value = [c.strip() for c in line.split("=")]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040052
53 # COUNT is a special token that indicates a new block of data
54 if name.upper() == "COUNT":
55 count = value
Alex Gaynord3ce7032013-11-11 14:46:20 -080056 data[section, count] = {}
Donald Stufft9e1a48b2013-08-09 00:32:30 -040057 # For all other tokens we simply want the name, value stored in
58 # the dictionary
59 else:
Alex Gaynord3ce7032013-11-11 14:46:20 -080060 data[section, count][name.lower()] = value.encode("ascii")
Donald Stufft9e1a48b2013-08-09 00:32:30 -040061
Alex Gaynor1fe70b12013-10-16 11:59:17 -070062 # We want to test only for a particular operation, we sort them for the
63 # benefit of the tests of this function.
Alex Gaynor521c42d2013-11-11 14:25:59 -080064 return [v for k, v in sorted(data.items(), key=lambda kv: kv[0])]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040065
66
Paul Kehrer1951bf62013-09-15 12:05:43 -050067def load_cryptrec_vectors(vector_data):
Paul Kehrere5805982013-09-27 11:26:01 -050068 cryptrec_list = []
Paul Kehrer1951bf62013-09-15 12:05:43 -050069
70 for line in vector_data:
71 line = line.strip()
72
73 # Blank lines and comments are ignored
74 if not line or line.startswith("#"):
75 continue
76
77 if line.startswith("K"):
Paul Kehrere5805982013-09-27 11:26:01 -050078 key = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050079 elif line.startswith("P"):
Paul Kehrere5805982013-09-27 11:26:01 -050080 pt = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050081 elif line.startswith("C"):
Paul Kehrere5805982013-09-27 11:26:01 -050082 ct = line.split(" : ")[1].replace(" ", "").encode("ascii")
83 # after a C is found the K+P+C tuple is complete
84 # there are many P+C pairs for each K
Alex Gaynor1fe70b12013-10-16 11:59:17 -070085 cryptrec_list.append({
86 "key": key,
87 "plaintext": pt,
88 "ciphertext": ct
89 })
Donald Stufft3359d7e2013-10-19 19:33:06 -040090 else:
91 raise ValueError("Invalid line in file '{}'".format(line))
Paul Kehrer1951bf62013-09-15 12:05:43 -050092 return cryptrec_list
93
94
Paul Kehrer6b99a1b2013-09-24 16:50:21 -050095def load_openssl_vectors(vector_data):
96 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -050097
98 for line in vector_data:
99 line = line.strip()
100
101 # Blank lines and comments are ignored
102 if not line or line.startswith("#"):
103 continue
104
105 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700106 vectors.append({
107 "key": vector[1].encode("ascii"),
108 "iv": vector[2].encode("ascii"),
109 "plaintext": vector[3].encode("ascii"),
110 "ciphertext": vector[4].encode("ascii"),
111 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500112 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500113
114
115def load_hash_vectors(vector_data):
116 vectors = []
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500117 key = None
118 msg = None
119 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500120
121 for line in vector_data:
122 line = line.strip()
123
Paul Kehrer87cd0db2013-10-18 18:01:26 -0500124 if not line or line.startswith("#") or line.startswith("["):
Paul Kehrer69e06522013-10-18 17:28:39 -0500125 continue
126
127 if line.startswith("Len"):
128 length = int(line.split(" = ")[1])
Paul Kehrer0317b042013-10-28 17:34:27 -0500129 elif line.startswith("Key"):
130 """
131 HMAC vectors contain a key attribute. Hash vectors do not.
132 """
133 key = line.split(" = ")[1].encode("ascii")
Paul Kehrer69e06522013-10-18 17:28:39 -0500134 elif line.startswith("Msg"):
135 """
136 In the NIST vectors they have chosen to represent an empty
137 string as hex 00, which is of course not actually an empty
138 string. So we parse the provided length and catch this edge case.
139 """
140 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
141 elif line.startswith("MD"):
142 md = line.split(" = ")[1]
Paul Kehrer0317b042013-10-28 17:34:27 -0500143 # after MD is found the Msg+MD (+ potential key) tuple is complete
Paul Kehrer00dd5092013-10-23 09:41:49 -0500144 if key is not None:
Paul Kehrer0317b042013-10-28 17:34:27 -0500145 vectors.append((msg, md, key))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500146 key = None
147 msg = None
148 md = None
Paul Kehrer00dd5092013-10-23 09:41:49 -0500149 else:
Paul Kehrer0317b042013-10-28 17:34:27 -0500150 vectors.append((msg, md))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500151 msg = None
152 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500153 else:
154 raise ValueError("Unknown line in hash vector")
155 return vectors