diff options
Diffstat (limited to 'src/lib/libcrypto/engine/eng_cryptodev.c')
| -rw-r--r-- | src/lib/libcrypto/engine/eng_cryptodev.c | 452 |
1 files changed, 369 insertions, 83 deletions
diff --git a/src/lib/libcrypto/engine/eng_cryptodev.c b/src/lib/libcrypto/engine/eng_cryptodev.c index ab38cd52f0..52f4ca3901 100644 --- a/src/lib/libcrypto/engine/eng_cryptodev.c +++ b/src/lib/libcrypto/engine/eng_cryptodev.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include <openssl/bn.h> | 32 | #include <openssl/bn.h> |
| 33 | 33 | ||
| 34 | #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ | 34 | #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ |
| 35 | (defined(OpenBSD) || defined(__FreeBSD_version)) | 35 | (defined(OpenBSD) || defined(__FreeBSD__)) |
| 36 | #include <sys/param.h> | 36 | #include <sys/param.h> |
| 37 | # if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) | 37 | # if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) |
| 38 | # define HAVE_CRYPTODEV | 38 | # define HAVE_CRYPTODEV |
| @@ -55,6 +55,10 @@ ENGINE_load_cryptodev(void) | |||
| 55 | 55 | ||
| 56 | #include <sys/types.h> | 56 | #include <sys/types.h> |
| 57 | #include <crypto/cryptodev.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> | ||
| 58 | #include <sys/ioctl.h> | 62 | #include <sys/ioctl.h> |
| 59 | #include <errno.h> | 63 | #include <errno.h> |
| 60 | #include <stdio.h> | 64 | #include <stdio.h> |
| @@ -68,6 +72,16 @@ ENGINE_load_cryptodev(void) | |||
| 68 | struct dev_crypto_state { | 72 | struct dev_crypto_state { |
| 69 | struct session_op d_sess; | 73 | struct session_op d_sess; |
| 70 | int d_fd; | 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 | |||
| 83 | int copy; | ||
| 84 | #endif | ||
| 71 | }; | 85 | }; |
| 72 | 86 | ||
| 73 | static u_int32_t cryptodev_asymfeat = 0; | 87 | static u_int32_t cryptodev_asymfeat = 0; |
| @@ -75,15 +89,14 @@ static u_int32_t cryptodev_asymfeat = 0; | |||
| 75 | static int get_asym_dev_crypto(void); | 89 | static int get_asym_dev_crypto(void); |
| 76 | static int open_dev_crypto(void); | 90 | static int open_dev_crypto(void); |
| 77 | static int get_dev_crypto(void); | 91 | static int get_dev_crypto(void); |
| 78 | static int cryptodev_max_iv(int cipher); | ||
| 79 | static int cryptodev_key_length_valid(int cipher, int len); | ||
| 80 | static int cipher_nid_to_cryptodev(int nid); | ||
| 81 | static int get_cryptodev_ciphers(const int **cnids); | 92 | static int get_cryptodev_ciphers(const int **cnids); |
| 93 | #ifdef USE_CRYPTODEV_DIGESTS | ||
| 82 | static int get_cryptodev_digests(const int **cnids); | 94 | static int get_cryptodev_digests(const int **cnids); |
| 95 | #endif | ||
| 83 | static int cryptodev_usable_ciphers(const int **nids); | 96 | static int cryptodev_usable_ciphers(const int **nids); |
| 84 | static int cryptodev_usable_digests(const int **nids); | 97 | static int cryptodev_usable_digests(const int **nids); |
| 85 | static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 98 | static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
| 86 | const unsigned char *in, unsigned int inl); | 99 | const unsigned char *in, size_t inl); |
| 87 | static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 100 | static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
| 88 | const unsigned char *iv, int enc); | 101 | const unsigned char *iv, int enc); |
| 89 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); | 102 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); |
| @@ -100,7 +113,7 @@ static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, | |||
| 100 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, | 113 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, |
| 101 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | 114 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
| 102 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, | 115 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, |
| 103 | RSA *rsa); | 116 | RSA *rsa, BN_CTX *ctx); |
| 104 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); | 117 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); |
| 105 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, | 118 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, |
| 106 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | 119 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
| @@ -117,7 +130,7 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | |||
| 117 | static int cryptodev_dh_compute_key(unsigned char *key, | 130 | static int cryptodev_dh_compute_key(unsigned char *key, |
| 118 | const BIGNUM *pub_key, DH *dh); | 131 | const BIGNUM *pub_key, DH *dh); |
| 119 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, | 132 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, |
| 120 | void (*f)()); | 133 | void (*f)(void)); |
| 121 | void ENGINE_load_cryptodev(void); | 134 | void ENGINE_load_cryptodev(void); |
| 122 | 135 | ||
| 123 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { | 136 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { |
| @@ -130,27 +143,34 @@ static struct { | |||
| 130 | int ivmax; | 143 | int ivmax; |
| 131 | int keylen; | 144 | int keylen; |
| 132 | } ciphers[] = { | 145 | } ciphers[] = { |
| 146 | { CRYPTO_ARC4, NID_rc4, 0, 16, }, | ||
| 133 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, | 147 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, |
| 134 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, | 148 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, |
| 135 | { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, | 149 | { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, |
| 150 | { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, }, | ||
| 151 | { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, }, | ||
| 136 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, | 152 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, |
| 137 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, | 153 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, |
| 138 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, | 154 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, |
| 139 | { 0, NID_undef, 0, 0, }, | 155 | { 0, NID_undef, 0, 0, }, |
| 140 | }; | 156 | }; |
| 141 | 157 | ||
| 158 | #ifdef USE_CRYPTODEV_DIGESTS | ||
| 142 | static struct { | 159 | static struct { |
| 143 | int id; | 160 | int id; |
| 144 | int nid; | 161 | int nid; |
| 162 | int keylen; | ||
| 145 | } digests[] = { | 163 | } digests[] = { |
| 146 | { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, }, | 164 | { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16}, |
| 147 | { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, }, | 165 | { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20}, |
| 148 | { CRYPTO_MD5_KPDK, NID_undef, }, | 166 | { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/}, |
| 149 | { CRYPTO_SHA1_KPDK, NID_undef, }, | 167 | { CRYPTO_MD5_KPDK, NID_undef, 0}, |
| 150 | { CRYPTO_MD5, NID_md5, }, | 168 | { CRYPTO_SHA1_KPDK, NID_undef, 0}, |
| 151 | { CRYPTO_SHA1, NID_undef, }, | 169 | { CRYPTO_MD5, NID_md5, 16}, |
| 152 | { 0, NID_undef, }, | 170 | { CRYPTO_SHA1, NID_sha1, 20}, |
| 171 | { 0, NID_undef, 0}, | ||
| 153 | }; | 172 | }; |
| 173 | #endif | ||
| 154 | 174 | ||
| 155 | /* | 175 | /* |
| 156 | * Return a fd if /dev/crypto seems usable, 0 otherwise. | 176 | * Return a fd if /dev/crypto seems usable, 0 otherwise. |
| @@ -203,50 +223,6 @@ get_asym_dev_crypto(void) | |||
| 203 | } | 223 | } |
| 204 | 224 | ||
| 205 | /* | 225 | /* |
| 206 | * XXXX this needs to be set for each alg - and determined from | ||
| 207 | * a running card. | ||
| 208 | */ | ||
| 209 | static int | ||
| 210 | cryptodev_max_iv(int cipher) | ||
| 211 | { | ||
| 212 | int i; | ||
| 213 | |||
| 214 | for (i = 0; ciphers[i].id; i++) | ||
| 215 | if (ciphers[i].id == cipher) | ||
| 216 | return (ciphers[i].ivmax); | ||
| 217 | return (0); | ||
| 218 | } | ||
| 219 | |||
| 220 | /* | ||
| 221 | * XXXX this needs to be set for each alg - and determined from | ||
| 222 | * a running card. For now, fake it out - but most of these | ||
| 223 | * for real devices should return 1 for the supported key | ||
| 224 | * sizes the device can handle. | ||
| 225 | */ | ||
| 226 | static int | ||
| 227 | cryptodev_key_length_valid(int cipher, int len) | ||
| 228 | { | ||
| 229 | int i; | ||
| 230 | |||
| 231 | for (i = 0; ciphers[i].id; i++) | ||
| 232 | if (ciphers[i].id == cipher) | ||
| 233 | return (ciphers[i].keylen == len); | ||
| 234 | return (0); | ||
| 235 | } | ||
| 236 | |||
| 237 | /* convert libcrypto nids to cryptodev */ | ||
| 238 | static int | ||
| 239 | cipher_nid_to_cryptodev(int nid) | ||
| 240 | { | ||
| 241 | int i; | ||
| 242 | |||
| 243 | for (i = 0; ciphers[i].id; i++) | ||
| 244 | if (ciphers[i].nid == nid) | ||
| 245 | return (ciphers[i].id); | ||
| 246 | return (0); | ||
| 247 | } | ||
| 248 | |||
| 249 | /* | ||
| 250 | * Find out what ciphers /dev/crypto will let us have a session for. | 226 | * Find out what ciphers /dev/crypto will let us have a session for. |
| 251 | * XXX note, that some of these openssl doesn't deal with yet! | 227 | * XXX note, that some of these openssl doesn't deal with yet! |
| 252 | * returning them here is harmless, as long as we return NULL | 228 | * returning them here is harmless, as long as we return NULL |
| @@ -264,7 +240,7 @@ get_cryptodev_ciphers(const int **cnids) | |||
| 264 | return (0); | 240 | return (0); |
| 265 | } | 241 | } |
| 266 | memset(&sess, 0, sizeof(sess)); | 242 | memset(&sess, 0, sizeof(sess)); |
| 267 | sess.key = (caddr_t)"123456781234567812345678"; | 243 | sess.key = (caddr_t)"123456789abcdefghijklmno"; |
| 268 | 244 | ||
| 269 | for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 245 | for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
| 270 | if (ciphers[i].nid == NID_undef) | 246 | if (ciphers[i].nid == NID_undef) |
| @@ -285,6 +261,7 @@ get_cryptodev_ciphers(const int **cnids) | |||
| 285 | return (count); | 261 | return (count); |
| 286 | } | 262 | } |
| 287 | 263 | ||
| 264 | #ifdef USE_CRYPTODEV_DIGESTS | ||
| 288 | /* | 265 | /* |
| 289 | * Find out what digests /dev/crypto will let us have a session for. | 266 | * Find out what digests /dev/crypto will let us have a session for. |
| 290 | * XXX note, that some of these openssl doesn't deal with yet! | 267 | * XXX note, that some of these openssl doesn't deal with yet! |
| @@ -303,10 +280,12 @@ get_cryptodev_digests(const int **cnids) | |||
| 303 | return (0); | 280 | return (0); |
| 304 | } | 281 | } |
| 305 | memset(&sess, 0, sizeof(sess)); | 282 | memset(&sess, 0, sizeof(sess)); |
| 283 | sess.mackey = (caddr_t)"123456789abcdefghijklmno"; | ||
| 306 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 284 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
| 307 | if (digests[i].nid == NID_undef) | 285 | if (digests[i].nid == NID_undef) |
| 308 | continue; | 286 | continue; |
| 309 | sess.mac = digests[i].id; | 287 | sess.mac = digests[i].id; |
| 288 | sess.mackeylen = digests[i].keylen; | ||
| 310 | sess.cipher = 0; | 289 | sess.cipher = 0; |
| 311 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && | 290 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
| 312 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) | 291 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
| @@ -320,6 +299,7 @@ get_cryptodev_digests(const int **cnids) | |||
| 320 | *cnids = NULL; | 299 | *cnids = NULL; |
| 321 | return (count); | 300 | return (count); |
| 322 | } | 301 | } |
| 302 | #endif /* 0 */ | ||
| 323 | 303 | ||
| 324 | /* | 304 | /* |
| 325 | * Find the useable ciphers|digests from dev/crypto - this is the first | 305 | * Find the useable ciphers|digests from dev/crypto - this is the first |
| @@ -351,6 +331,9 @@ cryptodev_usable_ciphers(const int **nids) | |||
| 351 | static int | 331 | static int |
| 352 | cryptodev_usable_digests(const int **nids) | 332 | cryptodev_usable_digests(const int **nids) |
| 353 | { | 333 | { |
| 334 | #ifdef USE_CRYPTODEV_DIGESTS | ||
| 335 | return (get_cryptodev_digests(nids)); | ||
| 336 | #else | ||
| 354 | /* | 337 | /* |
| 355 | * XXXX just disable all digests for now, because it sucks. | 338 | * XXXX just disable all digests for now, because it sucks. |
| 356 | * we need a better way to decide this - i.e. I may not | 339 | * we need a better way to decide this - i.e. I may not |
| @@ -365,16 +348,17 @@ cryptodev_usable_digests(const int **nids) | |||
| 365 | */ | 348 | */ |
| 366 | *nids = NULL; | 349 | *nids = NULL; |
| 367 | return (0); | 350 | return (0); |
| 351 | #endif | ||
| 368 | } | 352 | } |
| 369 | 353 | ||
| 370 | static int | 354 | static int |
| 371 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 355 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
| 372 | const unsigned char *in, unsigned int inl) | 356 | const unsigned char *in, size_t inl) |
| 373 | { | 357 | { |
| 374 | struct crypt_op cryp; | 358 | struct crypt_op cryp; |
| 375 | struct dev_crypto_state *state = ctx->cipher_data; | 359 | struct dev_crypto_state *state = ctx->cipher_data; |
| 376 | struct session_op *sess = &state->d_sess; | 360 | struct session_op *sess = &state->d_sess; |
| 377 | void *iiv; | 361 | const void *iiv; |
| 378 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | 362 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; |
| 379 | 363 | ||
| 380 | if (state->d_fd < 0) | 364 | if (state->d_fd < 0) |
| @@ -398,7 +382,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
| 398 | if (ctx->cipher->iv_len) { | 382 | if (ctx->cipher->iv_len) { |
| 399 | cryp.iv = (caddr_t) ctx->iv; | 383 | cryp.iv = (caddr_t) ctx->iv; |
| 400 | if (!ctx->encrypt) { | 384 | if (!ctx->encrypt) { |
| 401 | iiv = (void *) in + inl - ctx->cipher->iv_len; | 385 | iiv = in + inl - ctx->cipher->iv_len; |
| 402 | memcpy(save_iv, iiv, ctx->cipher->iv_len); | 386 | memcpy(save_iv, iiv, ctx->cipher->iv_len); |
| 403 | } | 387 | } |
| 404 | } else | 388 | } else |
| @@ -413,7 +397,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
| 413 | 397 | ||
| 414 | if (ctx->cipher->iv_len) { | 398 | if (ctx->cipher->iv_len) { |
| 415 | if (ctx->encrypt) | 399 | if (ctx->encrypt) |
| 416 | iiv = (void *) out + inl - ctx->cipher->iv_len; | 400 | iiv = out + inl - ctx->cipher->iv_len; |
| 417 | else | 401 | else |
| 418 | iiv = save_iv; | 402 | iiv = save_iv; |
| 419 | memcpy(ctx->iv, iiv, ctx->cipher->iv_len); | 403 | memcpy(ctx->iv, iiv, ctx->cipher->iv_len); |
| @@ -427,23 +411,27 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
| 427 | { | 411 | { |
| 428 | struct dev_crypto_state *state = ctx->cipher_data; | 412 | struct dev_crypto_state *state = ctx->cipher_data; |
| 429 | struct session_op *sess = &state->d_sess; | 413 | struct session_op *sess = &state->d_sess; |
| 430 | int cipher; | 414 | int cipher = -1, i; |
| 431 | 415 | ||
| 432 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) | 416 | for (i = 0; ciphers[i].id; i++) |
| 433 | return (0); | 417 | if (ctx->cipher->nid == ciphers[i].nid && |
| 434 | 418 | ctx->cipher->iv_len <= ciphers[i].ivmax && | |
| 435 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) | 419 | ctx->key_len == ciphers[i].keylen) { |
| 436 | return (0); | 420 | cipher = ciphers[i].id; |
| 421 | break; | ||
| 422 | } | ||
| 437 | 423 | ||
| 438 | if (!cryptodev_key_length_valid(cipher, ctx->key_len)) | 424 | if (!ciphers[i].id) { |
| 425 | state->d_fd = -1; | ||
| 439 | return (0); | 426 | return (0); |
| 427 | } | ||
| 440 | 428 | ||
| 441 | memset(sess, 0, sizeof(struct session_op)); | 429 | memset(sess, 0, sizeof(struct session_op)); |
| 442 | 430 | ||
| 443 | if ((state->d_fd = get_dev_crypto()) < 0) | 431 | if ((state->d_fd = get_dev_crypto()) < 0) |
| 444 | return (0); | 432 | return (0); |
| 445 | 433 | ||
| 446 | sess->key = (unsigned char *)key; | 434 | sess->key = (caddr_t)key; |
| 447 | sess->keylen = ctx->key_len; | 435 | sess->keylen = ctx->key_len; |
| 448 | sess->cipher = cipher; | 436 | sess->cipher = cipher; |
| 449 | 437 | ||
| @@ -496,6 +484,20 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
| 496 | * gets called when libcrypto requests a cipher NID. | 484 | * gets called when libcrypto requests a cipher NID. |
| 497 | */ | 485 | */ |
| 498 | 486 | ||
| 487 | /* RC4 */ | ||
| 488 | const EVP_CIPHER cryptodev_rc4 = { | ||
| 489 | NID_rc4, | ||
| 490 | 1, 16, 0, | ||
| 491 | EVP_CIPH_VARIABLE_LENGTH, | ||
| 492 | cryptodev_init_key, | ||
| 493 | cryptodev_cipher, | ||
| 494 | cryptodev_cleanup, | ||
| 495 | sizeof(struct dev_crypto_state), | ||
| 496 | NULL, | ||
| 497 | NULL, | ||
| 498 | NULL | ||
| 499 | }; | ||
| 500 | |||
| 499 | /* DES CBC EVP */ | 501 | /* DES CBC EVP */ |
| 500 | const EVP_CIPHER cryptodev_des_cbc = { | 502 | const EVP_CIPHER cryptodev_des_cbc = { |
| 501 | NID_des_cbc, | 503 | NID_des_cbc, |
| @@ -563,6 +565,32 @@ const EVP_CIPHER cryptodev_aes_cbc = { | |||
| 563 | NULL | 565 | NULL |
| 564 | }; | 566 | }; |
| 565 | 567 | ||
| 568 | const EVP_CIPHER cryptodev_aes_192_cbc = { | ||
| 569 | NID_aes_192_cbc, | ||
| 570 | 16, 24, 16, | ||
| 571 | EVP_CIPH_CBC_MODE, | ||
| 572 | cryptodev_init_key, | ||
| 573 | cryptodev_cipher, | ||
| 574 | cryptodev_cleanup, | ||
| 575 | sizeof(struct dev_crypto_state), | ||
| 576 | EVP_CIPHER_set_asn1_iv, | ||
| 577 | EVP_CIPHER_get_asn1_iv, | ||
| 578 | NULL | ||
| 579 | }; | ||
| 580 | |||
| 581 | const EVP_CIPHER cryptodev_aes_256_cbc = { | ||
| 582 | NID_aes_256_cbc, | ||
| 583 | 16, 32, 16, | ||
| 584 | EVP_CIPH_CBC_MODE, | ||
| 585 | cryptodev_init_key, | ||
| 586 | cryptodev_cipher, | ||
| 587 | cryptodev_cleanup, | ||
| 588 | sizeof(struct dev_crypto_state), | ||
| 589 | EVP_CIPHER_set_asn1_iv, | ||
| 590 | EVP_CIPHER_get_asn1_iv, | ||
| 591 | NULL | ||
| 592 | }; | ||
| 593 | |||
| 566 | /* | 594 | /* |
| 567 | * Registered by the ENGINE when used to find out how to deal with | 595 | * Registered by the ENGINE when used to find out how to deal with |
| 568 | * a particular NID in the ENGINE. this says what we'll do at the | 596 | * a particular NID in the ENGINE. this says what we'll do at the |
| @@ -576,6 +604,9 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
| 576 | return (cryptodev_usable_ciphers(nids)); | 604 | return (cryptodev_usable_ciphers(nids)); |
| 577 | 605 | ||
| 578 | switch (nid) { | 606 | switch (nid) { |
| 607 | case NID_rc4: | ||
| 608 | *cipher = &cryptodev_rc4; | ||
| 609 | break; | ||
| 579 | case NID_des_ede3_cbc: | 610 | case NID_des_ede3_cbc: |
| 580 | *cipher = &cryptodev_3des_cbc; | 611 | *cipher = &cryptodev_3des_cbc; |
| 581 | break; | 612 | break; |
| @@ -591,6 +622,12 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
| 591 | case NID_aes_128_cbc: | 622 | case NID_aes_128_cbc: |
| 592 | *cipher = &cryptodev_aes_cbc; | 623 | *cipher = &cryptodev_aes_cbc; |
| 593 | break; | 624 | break; |
| 625 | case NID_aes_192_cbc: | ||
| 626 | *cipher = &cryptodev_aes_192_cbc; | ||
| 627 | break; | ||
| 628 | case NID_aes_256_cbc: | ||
| 629 | *cipher = &cryptodev_aes_256_cbc; | ||
| 630 | break; | ||
| 594 | default: | 631 | default: |
| 595 | *cipher = NULL; | 632 | *cipher = NULL; |
| 596 | break; | 633 | break; |
| @@ -598,6 +635,234 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
| 598 | return (*cipher != NULL); | 635 | return (*cipher != NULL); |
| 599 | } | 636 | } |
| 600 | 637 | ||
| 638 | |||
| 639 | #ifdef USE_CRYPTODEV_DIGESTS | ||
| 640 | |||
| 641 | /* convert digest type to cryptodev */ | ||
| 642 | static int | ||
| 643 | digest_nid_to_cryptodev(int nid) | ||
| 644 | { | ||
| 645 | int i; | ||
| 646 | |||
| 647 | for (i = 0; digests[i].id; i++) | ||
| 648 | if (digests[i].nid == nid) | ||
| 649 | return (digests[i].id); | ||
| 650 | return (0); | ||
| 651 | } | ||
| 652 | |||
| 653 | |||
| 654 | static int | ||
| 655 | digest_key_length(int nid) | ||
| 656 | { | ||
| 657 | int i; | ||
| 658 | |||
| 659 | for (i = 0; digests[i].id; i++) | ||
| 660 | if (digests[i].nid == nid) | ||
| 661 | return digests[i].keylen; | ||
| 662 | return (0); | ||
| 663 | } | ||
| 664 | |||
| 665 | |||
| 666 | static int cryptodev_digest_init(EVP_MD_CTX *ctx) | ||
| 667 | { | ||
| 668 | struct dev_crypto_state *state = ctx->md_data; | ||
| 669 | struct session_op *sess = &state->d_sess; | ||
| 670 | int digest; | ||
| 671 | |||
| 672 | if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){ | ||
| 673 | printf("cryptodev_digest_init: Can't get digest \n"); | ||
| 674 | return (0); | ||
| 675 | } | ||
| 676 | |||
| 677 | memset(state, 0, sizeof(struct dev_crypto_state)); | ||
| 678 | |||
| 679 | if ((state->d_fd = get_dev_crypto()) < 0) { | ||
| 680 | printf("cryptodev_digest_init: Can't get Dev \n"); | ||
| 681 | return (0); | ||
| 682 | } | ||
| 683 | |||
| 684 | sess->mackey = state->dummy_mac_key; | ||
| 685 | sess->mackeylen = digest_key_length(ctx->digest->type); | ||
| 686 | sess->mac = digest; | ||
| 687 | |||
| 688 | if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { | ||
| 689 | close(state->d_fd); | ||
| 690 | state->d_fd = -1; | ||
| 691 | printf("cryptodev_digest_init: Open session failed\n"); | ||
| 692 | return (0); | ||
| 693 | } | ||
| 694 | |||
| 695 | return (1); | ||
| 696 | } | ||
| 697 | |||
| 698 | static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, | ||
| 699 | size_t count) | ||
| 700 | { | ||
| 701 | struct crypt_op cryp; | ||
| 702 | struct dev_crypto_state *state = ctx->md_data; | ||
| 703 | struct session_op *sess = &state->d_sess; | ||
| 704 | |||
| 705 | if (!data || state->d_fd < 0) { | ||
| 706 | printf("cryptodev_digest_update: illegal inputs \n"); | ||
| 707 | return (0); | ||
| 708 | } | ||
| 709 | |||
| 710 | if (!count) { | ||
| 711 | return (0); | ||
| 712 | } | ||
| 713 | |||
| 714 | if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { | ||
| 715 | /* if application doesn't support one buffer */ | ||
| 716 | state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); | ||
| 717 | |||
| 718 | if (!state->mac_data) { | ||
| 719 | printf("cryptodev_digest_update: realloc failed\n"); | ||
| 720 | return (0); | ||
| 721 | } | ||
| 722 | |||
| 723 | memcpy(state->mac_data + state->mac_len, data, count); | ||
| 724 | state->mac_len += count; | ||
| 725 | |||
| 726 | return (1); | ||
| 727 | } | ||
| 728 | |||
| 729 | memset(&cryp, 0, sizeof(cryp)); | ||
| 730 | |||
| 731 | cryp.ses = sess->ses; | ||
| 732 | cryp.flags = 0; | ||
| 733 | cryp.len = count; | ||
| 734 | cryp.src = (caddr_t) data; | ||
| 735 | cryp.dst = NULL; | ||
| 736 | cryp.mac = (caddr_t) state->digest_res; | ||
| 737 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { | ||
| 738 | printf("cryptodev_digest_update: digest failed\n"); | ||
| 739 | return (0); | ||
| 740 | } | ||
| 741 | return (1); | ||
| 742 | } | ||
| 743 | |||
| 744 | |||
| 745 | static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) | ||
| 746 | { | ||
| 747 | struct crypt_op cryp; | ||
| 748 | struct dev_crypto_state *state = ctx->md_data; | ||
| 749 | struct session_op *sess = &state->d_sess; | ||
| 750 | |||
| 751 | int ret = 1; | ||
| 752 | |||
| 753 | if (!md || state->d_fd < 0) { | ||
| 754 | printf("cryptodev_digest_final: illegal input\n"); | ||
| 755 | return(0); | ||
| 756 | } | ||
| 757 | |||
| 758 | if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) { | ||
| 759 | /* if application doesn't support one buffer */ | ||
| 760 | memset(&cryp, 0, sizeof(cryp)); | ||
| 761 | |||
| 762 | cryp.ses = sess->ses; | ||
| 763 | cryp.flags = 0; | ||
| 764 | cryp.len = state->mac_len; | ||
| 765 | cryp.src = state->mac_data; | ||
| 766 | cryp.dst = NULL; | ||
| 767 | cryp.mac = (caddr_t)md; | ||
| 768 | |||
| 769 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { | ||
| 770 | printf("cryptodev_digest_final: digest failed\n"); | ||
| 771 | return (0); | ||
| 772 | } | ||
| 773 | |||
| 774 | return 1; | ||
| 775 | } | ||
| 776 | |||
| 777 | memcpy(md, state->digest_res, ctx->digest->md_size); | ||
| 778 | |||
| 779 | return (ret); | ||
| 780 | } | ||
| 781 | |||
| 782 | |||
| 783 | static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) | ||
| 784 | { | ||
| 785 | int ret = 1; | ||
| 786 | struct dev_crypto_state *state = ctx->md_data; | ||
| 787 | struct session_op *sess = &state->d_sess; | ||
| 788 | |||
| 789 | if (state->d_fd < 0) { | ||
| 790 | printf("cryptodev_digest_cleanup: illegal input\n"); | ||
| 791 | return (0); | ||
| 792 | } | ||
| 793 | |||
| 794 | if (state->mac_data) { | ||
| 795 | OPENSSL_free(state->mac_data); | ||
| 796 | state->mac_data = NULL; | ||
| 797 | state->mac_len = 0; | ||
| 798 | } | ||
| 799 | |||
| 800 | if (state->copy) | ||
| 801 | return 1; | ||
| 802 | |||
| 803 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { | ||
| 804 | printf("cryptodev_digest_cleanup: failed to close session\n"); | ||
| 805 | ret = 0; | ||
| 806 | } else { | ||
| 807 | ret = 1; | ||
| 808 | } | ||
| 809 | close(state->d_fd); | ||
| 810 | state->d_fd = -1; | ||
| 811 | |||
| 812 | return (ret); | ||
| 813 | } | ||
| 814 | |||
| 815 | static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) | ||
| 816 | { | ||
| 817 | struct dev_crypto_state *fstate = from->md_data; | ||
| 818 | struct dev_crypto_state *dstate = to->md_data; | ||
| 819 | |||
| 820 | memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); | ||
| 821 | |||
| 822 | if (fstate->mac_len != 0) { | ||
| 823 | dstate->mac_data = OPENSSL_malloc(fstate->mac_len); | ||
| 824 | memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); | ||
| 825 | } | ||
| 826 | |||
| 827 | dstate->copy = 1; | ||
| 828 | |||
| 829 | return 1; | ||
| 830 | } | ||
| 831 | |||
| 832 | |||
| 833 | const EVP_MD cryptodev_sha1 = { | ||
| 834 | NID_sha1, | ||
| 835 | NID_undef, | ||
| 836 | SHA_DIGEST_LENGTH, | ||
| 837 | EVP_MD_FLAG_ONESHOT, | ||
| 838 | cryptodev_digest_init, | ||
| 839 | cryptodev_digest_update, | ||
| 840 | cryptodev_digest_final, | ||
| 841 | cryptodev_digest_copy, | ||
| 842 | cryptodev_digest_cleanup, | ||
| 843 | EVP_PKEY_NULL_method, | ||
| 844 | SHA_CBLOCK, | ||
| 845 | sizeof(struct dev_crypto_state), | ||
| 846 | }; | ||
| 847 | |||
| 848 | const EVP_MD cryptodev_md5 = { | ||
| 849 | NID_md5, | ||
| 850 | NID_undef, | ||
| 851 | 16 /* MD5_DIGEST_LENGTH */, | ||
| 852 | EVP_MD_FLAG_ONESHOT, | ||
| 853 | cryptodev_digest_init, | ||
| 854 | cryptodev_digest_update, | ||
| 855 | cryptodev_digest_final, | ||
| 856 | cryptodev_digest_copy, | ||
| 857 | cryptodev_digest_cleanup, | ||
| 858 | EVP_PKEY_NULL_method, | ||
| 859 | 64 /* MD5_CBLOCK */, | ||
| 860 | sizeof(struct dev_crypto_state), | ||
| 861 | }; | ||
| 862 | |||
| 863 | #endif /* USE_CRYPTODEV_DIGESTS */ | ||
| 864 | |||
| 865 | |||
| 601 | static int | 866 | static int |
| 602 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | 867 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, |
| 603 | const int **nids, int nid) | 868 | const int **nids, int nid) |
| @@ -606,10 +871,15 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
| 606 | return (cryptodev_usable_digests(nids)); | 871 | return (cryptodev_usable_digests(nids)); |
| 607 | 872 | ||
| 608 | switch (nid) { | 873 | switch (nid) { |
| 874 | #ifdef USE_CRYPTODEV_DIGESTS | ||
| 609 | case NID_md5: | 875 | case NID_md5: |
| 610 | *digest = NULL; /* need to make a clean md5 critter */ | 876 | *digest = &cryptodev_md5; |
| 611 | break; | 877 | break; |
| 878 | case NID_sha1: | ||
| 879 | *digest = &cryptodev_sha1; | ||
| 880 | break; | ||
| 612 | default: | 881 | default: |
| 882 | #endif /* USE_CRYPTODEV_DIGESTS */ | ||
| 613 | *digest = NULL; | 883 | *digest = NULL; |
| 614 | break; | 884 | break; |
| 615 | } | 885 | } |
| @@ -625,7 +895,7 @@ static int | |||
| 625 | bn2crparam(const BIGNUM *a, struct crparam *crp) | 895 | bn2crparam(const BIGNUM *a, struct crparam *crp) |
| 626 | { | 896 | { |
| 627 | int i, j, k; | 897 | int i, j, k; |
| 628 | ssize_t words, bytes, bits; | 898 | ssize_t bytes, bits; |
| 629 | u_char *b; | 899 | u_char *b; |
| 630 | 900 | ||
| 631 | crp->crp_p = NULL; | 901 | crp->crp_p = NULL; |
| @@ -637,8 +907,9 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
| 637 | b = malloc(bytes); | 907 | b = malloc(bytes); |
| 638 | if (b == NULL) | 908 | if (b == NULL) |
| 639 | return (1); | 909 | return (1); |
| 910 | memset(b, 0, bytes); | ||
| 640 | 911 | ||
| 641 | crp->crp_p = b; | 912 | crp->crp_p = (caddr_t) b; |
| 642 | crp->crp_nbits = bits; | 913 | crp->crp_nbits = bits; |
| 643 | 914 | ||
| 644 | for (i = 0, j = 0; i < a->top; i++) { | 915 | for (i = 0, j = 0; i < a->top; i++) { |
| @@ -681,7 +952,7 @@ zapparams(struct crypt_kop *kop) | |||
| 681 | { | 952 | { |
| 682 | int i; | 953 | int i; |
| 683 | 954 | ||
| 684 | for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) { | 955 | for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { |
| 685 | if (kop->crk_param[i].crp_p) | 956 | if (kop->crk_param[i].crp_p) |
| 686 | free(kop->crk_param[i].crp_p); | 957 | free(kop->crk_param[i].crp_p); |
| 687 | kop->crk_param[i].crp_p = NULL; | 958 | kop->crk_param[i].crp_p = NULL; |
| @@ -746,21 +1017,27 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
| 746 | goto err; | 1017 | goto err; |
| 747 | kop.crk_iparams = 3; | 1018 | kop.crk_iparams = 3; |
| 748 | 1019 | ||
| 749 | if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) { | 1020 | if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { |
| 1021 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | ||
| 1022 | printf("OCF asym process failed, Running in software\n"); | ||
| 1023 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | ||
| 1024 | |||
| 1025 | } else if (ECANCELED == kop.crk_status) { | ||
| 750 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | 1026 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
| 1027 | printf("OCF hardware operation cancelled. Running in Software\n"); | ||
| 751 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | 1028 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); |
| 752 | } | 1029 | } |
| 1030 | /* else cryptodev operation worked ok ==> ret = 1*/ | ||
| 1031 | |||
| 753 | err: | 1032 | err: |
| 754 | zapparams(&kop); | 1033 | zapparams(&kop); |
| 755 | return (ret); | 1034 | return (ret); |
| 756 | } | 1035 | } |
| 757 | 1036 | ||
| 758 | static int | 1037 | static int |
| 759 | cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | 1038 | cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) |
| 760 | { | 1039 | { |
| 761 | int r; | 1040 | int r; |
| 762 | BN_CTX *ctx; | ||
| 763 | |||
| 764 | ctx = BN_CTX_new(); | 1041 | ctx = BN_CTX_new(); |
| 765 | r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); | 1042 | r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); |
| 766 | BN_CTX_free(ctx); | 1043 | BN_CTX_free(ctx); |
| @@ -795,10 +1072,18 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) | |||
| 795 | goto err; | 1072 | goto err; |
| 796 | kop.crk_iparams = 6; | 1073 | kop.crk_iparams = 6; |
| 797 | 1074 | ||
| 798 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { | 1075 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { |
| 1076 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | ||
| 1077 | printf("OCF asym process failed, running in Software\n"); | ||
| 1078 | ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); | ||
| 1079 | |||
| 1080 | } else if (ECANCELED == kop.crk_status) { | ||
| 799 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | 1081 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
| 1082 | printf("OCF hardware operation cancelled. Running in Software\n"); | ||
| 800 | ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); | 1083 | ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx); |
| 801 | } | 1084 | } |
| 1085 | /* else cryptodev operation worked ok ==> ret = 1*/ | ||
| 1086 | |||
| 802 | err: | 1087 | err: |
| 803 | zapparams(&kop); | 1088 | zapparams(&kop); |
| 804 | return (ret); | 1089 | return (ret); |
| @@ -934,7 +1219,8 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
| 934 | kop.crk_iparams = 7; | 1219 | kop.crk_iparams = 7; |
| 935 | 1220 | ||
| 936 | if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { | 1221 | if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { |
| 937 | dsaret = kop.crk_status; | 1222 | /*OCF success value is 0, if not zero, change dsaret to fail*/ |
| 1223 | if(0 != kop.crk_status) dsaret = 0; | ||
| 938 | } else { | 1224 | } else { |
| 939 | const DSA_METHOD *meth = DSA_OpenSSL(); | 1225 | const DSA_METHOD *meth = DSA_OpenSSL(); |
| 940 | 1226 | ||
| @@ -994,7 +1280,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
| 994 | goto err; | 1280 | goto err; |
| 995 | kop.crk_iparams = 3; | 1281 | kop.crk_iparams = 3; |
| 996 | 1282 | ||
| 997 | kop.crk_param[3].crp_p = key; | 1283 | kop.crk_param[3].crp_p = (caddr_t) key; |
| 998 | kop.crk_param[3].crp_nbits = keylen * 8; | 1284 | kop.crk_param[3].crp_nbits = keylen * 8; |
| 999 | kop.crk_oparams = 1; | 1285 | kop.crk_oparams = 1; |
| 1000 | 1286 | ||
| @@ -1025,7 +1311,7 @@ static DH_METHOD cryptodev_dh = { | |||
| 1025 | * but I expect we'll want some options soon. | 1311 | * but I expect we'll want some options soon. |
| 1026 | */ | 1312 | */ |
| 1027 | static int | 1313 | static int |
| 1028 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | 1314 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) |
| 1029 | { | 1315 | { |
| 1030 | #ifdef HAVE_SYSLOG_R | 1316 | #ifdef HAVE_SYSLOG_R |
| 1031 | struct syslog_data sd = SYSLOG_DATA_INIT; | 1317 | struct syslog_data sd = SYSLOG_DATA_INIT; |
