1 /* 2 * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>. 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 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 #include <sys/types.h> 30 #include <sys/param.h> 31 #include <sys/ioctl.h> 32 #include <sys/sysctl.h> 33 #include <crypto/cryptodev.h> 34 35 #include <fcntl.h> 36 #include <unistd.h> 37 #include <errno.h> 38 #include <string.h> 39 #include <stdio.h> 40 41 #include "tcplay.h" 42 43 static 44 int 45 getallowsoft(void) 46 { 47 int old; 48 size_t olen; 49 50 olen = sizeof(old); 51 52 if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, NULL, 0) < 0) { 53 perror("accessing sysctl kern.cryptodevallowsoft failed"); 54 } 55 56 return old; 57 } 58 59 static 60 void 61 setallowsoft(int new) 62 { 63 int old; 64 size_t olen, nlen; 65 66 olen = nlen = sizeof(new); 67 68 if (sysctlbyname("kern.cryptodevallowsoft", &old, &olen, &new, nlen) < 0) { 69 perror("accessing sysctl kern.cryptodevallowsoft failed"); 70 } 71 } 72 73 static 74 int 75 get_cryptodev_cipher_id(struct tc_crypto_algo *cipher) 76 { 77 if (strcmp(cipher->name, "AES-128-XTS") == 0) 78 return CRYPTO_AES_XTS; 79 else if (strcmp(cipher->name, "AES-256-XTS") == 0) 80 return CRYPTO_AES_XTS; 81 else if (strcmp(cipher->name, "TWOFISH-128-XTS") == 0) 82 return CRYPTO_TWOFISH_XTS; 83 else if (strcmp(cipher->name, "TWOFISH-256-XTS") == 0) 84 return CRYPTO_TWOFISH_XTS; 85 else if (strcmp(cipher->name, "SERPENT-128-XTS") == 0) 86 return CRYPTO_SERPENT_XTS; 87 else if (strcmp(cipher->name, "SERPENT-256-XTS") == 0) 88 return CRYPTO_SERPENT_XTS; 89 else 90 return -1; 91 } 92 93 int 94 syscrypt(struct tc_crypto_algo *cipher, unsigned char *key, size_t klen, unsigned char *iv, 95 unsigned char *in, unsigned char *out, size_t len, int do_encrypt) 96 { 97 struct session_op session; 98 struct crypt_op cryp; 99 int cipher_id; 100 int cryptodev_fd = -1, fd = -1; 101 102 cipher_id = get_cryptodev_cipher_id(cipher); 103 if (cipher_id < 0) { 104 tc_log(1, "Cipher %s not found\n", 105 cipher->name); 106 return ENOENT; 107 } 108 109 if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { 110 perror("Could not open /dev/crypto"); 111 goto err; 112 } 113 if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { 114 perror("CRIOGET failed"); 115 goto err; 116 } 117 memset(&session, 0, sizeof(session)); 118 session.cipher = cipher_id; 119 session.key = (caddr_t) key; 120 session.keylen = klen; 121 if (ioctl(fd, CIOCGSESSION, &session) == -1) { 122 perror("CIOCGSESSION failed"); 123 goto err; 124 } 125 memset(&cryp, 0, sizeof(cryp)); 126 cryp.ses = session.ses; 127 cryp.op = do_encrypt ? COP_ENCRYPT : COP_DECRYPT; 128 cryp.flags = 0; 129 cryp.len = len; 130 cryp.src = (caddr_t) in; 131 cryp.dst = (caddr_t) out; 132 cryp.iv = (caddr_t) iv; 133 cryp.mac = 0; 134 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { 135 perror("CIOCCRYPT failed"); 136 goto err; 137 } 138 if (ioctl(fd, CIOCFSESSION, &session.ses) == -1) { 139 perror("CIOCFSESSION failed"); 140 goto err; 141 } 142 close(fd); 143 close(cryptodev_fd); 144 return (0); 145 146 err: 147 if (fd != -1) 148 close(fd); 149 if (cryptodev_fd != -1) 150 close(cryptodev_fd); 151 return (-1); 152 } 153 154 int 155 tc_crypto_init(void) 156 { 157 int allowed; 158 159 allowed = getallowsoft(); 160 if (allowed == 0) 161 setallowsoft(1); 162 163 return 0; 164 } 165 166