blob: 988a80b0d731fbe662d64ac7cc96b2b26cd4d816 [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("]"):
Paul Kehrerc985dbb2013-11-18 14:11:55 -060043 if "=" in line:
44 # GCM section headers
45 if "Keylen" in line:
46 section = line[1:-1]
47 else:
48 section += line[1:-1]
49 else:
50 # non-GCM section headers
51 section = line[1:-1]
Alex Gaynor521c42d2013-11-11 14:25:59 -080052 continue
53
Paul Kehrera43b6692013-11-12 15:35:49 -060054 if line.strip() == "FAIL":
55 data[section, count]["fail"] = True
56 continue
57
Donald Stufft9e1a48b2013-08-09 00:32:30 -040058 # Build our data using a simple Key = Value format
Paul Kehrera43b6692013-11-12 15:35:49 -060059 name, value = [c.strip() for c in line.split("=")]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040060
61 # COUNT is a special token that indicates a new block of data
62 if name.upper() == "COUNT":
63 count = value
Alex Gaynord3ce7032013-11-11 14:46:20 -080064 data[section, count] = {}
Donald Stufft9e1a48b2013-08-09 00:32:30 -040065 # For all other tokens we simply want the name, value stored in
66 # the dictionary
67 else:
Alex Gaynord3ce7032013-11-11 14:46:20 -080068 data[section, count][name.lower()] = value.encode("ascii")
Donald Stufft9e1a48b2013-08-09 00:32:30 -040069
Alex Gaynor1fe70b12013-10-16 11:59:17 -070070 # We want to test only for a particular operation, we sort them for the
71 # benefit of the tests of this function.
Alex Gaynor521c42d2013-11-11 14:25:59 -080072 return [v for k, v in sorted(data.items(), key=lambda kv: kv[0])]
Donald Stufft9e1a48b2013-08-09 00:32:30 -040073
74
Paul Kehrer1951bf62013-09-15 12:05:43 -050075def load_cryptrec_vectors(vector_data):
Paul Kehrere5805982013-09-27 11:26:01 -050076 cryptrec_list = []
Paul Kehrer1951bf62013-09-15 12:05:43 -050077
78 for line in vector_data:
79 line = line.strip()
80
81 # Blank lines and comments are ignored
82 if not line or line.startswith("#"):
83 continue
84
85 if line.startswith("K"):
Paul Kehrere5805982013-09-27 11:26:01 -050086 key = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050087 elif line.startswith("P"):
Paul Kehrere5805982013-09-27 11:26:01 -050088 pt = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050089 elif line.startswith("C"):
Paul Kehrere5805982013-09-27 11:26:01 -050090 ct = line.split(" : ")[1].replace(" ", "").encode("ascii")
91 # after a C is found the K+P+C tuple is complete
92 # there are many P+C pairs for each K
Alex Gaynor1fe70b12013-10-16 11:59:17 -070093 cryptrec_list.append({
94 "key": key,
95 "plaintext": pt,
96 "ciphertext": ct
97 })
Donald Stufft3359d7e2013-10-19 19:33:06 -040098 else:
99 raise ValueError("Invalid line in file '{}'".format(line))
Paul Kehrer1951bf62013-09-15 12:05:43 -0500100 return cryptrec_list
101
102
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500103def load_openssl_vectors(vector_data):
104 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500105
106 for line in vector_data:
107 line = line.strip()
108
109 # Blank lines and comments are ignored
110 if not line or line.startswith("#"):
111 continue
112
113 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700114 vectors.append({
115 "key": vector[1].encode("ascii"),
116 "iv": vector[2].encode("ascii"),
117 "plaintext": vector[3].encode("ascii"),
118 "ciphertext": vector[4].encode("ascii"),
119 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500120 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500121
122
123def load_hash_vectors(vector_data):
124 vectors = []
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500125 key = None
126 msg = None
127 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500128
129 for line in vector_data:
130 line = line.strip()
131
Paul Kehrer87cd0db2013-10-18 18:01:26 -0500132 if not line or line.startswith("#") or line.startswith("["):
Paul Kehrer69e06522013-10-18 17:28:39 -0500133 continue
134
135 if line.startswith("Len"):
136 length = int(line.split(" = ")[1])
Paul Kehrer0317b042013-10-28 17:34:27 -0500137 elif line.startswith("Key"):
138 """
139 HMAC vectors contain a key attribute. Hash vectors do not.
140 """
141 key = line.split(" = ")[1].encode("ascii")
Paul Kehrer69e06522013-10-18 17:28:39 -0500142 elif line.startswith("Msg"):
143 """
144 In the NIST vectors they have chosen to represent an empty
145 string as hex 00, which is of course not actually an empty
146 string. So we parse the provided length and catch this edge case.
147 """
148 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
149 elif line.startswith("MD"):
150 md = line.split(" = ")[1]
Paul Kehrer0317b042013-10-28 17:34:27 -0500151 # after MD is found the Msg+MD (+ potential key) tuple is complete
Paul Kehrer00dd5092013-10-23 09:41:49 -0500152 if key is not None:
Paul Kehrer0317b042013-10-28 17:34:27 -0500153 vectors.append((msg, md, key))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500154 key = None
155 msg = None
156 md = None
Paul Kehrer00dd5092013-10-23 09:41:49 -0500157 else:
Paul Kehrer0317b042013-10-28 17:34:27 -0500158 vectors.append((msg, md))
Paul Kehrer1bb8b712013-10-27 17:00:14 -0500159 msg = None
160 md = None
Paul Kehrer69e06522013-10-18 17:28:39 -0500161 else:
162 raise ValueError("Unknown line in hash vector")
163 return vectors