diff options
author | markus <> | 2003-05-11 21:36:59 +0000 |
---|---|---|
committer | markus <> | 2003-05-11 21:36:59 +0000 |
commit | 9cea7b85baecb1a02a3ea617de73d9693a9792eb (patch) | |
tree | b0ca83a03e35572831c5818cd2011868d462a5d1 /src/lib/libcrypto/engine/hw_cryptodev.c | |
parent | f8f1d7fabf136ce9810602509c477d2c42bf6d1c (diff) | |
download | openbsd-9cea7b85baecb1a02a3ea617de73d9693a9792eb.tar.gz openbsd-9cea7b85baecb1a02a3ea617de73d9693a9792eb.tar.bz2 openbsd-9cea7b85baecb1a02a3ea617de73d9693a9792eb.zip |
import 0.9.7b (without idea and rc5)
Diffstat (limited to 'src/lib/libcrypto/engine/hw_cryptodev.c')
-rw-r--r-- | src/lib/libcrypto/engine/hw_cryptodev.c | 540 |
1 files changed, 373 insertions, 167 deletions
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c index 7c3728f395..40af97ac24 100644 --- a/src/lib/libcrypto/engine/hw_cryptodev.c +++ b/src/lib/libcrypto/engine/hw_cryptodev.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2002 Bob Beck <beck@openbsd.org> | 2 | * Copyright (c) 2002 Bob Beck <beck@openbsd.org> |
3 | * Copyright (c) 2002 Theo de Raadt | 3 | * Copyright (c) 2002 Theo de Raadt |
4 | * Copyright (c) 2002 Markus Friedl | ||
4 | * All rights reserved. | 5 | * All rights reserved. |
5 | * | 6 | * |
6 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
@@ -28,33 +29,85 @@ | |||
28 | * | 29 | * |
29 | */ | 30 | */ |
30 | 31 | ||
31 | #include <sys/types.h> | 32 | #include <openssl/objects.h> |
33 | #include <openssl/engine.h> | ||
34 | #include <openssl/evp.h> | ||
35 | |||
36 | #if (defined(__unix__) || defined(unix)) && !defined(USG) | ||
32 | #include <sys/param.h> | 37 | #include <sys/param.h> |
38 | # if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) | ||
39 | # define HAVE_CRYPTODEV | ||
40 | # endif | ||
41 | # if (OpenBSD >= 200110) | ||
42 | # define HAVE_SYSLOG_R | ||
43 | # endif | ||
44 | #endif | ||
45 | |||
46 | #ifndef HAVE_CRYPTODEV | ||
47 | |||
48 | void | ||
49 | ENGINE_load_cryptodev(void) | ||
50 | { | ||
51 | /* This is a NOP on platforms without /dev/crypto */ | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | #else | ||
56 | |||
57 | #include <sys/types.h> | ||
33 | #include <crypto/cryptodev.h> | 58 | #include <crypto/cryptodev.h> |
34 | #include <sys/ioctl.h> | 59 | #include <sys/ioctl.h> |
35 | #include <errno.h> | 60 | #include <errno.h> |
36 | #include <stdio.h> | 61 | #include <stdio.h> |
37 | #include <unistd.h> | 62 | #include <unistd.h> |
38 | #include <fcntl.h> | 63 | #include <fcntl.h> |
39 | #include <syslog.h> | ||
40 | #include <stdarg.h> | 64 | #include <stdarg.h> |
41 | #include <ssl/objects.h> | 65 | #include <syslog.h> |
42 | #include <ssl/engine.h> | 66 | #include <errno.h> |
43 | #include <ssl/evp.h> | 67 | #include <string.h> |
44 | 68 | ||
45 | static int cryptodev_fd = -1; | 69 | struct dev_crypto_state { |
46 | static int cryptodev_sessions = 0; | 70 | struct session_op d_sess; |
47 | static u_int32_t cryptodev_symfeat = 0; | 71 | int d_fd; |
72 | }; | ||
48 | 73 | ||
74 | static u_int32_t cryptodev_asymfeat = 0; | ||
75 | |||
76 | static int get_asym_dev_crypto(void); | ||
77 | static int open_dev_crypto(void); | ||
78 | static int get_dev_crypto(void); | ||
79 | static int cryptodev_max_iv(int cipher); | ||
80 | static int cryptodev_key_length_valid(int cipher, int len); | ||
81 | static int cipher_nid_to_cryptodev(int nid); | ||
82 | static int get_cryptodev_ciphers(const int **cnids); | ||
83 | static int get_cryptodev_digests(const int **cnids); | ||
84 | static int cryptodev_usable_ciphers(const int **nids); | ||
85 | static int cryptodev_usable_digests(const int **nids); | ||
86 | static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
87 | const unsigned char *in, unsigned int inl); | ||
88 | static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
89 | const unsigned char *iv, int enc); | ||
90 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); | ||
91 | static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
92 | const int **nids, int nid); | ||
93 | static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | ||
94 | const int **nids, int nid); | ||
49 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); | 95 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); |
50 | static int crparam2bn(struct crparam *crp, BIGNUM *a); | 96 | static int crparam2bn(struct crparam *crp, BIGNUM *a); |
51 | static void zapparams(struct crypt_kop *kop); | 97 | static void zapparams(struct crypt_kop *kop); |
98 | static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, | ||
99 | int slen, BIGNUM *s); | ||
52 | 100 | ||
53 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); | ||
54 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, | 101 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, |
55 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | 102 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
103 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, | ||
104 | RSA *rsa); | ||
105 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); | ||
56 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, | 106 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, |
57 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | 107 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
108 | static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
109 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
110 | BN_CTX *ctx, BN_MONT_CTX *mont); | ||
58 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, | 111 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, |
59 | int dlen, DSA *dsa); | 112 | int dlen, DSA *dsa); |
60 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, | 113 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, |
@@ -64,6 +117,9 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | |||
64 | BN_MONT_CTX *m_ctx); | 117 | BN_MONT_CTX *m_ctx); |
65 | static int cryptodev_dh_compute_key(unsigned char *key, | 118 | static int cryptodev_dh_compute_key(unsigned char *key, |
66 | const BIGNUM *pub_key, DH *dh); | 119 | const BIGNUM *pub_key, DH *dh); |
120 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, | ||
121 | void (*f)()); | ||
122 | void ENGINE_load_cryptodev(void); | ||
67 | 123 | ||
68 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { | 124 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { |
69 | { 0, NULL, NULL, 0 } | 125 | { 0, NULL, NULL, 0 } |
@@ -77,11 +133,10 @@ static struct { | |||
77 | } ciphers[] = { | 133 | } ciphers[] = { |
78 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, | 134 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, |
79 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, | 135 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, |
80 | { CRYPTO_AES_CBC, NID_undef, 8, 24, }, | 136 | { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, |
81 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, | 137 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, |
82 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, }, | 138 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, |
83 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, | 139 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, |
84 | { CRYPTO_ARC4, NID_rc4, 8, 16, }, | ||
85 | { 0, NID_undef, 0, 0, }, | 140 | { 0, NID_undef, 0, 0, }, |
86 | }; | 141 | }; |
87 | 142 | ||
@@ -99,33 +154,53 @@ static struct { | |||
99 | }; | 154 | }; |
100 | 155 | ||
101 | /* | 156 | /* |
102 | * Return 1 if /dev/crypto seems usable, 0 otherwise , also | 157 | * Return a fd if /dev/crypto seems usable, 0 otherwise. |
103 | * does most of the work of initting the device, if not already | ||
104 | * done.. This should leave is with global fd initialized with CRIOGET. | ||
105 | */ | 158 | */ |
106 | static int | 159 | static int |
107 | check_dev_crypto() | 160 | open_dev_crypto(void) |
108 | { | 161 | { |
109 | int fd; | 162 | static int fd = -1; |
110 | 163 | ||
111 | if (cryptodev_fd == -1) { | 164 | if (fd == -1) { |
112 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) | 165 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) |
113 | return (0); | 166 | return (-1); |
114 | if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { | ||
115 | close(fd); | ||
116 | return (0); | ||
117 | } | ||
118 | close(fd); | ||
119 | /* close on exec */ | 167 | /* close on exec */ |
120 | if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { | 168 | if (fcntl(fd, F_SETFD, 1) == -1) { |
121 | close(cryptodev_fd); | 169 | close(fd); |
122 | cryptodev_fd = -1; | 170 | fd = -1; |
123 | return (0); | 171 | return (-1); |
124 | } | 172 | } |
125 | } | 173 | } |
126 | ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat); | 174 | return (fd); |
175 | } | ||
127 | 176 | ||
128 | return (1); | 177 | static int |
178 | get_dev_crypto(void) | ||
179 | { | ||
180 | int fd, retfd; | ||
181 | |||
182 | if ((fd = open_dev_crypto()) == -1) | ||
183 | return (-1); | ||
184 | if (ioctl(fd, CRIOGET, &retfd) == -1) | ||
185 | return (-1); | ||
186 | |||
187 | /* close on exec */ | ||
188 | if (fcntl(retfd, F_SETFD, 1) == -1) { | ||
189 | close(retfd); | ||
190 | return (-1); | ||
191 | } | ||
192 | return (retfd); | ||
193 | } | ||
194 | |||
195 | /* Caching version for asym operations */ | ||
196 | static int | ||
197 | get_asym_dev_crypto(void) | ||
198 | { | ||
199 | static int fd = -1; | ||
200 | |||
201 | if (fd == -1) | ||
202 | fd = get_dev_crypto(); | ||
203 | return fd; | ||
129 | } | 204 | } |
130 | 205 | ||
131 | /* | 206 | /* |
@@ -183,8 +258,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
183 | { | 258 | { |
184 | static int nids[CRYPTO_ALGORITHM_MAX]; | 259 | static int nids[CRYPTO_ALGORITHM_MAX]; |
185 | struct session_op sess; | 260 | struct session_op sess; |
186 | int i, count = 0; | 261 | int fd, i, count = 0; |
187 | 262 | ||
263 | if ((fd = get_dev_crypto()) < 0) { | ||
264 | *nids = NULL; | ||
265 | return (0); | ||
266 | } | ||
188 | memset(&sess, 0, sizeof(sess)); | 267 | memset(&sess, 0, sizeof(sess)); |
189 | sess.key = (caddr_t)"123456781234567812345678"; | 268 | sess.key = (caddr_t)"123456781234567812345678"; |
190 | 269 | ||
@@ -194,10 +273,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
194 | sess.cipher = ciphers[i].id; | 273 | sess.cipher = ciphers[i].id; |
195 | sess.keylen = ciphers[i].keylen; | 274 | sess.keylen = ciphers[i].keylen; |
196 | sess.mac = 0; | 275 | sess.mac = 0; |
197 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 276 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
198 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 277 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
199 | nids[count++] = ciphers[i].nid; | 278 | nids[count++] = ciphers[i].nid; |
200 | } | 279 | } |
280 | close(fd); | ||
281 | |||
201 | if (count > 0) | 282 | if (count > 0) |
202 | *cnids = nids; | 283 | *cnids = nids; |
203 | else | 284 | else |
@@ -216,18 +297,24 @@ get_cryptodev_digests(const int **cnids) | |||
216 | { | 297 | { |
217 | static int nids[CRYPTO_ALGORITHM_MAX]; | 298 | static int nids[CRYPTO_ALGORITHM_MAX]; |
218 | struct session_op sess; | 299 | struct session_op sess; |
219 | int i, count = 0; | 300 | int fd, i, count = 0; |
220 | 301 | ||
302 | if ((fd = get_dev_crypto()) < 0) { | ||
303 | *nids = NULL; | ||
304 | return (0); | ||
305 | } | ||
221 | memset(&sess, 0, sizeof(sess)); | 306 | memset(&sess, 0, sizeof(sess)); |
222 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 307 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
223 | if (digests[i].nid == NID_undef) | 308 | if (digests[i].nid == NID_undef) |
224 | continue; | 309 | continue; |
225 | sess.mac = digests[i].id; | 310 | sess.mac = digests[i].id; |
226 | sess.cipher = 0; | 311 | sess.cipher = 0; |
227 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 312 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
228 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 313 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
229 | nids[count++] = digests[i].nid; | 314 | nids[count++] = digests[i].nid; |
230 | } | 315 | } |
316 | close(fd); | ||
317 | |||
231 | if (count > 0) | 318 | if (count > 0) |
232 | *cnids = nids; | 319 | *cnids = nids; |
233 | else | 320 | else |
@@ -256,25 +343,15 @@ get_cryptodev_digests(const int **cnids) | |||
256 | * want most of the decisions made about what we actually want | 343 | * want most of the decisions made about what we actually want |
257 | * to use from /dev/crypto. | 344 | * to use from /dev/crypto. |
258 | */ | 345 | */ |
259 | int | 346 | static int |
260 | cryptodev_usable_ciphers(const int **nids) | 347 | cryptodev_usable_ciphers(const int **nids) |
261 | { | 348 | { |
262 | if (!check_dev_crypto()) { | ||
263 | *nids = NULL; | ||
264 | return (0); | ||
265 | } | ||
266 | |||
267 | /* find what the device can do. Unfortunately, we don't | ||
268 | * necessarily want all of these yet, because we aren't | ||
269 | * yet set up to do them | ||
270 | */ | ||
271 | return (get_cryptodev_ciphers(nids)); | 349 | return (get_cryptodev_ciphers(nids)); |
272 | } | 350 | } |
273 | 351 | ||
274 | int | 352 | static int |
275 | cryptodev_usable_digests(const int **nids) | 353 | cryptodev_usable_digests(const int **nids) |
276 | { | 354 | { |
277 | #if 1 | ||
278 | /* | 355 | /* |
279 | * XXXX just disable all digests for now, because it sucks. | 356 | * XXXX just disable all digests for now, because it sucks. |
280 | * we need a better way to decide this - i.e. I may not | 357 | * we need a better way to decide this - i.e. I may not |
@@ -289,29 +366,19 @@ cryptodev_usable_digests(const int **nids) | |||
289 | */ | 366 | */ |
290 | *nids = NULL; | 367 | *nids = NULL; |
291 | return (0); | 368 | return (0); |
292 | #endif | ||
293 | |||
294 | if (!check_dev_crypto()) { | ||
295 | *nids = NULL; | ||
296 | return (0); | ||
297 | } | ||
298 | return (get_cryptodev_digests(nids)); | ||
299 | } | 369 | } |
300 | 370 | ||
301 | 371 | static int | |
302 | int | ||
303 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 372 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
304 | const unsigned char *in, unsigned int inl) | 373 | const unsigned char *in, unsigned int inl) |
305 | { | 374 | { |
306 | struct crypt_op cryp; | 375 | struct crypt_op cryp; |
307 | struct session_op *sess = ctx->cipher_data; | 376 | struct dev_crypto_state *state = ctx->cipher_data; |
377 | struct session_op *sess = &state->d_sess; | ||
308 | void *iiv; | 378 | void *iiv; |
309 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | 379 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; |
310 | struct syslog_data sd = SYSLOG_DATA_INIT; | ||
311 | 380 | ||
312 | if (cryptodev_fd == -1) | 381 | if (state->d_fd < 0) |
313 | return (0); | ||
314 | if (sess == NULL) | ||
315 | return (0); | 382 | return (0); |
316 | if (!inl) | 383 | if (!inl) |
317 | return (1); | 384 | return (1); |
@@ -338,11 +405,10 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
338 | } else | 405 | } else |
339 | cryp.iv = NULL; | 406 | cryp.iv = NULL; |
340 | 407 | ||
341 | if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { | 408 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { |
342 | /* XXX need better errror handling | 409 | /* XXX need better errror handling |
343 | * this can fail for a number of different reasons. | 410 | * this can fail for a number of different reasons. |
344 | */ | 411 | */ |
345 | syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)"); | ||
346 | return (0); | 412 | return (0); |
347 | } | 413 | } |
348 | 414 | ||
@@ -356,20 +422,17 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
356 | return (1); | 422 | return (1); |
357 | } | 423 | } |
358 | 424 | ||
359 | int | 425 | static int |
360 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 426 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
361 | const unsigned char *iv, int enc) | 427 | const unsigned char *iv, int enc) |
362 | { | 428 | { |
363 | struct session_op *sess = ctx->cipher_data; | 429 | struct dev_crypto_state *state = ctx->cipher_data; |
364 | struct syslog_data sd = SYSLOG_DATA_INIT; | 430 | struct session_op *sess = &state->d_sess; |
365 | int cipher; | 431 | int cipher; |
366 | 432 | ||
367 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) | 433 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) |
368 | return (0); | 434 | return (0); |
369 | 435 | ||
370 | if (!check_dev_crypto()) | ||
371 | return (0); | ||
372 | |||
373 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) | 436 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) |
374 | return (0); | 437 | return (0); |
375 | 438 | ||
@@ -378,15 +441,18 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
378 | 441 | ||
379 | memset(sess, 0, sizeof(struct session_op)); | 442 | memset(sess, 0, sizeof(struct session_op)); |
380 | 443 | ||
444 | if ((state->d_fd = get_dev_crypto()) < 0) | ||
445 | return (0); | ||
446 | |||
381 | sess->key = (unsigned char *)key; | 447 | sess->key = (unsigned char *)key; |
382 | sess->keylen = ctx->key_len; | 448 | sess->keylen = ctx->key_len; |
383 | sess->cipher = cipher; | 449 | sess->cipher = cipher; |
384 | 450 | ||
385 | if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { | 451 | if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { |
386 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); | 452 | close(state->d_fd); |
453 | state->d_fd = -1; | ||
387 | return (0); | 454 | return (0); |
388 | } | 455 | } |
389 | cryptodev_sessions++; | ||
390 | return (1); | 456 | return (1); |
391 | } | 457 | } |
392 | 458 | ||
@@ -394,14 +460,14 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
394 | * free anything we allocated earlier when initting a | 460 | * free anything we allocated earlier when initting a |
395 | * session, and close the session. | 461 | * session, and close the session. |
396 | */ | 462 | */ |
397 | int | 463 | static int |
398 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | 464 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) |
399 | { | 465 | { |
400 | int ret = 0; | 466 | int ret = 0; |
401 | struct session_op *sess = ctx->cipher_data; | 467 | struct dev_crypto_state *state = ctx->cipher_data; |
402 | struct syslog_data sd = SYSLOG_DATA_INIT; | 468 | struct session_op *sess = &state->d_sess; |
403 | 469 | ||
404 | if (sess == NULL) | 470 | if (state->d_fd < 0) |
405 | return (0); | 471 | return (0); |
406 | 472 | ||
407 | /* XXX if this ioctl fails, someting's wrong. the invoker | 473 | /* XXX if this ioctl fails, someting's wrong. the invoker |
@@ -415,17 +481,14 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
415 | * print messages to users of the library. hmm.. | 481 | * print messages to users of the library. hmm.. |
416 | */ | 482 | */ |
417 | 483 | ||
418 | if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { | 484 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { |
419 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); | ||
420 | ret = 0; | 485 | ret = 0; |
421 | } else { | 486 | } else { |
422 | cryptodev_sessions--; | ||
423 | ret = 1; | 487 | ret = 1; |
424 | } | 488 | } |
425 | if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { | 489 | close(state->d_fd); |
426 | close(cryptodev_fd); /* XXX should this be closed? */ | 490 | state->d_fd = -1; |
427 | cryptodev_fd = -1; | 491 | |
428 | } | ||
429 | return (ret); | 492 | return (ret); |
430 | } | 493 | } |
431 | 494 | ||
@@ -434,20 +497,6 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
434 | * gets called when libcrypto requests a cipher NID. | 497 | * gets called when libcrypto requests a cipher NID. |
435 | */ | 498 | */ |
436 | 499 | ||
437 | /* ARC4 (16 byte key) */ | ||
438 | const EVP_CIPHER cryptodev_arc4_cipher = { | ||
439 | NID_rc4, | ||
440 | 1, 16, 0, | ||
441 | EVP_CIPH_VARIABLE_LENGTH, | ||
442 | cryptodev_init_key, | ||
443 | cryptodev_cipher, | ||
444 | cryptodev_cleanup, | ||
445 | sizeof(struct session_op), | ||
446 | NULL, | ||
447 | NULL, | ||
448 | NULL | ||
449 | }; | ||
450 | |||
451 | /* DES CBC EVP */ | 500 | /* DES CBC EVP */ |
452 | const EVP_CIPHER cryptodev_des_cbc = { | 501 | const EVP_CIPHER cryptodev_des_cbc = { |
453 | NID_des_cbc, | 502 | NID_des_cbc, |
@@ -456,7 +505,7 @@ const EVP_CIPHER cryptodev_des_cbc = { | |||
456 | cryptodev_init_key, | 505 | cryptodev_init_key, |
457 | cryptodev_cipher, | 506 | cryptodev_cipher, |
458 | cryptodev_cleanup, | 507 | cryptodev_cleanup, |
459 | sizeof(struct session_op), | 508 | sizeof(struct dev_crypto_state), |
460 | EVP_CIPHER_set_asn1_iv, | 509 | EVP_CIPHER_set_asn1_iv, |
461 | EVP_CIPHER_get_asn1_iv, | 510 | EVP_CIPHER_get_asn1_iv, |
462 | NULL | 511 | NULL |
@@ -470,19 +519,57 @@ const EVP_CIPHER cryptodev_3des_cbc = { | |||
470 | cryptodev_init_key, | 519 | cryptodev_init_key, |
471 | cryptodev_cipher, | 520 | cryptodev_cipher, |
472 | cryptodev_cleanup, | 521 | cryptodev_cleanup, |
473 | sizeof(struct session_op), | 522 | sizeof(struct dev_crypto_state), |
523 | EVP_CIPHER_set_asn1_iv, | ||
524 | EVP_CIPHER_get_asn1_iv, | ||
525 | NULL | ||
526 | }; | ||
527 | |||
528 | const EVP_CIPHER cryptodev_bf_cbc = { | ||
529 | NID_bf_cbc, | ||
530 | 8, 16, 8, | ||
531 | EVP_CIPH_CBC_MODE, | ||
532 | cryptodev_init_key, | ||
533 | cryptodev_cipher, | ||
534 | cryptodev_cleanup, | ||
535 | sizeof(struct dev_crypto_state), | ||
536 | EVP_CIPHER_set_asn1_iv, | ||
537 | EVP_CIPHER_get_asn1_iv, | ||
538 | NULL | ||
539 | }; | ||
540 | |||
541 | const EVP_CIPHER cryptodev_cast_cbc = { | ||
542 | NID_cast5_cbc, | ||
543 | 8, 16, 8, | ||
544 | EVP_CIPH_CBC_MODE, | ||
545 | cryptodev_init_key, | ||
546 | cryptodev_cipher, | ||
547 | cryptodev_cleanup, | ||
548 | sizeof(struct dev_crypto_state), | ||
474 | EVP_CIPHER_set_asn1_iv, | 549 | EVP_CIPHER_set_asn1_iv, |
475 | EVP_CIPHER_get_asn1_iv, | 550 | EVP_CIPHER_get_asn1_iv, |
476 | NULL | 551 | NULL |
477 | }; | 552 | }; |
478 | 553 | ||
554 | const EVP_CIPHER cryptodev_aes_cbc = { | ||
555 | NID_aes_128_cbc, | ||
556 | 16, 16, 16, | ||
557 | EVP_CIPH_CBC_MODE, | ||
558 | cryptodev_init_key, | ||
559 | cryptodev_cipher, | ||
560 | cryptodev_cleanup, | ||
561 | sizeof(struct dev_crypto_state), | ||
562 | EVP_CIPHER_set_asn1_iv, | ||
563 | EVP_CIPHER_get_asn1_iv, | ||
564 | NULL | ||
565 | }; | ||
479 | 566 | ||
480 | /* | 567 | /* |
481 | * Registered by the ENGINE when used to find out how to deal with | 568 | * Registered by the ENGINE when used to find out how to deal with |
482 | * a particular NID in the ENGINE. this says what we'll do at the | 569 | * a particular NID in the ENGINE. this says what we'll do at the |
483 | * top level - note, that list is restricted by what we answer with | 570 | * top level - note, that list is restricted by what we answer with |
484 | */ | 571 | */ |
485 | int | 572 | static int |
486 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | 573 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, |
487 | const int **nids, int nid) | 574 | const int **nids, int nid) |
488 | { | 575 | { |
@@ -490,15 +577,21 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
490 | return (cryptodev_usable_ciphers(nids)); | 577 | return (cryptodev_usable_ciphers(nids)); |
491 | 578 | ||
492 | switch (nid) { | 579 | switch (nid) { |
493 | case NID_rc4: | ||
494 | *cipher = &cryptodev_arc4_cipher; | ||
495 | break; | ||
496 | case NID_des_ede3_cbc: | 580 | case NID_des_ede3_cbc: |
497 | *cipher = &cryptodev_3des_cbc; | 581 | *cipher = &cryptodev_3des_cbc; |
498 | break; | 582 | break; |
499 | case NID_des_cbc: | 583 | case NID_des_cbc: |
500 | *cipher = &cryptodev_des_cbc; | 584 | *cipher = &cryptodev_des_cbc; |
501 | break; | 585 | break; |
586 | case NID_bf_cbc: | ||
587 | *cipher = &cryptodev_bf_cbc; | ||
588 | break; | ||
589 | case NID_cast5_cbc: | ||
590 | *cipher = &cryptodev_cast_cbc; | ||
591 | break; | ||
592 | case NID_aes_128_cbc: | ||
593 | *cipher = &cryptodev_aes_cbc; | ||
594 | break; | ||
502 | default: | 595 | default: |
503 | *cipher = NULL; | 596 | *cipher = NULL; |
504 | break; | 597 | break; |
@@ -506,7 +599,7 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
506 | return (*cipher != NULL); | 599 | return (*cipher != NULL); |
507 | } | 600 | } |
508 | 601 | ||
509 | int | 602 | static int |
510 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | 603 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, |
511 | const int **nids, int nid) | 604 | const int **nids, int nid) |
512 | { | 605 | { |
@@ -524,7 +617,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
524 | return (*digest != NULL); | 617 | return (*digest != NULL); |
525 | } | 618 | } |
526 | 619 | ||
527 | |||
528 | /* | 620 | /* |
529 | * Convert a BIGNUM to the representation that /dev/crypto needs. | 621 | * Convert a BIGNUM to the representation that /dev/crypto needs. |
530 | * Upon completion of use, the caller is responsible for freeing | 622 | * Upon completion of use, the caller is responsible for freeing |
@@ -533,7 +625,7 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
533 | static int | 625 | static int |
534 | bn2crparam(const BIGNUM *a, struct crparam *crp) | 626 | bn2crparam(const BIGNUM *a, struct crparam *crp) |
535 | { | 627 | { |
536 | int i, j, n; | 628 | int i, j, k; |
537 | ssize_t words, bytes, bits; | 629 | ssize_t words, bytes, bits; |
538 | u_char *b; | 630 | u_char *b; |
539 | 631 | ||
@@ -550,17 +642,13 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
550 | crp->crp_p = b; | 642 | crp->crp_p = b; |
551 | crp->crp_nbits = bits; | 643 | crp->crp_nbits = bits; |
552 | 644 | ||
553 | words = (bits + BN_BITS2 - 1) / BN_BITS2; | 645 | for (i = 0, j = 0; i < a->top; i++) { |
554 | 646 | for (k = 0; k < BN_BITS2 / 8; k++) { | |
555 | n = 0; | 647 | if ((j + k) >= bytes) |
556 | for (i = 0; i < words && n < bytes; i++) { | 648 | return (0); |
557 | BN_ULONG word; | 649 | b[j + k] = a->d[i] >> (k * 8); |
558 | |||
559 | word = a->d[i]; | ||
560 | for (j = 0 ; j < BN_BYTES && n < bytes; j++, n++) { | ||
561 | *b++ = (word & 0xff); | ||
562 | word >>= 8; | ||
563 | } | 650 | } |
651 | j += BN_BITS2 / 8; | ||
564 | } | 652 | } |
565 | return (0); | 653 | return (0); |
566 | } | 654 | } |
@@ -569,15 +657,22 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
569 | static int | 657 | static int |
570 | crparam2bn(struct crparam *crp, BIGNUM *a) | 658 | crparam2bn(struct crparam *crp, BIGNUM *a) |
571 | { | 659 | { |
660 | u_int8_t *pd; | ||
572 | int i, bytes; | 661 | int i, bytes; |
573 | 662 | ||
574 | bytes = (crp->crp_nbits + 7)/8; | 663 | bytes = (crp->crp_nbits + 7) / 8; |
575 | 664 | ||
576 | BN_zero(a); | 665 | if (bytes == 0) |
577 | for (i = bytes - 1; i >= 0; i--) { | 666 | return (-1); |
578 | BN_lshift(a, a, 8); | 667 | |
579 | BN_add_word(a, (u_char)crp->crp_p[i]); | 668 | if ((pd = (u_int8_t *) malloc(bytes)) == NULL) |
580 | } | 669 | return (-1); |
670 | |||
671 | for (i = 0; i < bytes; i++) | ||
672 | pd[i] = crp->crp_p[bytes - i - 1]; | ||
673 | |||
674 | BN_bin2bn(pd, bytes, a); | ||
675 | free(pd); | ||
581 | 676 | ||
582 | return (0); | 677 | return (0); |
583 | } | 678 | } |
@@ -596,25 +691,32 @@ zapparams(struct crypt_kop *kop) | |||
596 | } | 691 | } |
597 | 692 | ||
598 | static int | 693 | static int |
599 | cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s) | 694 | cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) |
600 | { | 695 | { |
601 | int ret = -1; | 696 | int fd, ret = -1; |
697 | |||
698 | if ((fd = get_asym_dev_crypto()) < 0) | ||
699 | return (ret); | ||
602 | 700 | ||
603 | if (r) { | 701 | if (r) { |
604 | kop->crk_param[kop->crk_iparams].crp_p = malloc(256); | 702 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); |
605 | kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8; | 703 | kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; |
606 | kop->crk_oparams++; | 704 | kop->crk_oparams++; |
607 | } | 705 | } |
608 | if (s) { | 706 | if (s) { |
609 | kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256); | 707 | kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char)); |
610 | kop->crk_param[kop->crk_iparams+1].crp_nbits = 256 * 8; | 708 | kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8; |
611 | kop->crk_oparams++; | 709 | kop->crk_oparams++; |
612 | } | 710 | } |
613 | 711 | ||
614 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) { | 712 | if (ioctl(fd, CIOCKEY, kop) == 0) { |
615 | crparam2bn(&kop->crk_param[3], r); | 713 | if (r) |
714 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); | ||
715 | if (s) | ||
716 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); | ||
616 | ret = 0; | 717 | ret = 0; |
617 | } | 718 | } |
719 | |||
618 | return (ret); | 720 | return (ret); |
619 | } | 721 | } |
620 | 722 | ||
@@ -623,38 +725,58 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |||
623 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) | 725 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) |
624 | { | 726 | { |
625 | struct crypt_kop kop; | 727 | struct crypt_kop kop; |
626 | int ret = 0; | 728 | int ret = 1; |
729 | |||
730 | /* Currently, we know we can do mod exp iff we can do any | ||
731 | * asymmetric operations at all. | ||
732 | */ | ||
733 | if (cryptodev_asymfeat == 0) { | ||
734 | ret = BN_mod_exp(r, a, p, m, ctx); | ||
735 | return (ret); | ||
736 | } | ||
627 | 737 | ||
628 | memset(&kop, 0, sizeof kop); | 738 | memset(&kop, 0, sizeof kop); |
629 | kop.crk_op = CRK_MOD_EXP; | 739 | kop.crk_op = CRK_MOD_EXP; |
630 | 740 | ||
631 | /* inputs: a m p */ | 741 | /* inputs: a^p % m */ |
632 | if (bn2crparam(a, &kop.crk_param[0])) | 742 | if (bn2crparam(a, &kop.crk_param[0])) |
633 | goto err; | 743 | goto err; |
634 | if (bn2crparam(m, &kop.crk_param[1])) | 744 | if (bn2crparam(p, &kop.crk_param[1])) |
635 | goto err; | 745 | goto err; |
636 | if (bn2crparam(p, &kop.crk_param[2])) | 746 | if (bn2crparam(m, &kop.crk_param[2])) |
637 | goto err; | 747 | goto err; |
638 | kop.crk_iparams = 3; | 748 | kop.crk_iparams = 3; |
639 | 749 | ||
640 | if (cryptodev_sym(&kop, r, NULL) == -1) { | 750 | if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) { |
641 | ret = BN_mod_exp(r, a, p, m, ctx); | 751 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
752 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | ||
642 | } | 753 | } |
643 | err: | 754 | err: |
644 | zapparams(&kop); | 755 | zapparams(&kop); |
645 | return (ret); | 756 | return (ret); |
646 | } | 757 | } |
647 | 758 | ||
759 | static int | ||
760 | cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | ||
761 | { | ||
762 | int r; | ||
763 | BN_CTX *ctx; | ||
764 | |||
765 | ctx = BN_CTX_new(); | ||
766 | r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); | ||
767 | BN_CTX_free(ctx); | ||
768 | return (r); | ||
769 | } | ||
648 | 770 | ||
649 | static int | 771 | static int |
650 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | 772 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) |
651 | { | 773 | { |
652 | struct crypt_kop kop; | 774 | struct crypt_kop kop; |
653 | int ret = 0; | 775 | int ret = 1; |
654 | 776 | ||
655 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { | 777 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { |
656 | /* XXX 0 means failure?? */ | 778 | /* XXX 0 means failure?? */ |
657 | goto err; | 779 | return (0); |
658 | } | 780 | } |
659 | 781 | ||
660 | memset(&kop, 0, sizeof kop); | 782 | memset(&kop, 0, sizeof kop); |
@@ -674,9 +796,8 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | |||
674 | goto err; | 796 | goto err; |
675 | kop.crk_iparams = 6; | 797 | kop.crk_iparams = 6; |
676 | 798 | ||
677 | if (cryptodev_sym(&kop, r0, NULL) == -1) { | 799 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { |
678 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | 800 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
679 | |||
680 | ret = (*meth->rsa_mod_exp)(r0, I, rsa); | 801 | ret = (*meth->rsa_mod_exp)(r0, I, rsa); |
681 | } | 802 | } |
682 | err: | 803 | err: |
@@ -690,8 +811,8 @@ static RSA_METHOD cryptodev_rsa = { | |||
690 | NULL, /* rsa_pub_dec */ | 811 | NULL, /* rsa_pub_dec */ |
691 | NULL, /* rsa_priv_enc */ | 812 | NULL, /* rsa_priv_enc */ |
692 | NULL, /* rsa_priv_dec */ | 813 | NULL, /* rsa_priv_dec */ |
693 | cryptodev_rsa_mod_exp, /* rsa_mod_exp */ | 814 | NULL, |
694 | cryptodev_bn_mod_exp, /* bn_mod_exp */ | 815 | NULL, |
695 | NULL, /* init */ | 816 | NULL, /* init */ |
696 | NULL, /* finish */ | 817 | NULL, /* finish */ |
697 | 0, /* flags */ | 818 | 0, /* flags */ |
@@ -707,6 +828,38 @@ cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | |||
707 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); | 828 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); |
708 | } | 829 | } |
709 | 830 | ||
831 | static int | ||
832 | cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
833 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
834 | BN_CTX *ctx, BN_MONT_CTX *mont) | ||
835 | { | ||
836 | BIGNUM t2; | ||
837 | int ret = 0; | ||
838 | |||
839 | BN_init(&t2); | ||
840 | |||
841 | /* v = ( g^u1 * y^u2 mod p ) mod q */ | ||
842 | /* let t1 = g ^ u1 mod p */ | ||
843 | ret = 0; | ||
844 | |||
845 | if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont)) | ||
846 | goto err; | ||
847 | |||
848 | /* let t2 = y ^ u2 mod p */ | ||
849 | if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont)) | ||
850 | goto err; | ||
851 | /* let u1 = t1 * t2 mod p */ | ||
852 | if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx)) | ||
853 | goto err; | ||
854 | |||
855 | BN_copy(t1,u1); | ||
856 | |||
857 | ret = 1; | ||
858 | err: | ||
859 | BN_free(&t2); | ||
860 | return(ret); | ||
861 | } | ||
862 | |||
710 | static DSA_SIG * | 863 | static DSA_SIG * |
711 | cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | 864 | cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) |
712 | { | 865 | { |
@@ -721,6 +874,7 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
721 | goto err; | 874 | goto err; |
722 | } | 875 | } |
723 | 876 | ||
877 | printf("bar\n"); | ||
724 | memset(&kop, 0, sizeof kop); | 878 | memset(&kop, 0, sizeof kop); |
725 | kop.crk_op = CRK_DSA_SIGN; | 879 | kop.crk_op = CRK_DSA_SIGN; |
726 | 880 | ||
@@ -737,13 +891,13 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
737 | goto err; | 891 | goto err; |
738 | kop.crk_iparams = 5; | 892 | kop.crk_iparams = 5; |
739 | 893 | ||
740 | if (cryptodev_sym(&kop, r, s) == 0) { | 894 | if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, |
895 | BN_num_bytes(dsa->q), s) == 0) { | ||
741 | dsaret = DSA_SIG_new(); | 896 | dsaret = DSA_SIG_new(); |
742 | dsaret->r = r; | 897 | dsaret->r = r; |
743 | dsaret->s = s; | 898 | dsaret->s = s; |
744 | } else { | 899 | } else { |
745 | const DSA_METHOD *meth = DSA_OpenSSL(); | 900 | const DSA_METHOD *meth = DSA_OpenSSL(); |
746 | |||
747 | BN_free(r); | 901 | BN_free(r); |
748 | BN_free(s); | 902 | BN_free(s); |
749 | dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); | 903 | dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); |
@@ -759,7 +913,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
759 | DSA_SIG *sig, DSA *dsa) | 913 | DSA_SIG *sig, DSA *dsa) |
760 | { | 914 | { |
761 | struct crypt_kop kop; | 915 | struct crypt_kop kop; |
762 | int dsaret = 0; | 916 | int dsaret = 1; |
763 | 917 | ||
764 | memset(&kop, 0, sizeof kop); | 918 | memset(&kop, 0, sizeof kop); |
765 | kop.crk_op = CRK_DSA_VERIFY; | 919 | kop.crk_op = CRK_DSA_VERIFY; |
@@ -781,7 +935,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
781 | goto err; | 935 | goto err; |
782 | kop.crk_iparams = 7; | 936 | kop.crk_iparams = 7; |
783 | 937 | ||
784 | if (cryptodev_sym(&kop, NULL, NULL) == 0) { | 938 | if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { |
785 | dsaret = kop.crk_status; | 939 | dsaret = kop.crk_status; |
786 | } else { | 940 | } else { |
787 | const DSA_METHOD *meth = DSA_OpenSSL(); | 941 | const DSA_METHOD *meth = DSA_OpenSSL(); |
@@ -796,11 +950,11 @@ err: | |||
796 | 950 | ||
797 | static DSA_METHOD cryptodev_dsa = { | 951 | static DSA_METHOD cryptodev_dsa = { |
798 | "cryptodev DSA method", | 952 | "cryptodev DSA method", |
799 | cryptodev_dsa_do_sign, | 953 | NULL, |
800 | NULL, /* dsa_sign_setup */ | 954 | NULL, /* dsa_sign_setup */ |
801 | cryptodev_dsa_verify, | 955 | NULL, |
802 | NULL, /* dsa_mod_exp */ | 956 | NULL, /* dsa_mod_exp */ |
803 | cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */ | 957 | NULL, |
804 | NULL, /* init */ | 958 | NULL, /* init */ |
805 | NULL, /* finish */ | 959 | NULL, /* finish */ |
806 | 0, /* flags */ | 960 | 0, /* flags */ |
@@ -819,8 +973,14 @@ static int | |||
819 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | 973 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) |
820 | { | 974 | { |
821 | struct crypt_kop kop; | 975 | struct crypt_kop kop; |
822 | int dhret = 0; | 976 | int dhret = 1; |
823 | int keylen; | 977 | int fd, keylen; |
978 | |||
979 | if ((fd = get_asym_dev_crypto()) < 0) { | ||
980 | const DH_METHOD *meth = DH_OpenSSL(); | ||
981 | |||
982 | return ((meth->compute_key)(key, pub_key, dh)); | ||
983 | } | ||
824 | 984 | ||
825 | keylen = BN_num_bits(dh->p); | 985 | keylen = BN_num_bits(dh->p); |
826 | 986 | ||
@@ -840,7 +1000,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
840 | kop.crk_param[3].crp_nbits = keylen * 8; | 1000 | kop.crk_param[3].crp_nbits = keylen * 8; |
841 | kop.crk_oparams = 1; | 1001 | kop.crk_oparams = 1; |
842 | 1002 | ||
843 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { | 1003 | if (ioctl(fd, CIOCKEY, &kop) == -1) { |
844 | const DH_METHOD *meth = DH_OpenSSL(); | 1004 | const DH_METHOD *meth = DH_OpenSSL(); |
845 | 1005 | ||
846 | dhret = (meth->compute_key)(key, pub_key, dh); | 1006 | dhret = (meth->compute_key)(key, pub_key, dh); |
@@ -854,8 +1014,8 @@ err: | |||
854 | static DH_METHOD cryptodev_dh = { | 1014 | static DH_METHOD cryptodev_dh = { |
855 | "cryptodev DH method", | 1015 | "cryptodev DH method", |
856 | NULL, /* cryptodev_dh_generate_key */ | 1016 | NULL, /* cryptodev_dh_generate_key */ |
857 | cryptodev_dh_compute_key, | 1017 | NULL, |
858 | cryptodev_mod_exp_dh, | 1018 | NULL, |
859 | NULL, | 1019 | NULL, |
860 | NULL, | 1020 | NULL, |
861 | 0, /* flags */ | 1021 | 0, /* flags */ |
@@ -869,12 +1029,18 @@ static DH_METHOD cryptodev_dh = { | |||
869 | static int | 1029 | static int |
870 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | 1030 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) |
871 | { | 1031 | { |
1032 | #ifdef HAVE_SYSLOG_R | ||
872 | struct syslog_data sd = SYSLOG_DATA_INIT; | 1033 | struct syslog_data sd = SYSLOG_DATA_INIT; |
1034 | #endif | ||
873 | 1035 | ||
874 | switch (cmd) { | 1036 | switch (cmd) { |
875 | default: | 1037 | default: |
1038 | #ifdef HAVE_SYSLOG_R | ||
876 | syslog_r(LOG_ERR, &sd, | 1039 | syslog_r(LOG_ERR, &sd, |
877 | "cryptodev_ctrl: unknown command %d", cmd); | 1040 | "cryptodev_ctrl: unknown command %d", cmd); |
1041 | #else | ||
1042 | syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); | ||
1043 | #endif | ||
878 | break; | 1044 | break; |
879 | } | 1045 | } |
880 | return (1); | 1046 | return (1); |
@@ -884,14 +1050,24 @@ void | |||
884 | ENGINE_load_cryptodev(void) | 1050 | ENGINE_load_cryptodev(void) |
885 | { | 1051 | { |
886 | ENGINE *engine = ENGINE_new(); | 1052 | ENGINE *engine = ENGINE_new(); |
887 | const RSA_METHOD *rsa_meth; | 1053 | int fd; |
888 | const DH_METHOD *dh_meth; | ||
889 | 1054 | ||
890 | if (engine == NULL) | 1055 | if (engine == NULL) |
891 | return; | 1056 | return; |
1057 | if ((fd = get_dev_crypto()) < 0) | ||
1058 | return; | ||
1059 | |||
1060 | /* | ||
1061 | * find out what asymmetric crypto algorithms we support | ||
1062 | */ | ||
1063 | if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | ||
1064 | close(fd); | ||
1065 | return; | ||
1066 | } | ||
1067 | close(fd); | ||
892 | 1068 | ||
893 | if (!ENGINE_set_id(engine, "cryptodev") || | 1069 | if (!ENGINE_set_id(engine, "cryptodev") || |
894 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || | 1070 | !ENGINE_set_name(engine, "BSD cryptodev engine") || |
895 | !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || | 1071 | !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || |
896 | !ENGINE_set_digests(engine, cryptodev_engine_digests) || | 1072 | !ENGINE_set_digests(engine, cryptodev_engine_digests) || |
897 | !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || | 1073 | !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || |
@@ -900,27 +1076,57 @@ ENGINE_load_cryptodev(void) | |||
900 | return; | 1076 | return; |
901 | } | 1077 | } |
902 | 1078 | ||
903 | if ((cryptodev_symfeat & CRSFEAT_RSA) && | 1079 | if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { |
904 | ENGINE_set_RSA(engine, &cryptodev_rsa)) { | 1080 | const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); |
905 | rsa_meth = RSA_PKCS1_SSLeay(); | 1081 | |
1082 | cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; | ||
1083 | cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; | ||
906 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; | 1084 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; |
907 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; | 1085 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; |
908 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec; | 1086 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; |
909 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; | 1087 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; |
1088 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1089 | cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; | ||
1090 | if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) | ||
1091 | cryptodev_rsa.rsa_mod_exp = | ||
1092 | cryptodev_rsa_mod_exp; | ||
1093 | else | ||
1094 | cryptodev_rsa.rsa_mod_exp = | ||
1095 | cryptodev_rsa_nocrt_mod_exp; | ||
1096 | } | ||
910 | } | 1097 | } |
911 | 1098 | ||
912 | if ((cryptodev_symfeat & CRSFEAT_DSA) && | 1099 | if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { |
913 | ENGINE_set_DSA(engine, &cryptodev_dsa)) { | 1100 | const DSA_METHOD *meth = DSA_OpenSSL(); |
1101 | |||
1102 | memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); | ||
1103 | if (cryptodev_asymfeat & CRF_DSA_SIGN) | ||
1104 | cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; | ||
1105 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1106 | cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; | ||
1107 | cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; | ||
1108 | } | ||
1109 | if (cryptodev_asymfeat & CRF_DSA_VERIFY) | ||
1110 | cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; | ||
914 | } | 1111 | } |
915 | 1112 | ||
916 | if ((cryptodev_symfeat & CRSFEAT_DH) && | 1113 | if (ENGINE_set_DH(engine, &cryptodev_dh)){ |
917 | ENGINE_set_DH(engine, &cryptodev_dh)) { | 1114 | const DH_METHOD *dh_meth = DH_OpenSSL(); |
918 | dh_meth = DH_OpenSSL(); | 1115 | |
919 | cryptodev_dh.generate_key = dh_meth->generate_key; | 1116 | cryptodev_dh.generate_key = dh_meth->generate_key; |
920 | cryptodev_dh.compute_key = dh_meth->compute_key; | 1117 | cryptodev_dh.compute_key = dh_meth->compute_key; |
1118 | cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; | ||
1119 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1120 | cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; | ||
1121 | if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) | ||
1122 | cryptodev_dh.compute_key = | ||
1123 | cryptodev_dh_compute_key; | ||
1124 | } | ||
921 | } | 1125 | } |
922 | 1126 | ||
923 | ENGINE_add(engine); | 1127 | ENGINE_add(engine); |
924 | ENGINE_free(engine); | 1128 | ENGINE_free(engine); |
925 | ERR_clear_error(); | 1129 | ERR_clear_error(); |
926 | } | 1130 | } |
1131 | |||
1132 | #endif /* HAVE_CRYPTODEV */ | ||