diff options
author | markus <> | 2002-06-13 18:37:32 +0000 |
---|---|---|
committer | markus <> | 2002-06-13 18:37:32 +0000 |
commit | 09ca6e6de39071310c47c09e4134588c92defcc3 (patch) | |
tree | ab84eb80d7fb6cef33314c74189fbcbb68e32595 /src/lib | |
parent | 9786c374f07e9e37fbda76ceae248529a5fbaabc (diff) | |
download | openbsd-09ca6e6de39071310c47c09e4134588c92defcc3.tar.gz openbsd-09ca6e6de39071310c47c09e4134588c92defcc3.tar.bz2 openbsd-09ca6e6de39071310c47c09e4134588c92defcc3.zip |
keep a FD per EVP_init, use a global FD for all asym operations;
ok beck@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/engine/hw_cryptodev.c | 168 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/engine/hw_cryptodev.c | 168 |
2 files changed, 170 insertions, 166 deletions
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c index d58c25ae9a..84b245e49f 100644 --- a/src/lib/libcrypto/engine/hw_cryptodev.c +++ b/src/lib/libcrypto/engine/hw_cryptodev.c | |||
@@ -45,8 +45,11 @@ | |||
45 | #include <errno.h> | 45 | #include <errno.h> |
46 | #include <string.h> | 46 | #include <string.h> |
47 | 47 | ||
48 | static int cryptodev_fd = -1; | 48 | struct dev_crypto_state { |
49 | static int cryptodev_sessions = 0; | 49 | struct session_op d_sess; |
50 | int d_fd; | ||
51 | }; | ||
52 | |||
50 | static u_int32_t cryptodev_asymfeat = 0; | 53 | static u_int32_t cryptodev_asymfeat = 0; |
51 | 54 | ||
52 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); | 55 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); |
@@ -106,31 +109,38 @@ static struct { | |||
106 | }; | 109 | }; |
107 | 110 | ||
108 | /* | 111 | /* |
109 | * Return 1 if /dev/crypto seems usable, 0 otherwise , also | 112 | * Return a fd if /dev/crypto seems usable, 0 otherwise. |
110 | * does most of the work of initting the device, if not already | ||
111 | * done.. This should leave is with global fd initialized with CRIOGET. | ||
112 | */ | 113 | */ |
113 | static int | 114 | static int |
114 | check_dev_crypto() | 115 | get_dev_crypto() |
115 | { | 116 | { |
116 | int fd; | 117 | int fd, retfd; |
117 | 118 | ||
118 | if (cryptodev_fd == -1) { | 119 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) |
119 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) | 120 | return (-1); |
120 | return (0); | 121 | if (ioctl(fd, CRIOGET, &retfd) == -1) { |
121 | if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { | ||
122 | close(fd); | ||
123 | return (0); | ||
124 | } | ||
125 | close(fd); | 122 | close(fd); |
126 | /* close on exec */ | 123 | return (-1); |
127 | if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { | ||
128 | close(cryptodev_fd); | ||
129 | cryptodev_fd = -1; | ||
130 | return (0); | ||
131 | } | ||
132 | } | 124 | } |
133 | return (1); | 125 | close(fd); |
126 | |||
127 | /* close on exec */ | ||
128 | if (fcntl(retfd, F_SETFD, 1) == -1) { | ||
129 | close(retfd); | ||
130 | return (-1); | ||
131 | } | ||
132 | return (retfd); | ||
133 | } | ||
134 | |||
135 | /* Caching version for asym operations */ | ||
136 | static int | ||
137 | get_asym_dev_crypto() | ||
138 | { | ||
139 | static int fd = -1; | ||
140 | |||
141 | if (fd == -1) | ||
142 | fd = get_dev_crypto(); | ||
143 | return fd; | ||
134 | } | 144 | } |
135 | 145 | ||
136 | /* | 146 | /* |
@@ -188,8 +198,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
188 | { | 198 | { |
189 | static int nids[CRYPTO_ALGORITHM_MAX]; | 199 | static int nids[CRYPTO_ALGORITHM_MAX]; |
190 | struct session_op sess; | 200 | struct session_op sess; |
191 | int i, count = 0; | 201 | int fd, i, count = 0; |
192 | 202 | ||
203 | if ((fd = get_dev_crypto()) < 0) { | ||
204 | *nids = NULL; | ||
205 | return (0); | ||
206 | } | ||
193 | memset(&sess, 0, sizeof(sess)); | 207 | memset(&sess, 0, sizeof(sess)); |
194 | sess.key = (caddr_t)"123456781234567812345678"; | 208 | sess.key = (caddr_t)"123456781234567812345678"; |
195 | 209 | ||
@@ -199,10 +213,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
199 | sess.cipher = ciphers[i].id; | 213 | sess.cipher = ciphers[i].id; |
200 | sess.keylen = ciphers[i].keylen; | 214 | sess.keylen = ciphers[i].keylen; |
201 | sess.mac = 0; | 215 | sess.mac = 0; |
202 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 216 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
203 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 217 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
204 | nids[count++] = ciphers[i].nid; | 218 | nids[count++] = ciphers[i].nid; |
205 | } | 219 | } |
220 | close(fd); | ||
221 | |||
206 | if (count > 0) | 222 | if (count > 0) |
207 | *cnids = nids; | 223 | *cnids = nids; |
208 | else | 224 | else |
@@ -221,18 +237,24 @@ get_cryptodev_digests(const int **cnids) | |||
221 | { | 237 | { |
222 | static int nids[CRYPTO_ALGORITHM_MAX]; | 238 | static int nids[CRYPTO_ALGORITHM_MAX]; |
223 | struct session_op sess; | 239 | struct session_op sess; |
224 | int i, count = 0; | 240 | int fd, i, count = 0; |
225 | 241 | ||
242 | if ((fd = get_dev_crypto()) < 0) { | ||
243 | *nids = NULL; | ||
244 | return (0); | ||
245 | } | ||
226 | memset(&sess, 0, sizeof(sess)); | 246 | memset(&sess, 0, sizeof(sess)); |
227 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 247 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
228 | if (digests[i].nid == NID_undef) | 248 | if (digests[i].nid == NID_undef) |
229 | continue; | 249 | continue; |
230 | sess.mac = digests[i].id; | 250 | sess.mac = digests[i].id; |
231 | sess.cipher = 0; | 251 | sess.cipher = 0; |
232 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 252 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
233 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 253 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
234 | nids[count++] = digests[i].nid; | 254 | nids[count++] = digests[i].nid; |
235 | } | 255 | } |
256 | close(fd); | ||
257 | |||
236 | if (count > 0) | 258 | if (count > 0) |
237 | *cnids = nids; | 259 | *cnids = nids; |
238 | else | 260 | else |
@@ -264,31 +286,12 @@ get_cryptodev_digests(const int **cnids) | |||
264 | int | 286 | int |
265 | cryptodev_usable_ciphers(const int **nids) | 287 | cryptodev_usable_ciphers(const int **nids) |
266 | { | 288 | { |
267 | struct syslog_data sd = SYSLOG_DATA_INIT; | ||
268 | |||
269 | if (!check_dev_crypto()) { | ||
270 | *nids = NULL; | ||
271 | return (0); | ||
272 | } | ||
273 | |||
274 | /* find what the device can do. Unfortunately, we don't | ||
275 | * necessarily want all of these yet, because we aren't | ||
276 | * yet set up to do them | ||
277 | */ | ||
278 | return (get_cryptodev_ciphers(nids)); | 289 | return (get_cryptodev_ciphers(nids)); |
279 | |||
280 | /* | ||
281 | * find out what asymmetric crypto algorithms we support | ||
282 | */ | ||
283 | if (ioctl(cryptodev_fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | ||
284 | syslog_r(LOG_ERR, &sd, "CIOCASYMFEAT failed (%m)"); | ||
285 | } | ||
286 | } | 290 | } |
287 | 291 | ||
288 | int | 292 | int |
289 | cryptodev_usable_digests(const int **nids) | 293 | cryptodev_usable_digests(const int **nids) |
290 | { | 294 | { |
291 | #if 1 | ||
292 | /* | 295 | /* |
293 | * XXXX just disable all digests for now, because it sucks. | 296 | * XXXX just disable all digests for now, because it sucks. |
294 | * we need a better way to decide this - i.e. I may not | 297 | * we need a better way to decide this - i.e. I may not |
@@ -303,29 +306,20 @@ cryptodev_usable_digests(const int **nids) | |||
303 | */ | 306 | */ |
304 | *nids = NULL; | 307 | *nids = NULL; |
305 | return (0); | 308 | return (0); |
306 | #endif | ||
307 | |||
308 | if (!check_dev_crypto()) { | ||
309 | *nids = NULL; | ||
310 | return (0); | ||
311 | } | ||
312 | return (get_cryptodev_digests(nids)); | ||
313 | } | 309 | } |
314 | 310 | ||
315 | |||
316 | int | 311 | int |
317 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 312 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
318 | const unsigned char *in, unsigned int inl) | 313 | const unsigned char *in, unsigned int inl) |
319 | { | 314 | { |
320 | struct crypt_op cryp; | 315 | struct crypt_op cryp; |
321 | struct session_op *sess = ctx->cipher_data; | 316 | struct dev_crypto_state *state = ctx->cipher_data; |
317 | struct session_op *sess = &state->d_sess; | ||
322 | void *iiv; | 318 | void *iiv; |
323 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | 319 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; |
324 | struct syslog_data sd = SYSLOG_DATA_INIT; | 320 | struct syslog_data sd = SYSLOG_DATA_INIT; |
325 | 321 | ||
326 | if (cryptodev_fd == -1) | 322 | if (state->d_fd < 0) |
327 | return (0); | ||
328 | if (sess == NULL) | ||
329 | return (0); | 323 | return (0); |
330 | if (!inl) | 324 | if (!inl) |
331 | return (1); | 325 | return (1); |
@@ -352,7 +346,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
352 | } else | 346 | } else |
353 | cryp.iv = NULL; | 347 | cryp.iv = NULL; |
354 | 348 | ||
355 | if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { | 349 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { |
356 | /* XXX need better errror handling | 350 | /* XXX need better errror handling |
357 | * this can fail for a number of different reasons. | 351 | * this can fail for a number of different reasons. |
358 | */ | 352 | */ |
@@ -374,16 +368,14 @@ int | |||
374 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 368 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
375 | const unsigned char *iv, int enc) | 369 | const unsigned char *iv, int enc) |
376 | { | 370 | { |
377 | struct session_op *sess = ctx->cipher_data; | 371 | struct dev_crypto_state *state = ctx->cipher_data; |
372 | struct session_op *sess = &state->d_sess; | ||
378 | struct syslog_data sd = SYSLOG_DATA_INIT; | 373 | struct syslog_data sd = SYSLOG_DATA_INIT; |
379 | int cipher; | 374 | int cipher; |
380 | 375 | ||
381 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) | 376 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) |
382 | return (0); | 377 | return (0); |
383 | 378 | ||
384 | if (!check_dev_crypto()) | ||
385 | return (0); | ||
386 | |||
387 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) | 379 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) |
388 | return (0); | 380 | return (0); |
389 | 381 | ||
@@ -392,15 +384,20 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
392 | 384 | ||
393 | memset(sess, 0, sizeof(struct session_op)); | 385 | memset(sess, 0, sizeof(struct session_op)); |
394 | 386 | ||
387 | if ((state->d_fd = get_dev_crypto()) < 0) | ||
388 | return (0); | ||
389 | |||
395 | sess->key = (unsigned char *)key; | 390 | sess->key = (unsigned char *)key; |
396 | sess->keylen = ctx->key_len; | 391 | sess->keylen = ctx->key_len; |
397 | sess->cipher = cipher; | 392 | sess->cipher = cipher; |
398 | 393 | ||
399 | if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { | 394 | if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { |
400 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); | 395 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); |
396 | |||
397 | close(state->d_fd); | ||
398 | state->d_fd = -1; | ||
401 | return (0); | 399 | return (0); |
402 | } | 400 | } |
403 | cryptodev_sessions++; | ||
404 | return (1); | 401 | return (1); |
405 | } | 402 | } |
406 | 403 | ||
@@ -412,10 +409,11 @@ int | |||
412 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | 409 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) |
413 | { | 410 | { |
414 | int ret = 0; | 411 | int ret = 0; |
415 | struct session_op *sess = ctx->cipher_data; | 412 | struct dev_crypto_state *state = ctx->cipher_data; |
413 | struct session_op *sess = &state->d_sess; | ||
416 | struct syslog_data sd = SYSLOG_DATA_INIT; | 414 | struct syslog_data sd = SYSLOG_DATA_INIT; |
417 | 415 | ||
418 | if (sess == NULL) | 416 | if (state->d_fd < 0) |
419 | return (0); | 417 | return (0); |
420 | 418 | ||
421 | /* XXX if this ioctl fails, someting's wrong. the invoker | 419 | /* XXX if this ioctl fails, someting's wrong. the invoker |
@@ -429,17 +427,15 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
429 | * print messages to users of the library. hmm.. | 427 | * print messages to users of the library. hmm.. |
430 | */ | 428 | */ |
431 | 429 | ||
432 | if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { | 430 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { |
433 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); | 431 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); |
434 | ret = 0; | 432 | ret = 0; |
435 | } else { | 433 | } else { |
436 | cryptodev_sessions--; | ||
437 | ret = 1; | 434 | ret = 1; |
438 | } | 435 | } |
439 | if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { | 436 | close(state->d_fd); |
440 | close(cryptodev_fd); /* XXX should this be closed? */ | 437 | state->d_fd = -1; |
441 | cryptodev_fd = -1; | 438 | |
442 | } | ||
443 | return (ret); | 439 | return (ret); |
444 | } | 440 | } |
445 | 441 | ||
@@ -662,7 +658,10 @@ zapparams(struct crypt_kop *kop) | |||
662 | static int | 658 | static int |
663 | cryptodev_sym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) | 659 | cryptodev_sym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) |
664 | { | 660 | { |
665 | int ret = -1; | 661 | int fd, ret = -1; |
662 | |||
663 | if ((fd = get_asym_dev_crypto()) < 0) | ||
664 | return (ret); | ||
666 | 665 | ||
667 | if (r) { | 666 | if (r) { |
668 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); | 667 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); |
@@ -675,13 +674,14 @@ cryptodev_sym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) | |||
675 | kop->crk_oparams++; | 674 | kop->crk_oparams++; |
676 | } | 675 | } |
677 | 676 | ||
678 | if (ioctl(cryptodev_fd, CIOCKEY, kop) == 0) { | 677 | if (ioctl(fd, CIOCKEY, kop) == 0) { |
679 | if (r) | 678 | if (r) |
680 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); | 679 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); |
681 | if (s) | 680 | if (s) |
682 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); | 681 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); |
683 | ret = 0; | 682 | ret = 0; |
684 | } | 683 | } |
684 | |||
685 | return (ret); | 685 | return (ret); |
686 | } | 686 | } |
687 | 687 | ||
@@ -940,7 +940,10 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
940 | { | 940 | { |
941 | struct crypt_kop kop; | 941 | struct crypt_kop kop; |
942 | int dhret = 1; | 942 | int dhret = 1; |
943 | int keylen; | 943 | int fd, keylen; |
944 | |||
945 | if ((fd = get_asym_dev_crypto()) < 0) | ||
946 | return (-1); | ||
944 | 947 | ||
945 | keylen = BN_num_bits(dh->p); | 948 | keylen = BN_num_bits(dh->p); |
946 | 949 | ||
@@ -960,7 +963,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
960 | kop.crk_param[3].crp_nbits = keylen * 8; | 963 | kop.crk_param[3].crp_nbits = keylen * 8; |
961 | kop.crk_oparams = 1; | 964 | kop.crk_oparams = 1; |
962 | 965 | ||
963 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { | 966 | if (ioctl(fd, CIOCKEY, &kop) == -1) { |
964 | const DH_METHOD *meth = DH_OpenSSL(); | 967 | const DH_METHOD *meth = DH_OpenSSL(); |
965 | 968 | ||
966 | dhret = (meth->compute_key)(key, pub_key, dh); | 969 | dhret = (meth->compute_key)(key, pub_key, dh); |
@@ -1005,22 +1008,22 @@ ENGINE_load_cryptodev(void) | |||
1005 | { | 1008 | { |
1006 | ENGINE *engine = ENGINE_new(); | 1009 | ENGINE *engine = ENGINE_new(); |
1007 | struct syslog_data sd = SYSLOG_DATA_INIT; | 1010 | struct syslog_data sd = SYSLOG_DATA_INIT; |
1011 | int fd; | ||
1008 | 1012 | ||
1009 | if (engine == NULL) | 1013 | if (engine == NULL) |
1010 | return; | 1014 | return; |
1011 | 1015 | if ((fd = get_dev_crypto()) < 0) | |
1012 | |||
1013 | if (!check_dev_crypto()) { | ||
1014 | return; | 1016 | return; |
1015 | } | ||
1016 | 1017 | ||
1017 | /* | 1018 | /* |
1018 | * find out what asymmetric crypto algorithms we support | 1019 | * find out what asymmetric crypto algorithms we support |
1019 | */ | 1020 | */ |
1020 | if (ioctl(cryptodev_fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | 1021 | if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { |
1021 | syslog_r(LOG_ERR, &sd, "CIOCASYMFEAT failed (%m)"); | 1022 | syslog_r(LOG_ERR, &sd, "CIOCASYMFEAT failed (%m)"); |
1023 | close(fd); | ||
1022 | return; | 1024 | return; |
1023 | } | 1025 | } |
1026 | close(fd); | ||
1024 | 1027 | ||
1025 | if (!ENGINE_set_id(engine, "cryptodev") || | 1028 | if (!ENGINE_set_id(engine, "cryptodev") || |
1026 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || | 1029 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || |
@@ -1084,4 +1087,3 @@ ENGINE_load_cryptodev(void) | |||
1084 | ENGINE_free(engine); | 1087 | ENGINE_free(engine); |
1085 | ERR_clear_error(); | 1088 | ERR_clear_error(); |
1086 | } | 1089 | } |
1087 | |||
diff --git a/src/lib/libssl/src/crypto/engine/hw_cryptodev.c b/src/lib/libssl/src/crypto/engine/hw_cryptodev.c index d58c25ae9a..84b245e49f 100644 --- a/src/lib/libssl/src/crypto/engine/hw_cryptodev.c +++ b/src/lib/libssl/src/crypto/engine/hw_cryptodev.c | |||
@@ -45,8 +45,11 @@ | |||
45 | #include <errno.h> | 45 | #include <errno.h> |
46 | #include <string.h> | 46 | #include <string.h> |
47 | 47 | ||
48 | static int cryptodev_fd = -1; | 48 | struct dev_crypto_state { |
49 | static int cryptodev_sessions = 0; | 49 | struct session_op d_sess; |
50 | int d_fd; | ||
51 | }; | ||
52 | |||
50 | static u_int32_t cryptodev_asymfeat = 0; | 53 | static u_int32_t cryptodev_asymfeat = 0; |
51 | 54 | ||
52 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); | 55 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); |
@@ -106,31 +109,38 @@ static struct { | |||
106 | }; | 109 | }; |
107 | 110 | ||
108 | /* | 111 | /* |
109 | * Return 1 if /dev/crypto seems usable, 0 otherwise , also | 112 | * Return a fd if /dev/crypto seems usable, 0 otherwise. |
110 | * does most of the work of initting the device, if not already | ||
111 | * done.. This should leave is with global fd initialized with CRIOGET. | ||
112 | */ | 113 | */ |
113 | static int | 114 | static int |
114 | check_dev_crypto() | 115 | get_dev_crypto() |
115 | { | 116 | { |
116 | int fd; | 117 | int fd, retfd; |
117 | 118 | ||
118 | if (cryptodev_fd == -1) { | 119 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) |
119 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) | 120 | return (-1); |
120 | return (0); | 121 | if (ioctl(fd, CRIOGET, &retfd) == -1) { |
121 | if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { | ||
122 | close(fd); | ||
123 | return (0); | ||
124 | } | ||
125 | close(fd); | 122 | close(fd); |
126 | /* close on exec */ | 123 | return (-1); |
127 | if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { | ||
128 | close(cryptodev_fd); | ||
129 | cryptodev_fd = -1; | ||
130 | return (0); | ||
131 | } | ||
132 | } | 124 | } |
133 | return (1); | 125 | close(fd); |
126 | |||
127 | /* close on exec */ | ||
128 | if (fcntl(retfd, F_SETFD, 1) == -1) { | ||
129 | close(retfd); | ||
130 | return (-1); | ||
131 | } | ||
132 | return (retfd); | ||
133 | } | ||
134 | |||
135 | /* Caching version for asym operations */ | ||
136 | static int | ||
137 | get_asym_dev_crypto() | ||
138 | { | ||
139 | static int fd = -1; | ||
140 | |||
141 | if (fd == -1) | ||
142 | fd = get_dev_crypto(); | ||
143 | return fd; | ||
134 | } | 144 | } |
135 | 145 | ||
136 | /* | 146 | /* |
@@ -188,8 +198,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
188 | { | 198 | { |
189 | static int nids[CRYPTO_ALGORITHM_MAX]; | 199 | static int nids[CRYPTO_ALGORITHM_MAX]; |
190 | struct session_op sess; | 200 | struct session_op sess; |
191 | int i, count = 0; | 201 | int fd, i, count = 0; |
192 | 202 | ||
203 | if ((fd = get_dev_crypto()) < 0) { | ||
204 | *nids = NULL; | ||
205 | return (0); | ||
206 | } | ||
193 | memset(&sess, 0, sizeof(sess)); | 207 | memset(&sess, 0, sizeof(sess)); |
194 | sess.key = (caddr_t)"123456781234567812345678"; | 208 | sess.key = (caddr_t)"123456781234567812345678"; |
195 | 209 | ||
@@ -199,10 +213,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
199 | sess.cipher = ciphers[i].id; | 213 | sess.cipher = ciphers[i].id; |
200 | sess.keylen = ciphers[i].keylen; | 214 | sess.keylen = ciphers[i].keylen; |
201 | sess.mac = 0; | 215 | sess.mac = 0; |
202 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 216 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
203 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 217 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
204 | nids[count++] = ciphers[i].nid; | 218 | nids[count++] = ciphers[i].nid; |
205 | } | 219 | } |
220 | close(fd); | ||
221 | |||
206 | if (count > 0) | 222 | if (count > 0) |
207 | *cnids = nids; | 223 | *cnids = nids; |
208 | else | 224 | else |
@@ -221,18 +237,24 @@ get_cryptodev_digests(const int **cnids) | |||
221 | { | 237 | { |
222 | static int nids[CRYPTO_ALGORITHM_MAX]; | 238 | static int nids[CRYPTO_ALGORITHM_MAX]; |
223 | struct session_op sess; | 239 | struct session_op sess; |
224 | int i, count = 0; | 240 | int fd, i, count = 0; |
225 | 241 | ||
242 | if ((fd = get_dev_crypto()) < 0) { | ||
243 | *nids = NULL; | ||
244 | return (0); | ||
245 | } | ||
226 | memset(&sess, 0, sizeof(sess)); | 246 | memset(&sess, 0, sizeof(sess)); |
227 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 247 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
228 | if (digests[i].nid == NID_undef) | 248 | if (digests[i].nid == NID_undef) |
229 | continue; | 249 | continue; |
230 | sess.mac = digests[i].id; | 250 | sess.mac = digests[i].id; |
231 | sess.cipher = 0; | 251 | sess.cipher = 0; |
232 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 252 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
233 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 253 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
234 | nids[count++] = digests[i].nid; | 254 | nids[count++] = digests[i].nid; |
235 | } | 255 | } |
256 | close(fd); | ||
257 | |||
236 | if (count > 0) | 258 | if (count > 0) |
237 | *cnids = nids; | 259 | *cnids = nids; |
238 | else | 260 | else |
@@ -264,31 +286,12 @@ get_cryptodev_digests(const int **cnids) | |||
264 | int | 286 | int |
265 | cryptodev_usable_ciphers(const int **nids) | 287 | cryptodev_usable_ciphers(const int **nids) |
266 | { | 288 | { |
267 | struct syslog_data sd = SYSLOG_DATA_INIT; | ||
268 | |||
269 | if (!check_dev_crypto()) { | ||
270 | *nids = NULL; | ||
271 | return (0); | ||
272 | } | ||
273 | |||
274 | /* find what the device can do. Unfortunately, we don't | ||
275 | * necessarily want all of these yet, because we aren't | ||
276 | * yet set up to do them | ||
277 | */ | ||
278 | return (get_cryptodev_ciphers(nids)); | 289 | return (get_cryptodev_ciphers(nids)); |
279 | |||
280 | /* | ||
281 | * find out what asymmetric crypto algorithms we support | ||
282 | */ | ||
283 | if (ioctl(cryptodev_fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | ||
284 | syslog_r(LOG_ERR, &sd, "CIOCASYMFEAT failed (%m)"); | ||
285 | } | ||
286 | } | 290 | } |
287 | 291 | ||
288 | int | 292 | int |
289 | cryptodev_usable_digests(const int **nids) | 293 | cryptodev_usable_digests(const int **nids) |
290 | { | 294 | { |
291 | #if 1 | ||
292 | /* | 295 | /* |
293 | * XXXX just disable all digests for now, because it sucks. | 296 | * XXXX just disable all digests for now, because it sucks. |
294 | * we need a better way to decide this - i.e. I may not | 297 | * we need a better way to decide this - i.e. I may not |
@@ -303,29 +306,20 @@ cryptodev_usable_digests(const int **nids) | |||
303 | */ | 306 | */ |
304 | *nids = NULL; | 307 | *nids = NULL; |
305 | return (0); | 308 | return (0); |
306 | #endif | ||
307 | |||
308 | if (!check_dev_crypto()) { | ||
309 | *nids = NULL; | ||
310 | return (0); | ||
311 | } | ||
312 | return (get_cryptodev_digests(nids)); | ||
313 | } | 309 | } |
314 | 310 | ||
315 | |||
316 | int | 311 | int |
317 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 312 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
318 | const unsigned char *in, unsigned int inl) | 313 | const unsigned char *in, unsigned int inl) |
319 | { | 314 | { |
320 | struct crypt_op cryp; | 315 | struct crypt_op cryp; |
321 | struct session_op *sess = ctx->cipher_data; | 316 | struct dev_crypto_state *state = ctx->cipher_data; |
317 | struct session_op *sess = &state->d_sess; | ||
322 | void *iiv; | 318 | void *iiv; |
323 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | 319 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; |
324 | struct syslog_data sd = SYSLOG_DATA_INIT; | 320 | struct syslog_data sd = SYSLOG_DATA_INIT; |
325 | 321 | ||
326 | if (cryptodev_fd == -1) | 322 | if (state->d_fd < 0) |
327 | return (0); | ||
328 | if (sess == NULL) | ||
329 | return (0); | 323 | return (0); |
330 | if (!inl) | 324 | if (!inl) |
331 | return (1); | 325 | return (1); |
@@ -352,7 +346,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
352 | } else | 346 | } else |
353 | cryp.iv = NULL; | 347 | cryp.iv = NULL; |
354 | 348 | ||
355 | if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { | 349 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { |
356 | /* XXX need better errror handling | 350 | /* XXX need better errror handling |
357 | * this can fail for a number of different reasons. | 351 | * this can fail for a number of different reasons. |
358 | */ | 352 | */ |
@@ -374,16 +368,14 @@ int | |||
374 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 368 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
375 | const unsigned char *iv, int enc) | 369 | const unsigned char *iv, int enc) |
376 | { | 370 | { |
377 | struct session_op *sess = ctx->cipher_data; | 371 | struct dev_crypto_state *state = ctx->cipher_data; |
372 | struct session_op *sess = &state->d_sess; | ||
378 | struct syslog_data sd = SYSLOG_DATA_INIT; | 373 | struct syslog_data sd = SYSLOG_DATA_INIT; |
379 | int cipher; | 374 | int cipher; |
380 | 375 | ||
381 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) | 376 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) |
382 | return (0); | 377 | return (0); |
383 | 378 | ||
384 | if (!check_dev_crypto()) | ||
385 | return (0); | ||
386 | |||
387 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) | 379 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) |
388 | return (0); | 380 | return (0); |
389 | 381 | ||
@@ -392,15 +384,20 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
392 | 384 | ||
393 | memset(sess, 0, sizeof(struct session_op)); | 385 | memset(sess, 0, sizeof(struct session_op)); |
394 | 386 | ||
387 | if ((state->d_fd = get_dev_crypto()) < 0) | ||
388 | return (0); | ||
389 | |||
395 | sess->key = (unsigned char *)key; | 390 | sess->key = (unsigned char *)key; |
396 | sess->keylen = ctx->key_len; | 391 | sess->keylen = ctx->key_len; |
397 | sess->cipher = cipher; | 392 | sess->cipher = cipher; |
398 | 393 | ||
399 | if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { | 394 | if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { |
400 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); | 395 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); |
396 | |||
397 | close(state->d_fd); | ||
398 | state->d_fd = -1; | ||
401 | return (0); | 399 | return (0); |
402 | } | 400 | } |
403 | cryptodev_sessions++; | ||
404 | return (1); | 401 | return (1); |
405 | } | 402 | } |
406 | 403 | ||
@@ -412,10 +409,11 @@ int | |||
412 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | 409 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) |
413 | { | 410 | { |
414 | int ret = 0; | 411 | int ret = 0; |
415 | struct session_op *sess = ctx->cipher_data; | 412 | struct dev_crypto_state *state = ctx->cipher_data; |
413 | struct session_op *sess = &state->d_sess; | ||
416 | struct syslog_data sd = SYSLOG_DATA_INIT; | 414 | struct syslog_data sd = SYSLOG_DATA_INIT; |
417 | 415 | ||
418 | if (sess == NULL) | 416 | if (state->d_fd < 0) |
419 | return (0); | 417 | return (0); |
420 | 418 | ||
421 | /* XXX if this ioctl fails, someting's wrong. the invoker | 419 | /* XXX if this ioctl fails, someting's wrong. the invoker |
@@ -429,17 +427,15 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
429 | * print messages to users of the library. hmm.. | 427 | * print messages to users of the library. hmm.. |
430 | */ | 428 | */ |
431 | 429 | ||
432 | if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { | 430 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { |
433 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); | 431 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); |
434 | ret = 0; | 432 | ret = 0; |
435 | } else { | 433 | } else { |
436 | cryptodev_sessions--; | ||
437 | ret = 1; | 434 | ret = 1; |
438 | } | 435 | } |
439 | if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { | 436 | close(state->d_fd); |
440 | close(cryptodev_fd); /* XXX should this be closed? */ | 437 | state->d_fd = -1; |
441 | cryptodev_fd = -1; | 438 | |
442 | } | ||
443 | return (ret); | 439 | return (ret); |
444 | } | 440 | } |
445 | 441 | ||
@@ -662,7 +658,10 @@ zapparams(struct crypt_kop *kop) | |||
662 | static int | 658 | static int |
663 | cryptodev_sym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) | 659 | cryptodev_sym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) |
664 | { | 660 | { |
665 | int ret = -1; | 661 | int fd, ret = -1; |
662 | |||
663 | if ((fd = get_asym_dev_crypto()) < 0) | ||
664 | return (ret); | ||
666 | 665 | ||
667 | if (r) { | 666 | if (r) { |
668 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); | 667 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); |
@@ -675,13 +674,14 @@ cryptodev_sym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) | |||
675 | kop->crk_oparams++; | 674 | kop->crk_oparams++; |
676 | } | 675 | } |
677 | 676 | ||
678 | if (ioctl(cryptodev_fd, CIOCKEY, kop) == 0) { | 677 | if (ioctl(fd, CIOCKEY, kop) == 0) { |
679 | if (r) | 678 | if (r) |
680 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); | 679 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); |
681 | if (s) | 680 | if (s) |
682 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); | 681 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); |
683 | ret = 0; | 682 | ret = 0; |
684 | } | 683 | } |
684 | |||
685 | return (ret); | 685 | return (ret); |
686 | } | 686 | } |
687 | 687 | ||
@@ -940,7 +940,10 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
940 | { | 940 | { |
941 | struct crypt_kop kop; | 941 | struct crypt_kop kop; |
942 | int dhret = 1; | 942 | int dhret = 1; |
943 | int keylen; | 943 | int fd, keylen; |
944 | |||
945 | if ((fd = get_asym_dev_crypto()) < 0) | ||
946 | return (-1); | ||
944 | 947 | ||
945 | keylen = BN_num_bits(dh->p); | 948 | keylen = BN_num_bits(dh->p); |
946 | 949 | ||
@@ -960,7 +963,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
960 | kop.crk_param[3].crp_nbits = keylen * 8; | 963 | kop.crk_param[3].crp_nbits = keylen * 8; |
961 | kop.crk_oparams = 1; | 964 | kop.crk_oparams = 1; |
962 | 965 | ||
963 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { | 966 | if (ioctl(fd, CIOCKEY, &kop) == -1) { |
964 | const DH_METHOD *meth = DH_OpenSSL(); | 967 | const DH_METHOD *meth = DH_OpenSSL(); |
965 | 968 | ||
966 | dhret = (meth->compute_key)(key, pub_key, dh); | 969 | dhret = (meth->compute_key)(key, pub_key, dh); |
@@ -1005,22 +1008,22 @@ ENGINE_load_cryptodev(void) | |||
1005 | { | 1008 | { |
1006 | ENGINE *engine = ENGINE_new(); | 1009 | ENGINE *engine = ENGINE_new(); |
1007 | struct syslog_data sd = SYSLOG_DATA_INIT; | 1010 | struct syslog_data sd = SYSLOG_DATA_INIT; |
1011 | int fd; | ||
1008 | 1012 | ||
1009 | if (engine == NULL) | 1013 | if (engine == NULL) |
1010 | return; | 1014 | return; |
1011 | 1015 | if ((fd = get_dev_crypto()) < 0) | |
1012 | |||
1013 | if (!check_dev_crypto()) { | ||
1014 | return; | 1016 | return; |
1015 | } | ||
1016 | 1017 | ||
1017 | /* | 1018 | /* |
1018 | * find out what asymmetric crypto algorithms we support | 1019 | * find out what asymmetric crypto algorithms we support |
1019 | */ | 1020 | */ |
1020 | if (ioctl(cryptodev_fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | 1021 | if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { |
1021 | syslog_r(LOG_ERR, &sd, "CIOCASYMFEAT failed (%m)"); | 1022 | syslog_r(LOG_ERR, &sd, "CIOCASYMFEAT failed (%m)"); |
1023 | close(fd); | ||
1022 | return; | 1024 | return; |
1023 | } | 1025 | } |
1026 | close(fd); | ||
1024 | 1027 | ||
1025 | if (!ENGINE_set_id(engine, "cryptodev") || | 1028 | if (!ENGINE_set_id(engine, "cryptodev") || |
1026 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || | 1029 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || |
@@ -1084,4 +1087,3 @@ ENGINE_load_cryptodev(void) | |||
1084 | ENGINE_free(engine); | 1087 | ENGINE_free(engine); |
1085 | ERR_clear_error(); | 1088 | ERR_clear_error(); |
1086 | } | 1089 | } |
1087 | |||