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