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