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