1 /* 2 * Copyright (c) 2002 Bob Beck <beck (at) openbsd.org> 3 * Copyright (c) 2002 Theo de Raadt 4 * Copyright (c) 2002 Markus Friedl 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 29 #include <openssl/objects.h> 30 #include <openssl/engine.h> 31 #include <openssl/evp.h> 32 #include <openssl/bn.h> 33 34 #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ 35 (defined(OpenBSD) || defined(__FreeBSD__)) 36 #include <sys/param.h> 37 # if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) 38 # define HAVE_CRYPTODEV 39 # endif 40 # if (OpenBSD >= 200110) 41 # define HAVE_SYSLOG_R 42 # endif 43 #endif 44 45 #ifndef HAVE_CRYPTODEV 46 47 void 48 ENGINE_load_cryptodev(void) 49 { 50 /* This is a NOP on platforms without /dev/crypto */ 51 return; 52 } 53 54 #else 55 56 #include <sys/types.h> 57 #include <crypto/cryptodev.h> 58 #include <crypto/dh/dh.h> 59 #include <crypto/dsa/dsa.h> 60 #include <crypto/err/err.h> 61 #include <crypto/rsa/rsa.h> 62 #include <sys/ioctl.h> 63 #include <errno.h> 64 #include <stdio.h> 65 #include <unistd.h> 66 #include <fcntl.h> 67 #include <stdarg.h> 68 #include <syslog.h> 69 #include <errno.h> 70 #include <string.h> 71 72 struct dev_crypto_state { 73 struct session_op d_sess; 74 int d_fd; 75 76 #ifdef USE_CRYPTODEV_DIGESTS 77 char dummy_mac_key[HASH_MAX_LEN]; 78 79 unsigned char digest_res[HASH_MAX_LEN]; 80 char *mac_data; 81 int mac_len; 82 #endif 83 }; 84 85 static u_int32_t cryptodev_asymfeat = 0; 86 87 static int get_asym_dev_crypto(void); 88 static int open_dev_crypto(void); 89 static int get_dev_crypto(void); 90 static int get_cryptodev_ciphers(const int **cnids); 91 #ifdef USE_CRYPTODEV_DIGESTS 92 static int get_cryptodev_digests(const int **cnids); 93 #endif 94 static int cryptodev_usable_ciphers(const int **nids); 95 static int cryptodev_usable_digests(const int **nids); 96 static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 97 const unsigned char *in, size_t inl); 98 static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 99 const unsigned char *iv, int enc); 100 static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); 101 static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 102 const int **nids, int nid); 103 static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, 104 const int **nids, int nid); 105 static int bn2crparam(const BIGNUM *a, struct crparam *crp); 106 static int crparam2bn(struct crparam *crp, BIGNUM *a); 107 static void zapparams(struct crypt_kop *kop); 108 static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, 109 int slen, BIGNUM *s); 110 111 static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, 112 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 113 static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, 114 RSA *rsa, BN_CTX *ctx); 115 static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); 116 static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, 117 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 118 static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, 119 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, 120 BN_CTX *ctx, BN_MONT_CTX *mont); 121 static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, 122 int dlen, DSA *dsa); 123 static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, 124 DSA_SIG *sig, DSA *dsa); 125 static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 126 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 127 BN_MONT_CTX *m_ctx); 128 static int cryptodev_dh_compute_key(unsigned char *key, 129 const BIGNUM *pub_key, DH *dh); 130 static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, 131 void (*f)(void)); 132 void ENGINE_load_cryptodev(void); 133 134 static const ENGINE_CMD_DEFN cryptodev_defns[] = { 135 { 0, NULL, NULL, 0 } 136 }; 137 138 static struct { 139 int id; 140 int nid; 141 int ivmax; 142 int keylen; 143 } ciphers[] = { 144 { CRYPTO_ARC4, NID_rc4, 0, 16, }, 145 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, 146 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, 147 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, 148 { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, }, 149 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, }, 150 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, 151 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, 152 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, 153 { 0, NID_undef, 0, 0, }, 154 }; 155 156 #ifdef USE_CRYPTODEV_DIGESTS 157 static struct { 158 int id; 159 int nid; 160 int keylen; 161 } digests[] = { 162 { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16}, 163 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20}, 164 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/}, 165 { CRYPTO_MD5_KPDK, NID_undef, 0}, 166 { CRYPTO_SHA1_KPDK, NID_undef, 0}, 167 { CRYPTO_MD5, NID_md5, 16}, 168 { CRYPTO_SHA1, NID_sha1, 20}, 169 { 0, NID_undef, 0}, 170 }; 171 #endif 172 173 /* 174 * Return a fd if /dev/crypto seems usable, 0 otherwise. 175 */ 176 static int 177 open_dev_crypto(void) 178 { 179 static int fd = -1; 180 181 if (fd == -1) { 182 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) 183 return (-1); 184 /* close on exec */ 185 if (fcntl(fd, F_SETFD, 1) == -1) { 186 close(fd); 187 fd = -1; 188 return (-1); 189 } 190 } 191 return (fd); 192 } 193 194 static int 195 get_dev_crypto(void) 196 { 197 int fd, retfd; 198 199 if ((fd = open_dev_crypto()) == -1) 200 return (-1); 201 #ifndef CRIOGET_NOT_NEEDED 202 if (ioctl(fd, CRIOGET, &retfd) == -1) 203 return (-1); 204 205 /* close on exec */ 206 if (fcntl(retfd, F_SETFD, 1) == -1) { 207 close(retfd); 208 return (-1); 209 } 210 #else 211 retfd = fd; 212 #endif 213 return (retfd); 214 } 215 216 static void put_dev_crypto(int fd) 217 { 218 #ifndef CRIOGET_NOT_NEEDED 219 close(fd); 220 #endif 221 } 222 223 /* Caching version for asym operations */ 224 static int 225 get_asym_dev_crypto(void) 226 { 227 static int fd = -1; 228 229 if (fd == -1) 230 fd = get_dev_crypto(); 231 return fd; 232 } 233 234 /* 235 * Find out what ciphers /dev/crypto will let us have a session for. 236 * XXX note, that some of these openssl doesn't deal with yet! 237 * returning them here is harmless, as long as we return NULL 238 * when asked for a handler in the cryptodev_engine_ciphers routine 239 */ 240 static int 241 get_cryptodev_ciphers(const int **cnids) 242 { 243 static int nids[CRYPTO_ALGORITHM_MAX]; 244 struct session_op sess; 245 int fd, i, count = 0; 246 247 if ((fd = get_dev_crypto()) < 0) { 248 *cnids = NULL; 249 return (0); 250 } 251 memset(&sess, 0, sizeof(sess)); 252 sess.key = (caddr_t)"123456789abcdefghijklmno"; 253 254 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { 255 if (ciphers[i].nid == NID_undef) 256 continue; 257 sess.cipher = ciphers[i].id; 258 sess.keylen = ciphers[i].keylen; 259 sess.mac = 0; 260 if (ioctl(fd, CIOCGSESSION, &sess) != -1 && 261 ioctl(fd, CIOCFSESSION, &sess.ses) != -1) 262 nids[count++] = ciphers[i].nid; 263 } 264 put_dev_crypto(fd); 265 266 if (count > 0) 267 *cnids = nids; 268 else 269 *cnids = NULL; 270 return (count); 271 } 272 273 #ifdef USE_CRYPTODEV_DIGESTS 274 /* 275 * Find out what digests /dev/crypto will let us have a session for. 276 * XXX note, that some of these openssl doesn't deal with yet! 277 * returning them here is harmless, as long as we return NULL 278 * when asked for a handler in the cryptodev_engine_digests routine 279 */ 280 static int 281 get_cryptodev_digests(const int **cnids) 282 { 283 static int nids[CRYPTO_ALGORITHM_MAX]; 284 struct session_op sess; 285 int fd, i, count = 0; 286 287 if ((fd = get_dev_crypto()) < 0) { 288 *cnids = NULL; 289 return (0); 290 } 291 memset(&sess, 0, sizeof(sess)); 292 sess.mackey = (caddr_t)"123456789abcdefghijklmno"; 293 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { 294 if (digests[i].nid == NID_undef) 295 continue; 296 sess.mac = digests[i].id; 297 sess.mackeylen = digests[i].keylen; 298 sess.cipher = 0; 299 if (ioctl(fd, CIOCGSESSION, &sess) != -1 && 300 ioctl(fd, CIOCFSESSION, &sess.ses) != -1) 301 nids[count++] = digests[i].nid; 302 } 303 put_dev_crypto(fd); 304 305 if (count > 0) 306 *cnids = nids; 307 else 308 *cnids = NULL; 309 return (count); 310 } 311 #endif /* 0 */ 312 313 /* 314 * Find the useable ciphers|digests from dev/crypto - this is the first 315 * thing called by the engine init crud which determines what it 316 * can use for ciphers from this engine. We want to return 317 * only what we can do, anythine else is handled by software. 318 * 319 * If we can't initialize the device to do anything useful for 320 * any reason, we want to return a NULL array, and 0 length, 321 * which forces everything to be done is software. By putting 322 * the initalization of the device in here, we ensure we can 323 * use this engine as the default, and if for whatever reason 324 * /dev/crypto won't do what we want it will just be done in 325 * software 326 * 327 * This can (should) be greatly expanded to perhaps take into 328 * account speed of the device, and what we want to do. 329 * (although the disabling of particular alg's could be controlled 330 * by the device driver with sysctl's.) - this is where we 331 * want most of the decisions made about what we actually want 332 * to use from /dev/crypto. 333 */ 334 static int 335 cryptodev_usable_ciphers(const int **nids) 336 { 337 return (get_cryptodev_ciphers(nids)); 338 } 339 340 static int 341 cryptodev_usable_digests(const int **nids) 342 { 343 #ifdef USE_CRYPTODEV_DIGESTS 344 return (get_cryptodev_digests(nids)); 345 #else 346 /* 347 * XXXX just disable all digests for now, because it sucks. 348 * we need a better way to decide this - i.e. I may not 349 * want digests on slow cards like hifn on fast machines, 350 * but might want them on slow or loaded machines, etc. 351 * will also want them when using crypto cards that don't 352 * suck moose gonads - would be nice to be able to decide something 353 * as reasonable default without having hackery that's card dependent. 354 * of course, the default should probably be just do everything, 355 * with perhaps a sysctl to turn algoritms off (or have them off 356 * by default) on cards that generally suck like the hifn. 357 */ 358 *nids = NULL; 359 return (0); 360 #endif 361 } 362 363 static int 364 cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 365 const unsigned char *in, size_t inl) 366 { 367 struct crypt_op cryp; 368 struct dev_crypto_state *state = ctx->cipher_data; 369 struct session_op *sess = &state->d_sess; 370 const void *iiv; 371 unsigned char save_iv[EVP_MAX_IV_LENGTH]; 372 373 if (state->d_fd < 0) 374 return (0); 375 if (!inl) 376 return (1); 377 if ((inl % ctx->cipher->block_size) != 0) 378 return (0); 379 380 memset(&cryp, 0, sizeof(cryp)); 381 382 cryp.ses = sess->ses; 383 cryp.flags = 0; 384 cryp.len = inl; 385 cryp.src = (caddr_t) in; 386 cryp.dst = (caddr_t) out; 387 cryp.mac = 0; 388 389 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; 390 391 if (ctx->cipher->iv_len) { 392 cryp.iv = (caddr_t) ctx->iv; 393 if (!ctx->encrypt) { 394 iiv = in + inl - ctx->cipher->iv_len; 395 memcpy(save_iv, iiv, ctx->cipher->iv_len); 396 } 397 } else 398 cryp.iv = NULL; 399 400 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { 401 /* XXX need better errror handling 402 * this can fail for a number of different reasons. 403 */ 404 return (0); 405 } 406 407 if (ctx->cipher->iv_len) { 408 if (ctx->encrypt) 409 iiv = out + inl - ctx->cipher->iv_len; 410 else 411 iiv = save_iv; 412 memcpy(ctx->iv, iiv, ctx->cipher->iv_len); 413 } 414 return (1); 415 } 416 417 static int 418 cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 419 const unsigned char *iv, int enc) 420 { 421 struct dev_crypto_state *state = ctx->cipher_data; 422 struct session_op *sess = &state->d_sess; 423 int cipher = -1, i; 424 425 for (i = 0; ciphers[i].id; i++) 426 if (ctx->cipher->nid == ciphers[i].nid && 427 ctx->cipher->iv_len <= ciphers[i].ivmax && 428 ctx->key_len == ciphers[i].keylen) { 429 cipher = ciphers[i].id; 430 break; 431 } 432 433 if (!ciphers[i].id) { 434 state->d_fd = -1; 435 return (0); 436 } 437 438 memset(sess, 0, sizeof(struct session_op)); 439 440 if ((state->d_fd = get_dev_crypto()) < 0) 441 return (0); 442 443 sess->key = (caddr_t)key; 444 sess->keylen = ctx->key_len; 445 sess->cipher = cipher; 446 447 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { 448 put_dev_crypto(state->d_fd); 449 state->d_fd = -1; 450 return (0); 451 } 452 return (1); 453 } 454 455 /* 456 * free anything we allocated earlier when initting a 457 * session, and close the session. 458 */ 459 static int 460 cryptodev_cleanup(EVP_CIPHER_CTX *ctx) 461 { 462 int ret = 0; 463 struct dev_crypto_state *state = ctx->cipher_data; 464 struct session_op *sess = &state->d_sess; 465 466 if (state->d_fd < 0) 467 return (0); 468 469 /* XXX if this ioctl fails, someting's wrong. the invoker 470 * may have called us with a bogus ctx, or we could 471 * have a device that for whatever reason just doesn't 472 * want to play ball - it's not clear what's right 473 * here - should this be an error? should it just 474 * increase a counter, hmm. For right now, we return 475 * 0 - I don't believe that to be "right". we could 476 * call the gorpy openssl lib error handlers that 477 * print messages to users of the library. hmm.. 478 */ 479 480 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { 481 ret = 0; 482 } else { 483 ret = 1; 484 } 485 put_dev_crypto(state->d_fd); 486 state->d_fd = -1; 487 488 return (ret); 489 } 490 491 /* 492 * libcrypto EVP stuff - this is how we get wired to EVP so the engine 493 * gets called when libcrypto requests a cipher NID. 494 */ 495 496 /* RC4 */ 497 const EVP_CIPHER cryptodev_rc4 = { 498 NID_rc4, 499 1, 16, 0, 500 EVP_CIPH_VARIABLE_LENGTH, 501 cryptodev_init_key, 502 cryptodev_cipher, 503 cryptodev_cleanup, 504 sizeof(struct dev_crypto_state), 505 NULL, 506 NULL, 507 NULL 508 }; 509 510 /* DES CBC EVP */ 511 const EVP_CIPHER cryptodev_des_cbc = { 512 NID_des_cbc, 513 8, 8, 8, 514 EVP_CIPH_CBC_MODE, 515 cryptodev_init_key, 516 cryptodev_cipher, 517 cryptodev_cleanup, 518 sizeof(struct dev_crypto_state), 519 EVP_CIPHER_set_asn1_iv, 520 EVP_CIPHER_get_asn1_iv, 521 NULL 522 }; 523 524 /* 3DES CBC EVP */ 525 const EVP_CIPHER cryptodev_3des_cbc = { 526 NID_des_ede3_cbc, 527 8, 24, 8, 528 EVP_CIPH_CBC_MODE, 529 cryptodev_init_key, 530 cryptodev_cipher, 531 cryptodev_cleanup, 532 sizeof(struct dev_crypto_state), 533 EVP_CIPHER_set_asn1_iv, 534 EVP_CIPHER_get_asn1_iv, 535 NULL 536 }; 537 538 const EVP_CIPHER cryptodev_bf_cbc = { 539 NID_bf_cbc, 540 8, 16, 8, 541 EVP_CIPH_CBC_MODE, 542 cryptodev_init_key, 543 cryptodev_cipher, 544 cryptodev_cleanup, 545 sizeof(struct dev_crypto_state), 546 EVP_CIPHER_set_asn1_iv, 547 EVP_CIPHER_get_asn1_iv, 548 NULL 549 }; 550 551 const EVP_CIPHER cryptodev_cast_cbc = { 552 NID_cast5_cbc, 553 8, 16, 8, 554 EVP_CIPH_CBC_MODE, 555 cryptodev_init_key, 556 cryptodev_cipher, 557 cryptodev_cleanup, 558 sizeof(struct dev_crypto_state), 559 EVP_CIPHER_set_asn1_iv, 560 EVP_CIPHER_get_asn1_iv, 561 NULL 562 }; 563 564 const EVP_CIPHER cryptodev_aes_cbc = { 565 NID_aes_128_cbc, 566 16, 16, 16, 567 EVP_CIPH_CBC_MODE, 568 cryptodev_init_key, 569 cryptodev_cipher, 570 cryptodev_cleanup, 571 sizeof(struct dev_crypto_state), 572 EVP_CIPHER_set_asn1_iv, 573 EVP_CIPHER_get_asn1_iv, 574 NULL 575 }; 576 577 const EVP_CIPHER cryptodev_aes_192_cbc = { 578 NID_aes_192_cbc, 579 16, 24, 16, 580 EVP_CIPH_CBC_MODE, 581 cryptodev_init_key, 582 cryptodev_cipher, 583 cryptodev_cleanup, 584 sizeof(struct dev_crypto_state), 585 EVP_CIPHER_set_asn1_iv, 586 EVP_CIPHER_get_asn1_iv, 587 NULL 588 }; 589 590 const EVP_CIPHER cryptodev_aes_256_cbc = { 591 NID_aes_256_cbc, 592 16, 32, 16, 593 EVP_CIPH_CBC_MODE, 594 cryptodev_init_key, 595 cryptodev_cipher, 596 cryptodev_cleanup, 597 sizeof(struct dev_crypto_state), 598 EVP_CIPHER_set_asn1_iv, 599 EVP_CIPHER_get_asn1_iv, 600 NULL 601 }; 602 603 /* 604 * Registered by the ENGINE when used to find out how to deal with 605 * a particular NID in the ENGINE. this says what we'll do at the 606 * top level - note, that list is restricted by what we answer with 607 */ 608 static int 609 cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 610 const int **nids, int nid) 611 { 612 if (!cipher) 613 return (cryptodev_usable_ciphers(nids)); 614 615 switch (nid) { 616 case NID_rc4: 617 *cipher = &cryptodev_rc4; 618 break; 619 case NID_des_ede3_cbc: 620 *cipher = &cryptodev_3des_cbc; 621 break; 622 case NID_des_cbc: 623 *cipher = &cryptodev_des_cbc; 624 break; 625 case NID_bf_cbc: 626 *cipher = &cryptodev_bf_cbc; 627 break; 628 case NID_cast5_cbc: 629 *cipher = &cryptodev_cast_cbc; 630 break; 631 case NID_aes_128_cbc: 632 *cipher = &cryptodev_aes_cbc; 633 break; 634 case NID_aes_192_cbc: 635 *cipher = &cryptodev_aes_192_cbc; 636 break; 637 case NID_aes_256_cbc: 638 *cipher = &cryptodev_aes_256_cbc; 639 break; 640 default: 641 *cipher = NULL; 642 break; 643 } 644 return (*cipher != NULL); 645 } 646 647 648 #ifdef USE_CRYPTODEV_DIGESTS 649 650 /* convert digest type to cryptodev */ 651 static int 652 digest_nid_to_cryptodev(int nid) 653 { 654 int i; 655 656 for (i = 0; digests[i].id; i++) 657 if (digests[i].nid == nid) 658 return (digests[i].id); 659 return (0); 660 } 661 662 663 static int 664 digest_key_length(int nid) 665 { 666 int i; 667 668 for (i = 0; digests[i].id; i++) 669 if (digests[i].nid == nid) 670 return digests[i].keylen; 671 return (0); 672 } 673 674 675 static int cryptodev_digest_init(EVP_MD_CTX *ctx) 676 { 677 struct dev_crypto_state *state = ctx->md_data; 678 struct session_op *sess = &state->d_sess; 679 int digest; 680 681 if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){ 682 printf("cryptodev_digest_init: Can't get digest \n"); 683 return (0); 684 } 685 686 memset(state, 0, sizeof(struct dev_crypto_state)); 687 688 if ((state->d_fd = get_dev_crypto()) < 0) { 689 printf("cryptodev_digest_init: Can't get Dev \n"); 690 return (0); 691 } 692 693 sess->mackey = state->dummy_mac_key; 694 sess->mackeylen = digest_key_length(ctx->digest->type); 695 sess->mac = digest; 696 697 if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { 698 put_dev_crypto(state->d_fd); 699 state->d_fd = -1; 700 printf("cryptodev_digest_init: Open session failed\n"); 701 return (0); 702 } 703 704 return (1); 705 } 706 707 static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, 708 size_t count) 709 { 710 struct crypt_op cryp; 711 struct dev_crypto_state *state = ctx->md_data; 712 struct session_op *sess = &state->d_sess; 713 714 if (!data || state->d_fd < 0) { 715 printf("cryptodev_digest_update: illegal inputs \n"); 716 return (0); 717 } 718 719 if (!count) { 720 return (0); 721 } 722 723 if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { 724 /* if application doesn't support one buffer */ 725 state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); 726 727 if (!state->mac_data) { 728 printf("cryptodev_digest_update: realloc failed\n"); 729 return (0); 730 } 731 732 memcpy(state->mac_data + state->mac_len, data, count); 733 state->mac_len += count; 734 735 return (1); 736 } 737 738 memset(&cryp, 0, sizeof(cryp)); 739 740 cryp.ses = sess->ses; 741 cryp.flags = 0; 742 cryp.len = count; 743 cryp.src = (caddr_t) data; 744 cryp.dst = NULL; 745 cryp.mac = (caddr_t) state->digest_res; 746 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { 747 printf("cryptodev_digest_update: digest failed\n"); 748 return (0); 749 } 750 return (1); 751 } 752 753 754 static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) 755 { 756 struct crypt_op cryp; 757 struct dev_crypto_state *state = ctx->md_data; 758 struct session_op *sess = &state->d_sess; 759 760 int ret = 1; 761 762 if (!md || state->d_fd < 0) { 763 printf("cryptodev_digest_final: illegal input\n"); 764 return(0); 765 } 766 767 if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) { 768 /* if application doesn't support one buffer */ 769 memset(&cryp, 0, sizeof(cryp)); 770 cryp.ses = sess->ses; 771 cryp.flags = 0; 772 cryp.len = state->mac_len; 773 cryp.src = state->mac_data; 774 cryp.dst = NULL; 775 cryp.mac = (caddr_t)md; 776 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { 777 printf("cryptodev_digest_final: digest failed\n"); 778 return (0); 779 } 780 781 return 1; 782 } 783 784 memcpy(md, state->digest_res, ctx->digest->md_size); 785 786 return (ret); 787 } 788 789 790 static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) 791 { 792 int ret = 1; 793 struct dev_crypto_state *state = ctx->md_data; 794 struct session_op *sess = &state->d_sess; 795 796 if (state == NULL) 797 return 0; 798 799 if (state->d_fd < 0) { 800 printf("cryptodev_digest_cleanup: illegal input\n"); 801 return (0); 802 } 803 804 if (state->mac_data) { 805 OPENSSL_free(state->mac_data); 806 state->mac_data = NULL; 807 state->mac_len = 0; 808 } 809 810 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { 811 printf("cryptodev_digest_cleanup: failed to close session\n"); 812 ret = 0; 813 } else { 814 ret = 1; 815 } 816 put_dev_crypto(state->d_fd); 817 state->d_fd = -1; 818 819 return (ret); 820 } 821 822 static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) 823 { 824 struct dev_crypto_state *fstate = from->md_data; 825 struct dev_crypto_state *dstate = to->md_data; 826 struct session_op *sess; 827 int digest; 828 829 if (dstate == NULL || fstate == NULL) 830 return 1; 831 832 memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); 833 834 sess = &dstate->d_sess; 835 836 digest = digest_nid_to_cryptodev(to->digest->type); 837 838 sess->mackey = dstate->dummy_mac_key; 839 sess->mackeylen = digest_key_length(to->digest->type); 840 sess->mac = digest; 841 842 dstate->d_fd = get_dev_crypto(); 843 844 if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) { 845 put_dev_crypto(dstate->d_fd); 846 dstate->d_fd = -1; 847 printf("cryptodev_digest_init: Open session failed\n"); 848 return (0); 849 } 850 851 if (fstate->mac_len != 0) { 852 if (fstate->mac_data != NULL) 853 { 854 dstate->mac_data = OPENSSL_malloc(fstate->mac_len); 855 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); 856 dstate->mac_len = fstate->mac_len; 857 } 858 } 859 860 return 1; 861 } 862 863 864 const EVP_MD cryptodev_sha1 = { 865 NID_sha1, 866 NID_undef, 867 SHA_DIGEST_LENGTH, 868 EVP_MD_FLAG_ONESHOT, 869 cryptodev_digest_init, 870 cryptodev_digest_update, 871 cryptodev_digest_final, 872 cryptodev_digest_copy, 873 cryptodev_digest_cleanup, 874 EVP_PKEY_NULL_method, 875 SHA_CBLOCK, 876 sizeof(struct dev_crypto_state), 877 }; 878 879 const EVP_MD cryptodev_md5 = { 880 NID_md5, 881 NID_undef, 882 16 /* MD5_DIGEST_LENGTH */, 883 EVP_MD_FLAG_ONESHOT, 884 cryptodev_digest_init, 885 cryptodev_digest_update, 886 cryptodev_digest_final, 887 cryptodev_digest_copy, 888 cryptodev_digest_cleanup, 889 EVP_PKEY_NULL_method, 890 64 /* MD5_CBLOCK */, 891 sizeof(struct dev_crypto_state), 892 }; 893 894 #endif /* USE_CRYPTODEV_DIGESTS */ 895 896 897 static int 898 cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, 899 const int **nids, int nid) 900 { 901 if (!digest) 902 return (cryptodev_usable_digests(nids)); 903 904 switch (nid) { 905 #ifdef USE_CRYPTODEV_DIGESTS 906 case NID_md5: 907 *digest = &cryptodev_md5; 908 break; 909 case NID_sha1: 910 *digest = &cryptodev_sha1; 911 break; 912 default: 913 #endif /* USE_CRYPTODEV_DIGESTS */ 914 *digest = NULL; 915 break; 916 } 917 return (*digest != NULL); 918 } 919 920 /* 921 * Convert a BIGNUM to the representation that /dev/crypto needs. 922 * Upon completion of use, the caller is responsible for freeing 923 * crp->crp_p. 924 */ 925 static int 926 bn2crparam(const BIGNUM *a, struct crparam *crp) 927 { 928 int i, j, k; 929 ssize_t bytes, bits; 930 u_char *b; 931 932 crp->crp_p = NULL; 933 crp->crp_nbits = 0; 934 935 bits = BN_num_bits(a); 936 bytes = (bits + 7) / 8; 937 938 b = malloc(bytes); 939 if (b == NULL) 940 return (1); 941 memset(b, 0, bytes); 942 943 crp->crp_p = (caddr_t) b; 944 crp->crp_nbits = bits; 945 946 for (i = 0, j = 0; i < a->top; i++) { 947 for (k = 0; k < BN_BITS2 / 8; k++) { 948 if ((j + k) >= bytes) 949 return (0); 950 b[j + k] = a->d[i] >> (k * 8); 951 } 952 j += BN_BITS2 / 8; 953 } 954 return (0); 955 } 956 957 /* Convert a /dev/crypto parameter to a BIGNUM */ 958 static int 959 crparam2bn(struct crparam *crp, BIGNUM *a) 960 { 961 u_int8_t *pd; 962 int i, bytes; 963 964 bytes = (crp->crp_nbits + 7) / 8; 965 966 if (bytes == 0) 967 return (-1); 968 969 if ((pd = (u_int8_t *) malloc(bytes)) == NULL) 970 return (-1); 971 972 for (i = 0; i < bytes; i++) 973 pd[i] = crp->crp_p[bytes - i - 1]; 974 975 BN_bin2bn(pd, bytes, a); 976 free(pd); 977 978 return (0); 979 } 980 981 static void 982 zapparams(struct crypt_kop *kop) 983 { 984 int i; 985 986 for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { 987 if (kop->crk_param[i].crp_p) 988 free(kop->crk_param[i].crp_p); 989 kop->crk_param[i].crp_p = NULL; 990 kop->crk_param[i].crp_nbits = 0; 991 } 992 } 993 994 static int 995 cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) 996 { 997 int fd, ret = -1; 998 999 if ((fd = get_asym_dev_crypto()) < 0) 1000 return (ret); 1001 1002 if (r) { 1003 kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); 1004 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; 1005 kop->crk_oparams++; 1006 } 1007 if (s) { 1008 kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char)); 1009 kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8; 1010 kop->crk_oparams++; 1011 } 1012 1013 if (ioctl(fd, CIOCKEY, kop) == 0) { 1014 if (r) 1015 crparam2bn(&kop->crk_param[kop->crk_iparams], r); 1016 if (s) 1017 crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); 1018 ret = 0; 1019 } 1020 1021 return (ret); 1022 } 1023 1024 static int 1025 cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 1026 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 1027 { 1028 struct crypt_kop kop; 1029 int ret = 1; 1030 1031 /* Currently, we know we can do mod exp iff we can do any 1032 * asymmetric operations at all. 1033 */ 1034 if (cryptodev_asymfeat == 0) { 1035 ret = BN_mod_exp(r, a, p, m, ctx); 1036 return (ret); 1037 } 1038 1039 memset(&kop, 0, sizeof kop); 1040 kop.crk_op = CRK_MOD_EXP; 1041 1042 /* inputs: a^p % m */ 1043 if (bn2crparam(a, &kop.crk_param[0])) 1044 goto err; 1045 if (bn2crparam(p, &kop.crk_param[1])) 1046 goto err; 1047 if (bn2crparam(m, &kop.crk_param[2])) 1048 goto err; 1049 kop.crk_iparams = 3; 1050 1051 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { 1052 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1053 printf("OCF asym process failed, Running in software\n"); 1054 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); 1055 1056 } else if (ECANCELED == kop.crk_status) { 1057 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1058 printf("OCF hardware operation cancelled. Running in Software\n"); 1059 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); 1060 } 1061 /* else cryptodev operation worked ok ==> ret = 1*/ 1062 1063 err: 1064 zapparams(&kop); 1065 return (ret); 1066 } 1067 1068 static int 1069 cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) 1070 { 1071 int r; 1072 ctx = BN_CTX_new(); 1073 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); 1074 BN_CTX_free(ctx); 1075 return (r); 1076 } 1077 1078 static int 1079 cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) 1080 { 1081 struct crypt_kop kop; 1082 int ret = 1; 1083 1084 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 1085 /* XXX 0 means failure?? */ 1086 return (0); 1087 } 1088 1089 memset(&kop, 0, sizeof kop); 1090 kop.crk_op = CRK_MOD_EXP_CRT; 1091 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ 1092 if (bn2crparam(rsa->p, &kop.crk_param[0])) 1093 goto err; 1094 if (bn2crparam(rsa->q, &kop.crk_param[1])) 1095 goto err; 1096 if (bn2crparam(I, &kop.crk_param[2])) 1097 goto err; 1098 if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) 1099 goto err; 1100 if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) 1101 goto err; 1102 if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) 1103 goto err; 1104 kop.crk_iparams = 6; 1105 1106 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { 1107 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1108 printf("OCF asym process failed, running in Software\n"); 1109 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); 1110 1111 } else if (ECANCELED == kop.crk_status) { 1112 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1113 printf("OCF hardware operation cancelled. Running in Software\n"); 1114 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); 1115 } 1116 /* else cryptodev operation worked ok ==> ret = 1*/ 1117 1118 err: 1119 zapparams(&kop); 1120 return (ret); 1121 } 1122 1123 static RSA_METHOD cryptodev_rsa = { 1124 "cryptodev RSA method", 1125 NULL, /* rsa_pub_enc */ 1126 NULL, /* rsa_pub_dec */ 1127 NULL, /* rsa_priv_enc */ 1128 NULL, /* rsa_priv_dec */ 1129 NULL, 1130 NULL, 1131 NULL, /* init */ 1132 NULL, /* finish */ 1133 0, /* flags */ 1134 NULL, /* app_data */ 1135 NULL, /* rsa_sign */ 1136 NULL /* rsa_verify */ 1137 }; 1138 1139 static int 1140 cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 1141 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1142 { 1143 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); 1144 } 1145 1146 static int 1147 cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, 1148 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, 1149 BN_CTX *ctx, BN_MONT_CTX *mont) 1150 { 1151 BIGNUM t2; 1152 int ret = 0; 1153 1154 BN_init(&t2); 1155 1156 /* v = ( g^u1 * y^u2 mod p ) mod q */ 1157 /* let t1 = g ^ u1 mod p */ 1158 ret = 0; 1159 1160 if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont)) 1161 goto err; 1162 1163 /* let t2 = y ^ u2 mod p */ 1164 if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont)) 1165 goto err; 1166 /* let u1 = t1 * t2 mod p */ 1167 if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx)) 1168 goto err; 1169 1170 BN_copy(t1,u1); 1171 1172 ret = 1; 1173 err: 1174 BN_free(&t2); 1175 return(ret); 1176 } 1177 1178 static DSA_SIG * 1179 cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) 1180 { 1181 struct crypt_kop kop; 1182 BIGNUM *r = NULL, *s = NULL; 1183 DSA_SIG *dsaret = NULL; 1184 1185 if ((r = BN_new()) == NULL) 1186 goto err; 1187 if ((s = BN_new()) == NULL) { 1188 BN_free(r); 1189 goto err; 1190 } 1191 1192 memset(&kop, 0, sizeof kop); 1193 kop.crk_op = CRK_DSA_SIGN; 1194 1195 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ 1196 kop.crk_param[0].crp_p = (caddr_t)dgst; 1197 kop.crk_param[0].crp_nbits = dlen * 8; 1198 if (bn2crparam(dsa->p, &kop.crk_param[1])) 1199 goto err; 1200 if (bn2crparam(dsa->q, &kop.crk_param[2])) 1201 goto err; 1202 if (bn2crparam(dsa->g, &kop.crk_param[3])) 1203 goto err; 1204 if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) 1205 goto err; 1206 kop.crk_iparams = 5; 1207 1208 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, 1209 BN_num_bytes(dsa->q), s) == 0) { 1210 dsaret = DSA_SIG_new(); 1211 dsaret->r = r; 1212 dsaret->s = s; 1213 } else { 1214 const DSA_METHOD *meth = DSA_OpenSSL(); 1215 BN_free(r); 1216 BN_free(s); 1217 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); 1218 } 1219 err: 1220 kop.crk_param[0].crp_p = NULL; 1221 zapparams(&kop); 1222 return (dsaret); 1223 } 1224 1225 static int 1226 cryptodev_dsa_verify(const unsigned char *dgst, int dlen, 1227 DSA_SIG *sig, DSA *dsa) 1228 { 1229 struct crypt_kop kop; 1230 int dsaret = 1; 1231 1232 memset(&kop, 0, sizeof kop); 1233 kop.crk_op = CRK_DSA_VERIFY; 1234 1235 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ 1236 kop.crk_param[0].crp_p = (caddr_t)dgst; 1237 kop.crk_param[0].crp_nbits = dlen * 8; 1238 if (bn2crparam(dsa->p, &kop.crk_param[1])) 1239 goto err; 1240 if (bn2crparam(dsa->q, &kop.crk_param[2])) 1241 goto err; 1242 if (bn2crparam(dsa->g, &kop.crk_param[3])) 1243 goto err; 1244 if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) 1245 goto err; 1246 if (bn2crparam(sig->r, &kop.crk_param[5])) 1247 goto err; 1248 if (bn2crparam(sig->s, &kop.crk_param[6])) 1249 goto err; 1250 kop.crk_iparams = 7; 1251 1252 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { 1253 /*OCF success value is 0, if not zero, change dsaret to fail*/ 1254 if(0 != kop.crk_status) dsaret = 0; 1255 } else { 1256 const DSA_METHOD *meth = DSA_OpenSSL(); 1257 1258 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa); 1259 } 1260 err: 1261 kop.crk_param[0].crp_p = NULL; 1262 zapparams(&kop); 1263 return (dsaret); 1264 } 1265 1266 static DSA_METHOD cryptodev_dsa = { 1267 "cryptodev DSA method", 1268 NULL, 1269 NULL, /* dsa_sign_setup */ 1270 NULL, 1271 NULL, /* dsa_mod_exp */ 1272 NULL, 1273 NULL, /* init */ 1274 NULL, /* finish */ 1275 0, /* flags */ 1276 NULL /* app_data */ 1277 }; 1278 1279 static int 1280 cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 1281 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 1282 BN_MONT_CTX *m_ctx) 1283 { 1284 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); 1285 } 1286 1287 static int 1288 cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) 1289 { 1290 struct crypt_kop kop; 1291 int dhret = 1; 1292 int fd, keylen; 1293 1294 if ((fd = get_asym_dev_crypto()) < 0) { 1295 const DH_METHOD *meth = DH_OpenSSL(); 1296 1297 return ((meth->compute_key)(key, pub_key, dh)); 1298 } 1299 1300 keylen = BN_num_bits(dh->p); 1301 1302 memset(&kop, 0, sizeof kop); 1303 kop.crk_op = CRK_DH_COMPUTE_KEY; 1304 1305 /* inputs: dh->priv_key pub_key dh->p key */ 1306 if (bn2crparam(dh->priv_key, &kop.crk_param[0])) 1307 goto err; 1308 if (bn2crparam(pub_key, &kop.crk_param[1])) 1309 goto err; 1310 if (bn2crparam(dh->p, &kop.crk_param[2])) 1311 goto err; 1312 kop.crk_iparams = 3; 1313 1314 kop.crk_param[3].crp_p = (caddr_t) key; 1315 kop.crk_param[3].crp_nbits = keylen * 8; 1316 kop.crk_oparams = 1; 1317 1318 if (ioctl(fd, CIOCKEY, &kop) == -1) { 1319 const DH_METHOD *meth = DH_OpenSSL(); 1320 1321 dhret = (meth->compute_key)(key, pub_key, dh); 1322 } 1323 err: 1324 kop.crk_param[3].crp_p = NULL; 1325 zapparams(&kop); 1326 return (dhret); 1327 } 1328 1329 static DH_METHOD cryptodev_dh = { 1330 "cryptodev DH method", 1331 NULL, /* cryptodev_dh_generate_key */ 1332 NULL, 1333 NULL, 1334 NULL, 1335 NULL, 1336 0, /* flags */ 1337 NULL /* app_data */ 1338 }; 1339 1340 /* 1341 * ctrl right now is just a wrapper that doesn't do much 1342 * but I expect we'll want some options soon. 1343 */ 1344 static int 1345 cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) 1346 { 1347 #ifdef HAVE_SYSLOG_R 1348 struct syslog_data sd = SYSLOG_DATA_INIT; 1349 #endif 1350 1351 switch (cmd) { 1352 default: 1353 #ifdef HAVE_SYSLOG_R 1354 syslog_r(LOG_ERR, &sd, 1355 "cryptodev_ctrl: unknown command %d", cmd); 1356 #else 1357 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); 1358 #endif 1359 break; 1360 } 1361 return (1); 1362 } 1363 1364 void 1365 ENGINE_load_cryptodev(void) 1366 { 1367 ENGINE *engine = ENGINE_new(); 1368 int fd; 1369 1370 if (engine == NULL) 1371 return; 1372 if ((fd = get_dev_crypto()) < 0) { 1373 ENGINE_free(engine); 1374 return; 1375 } 1376 1377 /* 1378 * find out what asymmetric crypto algorithms we support 1379 */ 1380 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { 1381 put_dev_crypto(fd); 1382 ENGINE_free(engine); 1383 return; 1384 } 1385 put_dev_crypto(fd); 1386 1387 if (!ENGINE_set_id(engine, "cryptodev") || 1388 !ENGINE_set_name(engine, "BSD cryptodev engine") || 1389 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || 1390 !ENGINE_set_digests(engine, cryptodev_engine_digests) || 1391 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || 1392 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { 1393 ENGINE_free(engine); 1394 return; 1395 } 1396 1397 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { 1398 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); 1399 1400 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; 1401 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; 1402 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; 1403 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; 1404 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; 1405 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; 1406 if (cryptodev_asymfeat & CRF_MOD_EXP) { 1407 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; 1408 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) 1409 cryptodev_rsa.rsa_mod_exp = 1410 cryptodev_rsa_mod_exp; 1411 else 1412 cryptodev_rsa.rsa_mod_exp = 1413 cryptodev_rsa_nocrt_mod_exp; 1414 } 1415 } 1416 1417 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { 1418 const DSA_METHOD *meth = DSA_OpenSSL(); 1419 1420 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); 1421 if (cryptodev_asymfeat & CRF_DSA_SIGN) 1422 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; 1423 if (cryptodev_asymfeat & CRF_MOD_EXP) { 1424 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; 1425 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; 1426 } 1427 if (cryptodev_asymfeat & CRF_DSA_VERIFY) 1428 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; 1429 } 1430 1431 if (ENGINE_set_DH(engine, &cryptodev_dh)){ 1432 const DH_METHOD *dh_meth = DH_OpenSSL(); 1433 1434 cryptodev_dh.generate_key = dh_meth->generate_key; 1435 cryptodev_dh.compute_key = dh_meth->compute_key; 1436 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; 1437 if (cryptodev_asymfeat & CRF_MOD_EXP) { 1438 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; 1439 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) 1440 cryptodev_dh.compute_key = 1441 cryptodev_dh_compute_key; 1442 } 1443 } 1444 1445 ENGINE_add(engine); 1446 ENGINE_free(engine); 1447 ERR_clear_error(); 1448 } 1449 1450 #endif /* HAVE_CRYPTODEV */ 1451