1 /*- 2 * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 13 * 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 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/param.h> 30 31 #include <errno.h> 32 #include <fcntl.h> 33 #include <string.h> 34 35 #include <atf-c.h> 36 37 /* Be sure to include tree copy rather than system copy. */ 38 #include "cryptodev.h" 39 40 #include "freebsd_test_suite/macros.h" 41 42 struct poly1305_kat { 43 const char *vector_name; 44 const char *test_key_hex; 45 const char *test_msg_hex; 46 const size_t test_msg_len; 47 48 const char *expected_tag_hex; 49 }; 50 51 static const struct poly1305_kat rfc7539_kats[] = { 52 { 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", 56 .test_msg_hex = 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 " 59 "75 70", 60 .test_msg_len = 34, 61 .expected_tag_hex = "a8:06:1d:c1:30:51:36:c6:c2:2b:8b:af:0c:01:27:a9", 62 }, 63 { 64 .vector_name = "RFC 7539 \xc2\xa7 A.3 #1", 65 .test_key_hex = 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 ", 68 .test_msg_hex = 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 ", 73 .test_msg_len = 64, 74 .expected_tag_hex = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 75 }, 76 { 77 .vector_name = "RFC 7539 \xc2\xa7 A.3 #2", 78 .test_key_hex = 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 ", 81 .test_msg_hex = 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", 106 .test_msg_len = 375, 107 .expected_tag_hex = "36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e", 108 }, 109 { 110 .vector_name = "RFC 7539 \xc2\xa7 A.3 #3", 111 .test_key_hex = 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 ", 114 .test_msg_hex = 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", 139 .test_msg_len = 375, 140 .expected_tag_hex = "f3 47 7e 7c d9 54 17 af 89 a6 b8 79 4c 31 0c f0", 141 }, 142 { 143 .vector_name = "RFC 7539 \xc2\xa7 A.3 #4", 144 .test_key_hex = 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 ", 147 .test_msg_hex = 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", 156 .test_msg_len = 127, 157 .expected_tag_hex = "45 41 66 9a 7e aa ee 61 e7 08 dc 7c bc c5 eb 62", 158 }, 159 { 160 .vector_name = "RFC 7539 \xc2\xa7 A.3 #5", 161 .test_key_hex = 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 ", 164 .test_msg_hex = 165 "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF", 166 .test_msg_len = 16, 167 .expected_tag_hex = "03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 168 }, 169 { 170 .vector_name = "RFC 7539 \xc2\xa7 A.3 #6", 171 .test_key_hex = 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 ", 174 .test_msg_hex = 175 "02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 176 .test_msg_len = 16, 177 .expected_tag_hex = "03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 178 179 }, 180 { 181 .vector_name = "RFC 7539 \xc2\xa7 A.3 #7", 182 .test_key_hex = 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 ", 185 .test_msg_hex = 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", 189 .test_msg_len = 48, 190 .expected_tag_hex = "05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 191 }, 192 { 193 .vector_name = "RFC 7539 \xc2\xa7 A.3 #8", 194 .test_key_hex = 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 ", 197 .test_msg_hex = 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", 201 .test_msg_len = 48, 202 .expected_tag_hex = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 203 }, 204 { 205 .vector_name = "RFC 7539 \xc2\xa7 A.3 #9", 206 .test_key_hex = 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 ", 209 .test_msg_hex = 210 "FD FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF", 211 .test_msg_len = 16, 212 .expected_tag_hex = "FA FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF", 213 }, 214 { 215 .vector_name = "RFC 7539 \xc2\xa7 A.3 #10", 216 .test_key_hex = 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 ", 219 .test_msg_hex = 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", 224 .test_msg_len = 64, 225 .expected_tag_hex = "14 00 00 00 00 00 00 00 55 00 00 00 00 00 00 00", 226 }, 227 { 228 .vector_name = "RFC 7539 \xc2\xa7 A.3 #11", 229 .test_key_hex = 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 ", 232 .test_msg_hex = 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", 236 .test_msg_len = 48, 237 .expected_tag_hex = "13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", 238 }, 239 }; 240 241 static void 242 parse_hex(const struct poly1305_kat *kat, const char *hexstr, void *voutput, 243 size_t explen) 244 { 245 /* Space or colon delimited; may contain a single trailing space; 246 * length should match exactly. 247 */ 248 const char *sep, *it; 249 size_t sym_len, count; 250 char hbyte[3], *out; 251 int res; 252 253 out = voutput; 254 memset(hbyte, 0, sizeof(hbyte)); 255 256 it = hexstr; 257 count = 0; 258 while (true) { 259 sep = strpbrk(it, " :"); 260 if (sep == NULL) 261 sym_len = strlen(it); 262 else 263 sym_len = sep - it; 264 265 ATF_REQUIRE_EQ_MSG(sym_len, 2, 266 "invalid hex byte '%.*s' in vector %s", (int)sym_len, it, 267 kat->vector_name); 268 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, 273 kat->vector_name); 274 275 count++; 276 ATF_REQUIRE_MSG(count <= explen, 277 "got longer than expected value at %s", kat->vector_name); 278 279 if (sep == NULL) 280 break; 281 it = sep; 282 while (*it == ' ' || *it == ':') 283 it++; 284 if (*it == 0) 285 break; 286 } 287 288 ATF_REQUIRE_EQ_MSG(count, explen, "got short value at %s", 289 kat->vector_name); 290 } 291 292 static void 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)]) 296 { 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); 300 } 301 302 static int 303 get_handle_fd(void) 304 { 305 int fd; 306 307 fd = open("/dev/crypto", O_RDWR); 308 ATF_REQUIRE(fd >= 0); 309 return (fd); 310 } 311 312 static int 313 create_session(int fd, int alg, int crid, const void *key, size_t klen) 314 { 315 struct session2_op sop; 316 317 memset(&sop, 0, sizeof(sop)); 318 319 sop.mac = alg; 320 sop.mackey = key; 321 sop.mackeylen = klen; 322 sop.crid = crid; 323 324 ATF_REQUIRE_MSG(ioctl(fd, CIOCGSESSION2, &sop) >= 0, 325 "alg %d keylen %zu, errno=%d (%s)", alg, klen, errno, 326 strerror(errno)); 327 return (sop.ses); 328 } 329 330 static void 331 destroy_session(int fd, int _ses) 332 { 333 uint32_t ses; 334 335 ses = _ses; 336 ATF_REQUIRE_MSG(ioctl(fd, CIOCFSESSION, &ses) >= 0, 337 "destroy session failed, errno=%d (%s)", errno, strerror(errno)); 338 } 339 340 static void 341 do_cryptop(int fd, int ses, const void *inp, size_t inlen, void *out) 342 { 343 struct crypt_op cop; 344 345 memset(&cop, 0, sizeof(cop)); 346 347 cop.ses = ses; 348 cop.len = inlen; 349 cop.src = inp; 350 cop.mac = out; 351 ATF_CHECK_MSG(ioctl(fd, CIOCCRYPT, &cop) >= 0, "ioctl(CIOCCRYPT)"); 352 } 353 354 static void 355 test_rfc7539_poly1305_vectors(int crid, const char *modname) 356 { 357 uint8_t comptag[POLY1305_HASH_LEN], exptag[POLY1305_HASH_LEN], 358 key[POLY1305_KEY_LEN], msg[512]; 359 int fd, ses; 360 size_t i; 361 362 ATF_REQUIRE_KERNEL_MODULE(modname); 363 ATF_REQUIRE_KERNEL_MODULE("cryptodev"); 364 365 fd = get_handle_fd(); 366 367 for (i = 0; i < nitems(rfc7539_kats); i++) { 368 const struct poly1305_kat *kat; 369 370 kat = &rfc7539_kats[i]; 371 parse_vector(kat, key, msg, exptag); 372 373 ses = create_session(fd, CRYPTO_POLY1305, crid, key, sizeof(key)); 374 375 do_cryptop(fd, ses, msg, kat->test_msg_len, comptag); 376 ATF_CHECK_EQ_MSG(memcmp(comptag, exptag, sizeof(exptag)), 0, 377 "KAT %s failed:", kat->vector_name); 378 379 destroy_session(fd, ses); 380 } 381 } 382 383 ATF_TC_WITHOUT_HEAD(poly1305_vectors); 384 ATF_TC_BODY(poly1305_vectors, tc) 385 { 386 ATF_REQUIRE_SYSCTL_INT("kern.crypto.allow_soft", 1); 387 test_rfc7539_poly1305_vectors(CRYPTO_FLAG_SOFTWARE, "nexus/cryptosoft"); 388 } 389 390 ATF_TP_ADD_TCS(tp) 391 { 392 393 ATF_TP_ADD_TC(tp, poly1305_vectors); 394 395 return (atf_no_error()); 396 } 397