blob: ad676c04cc425f9d590f9d1bc1dc25e97ee80dd8 [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
Alex Gaynor1fe70b12013-10-16 11:59:17 -070017def load_nist_vectors(vector_data, op):
Donald Stufft9e1a48b2013-08-09 00:32:30 -040018 section, count, data = None, None, {}
19
20 for line in vector_data:
21 line = line.strip()
22
23 # Blank lines are ignored
24 if not line:
25 continue
26
27 # Lines starting with # are comments
28 if line.startswith("#"):
29 continue
30
31 # Look for section headers
32 if line.startswith("[") and line.endswith("]"):
33 section = line[1:-1]
34 data[section] = {}
35 continue
36
37 # Build our data using a simple Key = Value format
38 name, value = line.split(" = ")
39
40 # COUNT is a special token that indicates a new block of data
41 if name.upper() == "COUNT":
42 count = value
43 data[section][count] = {}
44 # For all other tokens we simply want the name, value stored in
45 # the dictionary
46 else:
Alex Gaynor1fe70b12013-10-16 11:59:17 -070047 data[section][count][name.lower()] = value.encode("ascii")
Donald Stufft9e1a48b2013-08-09 00:32:30 -040048
Alex Gaynor1fe70b12013-10-16 11:59:17 -070049 # We want to test only for a particular operation, we sort them for the
50 # benefit of the tests of this function.
51 return [v for k, v in sorted(data[op].items(), key=lambda kv: kv[0])]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040052
53
Alex Gaynor1fe70b12013-10-16 11:59:17 -070054def load_nist_vectors_from_file(filename, op):
Donald Stufft9e1a48b2013-08-09 00:32:30 -040055 base = os.path.join(
Donald Stufftf04317a2013-10-27 16:44:30 -040056 os.path.dirname(__file__), "hazmat", "primitives", "vectors", "NIST",
Donald Stufft9e1a48b2013-08-09 00:32:30 -040057 )
58 with open(os.path.join(base, filename), "r") as vector_file:
Alex Gaynor1fe70b12013-10-16 11:59:17 -070059 return load_nist_vectors(vector_file, op)
Paul Kehrer1951bf62013-09-15 12:05:43 -050060
61
62def load_cryptrec_vectors_from_file(filename):
63 base = os.path.join(
Donald Stufftf04317a2013-10-27 16:44:30 -040064 os.path.dirname(__file__),
65 "hazmat", "primitives", "vectors", "CRYPTREC",
Paul Kehrer1951bf62013-09-15 12:05:43 -050066 )
67 with open(os.path.join(base, filename), "r") as vector_file:
68 return load_cryptrec_vectors(vector_file)
69
70
71def load_cryptrec_vectors(vector_data):
Paul Kehrere5805982013-09-27 11:26:01 -050072 cryptrec_list = []
Paul Kehrer1951bf62013-09-15 12:05:43 -050073
74 for line in vector_data:
75 line = line.strip()
76
77 # Blank lines and comments are ignored
78 if not line or line.startswith("#"):
79 continue
80
81 if line.startswith("K"):
Paul Kehrere5805982013-09-27 11:26:01 -050082 key = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050083 elif line.startswith("P"):
Paul Kehrere5805982013-09-27 11:26:01 -050084 pt = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050085 elif line.startswith("C"):
Paul Kehrere5805982013-09-27 11:26:01 -050086 ct = line.split(" : ")[1].replace(" ", "").encode("ascii")
87 # after a C is found the K+P+C tuple is complete
88 # there are many P+C pairs for each K
Alex Gaynor1fe70b12013-10-16 11:59:17 -070089 cryptrec_list.append({
90 "key": key,
91 "plaintext": pt,
92 "ciphertext": ct
93 })
Donald Stufft3359d7e2013-10-19 19:33:06 -040094 else:
95 raise ValueError("Invalid line in file '{}'".format(line))
Paul Kehrer1951bf62013-09-15 12:05:43 -050096 return cryptrec_list
97
98
Paul Kehrer6b99a1b2013-09-24 16:50:21 -050099def load_openssl_vectors_from_file(filename):
Paul Kehrer1951bf62013-09-15 12:05:43 -0500100 base = os.path.join(
Donald Stufftf04317a2013-10-27 16:44:30 -0400101 os.path.dirname(__file__),
102 "hazmat", "primitives", "vectors", "OpenSSL",
Paul Kehrer1951bf62013-09-15 12:05:43 -0500103 )
104 with open(os.path.join(base, filename), "r") as vector_file:
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500105 return load_openssl_vectors(vector_file)
Paul Kehrer1951bf62013-09-15 12:05:43 -0500106
107
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500108def load_openssl_vectors(vector_data):
109 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500110
111 for line in vector_data:
112 line = line.strip()
113
114 # Blank lines and comments are ignored
115 if not line or line.startswith("#"):
116 continue
117
118 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700119 vectors.append({
120 "key": vector[1].encode("ascii"),
121 "iv": vector[2].encode("ascii"),
122 "plaintext": vector[3].encode("ascii"),
123 "ciphertext": vector[4].encode("ascii"),
124 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500125 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500126
127
128def load_hash_vectors(vector_data):
129 vectors = []
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500130 key = None
131 msg = None
132 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500133
134 for line in vector_data:
135 line = line.strip()
136
Paul Kehrer87cd0db2013-10-18 18:01:26 -0500137 if not line or line.startswith("#") or line.startswith("["):
Paul Kehrer69e06522013-10-18 17:28:39 -0500138 continue
139
140 if line.startswith("Len"):
141 length = int(line.split(" = ")[1])
Paul Kehrer0317b042013-10-28 17:34:27 -0500142 elif line.startswith("Key"):
143 """
144 HMAC vectors contain a key attribute. Hash vectors do not.
145 """
146 key = line.split(" = ")[1].encode("ascii")
Paul Kehrer69e06522013-10-18 17:28:39 -0500147 elif line.startswith("Msg"):
148 """
149 In the NIST vectors they have chosen to represent an empty
150 string as hex 00, which is of course not actually an empty
151 string. So we parse the provided length and catch this edge case.
152 """
153 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
154 elif line.startswith("MD"):
155 md = line.split(" = ")[1]
Paul Kehrer0317b042013-10-28 17:34:27 -0500156 # after MD is found the Msg+MD (+ potential key) tuple is complete
Paul Kehrer00dd5092013-10-23 09:41:49 -0500157 if key is not None:
Paul Kehrer0317b042013-10-28 17:34:27 -0500158 vectors.append((msg, md, key))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500159 key = None
160 msg = None
161 md = None
Paul Kehrer00dd5092013-10-23 09:41:49 -0500162 else:
Paul Kehrer0317b042013-10-28 17:34:27 -0500163 vectors.append((msg, md))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500164 msg = None
165 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500166 else:
167 raise ValueError("Unknown line in hash vector")
168 return vectors
169
170
171def load_hash_vectors_from_file(filename):
172 base = os.path.join(
Donald Stufftf04317a2013-10-27 16:44:30 -0400173 os.path.dirname(__file__), "hazmat", "primitives", "vectors"
Paul Kehrer69e06522013-10-18 17:28:39 -0500174 )
175 with open(os.path.join(base, filename), "r") as vector_file:
176 return load_hash_vectors(vector_file)