| OLD | NEW |
| (Empty) |
| 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_le
n + 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_l
en); | |
| 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(cha
r)); | |
| 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(c
har)); | |
| 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 */ | |
| OLD | NEW |