diff options
author | djm <> | 2010-10-01 22:54:19 +0000 |
---|---|---|
committer | djm <> | 2010-10-01 22:54:19 +0000 |
commit | 6ddfb710ab14b10183ff3a6a32f643554c80065e (patch) | |
tree | 03b202b49e2c6367ae5dec12d939ea99c9ca36b3 /src/lib/libcrypto/engine/eng_cryptodev.c | |
parent | b204ac0374903f9d6a2fcc50cfd94578e357d00a (diff) | |
parent | 242690ab2a8e991b85b4735c4e0bac0ec7bd3481 (diff) | |
download | openbsd-6ddfb710ab14b10183ff3a6a32f643554c80065e.tar.gz openbsd-6ddfb710ab14b10183ff3a6a32f643554c80065e.tar.bz2 openbsd-6ddfb710ab14b10183ff3a6a32f643554c80065e.zip |
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
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; |