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 /* 30 * Derived from blake2b-test.c and blake2s-test.c: 31 * 32 * BLAKE2 reference source code package - optimized C implementations 33 * 34 * Written in 2012 by Samuel Neves <sneves@dei.uc.pt> 35 * 36 * To the extent possible under law, the author(s) have dedicated all copyright 37 * and related and neighboring rights to this software to the public domain 38 * worldwide. This software is distributed without any warranty. 39 * 40 * You should have received a copy of the CC0 Public Domain Dedication along with 41 * this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. 42 */ 43 44 #include <sys/param.h> 45 46 #include <errno.h> 47 #include <fcntl.h> 48 #include <string.h> 49 50 #include <atf-c.h> 51 52 /* Be sure to include tree copy rather than system copy. */ 53 #include "cryptodev.h" 54 55 #include "freebsd_test_suite/macros.h" 56 57 #include <blake2.h> 58 #include "blake2-kat.h" 59 60 static uint8_t key2b[BLAKE2B_KEYBYTES]; 61 static uint8_t key2s[BLAKE2S_KEYBYTES]; 62 static uint8_t katbuf[KAT_LENGTH]; 63 64 static void 65 initialize_constant_buffers(void) 66 { 67 size_t i; 68 69 for (i = 0; i < sizeof(key2b); i++) 70 key2b[i] = (uint8_t)i; 71 for (i = 0; i < sizeof(key2s); i++) 72 key2s[i] = (uint8_t)i; 73 for (i = 0; i < sizeof(katbuf); i++) 74 katbuf[i] = (uint8_t)i; 75 } 76 77 static int 78 get_handle_fd(void) 79 { 80 int dc_fd, fd; 81 82 dc_fd = open("/dev/crypto", O_RDWR); 83 84 /* 85 * Why do we do this dance instead of just operating on /dev/crypto 86 * directly? I have no idea. 87 */ 88 ATF_REQUIRE(dc_fd >= 0); 89 ATF_REQUIRE(ioctl(dc_fd, CRIOGET, &fd) != -1); 90 close(dc_fd); 91 return (fd); 92 } 93 94 static int 95 create_session(int fd, int alg, int crid, const void *key, size_t klen) 96 { 97 struct session2_op sop; 98 99 memset(&sop, 0, sizeof(sop)); 100 101 sop.mac = alg; 102 sop.mackey = key; 103 sop.mackeylen = klen; 104 sop.crid = crid; 105 106 ATF_REQUIRE_MSG(ioctl(fd, CIOCGSESSION2, &sop) >= 0, 107 "alg %d keylen %zu, errno=%d (%s)", alg, klen, errno, 108 strerror(errno)); 109 return (sop.ses); 110 } 111 112 static void 113 do_cryptop(int fd, int ses, size_t inlen, void *out) 114 { 115 struct crypt_op cop; 116 117 memset(&cop, 0, sizeof(cop)); 118 119 cop.ses = ses; 120 cop.len = inlen; 121 cop.src = katbuf; 122 cop.mac = out; 123 ATF_CHECK_MSG(ioctl(fd, CIOCCRYPT, &cop) >= 0, "ioctl(CIOCCRYPT)"); 124 } 125 126 static void 127 test_blake2b_vectors(int crid, const char *modname) 128 { 129 uint8_t hash[BLAKE2B_OUTBYTES]; 130 int fd, ses; 131 size_t i; 132 133 ATF_REQUIRE_KERNEL_MODULE(modname); 134 ATF_REQUIRE_KERNEL_MODULE("cryptodev"); 135 136 initialize_constant_buffers(); 137 fd = get_handle_fd(); 138 ses = create_session(fd, CRYPTO_BLAKE2B, crid, key2b, sizeof(key2b)); 139 140 for (i = 0; i < sizeof(katbuf); i++) { 141 do_cryptop(fd, ses, i, hash); 142 ATF_CHECK_EQ_MSG( 143 memcmp(hash, blake2b_keyed_kat[i], sizeof(hash)), 144 0, 145 "different at %zu", i); 146 } 147 } 148 149 static void 150 test_blake2s_vectors(int crid, const char *modname) 151 { 152 uint8_t hash[BLAKE2S_OUTBYTES]; 153 int fd, ses; 154 size_t i; 155 156 ATF_REQUIRE_KERNEL_MODULE(modname); 157 ATF_REQUIRE_KERNEL_MODULE("cryptodev"); 158 159 initialize_constant_buffers(); 160 fd = get_handle_fd(); 161 ses = create_session(fd, CRYPTO_BLAKE2S, crid, key2s, sizeof(key2s)); 162 163 for (i = 0; i < sizeof(katbuf); i++) { 164 do_cryptop(fd, ses, i, hash); 165 ATF_CHECK_EQ_MSG( 166 memcmp(hash, blake2s_keyed_kat[i], sizeof(hash)), 167 0, 168 "different at %zu", i); 169 } 170 } 171 172 ATF_TC_WITHOUT_HEAD(blake2b_vectors); 173 ATF_TC_BODY(blake2b_vectors, tc) 174 { 175 ATF_REQUIRE_SYSCTL_INT("kern.cryptodevallowsoft", 1); 176 test_blake2b_vectors(CRYPTO_FLAG_SOFTWARE, "nexus/cryptosoft"); 177 } 178 179 ATF_TC_WITHOUT_HEAD(blake2s_vectors); 180 ATF_TC_BODY(blake2s_vectors, tc) 181 { 182 ATF_REQUIRE_SYSCTL_INT("kern.cryptodevallowsoft", 1); 183 test_blake2s_vectors(CRYPTO_FLAG_SOFTWARE, "nexus/cryptosoft"); 184 } 185 186 #if defined(__i386__) || defined(__amd64__) 187 ATF_TC_WITHOUT_HEAD(blake2b_vectors_x86); 188 ATF_TC_BODY(blake2b_vectors_x86, tc) 189 { 190 test_blake2b_vectors(CRYPTO_FLAG_HARDWARE, "nexus/blake2"); 191 } 192 193 ATF_TC_WITHOUT_HEAD(blake2s_vectors_x86); 194 ATF_TC_BODY(blake2s_vectors_x86, tc) 195 { 196 test_blake2s_vectors(CRYPTO_FLAG_HARDWARE, "nexus/blake2"); 197 } 198 #endif 199 200 ATF_TP_ADD_TCS(tp) 201 { 202 203 ATF_TP_ADD_TC(tp, blake2b_vectors); 204 ATF_TP_ADD_TC(tp, blake2s_vectors); 205 #if defined(__i386__) || defined(__amd64__) 206 ATF_TP_ADD_TC(tp, blake2b_vectors_x86); 207 ATF_TP_ADD_TC(tp, blake2s_vectors_x86); 208 #endif 209 210 return (atf_no_error()); 211 } 212