eng_cryptodev.c revision 325335
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 char *mac_data = 814 OPENSSL_realloc(state->mac_data, state->mac_len + count); 815 816 if (mac_data == NULL) { 817 printf("cryptodev_digest_update: realloc failed\n"); 818 return (0); 819 } 820 821 state->mac_data = mac_data; 822 memcpy(state->mac_data + state->mac_len, data, count); 823 state->mac_len += count; 824 825 return (1); 826 } 827 828 memset(&cryp, 0, sizeof(cryp)); 829 830 cryp.ses = sess->ses; 831 cryp.flags = 0; 832 cryp.len = count; 833 cryp.src = (caddr_t) data; 834 cryp.dst = NULL; 835 cryp.mac = (caddr_t) state->digest_res; 836 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { 837 printf("cryptodev_digest_update: digest failed\n"); 838 return (0); 839 } 840 return (1); 841} 842 843static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) 844{ 845 struct crypt_op cryp; 846 struct dev_crypto_state *state = ctx->md_data; 847 struct session_op *sess = &state->d_sess; 848 849 int ret = 1; 850 851 if (!md || state->d_fd < 0) { 852 printf("cryptodev_digest_final: illegal input\n"); 853 return (0); 854 } 855 856 if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { 857 /* if application doesn't support one buffer */ 858 memset(&cryp, 0, sizeof(cryp)); 859 cryp.ses = sess->ses; 860 cryp.flags = 0; 861 cryp.len = state->mac_len; 862 cryp.src = state->mac_data; 863 cryp.dst = NULL; 864 cryp.mac = (caddr_t) md; 865 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { 866 printf("cryptodev_digest_final: digest failed\n"); 867 return (0); 868 } 869 870 return 1; 871 } 872 873 memcpy(md, state->digest_res, ctx->digest->md_size); 874 875 return (ret); 876} 877 878static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) 879{ 880 int ret = 1; 881 struct dev_crypto_state *state = ctx->md_data; 882 struct session_op *sess = &state->d_sess; 883 884 if (state == NULL) 885 return 0; 886 887 if (state->d_fd < 0) { 888 printf("cryptodev_digest_cleanup: illegal input\n"); 889 return (0); 890 } 891 892 if (state->mac_data) { 893 OPENSSL_free(state->mac_data); 894 state->mac_data = NULL; 895 state->mac_len = 0; 896 } 897 898 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { 899 printf("cryptodev_digest_cleanup: failed to close session\n"); 900 ret = 0; 901 } else { 902 ret = 1; 903 } 904 put_dev_crypto(state->d_fd); 905 state->d_fd = -1; 906 907 return (ret); 908} 909 910static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) 911{ 912 struct dev_crypto_state *fstate = from->md_data; 913 struct dev_crypto_state *dstate = to->md_data; 914 struct session_op *sess; 915 int digest; 916 917 if (dstate == NULL || fstate == NULL) 918 return 1; 919 920 memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); 921 922 sess = &dstate->d_sess; 923 924 digest = digest_nid_to_cryptodev(to->digest->type); 925 926 sess->mackey = dstate->dummy_mac_key; 927 sess->mackeylen = digest_key_length(to->digest->type); 928 sess->mac = digest; 929 930 dstate->d_fd = get_dev_crypto(); 931 932 if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) { 933 put_dev_crypto(dstate->d_fd); 934 dstate->d_fd = -1; 935 printf("cryptodev_digest_init: Open session failed\n"); 936 return (0); 937 } 938 939 dstate->mac_len = fstate->mac_len; 940 if (fstate->mac_len != 0) { 941 if (fstate->mac_data != NULL) { 942 dstate->mac_data = OPENSSL_malloc(fstate->mac_len); 943 if (dstate->mac_data == NULL) { 944 printf("cryptodev_digest_init: malloc failed\n"); 945 return 0; 946 } 947 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); 948 } 949 } 950 951 return 1; 952} 953 954const EVP_MD cryptodev_sha1 = { 955 NID_sha1, 956 NID_undef, 957 SHA_DIGEST_LENGTH, 958 EVP_MD_FLAG_ONESHOT, 959 cryptodev_digest_init, 960 cryptodev_digest_update, 961 cryptodev_digest_final, 962 cryptodev_digest_copy, 963 cryptodev_digest_cleanup, 964 EVP_PKEY_NULL_method, 965 SHA_CBLOCK, 966 sizeof(struct dev_crypto_state), 967}; 968 969const EVP_MD cryptodev_md5 = { 970 NID_md5, 971 NID_undef, 972 16 /* MD5_DIGEST_LENGTH */ , 973 EVP_MD_FLAG_ONESHOT, 974 cryptodev_digest_init, 975 cryptodev_digest_update, 976 cryptodev_digest_final, 977 cryptodev_digest_copy, 978 cryptodev_digest_cleanup, 979 EVP_PKEY_NULL_method, 980 64 /* MD5_CBLOCK */ , 981 sizeof(struct dev_crypto_state), 982}; 983 984# endif /* USE_CRYPTODEV_DIGESTS */ 985 986static int 987cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, 988 const int **nids, int nid) 989{ 990 if (!digest) 991 return (cryptodev_usable_digests(nids)); 992 993 switch (nid) { 994# ifdef USE_CRYPTODEV_DIGESTS 995 case NID_md5: 996 *digest = &cryptodev_md5; 997 break; 998 case NID_sha1: 999 *digest = &cryptodev_sha1; 1000 break; 1001 default: 1002# endif /* USE_CRYPTODEV_DIGESTS */ 1003 *digest = NULL; 1004 break; 1005 } 1006 return (*digest != NULL); 1007} 1008 1009/* 1010 * Convert a BIGNUM to the representation that /dev/crypto needs. 1011 * Upon completion of use, the caller is responsible for freeing 1012 * crp->crp_p. 1013 */ 1014static int bn2crparam(const BIGNUM *a, struct crparam *crp) 1015{ 1016 int i, j, k; 1017 ssize_t bytes, bits; 1018 u_char *b; 1019 1020 crp->crp_p = NULL; 1021 crp->crp_nbits = 0; 1022 1023 bits = BN_num_bits(a); 1024 bytes = (bits + 7) / 8; 1025 1026 b = malloc(bytes); 1027 if (b == NULL) 1028 return (1); 1029 memset(b, 0, bytes); 1030 1031 crp->crp_p = (caddr_t) b; 1032 crp->crp_nbits = bits; 1033 1034 for (i = 0, j = 0; i < a->top; i++) { 1035 for (k = 0; k < BN_BITS2 / 8; k++) { 1036 if ((j + k) >= bytes) 1037 return (0); 1038 b[j + k] = a->d[i] >> (k * 8); 1039 } 1040 j += BN_BITS2 / 8; 1041 } 1042 return (0); 1043} 1044 1045/* Convert a /dev/crypto parameter to a BIGNUM */ 1046static int crparam2bn(struct crparam *crp, BIGNUM *a) 1047{ 1048 u_int8_t *pd; 1049 int i, bytes; 1050 1051 bytes = (crp->crp_nbits + 7) / 8; 1052 1053 if (bytes == 0) 1054 return (-1); 1055 1056 if ((pd = (u_int8_t *) malloc(bytes)) == NULL) 1057 return (-1); 1058 1059 for (i = 0; i < bytes; i++) 1060 pd[i] = crp->crp_p[bytes - i - 1]; 1061 1062 BN_bin2bn(pd, bytes, a); 1063 free(pd); 1064 1065 return (0); 1066} 1067 1068static void zapparams(struct crypt_kop *kop) 1069{ 1070 int i; 1071 1072 for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { 1073 OPENSSL_free(kop->crk_param[i].crp_p); 1074 kop->crk_param[i].crp_p = NULL; 1075 kop->crk_param[i].crp_nbits = 0; 1076 } 1077} 1078 1079static int 1080cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, 1081 BIGNUM *s) 1082{ 1083 int fd, ret = -1; 1084 1085 if ((fd = get_asym_dev_crypto()) < 0) 1086 return ret; 1087 1088 if (r) { 1089 kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_malloc(rlen); 1090 if (kop->crk_param[kop->crk_iparams].crp_p == NULL) 1091 return ret; 1092 memset(kop->crk_param[kop->crk_iparams].crp_p, 0, (size_t)rlen); 1093 kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; 1094 kop->crk_oparams++; 1095 } 1096 if (s) { 1097 kop->crk_param[kop->crk_iparams + 1].crp_p = OPENSSL_malloc(slen); 1098 /* No need to free the kop->crk_iparams parameter if it was allocated, 1099 * callers of this routine have to free allocated parameters through 1100 * zapparams both in case of success and failure 1101 */ 1102 if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL) 1103 return ret; 1104 memset(kop->crk_param[kop->crk_iparams + 1].crp_p, 0, (size_t)slen); 1105 kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; 1106 kop->crk_oparams++; 1107 } 1108 1109 if (ioctl(fd, CIOCKEY, kop) == 0) { 1110 if (r) 1111 crparam2bn(&kop->crk_param[kop->crk_iparams], r); 1112 if (s) 1113 crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s); 1114 ret = 0; 1115 } 1116 1117 return ret; 1118} 1119 1120static int 1121cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, 1122 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) 1123{ 1124 struct crypt_kop kop; 1125 int ret = 1; 1126 1127 /* 1128 * Currently, we know we can do mod exp iff we can do any asymmetric 1129 * operations at all. 1130 */ 1131 if (cryptodev_asymfeat == 0) { 1132 ret = BN_mod_exp(r, a, p, m, ctx); 1133 return (ret); 1134 } 1135 1136 memset(&kop, 0, sizeof kop); 1137 kop.crk_op = CRK_MOD_EXP; 1138 1139 /* inputs: a^p % m */ 1140 if (bn2crparam(a, &kop.crk_param[0])) 1141 goto err; 1142 if (bn2crparam(p, &kop.crk_param[1])) 1143 goto err; 1144 if (bn2crparam(m, &kop.crk_param[2])) 1145 goto err; 1146 kop.crk_iparams = 3; 1147 1148 if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { 1149 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1150 printf("OCF asym process failed, Running in software\n"); 1151 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); 1152 1153 } else if (ECANCELED == kop.crk_status) { 1154 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1155 printf("OCF hardware operation cancelled. Running in Software\n"); 1156 ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); 1157 } 1158 /* else cryptodev operation worked ok ==> ret = 1 */ 1159 1160 err: 1161 zapparams(&kop); 1162 return (ret); 1163} 1164 1165static int 1166cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, 1167 BN_CTX *ctx) 1168{ 1169 int r; 1170 ctx = BN_CTX_new(); 1171 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); 1172 BN_CTX_free(ctx); 1173 return (r); 1174} 1175 1176static int 1177cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) 1178{ 1179 struct crypt_kop kop; 1180 int ret = 1; 1181 1182 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { 1183 /* XXX 0 means failure?? */ 1184 return (0); 1185 } 1186 1187 memset(&kop, 0, sizeof kop); 1188 kop.crk_op = CRK_MOD_EXP_CRT; 1189 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ 1190 if (bn2crparam(rsa->p, &kop.crk_param[0])) 1191 goto err; 1192 if (bn2crparam(rsa->q, &kop.crk_param[1])) 1193 goto err; 1194 if (bn2crparam(I, &kop.crk_param[2])) 1195 goto err; 1196 if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) 1197 goto err; 1198 if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) 1199 goto err; 1200 if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) 1201 goto err; 1202 kop.crk_iparams = 6; 1203 1204 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { 1205 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1206 printf("OCF asym process failed, running in Software\n"); 1207 ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); 1208 1209 } else if (ECANCELED == kop.crk_status) { 1210 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1211 printf("OCF hardware operation cancelled. Running in Software\n"); 1212 ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); 1213 } 1214 /* else cryptodev operation worked ok ==> ret = 1 */ 1215 1216 err: 1217 zapparams(&kop); 1218 return (ret); 1219} 1220 1221static RSA_METHOD cryptodev_rsa = { 1222 "cryptodev RSA method", 1223 NULL, /* rsa_pub_enc */ 1224 NULL, /* rsa_pub_dec */ 1225 NULL, /* rsa_priv_enc */ 1226 NULL, /* rsa_priv_dec */ 1227 NULL, 1228 NULL, 1229 NULL, /* init */ 1230 NULL, /* finish */ 1231 0, /* flags */ 1232 NULL, /* app_data */ 1233 NULL, /* rsa_sign */ 1234 NULL /* rsa_verify */ 1235}; 1236 1237static int 1238cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 1239 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1240{ 1241 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); 1242} 1243 1244static int 1245cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, 1246 BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, 1247 BN_CTX *ctx, BN_MONT_CTX *mont) 1248{ 1249 BIGNUM t2; 1250 int ret = 0; 1251 1252 BN_init(&t2); 1253 1254 /* v = ( g^u1 * y^u2 mod p ) mod q */ 1255 /* let t1 = g ^ u1 mod p */ 1256 ret = 0; 1257 1258 if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont)) 1259 goto err; 1260 1261 /* let t2 = y ^ u2 mod p */ 1262 if (!dsa->meth->bn_mod_exp(dsa, &t2, dsa->pub_key, u2, dsa->p, ctx, mont)) 1263 goto err; 1264 /* let u1 = t1 * t2 mod p */ 1265 if (!BN_mod_mul(u1, t1, &t2, dsa->p, ctx)) 1266 goto err; 1267 1268 BN_copy(t1, u1); 1269 1270 ret = 1; 1271 err: 1272 BN_free(&t2); 1273 return (ret); 1274} 1275 1276static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, 1277 DSA *dsa) 1278{ 1279 struct crypt_kop kop; 1280 BIGNUM *r = NULL, *s = NULL; 1281 DSA_SIG *dsaret = NULL; 1282 1283 if ((r = BN_new()) == NULL) 1284 goto err; 1285 if ((s = BN_new()) == NULL) { 1286 BN_free(r); 1287 goto err; 1288 } 1289 1290 memset(&kop, 0, sizeof kop); 1291 kop.crk_op = CRK_DSA_SIGN; 1292 1293 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ 1294 kop.crk_param[0].crp_p = (caddr_t) dgst; 1295 kop.crk_param[0].crp_nbits = dlen * 8; 1296 if (bn2crparam(dsa->p, &kop.crk_param[1])) 1297 goto err; 1298 if (bn2crparam(dsa->q, &kop.crk_param[2])) 1299 goto err; 1300 if (bn2crparam(dsa->g, &kop.crk_param[3])) 1301 goto err; 1302 if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) 1303 goto err; 1304 kop.crk_iparams = 5; 1305 1306 if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, 1307 BN_num_bytes(dsa->q), s) == 0) { 1308 dsaret = DSA_SIG_new(); 1309 if (dsaret == NULL) 1310 goto err; 1311 dsaret->r = r; 1312 dsaret->s = s; 1313 r = s = NULL; 1314 } else { 1315 const DSA_METHOD *meth = DSA_OpenSSL(); 1316 dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); 1317 } 1318 err: 1319 BN_free(r); 1320 BN_free(s); 1321 kop.crk_param[0].crp_p = NULL; 1322 zapparams(&kop); 1323 return (dsaret); 1324} 1325 1326static int 1327cryptodev_dsa_verify(const unsigned char *dgst, int dlen, 1328 DSA_SIG *sig, DSA *dsa) 1329{ 1330 struct crypt_kop kop; 1331 int dsaret = 1; 1332 1333 memset(&kop, 0, sizeof kop); 1334 kop.crk_op = CRK_DSA_VERIFY; 1335 1336 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ 1337 kop.crk_param[0].crp_p = (caddr_t) dgst; 1338 kop.crk_param[0].crp_nbits = dlen * 8; 1339 if (bn2crparam(dsa->p, &kop.crk_param[1])) 1340 goto err; 1341 if (bn2crparam(dsa->q, &kop.crk_param[2])) 1342 goto err; 1343 if (bn2crparam(dsa->g, &kop.crk_param[3])) 1344 goto err; 1345 if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) 1346 goto err; 1347 if (bn2crparam(sig->r, &kop.crk_param[5])) 1348 goto err; 1349 if (bn2crparam(sig->s, &kop.crk_param[6])) 1350 goto err; 1351 kop.crk_iparams = 7; 1352 1353 if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { 1354 /* 1355 * OCF success value is 0, if not zero, change dsaret to fail 1356 */ 1357 if (0 != kop.crk_status) 1358 dsaret = 0; 1359 } else { 1360 const DSA_METHOD *meth = DSA_OpenSSL(); 1361 1362 dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); 1363 } 1364 err: 1365 kop.crk_param[0].crp_p = NULL; 1366 zapparams(&kop); 1367 return (dsaret); 1368} 1369 1370static DSA_METHOD cryptodev_dsa = { 1371 "cryptodev DSA method", 1372 NULL, 1373 NULL, /* dsa_sign_setup */ 1374 NULL, 1375 NULL, /* dsa_mod_exp */ 1376 NULL, 1377 NULL, /* init */ 1378 NULL, /* finish */ 1379 0, /* flags */ 1380 NULL /* app_data */ 1381}; 1382 1383static int 1384cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, 1385 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, 1386 BN_MONT_CTX *m_ctx) 1387{ 1388 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); 1389} 1390 1391static int 1392cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) 1393{ 1394 struct crypt_kop kop; 1395 int dhret = 1; 1396 int fd, keylen; 1397 1398 if ((fd = get_asym_dev_crypto()) < 0) { 1399 const DH_METHOD *meth = DH_OpenSSL(); 1400 1401 return ((meth->compute_key) (key, pub_key, dh)); 1402 } 1403 1404 keylen = BN_num_bits(dh->p); 1405 1406 memset(&kop, 0, sizeof kop); 1407 kop.crk_op = CRK_DH_COMPUTE_KEY; 1408 1409 /* inputs: dh->priv_key pub_key dh->p key */ 1410 if (bn2crparam(dh->priv_key, &kop.crk_param[0])) 1411 goto err; 1412 if (bn2crparam(pub_key, &kop.crk_param[1])) 1413 goto err; 1414 if (bn2crparam(dh->p, &kop.crk_param[2])) 1415 goto err; 1416 kop.crk_iparams = 3; 1417 1418 kop.crk_param[3].crp_p = (caddr_t) key; 1419 kop.crk_param[3].crp_nbits = keylen * 8; 1420 kop.crk_oparams = 1; 1421 1422 if (ioctl(fd, CIOCKEY, &kop) == -1) { 1423 const DH_METHOD *meth = DH_OpenSSL(); 1424 1425 dhret = (meth->compute_key) (key, pub_key, dh); 1426 } 1427 err: 1428 kop.crk_param[3].crp_p = NULL; 1429 zapparams(&kop); 1430 return (dhret); 1431} 1432 1433static DH_METHOD cryptodev_dh = { 1434 "cryptodev DH method", 1435 NULL, /* cryptodev_dh_generate_key */ 1436 NULL, 1437 NULL, 1438 NULL, 1439 NULL, 1440 0, /* flags */ 1441 NULL /* app_data */ 1442}; 1443 1444/* 1445 * ctrl right now is just a wrapper that doesn't do much 1446 * but I expect we'll want some options soon. 1447 */ 1448static int 1449cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 1450{ 1451# ifdef HAVE_SYSLOG_R 1452 struct syslog_data sd = SYSLOG_DATA_INIT; 1453# endif 1454 1455 switch (cmd) { 1456 default: 1457# ifdef HAVE_SYSLOG_R 1458 syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd); 1459# else 1460 syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); 1461# endif 1462 break; 1463 } 1464 return (1); 1465} 1466 1467void ENGINE_load_cryptodev(void) 1468{ 1469 ENGINE *engine = ENGINE_new(); 1470 int fd; 1471 1472 if (engine == NULL) 1473 return; 1474 if ((fd = get_dev_crypto()) < 0) { 1475 ENGINE_free(engine); 1476 return; 1477 } 1478 1479 /* 1480 * find out what asymmetric crypto algorithms we support 1481 */ 1482 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { 1483 put_dev_crypto(fd); 1484 ENGINE_free(engine); 1485 return; 1486 } 1487 put_dev_crypto(fd); 1488 1489 if (!ENGINE_set_id(engine, "cryptodev") || 1490 !ENGINE_set_name(engine, "BSD cryptodev engine") || 1491 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || 1492 !ENGINE_set_digests(engine, cryptodev_engine_digests) || 1493 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || 1494 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { 1495 ENGINE_free(engine); 1496 return; 1497 } 1498 1499 if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { 1500 const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); 1501 1502 cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; 1503 cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; 1504 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; 1505 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; 1506 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; 1507 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; 1508 if (cryptodev_asymfeat & CRF_MOD_EXP) { 1509 cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; 1510 if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) 1511 cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; 1512 else 1513 cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; 1514 } 1515 } 1516 1517 if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { 1518 const DSA_METHOD *meth = DSA_OpenSSL(); 1519 1520 memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); 1521 if (cryptodev_asymfeat & CRF_DSA_SIGN) 1522 cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; 1523 if (cryptodev_asymfeat & CRF_MOD_EXP) { 1524 cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; 1525 cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; 1526 } 1527 if (cryptodev_asymfeat & CRF_DSA_VERIFY) 1528 cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; 1529 } 1530 1531 if (ENGINE_set_DH(engine, &cryptodev_dh)) { 1532 const DH_METHOD *dh_meth = DH_OpenSSL(); 1533 1534 cryptodev_dh.generate_key = dh_meth->generate_key; 1535 cryptodev_dh.compute_key = dh_meth->compute_key; 1536 cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; 1537 if (cryptodev_asymfeat & CRF_MOD_EXP) { 1538 cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; 1539 if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) 1540 cryptodev_dh.compute_key = cryptodev_dh_compute_key; 1541 } 1542 } 1543 1544 ENGINE_add(engine); 1545 ENGINE_free(engine); 1546 ERR_clear_error(); 1547} 1548 1549#endif /* HAVE_CRYPTODEV */ 1550