1 /* Written by Ben Laurie, 2001 */ 2 /* 3 * Copyright (c) 2001 The OpenSSL Project. 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 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core@openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 */ 49 50 #include <openssl/evp.h> 51 #include <openssl/objects.h> 52 #include <openssl/rsa.h> 53 #include "evp_locl.h" 54 55 /* 56 * This stuff should now all be supported through 57 * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up 58 */ 59 static void *dummy = &dummy; 60 61 #if 0 62 63 /* check flag after OpenSSL headers to ensure make depend works */ 64 # ifdef OPENSSL_OPENBSD_DEV_CRYPTO 65 66 # include <fcntl.h> 67 # include <stdio.h> 68 # include <errno.h> 69 # include <sys/ioctl.h> 70 # include <crypto/cryptodev.h> 71 # include <unistd.h> 72 # include <assert.h> 73 74 /* longest key supported in hardware */ 75 # define MAX_HW_KEY 24 76 # define MAX_HW_IV 8 77 78 # define MD5_DIGEST_LENGTH 16 79 # define MD5_CBLOCK 64 80 81 static int fd; 82 static int dev_failed; 83 84 typedef struct session_op session_op; 85 86 # define CDATA(ctx) EVP_C_DATA(session_op,ctx) 87 88 static void err(const char *str) 89 { 90 fprintf(stderr, "%s: errno %d\n", str, errno); 91 } 92 93 static int dev_crypto_init(session_op *ses) 94 { 95 if (dev_failed) 96 return 0; 97 if (!fd) { 98 int cryptodev_fd; 99 100 if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { 101 err("/dev/crypto"); 102 dev_failed = 1; 103 return 0; 104 } 105 if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { 106 err("CRIOGET failed"); 107 close(cryptodev_fd); 108 dev_failed = 1; 109 return 0; 110 } 111 close(cryptodev_fd); 112 } 113 assert(ses); 114 memset(ses, '\0', sizeof(*ses)); 115 116 return 1; 117 } 118 119 static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx) 120 { 121 if (ioctl(fd, CIOCFSESSION, &CDATA(ctx)->ses) == -1) 122 err("CIOCFSESSION failed"); 123 124 OPENSSL_free(CDATA(ctx)->key); 125 126 return 1; 127 } 128 129 static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx, int cipher, 130 const unsigned char *key, int klen) 131 { 132 if (!dev_crypto_init(CDATA(ctx))) 133 return 0; 134 135 CDATA(ctx)->key = OPENSSL_malloc(MAX_HW_KEY); 136 if (CDATA(ctx)->key == NULL { 137 err("CDATA(ctx)->key memory allocation failed"); 138 return 0; 139 } 140 141 assert(ctx->cipher->iv_len <= MAX_HW_IV); 142 143 memcpy(CDATA(ctx)->key, key, klen); 144 145 CDATA(ctx)->cipher = cipher; 146 CDATA(ctx)->keylen = klen; 147 148 if (ioctl(fd, CIOCGSESSION, CDATA(ctx)) == -1) { 149 err("CIOCGSESSION failed"); 150 return 0; 151 } 152 return 1; 153 } 154 155 static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 156 const unsigned char *in, unsigned int inl) 157 { 158 struct crypt_op cryp; 159 unsigned char lb[MAX_HW_IV]; 160 161 if (!inl) 162 return 1; 163 164 assert(CDATA(ctx)); 165 assert(!dev_failed); 166 167 memset(&cryp, '\0', sizeof(cryp)); 168 cryp.ses = CDATA(ctx)->ses; 169 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; 170 cryp.flags = 0; 171 cryp.len = inl; 172 assert((inl & (ctx->cipher->block_size - 1)) == 0); 173 cryp.src = (caddr_t) in; 174 cryp.dst = (caddr_t) out; 175 cryp.mac = 0; 176 if (ctx->cipher->iv_len) 177 cryp.iv = (caddr_t) ctx->iv; 178 179 if (!ctx->encrypt) 180 memcpy(lb, &in[cryp.len - ctx->cipher->iv_len], ctx->cipher->iv_len); 181 182 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { 183 if (errno == EINVAL) { /* buffers are misaligned */ 184 unsigned int cinl = 0; 185 char *cin = NULL; 186 char *cout = NULL; 187 188 /* NB: this can only make cinl != inl with stream ciphers */ 189 cinl = (inl + 3) / 4 * 4; 190 191 if (((unsigned long)in & 3) || cinl != inl) { 192 cin = OPENSSL_malloc(cinl); 193 if (cin == NULL) { 194 err("cin - memory allocation failed"); 195 abort(); 196 return 0; 197 } 198 memcpy(cin, in, inl); 199 cryp.src = cin; 200 } 201 202 if (((unsigned long)out & 3) || cinl != inl) { 203 cout = OPENSSL_malloc(cinl); 204 cryp.dst = cout; 205 } 206 207 cryp.len = cinl; 208 209 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { 210 err("CIOCCRYPT(2) failed"); 211 printf("src=%p dst=%p\n", cryp.src, cryp.dst); 212 abort(); 213 return 0; 214 } 215 216 if (cout) { 217 memcpy(out, cout, inl); 218 OPENSSL_free(cout); 219 } 220 if (cin) 221 OPENSSL_free(cin); 222 } else { 223 err("CIOCCRYPT failed"); 224 abort(); 225 return 0; 226 } 227 } 228 229 if (ctx->encrypt) 230 memcpy(ctx->iv, &out[cryp.len - ctx->cipher->iv_len], 231 ctx->cipher->iv_len); 232 else 233 memcpy(ctx->iv, lb, ctx->cipher->iv_len); 234 235 return 1; 236 } 237 238 static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx, 239 const unsigned char *key, 240 const unsigned char *iv, int enc) 241 { 242 return dev_crypto_init_key(ctx, CRYPTO_3DES_CBC, key, 24); 243 } 244 245 # define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher 246 247 BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8, 248 0, dev_crypto_des_ede3_init_key, 249 dev_crypto_cleanup, 250 EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) 251 252 static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx, 253 const unsigned char *key, 254 const unsigned char *iv, int enc) 255 { 256 return dev_crypto_init_key(ctx, CRYPTO_ARC4, key, 16); 257 } 258 259 static const EVP_CIPHER r4_cipher = { 260 NID_rc4, 261 1, 16, 0, /* FIXME: key should be up to 256 bytes */ 262 EVP_CIPH_VARIABLE_LENGTH, 263 dev_crypto_rc4_init_key, 264 dev_crypto_cipher, 265 dev_crypto_cleanup, 266 sizeof(session_op), 267 NULL, 268 NULL, 269 NULL 270 }; 271 272 const EVP_CIPHER *EVP_dev_crypto_rc4(void) 273 { 274 return &r4_cipher; 275 } 276 277 typedef struct { 278 session_op sess; 279 char *data; 280 int len; 281 unsigned char md[EVP_MAX_MD_SIZE]; 282 } MD_DATA; 283 284 static int dev_crypto_init_digest(MD_DATA *md_data, int mac) 285 { 286 if (!dev_crypto_init(&md_data->sess)) 287 return 0; 288 289 md_data->len = 0; 290 md_data->data = NULL; 291 292 md_data->sess.mac = mac; 293 294 if (ioctl(fd, CIOCGSESSION, &md_data->sess) == -1) { 295 err("CIOCGSESSION failed"); 296 return 0; 297 } 298 return 1; 299 } 300 301 static int dev_crypto_cleanup_digest(MD_DATA *md_data) 302 { 303 if (ioctl(fd, CIOCFSESSION, &md_data->sess.ses) == -1) { 304 err("CIOCFSESSION failed"); 305 return 0; 306 } 307 308 return 1; 309 } 310 311 /* FIXME: if device can do chained MACs, then don't accumulate */ 312 /* FIXME: move accumulation to the framework */ 313 static int dev_crypto_md5_init(EVP_MD_CTX *ctx) 314 { 315 return dev_crypto_init_digest(ctx->md_data, CRYPTO_MD5); 316 } 317 318 static int do_digest(int ses, unsigned char *md, const void *data, int len) 319 { 320 struct crypt_op cryp; 321 static unsigned char md5zero[16] = { 322 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 323 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e 324 }; 325 326 /* some cards can't do zero length */ 327 if (!len) { 328 memcpy(md, md5zero, 16); 329 return 1; 330 } 331 332 memset(&cryp, '\0', sizeof(cryp)); 333 cryp.ses = ses; 334 cryp.op = COP_ENCRYPT; /* required to do the MAC rather than check 335 * it */ 336 cryp.len = len; 337 cryp.src = (caddr_t) data; 338 cryp.dst = (caddr_t) data; // FIXME!!! 339 cryp.mac = (caddr_t) md; 340 341 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { 342 if (errno == EINVAL) { /* buffer is misaligned */ 343 char *dcopy; 344 345 dcopy = OPENSSL_malloc(len); 346 if (dcopy == NULL) { 347 err("dcopy - memory allocation failed"); 348 abort(); 349 return 0; 350 } 351 memcpy(dcopy, data, len); 352 cryp.src = dcopy; 353 cryp.dst = cryp.src; // FIXME!!! 354 355 if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { 356 err("CIOCCRYPT(MAC2) failed"); 357 abort(); 358 return 0; 359 } 360 OPENSSL_free(dcopy); 361 } else { 362 err("CIOCCRYPT(MAC) failed"); 363 abort(); 364 return 0; 365 } 366 } 367 // printf("done\n"); 368 369 return 1; 370 } 371 372 static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data, 373 unsigned long len) 374 { 375 MD_DATA *md_data = ctx->md_data; 376 377 if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) 378 return do_digest(md_data->sess.ses, md_data->md, data, len); 379 380 md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len); 381 if (md_data->data == NULL) { 382 err("DEV_CRYPTO_MD5_UPDATE: unable to allocate memory"); 383 abort(); 384 } 385 memcpy(md_data->data + md_data->len, data, len); 386 md_data->len += len; 387 388 return 1; 389 } 390 391 static int dev_crypto_md5_final(EVP_MD_CTX *ctx, unsigned char *md) 392 { 393 int ret; 394 MD_DATA *md_data = ctx->md_data; 395 396 if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) { 397 memcpy(md, md_data->md, MD5_DIGEST_LENGTH); 398 ret = 1; 399 } else { 400 ret = do_digest(md_data->sess.ses, md, md_data->data, md_data->len); 401 OPENSSL_free(md_data->data); 402 md_data->data = NULL; 403 md_data->len = 0; 404 } 405 406 return ret; 407 } 408 409 static int dev_crypto_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) 410 { 411 const MD_DATA *from_md = from->md_data; 412 MD_DATA *to_md = to->md_data; 413 414 // How do we copy sessions? 415 assert(from->digest->flags & EVP_MD_FLAG_ONESHOT); 416 417 to_md->data = OPENSSL_malloc(from_md->len); 418 if (to_md->data == NULL) { 419 err("DEV_CRYPTO_MD5_COPY: unable to allocate memory"); 420 abort(); 421 } 422 memcpy(to_md->data, from_md->data, from_md->len); 423 424 return 1; 425 } 426 427 static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx) 428 { 429 return dev_crypto_cleanup_digest(ctx->md_data); 430 } 431 432 static const EVP_MD md5_md = { 433 NID_md5, 434 NID_md5WithRSAEncryption, 435 MD5_DIGEST_LENGTH, 436 EVP_MD_FLAG_ONESHOT, // XXX: set according to device info... 437 dev_crypto_md5_init, 438 dev_crypto_md5_update, 439 dev_crypto_md5_final, 440 dev_crypto_md5_copy, 441 dev_crypto_md5_cleanup, 442 EVP_PKEY_RSA_method, 443 MD5_CBLOCK, 444 sizeof(MD_DATA), 445 }; 446 447 const EVP_MD *EVP_dev_crypto_md5(void) 448 { 449 return &md5_md; 450 } 451 452 # endif 453 #endif 454