blob: a97cdf7aee804d01e1d83280c11b1e80a5ffd3d2 [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 = []
130
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
154 try:
155 vectors.append((msg, md, key))
156 except:
157 vectors.append((msg, md))
Paul Kehrer69e06522013-10-18 17:28:39 -0500158 else:
159 raise ValueError("Unknown line in hash vector")
160 return vectors
161
162
163def load_hash_vectors_from_file(filename):
164 base = os.path.join(
Donald Stufftf04317a2013-10-27 16:44:30 -0400165 os.path.dirname(__file__), "hazmat", "primitives", "vectors"
Paul Kehrer69e06522013-10-18 17:28:39 -0500166 )
167 with open(os.path.join(base, filename), "r") as vector_file:
168 return load_hash_vectors(vector_file)