blob: fa7cc68dc9f246e50174cfde4a2ec674e9999cc7 [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 })
Donald Stufft3359d7e2013-10-19 19:33:06 -040093 else:
94 raise ValueError("Invalid line in file '{}'".format(line))
Paul Kehrer1951bf62013-09-15 12:05:43 -050095 return cryptrec_list
96
97
Paul Kehrer6b99a1b2013-09-24 16:50:21 -050098def load_openssl_vectors_from_file(filename):
Paul Kehrer1951bf62013-09-15 12:05:43 -050099 base = os.path.join(
100 os.path.dirname(__file__), "primitives", "vectors", "OpenSSL",
101 )
102 with open(os.path.join(base, filename), "r") as vector_file:
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500103 return load_openssl_vectors(vector_file)
Paul Kehrer1951bf62013-09-15 12:05:43 -0500104
105
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500106def load_openssl_vectors(vector_data):
107 vectors = []
Paul Kehrer1951bf62013-09-15 12:05:43 -0500108
109 for line in vector_data:
110 line = line.strip()
111
112 # Blank lines and comments are ignored
113 if not line or line.startswith("#"):
114 continue
115
116 vector = line.split(":")
Alex Gaynor016eed12013-10-16 14:16:04 -0700117 vectors.append({
118 "key": vector[1].encode("ascii"),
119 "iv": vector[2].encode("ascii"),
120 "plaintext": vector[3].encode("ascii"),
121 "ciphertext": vector[4].encode("ascii"),
122 })
Paul Kehrer6b99a1b2013-09-24 16:50:21 -0500123 return vectors
Paul Kehrer69e06522013-10-18 17:28:39 -0500124
125
126def load_hash_vectors(vector_data):
127 vectors = []
128
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])
137 elif line.startswith("Msg"):
138 """
139 In the NIST vectors they have chosen to represent an empty
140 string as hex 00, which is of course not actually an empty
141 string. So we parse the provided length and catch this edge case.
142 """
143 msg = line.split(" = ")[1].encode("ascii") if length > 0 else b""
144 elif line.startswith("MD"):
145 md = line.split(" = ")[1]
146 # after MD is found the Msg+MD tuple is complete
147 vectors.append((msg, md))
148 else:
149 raise ValueError("Unknown line in hash vector")
150 return vectors
151
152
153def load_hash_vectors_from_file(filename):
154 base = os.path.join(
155 os.path.dirname(__file__), "primitives", "vectors"
156 )
157 with open(os.path.join(base, filename), "r") as vector_file:
158 return load_hash_vectors(vector_file)