blob: 03b780f8ee8d2cdf51a9746a0d6963e96ef0ced0 [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(
56 os.path.dirname(__file__), "primitives", "vectors", "NIST",
57 )
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(
64 os.path.dirname(__file__), "primitives", "vectors", "CRYPTREC",
65 )
66 with open(os.path.join(base, filename), "r") as vector_file:
67 return load_cryptrec_vectors(vector_file)
68
69
70def load_cryptrec_vectors(vector_data):
Paul Kehrere5805982013-09-27 11:26:01 -050071 cryptrec_list = []
Paul Kehrer1951bf62013-09-15 12:05:43 -050072
73 for line in vector_data:
74 line = line.strip()
75
76 # Blank lines and comments are ignored
77 if not line or line.startswith("#"):
78 continue
79
80 if line.startswith("K"):
Paul Kehrere5805982013-09-27 11:26:01 -050081 key = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050082 elif line.startswith("P"):
Paul Kehrere5805982013-09-27 11:26:01 -050083 pt = line.split(" : ")[1].replace(" ", "").encode("ascii")
Paul Kehrer1951bf62013-09-15 12:05:43 -050084 elif line.startswith("C"):
Paul Kehrere5805982013-09-27 11:26:01 -050085 ct = line.split(" : ")[1].replace(" ", "").encode("ascii")
86 # after a C is found the K+P+C tuple is complete
87 # there are many P+C pairs for each K
Alex Gaynor1fe70b12013-10-16 11:59:17 -070088 cryptrec_list.append({
89 "key": key,
90 "plaintext": pt,
91 "ciphertext": ct
92 })
Paul Kehrer1951bf62013-09-15 12:05:43 -050093 return cryptrec_list
94
95
Paul Kehrer6b99a1b2013-09-24 16:50:21 -050096def load_openssl_vectors_from_file(filename):
Paul Kehrer1951bf62013-09-15 12:05:43 -050097 base = os.path.join(
98 os.path.dirname(__file__), "primitives", "vectors", "OpenSSL",
99 )
100 with open(os.path.join(base, filename), "r") as vector_file:
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500101 return load_openssl_vectors(vector_file)
Paul Kehrer1951bf62013-09-15 12:05:43 -0500102
103
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500104def load_openssl_vectors(vector_data):
105 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500106
107 for line in vector_data:
108 line = line.strip()
109
110 # Blank lines and comments are ignored
111 if not line or line.startswith("#"):
112 continue
113
114 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700115 vectors.append({
116 "key": vector[1].encode("ascii"),
117 "iv": vector[2].encode("ascii"),
118 "plaintext": vector[3].encode("ascii"),
119 "ciphertext": vector[4].encode("ascii"),
120 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500121 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500122
123
124def load_hash_vectors(vector_data):
125 vectors = []
126
127 for line in vector_data:
128 line = line.strip()
129
Paul Kehrer87cd0db2013-10-18 18:01:26 -0500130 if not line or line.startswith("#") or line.startswith("["):
Paul Kehrer69e06522013-10-18 17:28:39 -0500131 continue
132
133 if line.startswith("Len"):
134 length = int(line.split(" = ")[1])
135 elif line.startswith("Msg"):
136 """
137 In the NIST vectors they have chosen to represent an empty
138 string as hex 00, which is of course not actually an empty
139 string. So we parse the provided length and catch this edge case.
140 """
141 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
142 elif line.startswith("MD"):
143 md = line.split(" = ")[1]
144 # after MD is found the Msg+MD tuple is complete
145 vectors.append((msg, md))
146 else:
147 raise ValueError("Unknown line in hash vector")
148 return vectors
149
150
151def load_hash_vectors_from_file(filename):
152 base = os.path.join(
153 os.path.dirname(__file__), "primitives", "vectors"
154 )
155 with open(os.path.join(base, filename), "r") as vector_file:
156 return load_hash_vectors(vector_file)