2 * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
37 /* Be sure to include tree copy rather than system copy. */
38 #include "cryptodev.h"
40 #include "freebsd_test_suite/macros.h"
43 const char *vector_name;
44 const char *test_key_hex;
45 const char *test_msg_hex;
46 const size_t test_msg_len;
48 const char *expected_tag_hex;
51 static const struct poly1305_kat rfc7539_kats[] = {
53 .vector_name = "RFC 7539 \xc2\xa7 2.5.2",
54 .test_key_hex = "85:d6:be:78:57:55:6d:33:7f:44:52:fe:42:d5:06:a8"
55 ":01:03:80:8a:fb:0d:b2:fd:4a:bf:f6:af:41:49:f5:1b",
57 "43 72 79 70 74 6f 67 72 61 70 68 69 63 20 46 6f "
58 "72 75 6d 20 52 65 73 65 61 72 63 68 20 47 72 6f "
61 .expected_tag_hex = "a8:06:1d:c1:30:51:36:c6:c2:2b:8b:af:0c:01:27:a9",
64 .vector_name = "RFC 7539 \xc2\xa7 A.3 #1",
66 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
67 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
69 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
70 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
71 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
72 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
74 .expected_tag_hex = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
77 .vector_name = "RFC 7539 \xc2\xa7 A.3 #2",
79 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
80 "36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e ",
82 "41 6e 79 20 73 75 62 6d 69 73 73 69 6f 6e 20 74 "
83 "6f 20 74 68 65 20 49 45 54 46 20 69 6e 74 65 6e "
84 "64 65 64 20 62 79 20 74 68 65 20 43 6f 6e 74 72 "
85 "69 62 75 74 6f 72 20 66 6f 72 20 70 75 62 6c 69 "
86 "63 61 74 69 6f 6e 20 61 73 20 61 6c 6c 20 6f 72 "
87 "20 70 61 72 74 20 6f 66 20 61 6e 20 49 45 54 46 "
88 "20 49 6e 74 65 72 6e 65 74 2d 44 72 61 66 74 20 "
89 "6f 72 20 52 46 43 20 61 6e 64 20 61 6e 79 20 73 "
90 "74 61 74 65 6d 65 6e 74 20 6d 61 64 65 20 77 69 "
91 "74 68 69 6e 20 74 68 65 20 63 6f 6e 74 65 78 74 "
92 "20 6f 66 20 61 6e 20 49 45 54 46 20 61 63 74 69 "
93 "76 69 74 79 20 69 73 20 63 6f 6e 73 69 64 65 72 "
94 "65 64 20 61 6e 20 22 49 45 54 46 20 43 6f 6e 74 "
95 "72 69 62 75 74 69 6f 6e 22 2e 20 53 75 63 68 20 "
96 "73 74 61 74 65 6d 65 6e 74 73 20 69 6e 63 6c 75 "
97 "64 65 20 6f 72 61 6c 20 73 74 61 74 65 6d 65 6e "
98 "74 73 20 69 6e 20 49 45 54 46 20 73 65 73 73 69 "
99 "6f 6e 73 2c 20 61 73 20 77 65 6c 6c 20 61 73 20 "
100 "77 72 69 74 74 65 6e 20 61 6e 64 20 65 6c 65 63 "
101 "74 72 6f 6e 69 63 20 63 6f 6d 6d 75 6e 69 63 61 "
102 "74 69 6f 6e 73 20 6d 61 64 65 20 61 74 20 61 6e "
103 "79 20 74 69 6d 65 20 6f 72 20 70 6c 61 63 65 2c "
104 "20 77 68 69 63 68 20 61 72 65 20 61 64 64 72 65 "
105 "73 73 65 64 20 74 6f",
107 .expected_tag_hex = "36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e",
110 .vector_name = "RFC 7539 \xc2\xa7 A.3 #3",
112 "36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e "
113 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
115 "41 6e 79 20 73 75 62 6d 69 73 73 69 6f 6e 20 74 "
116 "6f 20 74 68 65 20 49 45 54 46 20 69 6e 74 65 6e "
117 "64 65 64 20 62 79 20 74 68 65 20 43 6f 6e 74 72 "
118 "69 62 75 74 6f 72 20 66 6f 72 20 70 75 62 6c 69 "
119 "63 61 74 69 6f 6e 20 61 73 20 61 6c 6c 20 6f 72 "
120 "20 70 61 72 74 20 6f 66 20 61 6e 20 49 45 54 46 "
121 "20 49 6e 74 65 72 6e 65 74 2d 44 72 61 66 74 20 "
122 "6f 72 20 52 46 43 20 61 6e 64 20 61 6e 79 20 73 "
123 "74 61 74 65 6d 65 6e 74 20 6d 61 64 65 20 77 69 "
124 "74 68 69 6e 20 74 68 65 20 63 6f 6e 74 65 78 74 "
125 "20 6f 66 20 61 6e 20 49 45 54 46 20 61 63 74 69 "
126 "76 69 74 79 20 69 73 20 63 6f 6e 73 69 64 65 72 "
127 "65 64 20 61 6e 20 22 49 45 54 46 20 43 6f 6e 74 "
128 "72 69 62 75 74 69 6f 6e 22 2e 20 53 75 63 68 20 "
129 "73 74 61 74 65 6d 65 6e 74 73 20 69 6e 63 6c 75 "
130 "64 65 20 6f 72 61 6c 20 73 74 61 74 65 6d 65 6e "
131 "74 73 20 69 6e 20 49 45 54 46 20 73 65 73 73 69 "
132 "6f 6e 73 2c 20 61 73 20 77 65 6c 6c 20 61 73 20 "
133 "77 72 69 74 74 65 6e 20 61 6e 64 20 65 6c 65 63 "
134 "74 72 6f 6e 69 63 20 63 6f 6d 6d 75 6e 69 63 61 "
135 "74 69 6f 6e 73 20 6d 61 64 65 20 61 74 20 61 6e "
136 "79 20 74 69 6d 65 20 6f 72 20 70 6c 61 63 65 2c "
137 "20 77 68 69 63 68 20 61 72 65 20 61 64 64 72 65 "
138 "73 73 65 64 20 74 6f",
140 .expected_tag_hex = "f3 47 7e 7c d9 54 17 af 89 a6 b8 79 4c 31 0c f0",
143 .vector_name = "RFC 7539 \xc2\xa7 A.3 #4",
145 "1c 92 40 a5 eb 55 d3 8a f3 33 88 86 04 f6 b5 f0 "
146 "47 39 17 c1 40 2b 80 09 9d ca 5c bc 20 70 75 c0 ",
148 "27 54 77 61 73 20 62 72 69 6c 6c 69 67 2c 20 61 "
149 "6e 64 20 74 68 65 20 73 6c 69 74 68 79 20 74 6f "
150 "76 65 73 0a 44 69 64 20 67 79 72 65 20 61 6e 64 "
151 "20 67 69 6d 62 6c 65 20 69 6e 20 74 68 65 20 77 "
152 "61 62 65 3a 0a 41 6c 6c 20 6d 69 6d 73 79 20 77 "
153 "65 72 65 20 74 68 65 20 62 6f 72 6f 67 6f 76 65 "
154 "73 2c 0a 41 6e 64 20 74 68 65 20 6d 6f 6d 65 20 "
155 "72 61 74 68 73 20 6f 75 74 67 72 61 62 65 2e",
157 .expected_tag_hex = "45 41 66 9a 7e aa ee 61 e7 08 dc 7c bc c5 eb 62",
160 .vector_name = "RFC 7539 \xc2\xa7 A.3 #5",
162 "02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
163 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
165 "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF",
167 .expected_tag_hex = "03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
170 .vector_name = "RFC 7539 \xc2\xa7 A.3 #6",
172 "02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
173 "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ",
175 "02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
177 .expected_tag_hex = "03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
181 .vector_name = "RFC 7539 \xc2\xa7 A.3 #7",
183 "01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
184 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
186 "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF "
187 "F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF "
188 "11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
190 .expected_tag_hex = "05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
193 .vector_name = "RFC 7539 \xc2\xa7 A.3 #8",
195 "01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
196 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
198 "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF "
199 "FB FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE "
200 "01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01",
202 .expected_tag_hex = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
205 .vector_name = "RFC 7539 \xc2\xa7 A.3 #9",
207 "02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
208 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
210 "FD FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF",
212 .expected_tag_hex = "FA FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF",
215 .vector_name = "RFC 7539 \xc2\xa7 A.3 #10",
217 "01 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 "
218 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
220 "E3 35 94 D7 50 5E 43 B9 00 00 00 00 00 00 00 00 "
221 "33 94 D7 50 5E 43 79 CD 01 00 00 00 00 00 00 00 "
222 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
223 "01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
225 .expected_tag_hex = "14 00 00 00 00 00 00 00 55 00 00 00 00 00 00 00",
228 .vector_name = "RFC 7539 \xc2\xa7 A.3 #11",
230 "01 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 "
231 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ",
233 "E3 35 94 D7 50 5E 43 B9 00 00 00 00 00 00 00 00 "
234 "33 94 D7 50 5E 43 79 CD 01 00 00 00 00 00 00 00 "
235 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
237 .expected_tag_hex = "13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
242 parse_hex(const struct poly1305_kat *kat, const char *hexstr, void *voutput,
245 /* Space or colon delimited; may contain a single trailing space;
246 * length should match exactly.
248 const char *sep, *it;
249 size_t sym_len, count;
254 memset(hbyte, 0, sizeof(hbyte));
259 sep = strpbrk(it, " :");
261 sym_len = strlen(it);
265 ATF_REQUIRE_EQ_MSG(sym_len, 2,
266 "invalid hex byte '%.*s' in vector %s", (int)sym_len, it,
269 memcpy(hbyte, it, 2);
270 res = sscanf(hbyte, "%hhx", &out[count]);
271 ATF_REQUIRE_EQ_MSG(res, 1,
272 "invalid hex byte '%s' in vector %s", hbyte,
276 ATF_REQUIRE_MSG(count <= explen,
277 "got longer than expected value at %s", kat->vector_name);
282 while (*it == ' ' || *it == ':')
288 ATF_REQUIRE_EQ_MSG(count, explen, "got short value at %s",
293 parse_vector(const struct poly1305_kat *kat,
294 uint8_t key[__min_size(POLY1305_KEY_LEN)], char *msg,
295 uint8_t exptag[__min_size(POLY1305_HASH_LEN)])
297 parse_hex(kat, kat->test_key_hex, key, POLY1305_KEY_LEN);
298 parse_hex(kat, kat->test_msg_hex, msg, kat->test_msg_len);
299 parse_hex(kat, kat->expected_tag_hex, exptag, POLY1305_HASH_LEN);
307 dc_fd = open("/dev/crypto", O_RDWR);
310 * Why do we do this dance instead of just operating on /dev/crypto
311 * directly? I have no idea.
313 ATF_REQUIRE(dc_fd >= 0);
314 ATF_REQUIRE(ioctl(dc_fd, CRIOGET, &fd) != -1);
320 create_session(int fd, int alg, int crid, const void *key, size_t klen)
322 struct session2_op sop;
324 memset(&sop, 0, sizeof(sop));
328 sop.mackeylen = klen;
331 ATF_REQUIRE_MSG(ioctl(fd, CIOCGSESSION2, &sop) >= 0,
332 "alg %d keylen %zu, errno=%d (%s)", alg, klen, errno,
338 destroy_session(int fd, int _ses)
343 ATF_REQUIRE_MSG(ioctl(fd, CIOCFSESSION, &ses) >= 0,
344 "destroy session failed, errno=%d (%s)", errno, strerror(errno));
348 do_cryptop(int fd, int ses, const void *inp, size_t inlen, void *out)
352 memset(&cop, 0, sizeof(cop));
358 ATF_CHECK_MSG(ioctl(fd, CIOCCRYPT, &cop) >= 0, "ioctl(CIOCCRYPT)");
362 test_rfc7539_poly1305_vectors(int crid, const char *modname)
364 uint8_t comptag[POLY1305_HASH_LEN], exptag[POLY1305_HASH_LEN],
365 key[POLY1305_KEY_LEN], msg[512];
369 ATF_REQUIRE_KERNEL_MODULE(modname);
370 ATF_REQUIRE_KERNEL_MODULE("cryptodev");
372 fd = get_handle_fd();
374 for (i = 0; i < nitems(rfc7539_kats); i++) {
375 const struct poly1305_kat *kat;
377 kat = &rfc7539_kats[i];
378 parse_vector(kat, key, msg, exptag);
380 ses = create_session(fd, CRYPTO_POLY1305, crid, key, sizeof(key));
382 do_cryptop(fd, ses, msg, kat->test_msg_len, comptag);
383 ATF_CHECK_EQ_MSG(memcmp(comptag, exptag, sizeof(exptag)), 0,
384 "KAT %s failed:", kat->vector_name);
386 destroy_session(fd, ses);
390 ATF_TC_WITHOUT_HEAD(poly1305_vectors);
391 ATF_TC_BODY(poly1305_vectors, tc)
393 ATF_REQUIRE_SYSCTL_INT("kern.cryptodevallowsoft", 1);
394 test_rfc7539_poly1305_vectors(CRYPTO_FLAG_SOFTWARE, "nexus/cryptosoft");
400 ATF_TP_ADD_TC(tp, poly1305_vectors);
402 return (atf_no_error());