diff options
Diffstat (limited to 'src/lib/libcrypto/engine/hw_cryptodev.c')
-rw-r--r-- | src/lib/libcrypto/engine/hw_cryptodev.c | 505 |
1 files changed, 343 insertions, 162 deletions
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c index 7c3728f395..954eb85207 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 |
@@ -36,25 +37,56 @@ | |||
36 | #include <stdio.h> | 37 | #include <stdio.h> |
37 | #include <unistd.h> | 38 | #include <unistd.h> |
38 | #include <fcntl.h> | 39 | #include <fcntl.h> |
39 | #include <syslog.h> | ||
40 | #include <stdarg.h> | 40 | #include <stdarg.h> |
41 | #include <syslog.h> | ||
41 | #include <ssl/objects.h> | 42 | #include <ssl/objects.h> |
42 | #include <ssl/engine.h> | 43 | #include <ssl/engine.h> |
43 | #include <ssl/evp.h> | 44 | #include <ssl/evp.h> |
45 | #include <errno.h> | ||
46 | #include <string.h> | ||
44 | 47 | ||
45 | static int cryptodev_fd = -1; | 48 | struct dev_crypto_state { |
46 | static int cryptodev_sessions = 0; | 49 | struct session_op d_sess; |
47 | static u_int32_t cryptodev_symfeat = 0; | 50 | int d_fd; |
51 | }; | ||
48 | 52 | ||
53 | static u_int32_t cryptodev_asymfeat = 0; | ||
54 | |||
55 | static int get_asym_dev_crypto(void); | ||
56 | static int open_dev_crypto(void); | ||
57 | static int get_dev_crypto(void); | ||
58 | static int cryptodev_max_iv(int cipher); | ||
59 | static int cryptodev_key_length_valid(int cipher, int len); | ||
60 | static int cipher_nid_to_cryptodev(int nid); | ||
61 | static int get_cryptodev_ciphers(const int **cnids); | ||
62 | static int get_cryptodev_digests(const int **cnids); | ||
63 | static int cryptodev_usable_ciphers(const int **nids); | ||
64 | static int cryptodev_usable_digests(const int **nids); | ||
65 | static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
66 | const unsigned char *in, unsigned int inl); | ||
67 | static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
68 | const unsigned char *iv, int enc); | ||
69 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); | ||
70 | static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
71 | const int **nids, int nid); | ||
72 | static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | ||
73 | const int **nids, int nid); | ||
49 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); | 74 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); |
50 | static int crparam2bn(struct crparam *crp, BIGNUM *a); | 75 | static int crparam2bn(struct crparam *crp, BIGNUM *a); |
51 | static void zapparams(struct crypt_kop *kop); | 76 | static void zapparams(struct crypt_kop *kop); |
77 | static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, | ||
78 | int slen, BIGNUM *s); | ||
52 | 79 | ||
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, | 80 | 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); | 81 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
82 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, | ||
83 | RSA *rsa); | ||
84 | 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, | 85 | 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); | 86 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); |
87 | static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
88 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
89 | BN_CTX *ctx, BN_MONT_CTX *mont); | ||
58 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, | 90 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, |
59 | int dlen, DSA *dsa); | 91 | int dlen, DSA *dsa); |
60 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, | 92 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, |
@@ -64,8 +96,15 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | |||
64 | BN_MONT_CTX *m_ctx); | 96 | BN_MONT_CTX *m_ctx); |
65 | static int cryptodev_dh_compute_key(unsigned char *key, | 97 | static int cryptodev_dh_compute_key(unsigned char *key, |
66 | const BIGNUM *pub_key, DH *dh); | 98 | const BIGNUM *pub_key, DH *dh); |
99 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, | ||
100 | void (*f)()); | ||
101 | void ENGINE_load_cryptodev(void); | ||
67 | 102 | ||
68 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { | 103 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { |
104 | {ENGINE_CMD_BASE, | ||
105 | "SO_PATH", | ||
106 | "Specifies the path to the some stupid shared library", | ||
107 | ENGINE_CMD_FLAG_STRING}, | ||
69 | { 0, NULL, NULL, 0 } | 108 | { 0, NULL, NULL, 0 } |
70 | }; | 109 | }; |
71 | 110 | ||
@@ -77,11 +116,10 @@ static struct { | |||
77 | } ciphers[] = { | 116 | } ciphers[] = { |
78 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, | 117 | { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, |
79 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, | 118 | { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, |
80 | { CRYPTO_AES_CBC, NID_undef, 8, 24, }, | 119 | { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, |
81 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, | 120 | { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, |
82 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, }, | 121 | { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, |
83 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, | 122 | { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, }, |
84 | { CRYPTO_ARC4, NID_rc4, 8, 16, }, | ||
85 | { 0, NID_undef, 0, 0, }, | 123 | { 0, NID_undef, 0, 0, }, |
86 | }; | 124 | }; |
87 | 125 | ||
@@ -99,33 +137,53 @@ static struct { | |||
99 | }; | 137 | }; |
100 | 138 | ||
101 | /* | 139 | /* |
102 | * Return 1 if /dev/crypto seems usable, 0 otherwise , also | 140 | * 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 | */ | 141 | */ |
106 | static int | 142 | static int |
107 | check_dev_crypto() | 143 | open_dev_crypto(void) |
108 | { | 144 | { |
109 | int fd; | 145 | static int fd = -1; |
110 | 146 | ||
111 | if (cryptodev_fd == -1) { | 147 | if (fd == -1) { |
112 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) | 148 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) |
113 | return (0); | 149 | return (-1); |
114 | if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) { | ||
115 | close(fd); | ||
116 | return (0); | ||
117 | } | ||
118 | close(fd); | ||
119 | /* close on exec */ | 150 | /* close on exec */ |
120 | if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) { | 151 | if (fcntl(fd, F_SETFD, 1) == -1) { |
121 | close(cryptodev_fd); | 152 | close(fd); |
122 | cryptodev_fd = -1; | 153 | fd = -1; |
123 | return (0); | 154 | return (-1); |
124 | } | 155 | } |
125 | } | 156 | } |
126 | ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat); | 157 | return (fd); |
158 | } | ||
127 | 159 | ||
128 | return (1); | 160 | static int |
161 | get_dev_crypto(void) | ||
162 | { | ||
163 | int fd, retfd; | ||
164 | |||
165 | if ((fd = open_dev_crypto()) == -1) | ||
166 | return (-1); | ||
167 | if (ioctl(fd, CRIOGET, &retfd) == -1) | ||
168 | return (-1); | ||
169 | |||
170 | /* close on exec */ | ||
171 | if (fcntl(retfd, F_SETFD, 1) == -1) { | ||
172 | close(retfd); | ||
173 | return (-1); | ||
174 | } | ||
175 | return (retfd); | ||
176 | } | ||
177 | |||
178 | /* Caching version for asym operations */ | ||
179 | static int | ||
180 | get_asym_dev_crypto(void) | ||
181 | { | ||
182 | static int fd = -1; | ||
183 | |||
184 | if (fd == -1) | ||
185 | fd = get_dev_crypto(); | ||
186 | return fd; | ||
129 | } | 187 | } |
130 | 188 | ||
131 | /* | 189 | /* |
@@ -183,8 +241,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
183 | { | 241 | { |
184 | static int nids[CRYPTO_ALGORITHM_MAX]; | 242 | static int nids[CRYPTO_ALGORITHM_MAX]; |
185 | struct session_op sess; | 243 | struct session_op sess; |
186 | int i, count = 0; | 244 | int fd, i, count = 0; |
187 | 245 | ||
246 | if ((fd = get_dev_crypto()) < 0) { | ||
247 | *nids = NULL; | ||
248 | return (0); | ||
249 | } | ||
188 | memset(&sess, 0, sizeof(sess)); | 250 | memset(&sess, 0, sizeof(sess)); |
189 | sess.key = (caddr_t)"123456781234567812345678"; | 251 | sess.key = (caddr_t)"123456781234567812345678"; |
190 | 252 | ||
@@ -194,10 +256,12 @@ get_cryptodev_ciphers(const int **cnids) | |||
194 | sess.cipher = ciphers[i].id; | 256 | sess.cipher = ciphers[i].id; |
195 | sess.keylen = ciphers[i].keylen; | 257 | sess.keylen = ciphers[i].keylen; |
196 | sess.mac = 0; | 258 | sess.mac = 0; |
197 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 259 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
198 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 260 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
199 | nids[count++] = ciphers[i].nid; | 261 | nids[count++] = ciphers[i].nid; |
200 | } | 262 | } |
263 | close(fd); | ||
264 | |||
201 | if (count > 0) | 265 | if (count > 0) |
202 | *cnids = nids; | 266 | *cnids = nids; |
203 | else | 267 | else |
@@ -216,18 +280,24 @@ get_cryptodev_digests(const int **cnids) | |||
216 | { | 280 | { |
217 | static int nids[CRYPTO_ALGORITHM_MAX]; | 281 | static int nids[CRYPTO_ALGORITHM_MAX]; |
218 | struct session_op sess; | 282 | struct session_op sess; |
219 | int i, count = 0; | 283 | int fd, i, count = 0; |
220 | 284 | ||
285 | if ((fd = get_dev_crypto()) < 0) { | ||
286 | *nids = NULL; | ||
287 | return (0); | ||
288 | } | ||
221 | memset(&sess, 0, sizeof(sess)); | 289 | memset(&sess, 0, sizeof(sess)); |
222 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | 290 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { |
223 | if (digests[i].nid == NID_undef) | 291 | if (digests[i].nid == NID_undef) |
224 | continue; | 292 | continue; |
225 | sess.mac = digests[i].id; | 293 | sess.mac = digests[i].id; |
226 | sess.cipher = 0; | 294 | sess.cipher = 0; |
227 | if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 && | 295 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && |
228 | ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1) | 296 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) |
229 | nids[count++] = digests[i].nid; | 297 | nids[count++] = digests[i].nid; |
230 | } | 298 | } |
299 | close(fd); | ||
300 | |||
231 | if (count > 0) | 301 | if (count > 0) |
232 | *cnids = nids; | 302 | *cnids = nids; |
233 | else | 303 | else |
@@ -256,25 +326,15 @@ get_cryptodev_digests(const int **cnids) | |||
256 | * want most of the decisions made about what we actually want | 326 | * want most of the decisions made about what we actually want |
257 | * to use from /dev/crypto. | 327 | * to use from /dev/crypto. |
258 | */ | 328 | */ |
259 | int | 329 | static int |
260 | cryptodev_usable_ciphers(const int **nids) | 330 | cryptodev_usable_ciphers(const int **nids) |
261 | { | 331 | { |
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)); | 332 | return (get_cryptodev_ciphers(nids)); |
272 | } | 333 | } |
273 | 334 | ||
274 | int | 335 | static int |
275 | cryptodev_usable_digests(const int **nids) | 336 | cryptodev_usable_digests(const int **nids) |
276 | { | 337 | { |
277 | #if 1 | ||
278 | /* | 338 | /* |
279 | * XXXX just disable all digests for now, because it sucks. | 339 | * XXXX just disable all digests for now, because it sucks. |
280 | * we need a better way to decide this - i.e. I may not | 340 | * we need a better way to decide this - i.e. I may not |
@@ -289,29 +349,19 @@ cryptodev_usable_digests(const int **nids) | |||
289 | */ | 349 | */ |
290 | *nids = NULL; | 350 | *nids = NULL; |
291 | return (0); | 351 | return (0); |
292 | #endif | ||
293 | |||
294 | if (!check_dev_crypto()) { | ||
295 | *nids = NULL; | ||
296 | return (0); | ||
297 | } | ||
298 | return (get_cryptodev_digests(nids)); | ||
299 | } | 352 | } |
300 | 353 | ||
301 | 354 | static int | |
302 | int | ||
303 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 355 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
304 | const unsigned char *in, unsigned int inl) | 356 | const unsigned char *in, unsigned int inl) |
305 | { | 357 | { |
306 | struct crypt_op cryp; | 358 | struct crypt_op cryp; |
307 | struct session_op *sess = ctx->cipher_data; | 359 | struct dev_crypto_state *state = ctx->cipher_data; |
360 | struct session_op *sess = &state->d_sess; | ||
308 | void *iiv; | 361 | void *iiv; |
309 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | 362 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; |
310 | struct syslog_data sd = SYSLOG_DATA_INIT; | ||
311 | 363 | ||
312 | if (cryptodev_fd == -1) | 364 | if (state->d_fd < 0) |
313 | return (0); | ||
314 | if (sess == NULL) | ||
315 | return (0); | 365 | return (0); |
316 | if (!inl) | 366 | if (!inl) |
317 | return (1); | 367 | return (1); |
@@ -338,11 +388,10 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
338 | } else | 388 | } else |
339 | cryp.iv = NULL; | 389 | cryp.iv = NULL; |
340 | 390 | ||
341 | if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) { | 391 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { |
342 | /* XXX need better errror handling | 392 | /* XXX need better errror handling |
343 | * this can fail for a number of different reasons. | 393 | * this can fail for a number of different reasons. |
344 | */ | 394 | */ |
345 | syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)"); | ||
346 | return (0); | 395 | return (0); |
347 | } | 396 | } |
348 | 397 | ||
@@ -356,20 +405,17 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
356 | return (1); | 405 | return (1); |
357 | } | 406 | } |
358 | 407 | ||
359 | int | 408 | static int |
360 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | 409 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
361 | const unsigned char *iv, int enc) | 410 | const unsigned char *iv, int enc) |
362 | { | 411 | { |
363 | struct session_op *sess = ctx->cipher_data; | 412 | struct dev_crypto_state *state = ctx->cipher_data; |
364 | struct syslog_data sd = SYSLOG_DATA_INIT; | 413 | struct session_op *sess = &state->d_sess; |
365 | int cipher; | 414 | int cipher; |
366 | 415 | ||
367 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) | 416 | if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) |
368 | return (0); | 417 | return (0); |
369 | 418 | ||
370 | if (!check_dev_crypto()) | ||
371 | return (0); | ||
372 | |||
373 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) | 419 | if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) |
374 | return (0); | 420 | return (0); |
375 | 421 | ||
@@ -378,15 +424,18 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
378 | 424 | ||
379 | memset(sess, 0, sizeof(struct session_op)); | 425 | memset(sess, 0, sizeof(struct session_op)); |
380 | 426 | ||
427 | if ((state->d_fd = get_dev_crypto()) < 0) | ||
428 | return (0); | ||
429 | |||
381 | sess->key = (unsigned char *)key; | 430 | sess->key = (unsigned char *)key; |
382 | sess->keylen = ctx->key_len; | 431 | sess->keylen = ctx->key_len; |
383 | sess->cipher = cipher; | 432 | sess->cipher = cipher; |
384 | 433 | ||
385 | if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) { | 434 | if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { |
386 | syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)"); | 435 | close(state->d_fd); |
436 | state->d_fd = -1; | ||
387 | return (0); | 437 | return (0); |
388 | } | 438 | } |
389 | cryptodev_sessions++; | ||
390 | return (1); | 439 | return (1); |
391 | } | 440 | } |
392 | 441 | ||
@@ -394,14 +443,14 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |||
394 | * free anything we allocated earlier when initting a | 443 | * free anything we allocated earlier when initting a |
395 | * session, and close the session. | 444 | * session, and close the session. |
396 | */ | 445 | */ |
397 | int | 446 | static int |
398 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | 447 | cryptodev_cleanup(EVP_CIPHER_CTX *ctx) |
399 | { | 448 | { |
400 | int ret = 0; | 449 | int ret = 0; |
401 | struct session_op *sess = ctx->cipher_data; | 450 | struct dev_crypto_state *state = ctx->cipher_data; |
402 | struct syslog_data sd = SYSLOG_DATA_INIT; | 451 | struct session_op *sess = &state->d_sess; |
403 | 452 | ||
404 | if (sess == NULL) | 453 | if (state->d_fd < 0) |
405 | return (0); | 454 | return (0); |
406 | 455 | ||
407 | /* XXX if this ioctl fails, someting's wrong. the invoker | 456 | /* XXX if this ioctl fails, someting's wrong. the invoker |
@@ -415,17 +464,14 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
415 | * print messages to users of the library. hmm.. | 464 | * print messages to users of the library. hmm.. |
416 | */ | 465 | */ |
417 | 466 | ||
418 | if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) { | 467 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { |
419 | syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)"); | ||
420 | ret = 0; | 468 | ret = 0; |
421 | } else { | 469 | } else { |
422 | cryptodev_sessions--; | ||
423 | ret = 1; | 470 | ret = 1; |
424 | } | 471 | } |
425 | if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) { | 472 | close(state->d_fd); |
426 | close(cryptodev_fd); /* XXX should this be closed? */ | 473 | state->d_fd = -1; |
427 | cryptodev_fd = -1; | 474 | |
428 | } | ||
429 | return (ret); | 475 | return (ret); |
430 | } | 476 | } |
431 | 477 | ||
@@ -434,20 +480,6 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx) | |||
434 | * gets called when libcrypto requests a cipher NID. | 480 | * gets called when libcrypto requests a cipher NID. |
435 | */ | 481 | */ |
436 | 482 | ||
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 */ | 483 | /* DES CBC EVP */ |
452 | const EVP_CIPHER cryptodev_des_cbc = { | 484 | const EVP_CIPHER cryptodev_des_cbc = { |
453 | NID_des_cbc, | 485 | NID_des_cbc, |
@@ -456,7 +488,7 @@ const EVP_CIPHER cryptodev_des_cbc = { | |||
456 | cryptodev_init_key, | 488 | cryptodev_init_key, |
457 | cryptodev_cipher, | 489 | cryptodev_cipher, |
458 | cryptodev_cleanup, | 490 | cryptodev_cleanup, |
459 | sizeof(struct session_op), | 491 | sizeof(struct dev_crypto_state), |
460 | EVP_CIPHER_set_asn1_iv, | 492 | EVP_CIPHER_set_asn1_iv, |
461 | EVP_CIPHER_get_asn1_iv, | 493 | EVP_CIPHER_get_asn1_iv, |
462 | NULL | 494 | NULL |
@@ -470,19 +502,57 @@ const EVP_CIPHER cryptodev_3des_cbc = { | |||
470 | cryptodev_init_key, | 502 | cryptodev_init_key, |
471 | cryptodev_cipher, | 503 | cryptodev_cipher, |
472 | cryptodev_cleanup, | 504 | cryptodev_cleanup, |
473 | sizeof(struct session_op), | 505 | sizeof(struct dev_crypto_state), |
506 | EVP_CIPHER_set_asn1_iv, | ||
507 | EVP_CIPHER_get_asn1_iv, | ||
508 | NULL | ||
509 | }; | ||
510 | |||
511 | const EVP_CIPHER cryptodev_bf_cbc = { | ||
512 | NID_bf_cbc, | ||
513 | 8, 16, 8, | ||
514 | EVP_CIPH_CBC_MODE, | ||
515 | cryptodev_init_key, | ||
516 | cryptodev_cipher, | ||
517 | cryptodev_cleanup, | ||
518 | sizeof(struct dev_crypto_state), | ||
519 | EVP_CIPHER_set_asn1_iv, | ||
520 | EVP_CIPHER_get_asn1_iv, | ||
521 | NULL | ||
522 | }; | ||
523 | |||
524 | const EVP_CIPHER cryptodev_cast_cbc = { | ||
525 | NID_cast5_cbc, | ||
526 | 8, 16, 8, | ||
527 | EVP_CIPH_CBC_MODE, | ||
528 | cryptodev_init_key, | ||
529 | cryptodev_cipher, | ||
530 | cryptodev_cleanup, | ||
531 | sizeof(struct dev_crypto_state), | ||
474 | EVP_CIPHER_set_asn1_iv, | 532 | EVP_CIPHER_set_asn1_iv, |
475 | EVP_CIPHER_get_asn1_iv, | 533 | EVP_CIPHER_get_asn1_iv, |
476 | NULL | 534 | NULL |
477 | }; | 535 | }; |
478 | 536 | ||
537 | const EVP_CIPHER cryptodev_aes_cbc = { | ||
538 | NID_aes_128_cbc, | ||
539 | 16, 16, 16, | ||
540 | EVP_CIPH_CBC_MODE, | ||
541 | cryptodev_init_key, | ||
542 | cryptodev_cipher, | ||
543 | cryptodev_cleanup, | ||
544 | sizeof(struct dev_crypto_state), | ||
545 | EVP_CIPHER_set_asn1_iv, | ||
546 | EVP_CIPHER_get_asn1_iv, | ||
547 | NULL | ||
548 | }; | ||
479 | 549 | ||
480 | /* | 550 | /* |
481 | * Registered by the ENGINE when used to find out how to deal with | 551 | * 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 | 552 | * 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 | 553 | * top level - note, that list is restricted by what we answer with |
484 | */ | 554 | */ |
485 | int | 555 | static int |
486 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | 556 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, |
487 | const int **nids, int nid) | 557 | const int **nids, int nid) |
488 | { | 558 | { |
@@ -490,15 +560,21 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
490 | return (cryptodev_usable_ciphers(nids)); | 560 | return (cryptodev_usable_ciphers(nids)); |
491 | 561 | ||
492 | switch (nid) { | 562 | switch (nid) { |
493 | case NID_rc4: | ||
494 | *cipher = &cryptodev_arc4_cipher; | ||
495 | break; | ||
496 | case NID_des_ede3_cbc: | 563 | case NID_des_ede3_cbc: |
497 | *cipher = &cryptodev_3des_cbc; | 564 | *cipher = &cryptodev_3des_cbc; |
498 | break; | 565 | break; |
499 | case NID_des_cbc: | 566 | case NID_des_cbc: |
500 | *cipher = &cryptodev_des_cbc; | 567 | *cipher = &cryptodev_des_cbc; |
501 | break; | 568 | break; |
569 | case NID_bf_cbc: | ||
570 | *cipher = &cryptodev_bf_cbc; | ||
571 | break; | ||
572 | case NID_cast5_cbc: | ||
573 | *cipher = &cryptodev_cast_cbc; | ||
574 | break; | ||
575 | case NID_aes_128_cbc: | ||
576 | *cipher = &cryptodev_aes_cbc; | ||
577 | break; | ||
502 | default: | 578 | default: |
503 | *cipher = NULL; | 579 | *cipher = NULL; |
504 | break; | 580 | break; |
@@ -506,7 +582,7 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |||
506 | return (*cipher != NULL); | 582 | return (*cipher != NULL); |
507 | } | 583 | } |
508 | 584 | ||
509 | int | 585 | static int |
510 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | 586 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, |
511 | const int **nids, int nid) | 587 | const int **nids, int nid) |
512 | { | 588 | { |
@@ -524,7 +600,6 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
524 | return (*digest != NULL); | 600 | return (*digest != NULL); |
525 | } | 601 | } |
526 | 602 | ||
527 | |||
528 | /* | 603 | /* |
529 | * Convert a BIGNUM to the representation that /dev/crypto needs. | 604 | * Convert a BIGNUM to the representation that /dev/crypto needs. |
530 | * Upon completion of use, the caller is responsible for freeing | 605 | * Upon completion of use, the caller is responsible for freeing |
@@ -533,7 +608,7 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |||
533 | static int | 608 | static int |
534 | bn2crparam(const BIGNUM *a, struct crparam *crp) | 609 | bn2crparam(const BIGNUM *a, struct crparam *crp) |
535 | { | 610 | { |
536 | int i, j, n; | 611 | int i, j, k; |
537 | ssize_t words, bytes, bits; | 612 | ssize_t words, bytes, bits; |
538 | u_char *b; | 613 | u_char *b; |
539 | 614 | ||
@@ -550,17 +625,13 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
550 | crp->crp_p = b; | 625 | crp->crp_p = b; |
551 | crp->crp_nbits = bits; | 626 | crp->crp_nbits = bits; |
552 | 627 | ||
553 | words = (bits + BN_BITS2 - 1) / BN_BITS2; | 628 | for (i = 0, j = 0; i < a->top; i++) { |
554 | 629 | for (k = 0; k < BN_BITS2 / 8; k++) { | |
555 | n = 0; | 630 | if ((j + k) >= bytes) |
556 | for (i = 0; i < words && n < bytes; i++) { | 631 | return (0); |
557 | BN_ULONG word; | 632 | 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 | } | 633 | } |
634 | j += BN_BITS2 / 8; | ||
564 | } | 635 | } |
565 | return (0); | 636 | return (0); |
566 | } | 637 | } |
@@ -569,15 +640,22 @@ bn2crparam(const BIGNUM *a, struct crparam *crp) | |||
569 | static int | 640 | static int |
570 | crparam2bn(struct crparam *crp, BIGNUM *a) | 641 | crparam2bn(struct crparam *crp, BIGNUM *a) |
571 | { | 642 | { |
643 | u_int8_t *pd; | ||
572 | int i, bytes; | 644 | int i, bytes; |
573 | 645 | ||
574 | bytes = (crp->crp_nbits + 7)/8; | 646 | bytes = (crp->crp_nbits + 7) / 8; |
575 | 647 | ||
576 | BN_zero(a); | 648 | if (bytes == 0) |
577 | for (i = bytes - 1; i >= 0; i--) { | 649 | return (-1); |
578 | BN_lshift(a, a, 8); | 650 | |
579 | BN_add_word(a, (u_char)crp->crp_p[i]); | 651 | if ((pd = (u_int8_t *) malloc(bytes)) == NULL) |
580 | } | 652 | return (-1); |
653 | |||
654 | for (i = 0; i < bytes; i++) | ||
655 | pd[i] = crp->crp_p[bytes - i - 1]; | ||
656 | |||
657 | BN_bin2bn(pd, bytes, a); | ||
658 | free(pd); | ||
581 | 659 | ||
582 | return (0); | 660 | return (0); |
583 | } | 661 | } |
@@ -596,25 +674,32 @@ zapparams(struct crypt_kop *kop) | |||
596 | } | 674 | } |
597 | 675 | ||
598 | static int | 676 | static int |
599 | cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s) | 677 | cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s) |
600 | { | 678 | { |
601 | int ret = -1; | 679 | int fd, ret = -1; |
680 | |||
681 | if ((fd = get_asym_dev_crypto()) < 0) | ||
682 | return (ret); | ||
602 | 683 | ||
603 | if (r) { | 684 | if (r) { |
604 | kop->crk_param[kop->crk_iparams].crp_p = malloc(256); | 685 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); |
605 | kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8; | 686 | kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; |
606 | kop->crk_oparams++; | 687 | kop->crk_oparams++; |
607 | } | 688 | } |
608 | if (s) { | 689 | if (s) { |
609 | kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256); | 690 | 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; | 691 | kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8; |
611 | kop->crk_oparams++; | 692 | kop->crk_oparams++; |
612 | } | 693 | } |
613 | 694 | ||
614 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) { | 695 | if (ioctl(fd, CIOCKEY, kop) == 0) { |
615 | crparam2bn(&kop->crk_param[3], r); | 696 | if (r) |
697 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); | ||
698 | if (s) | ||
699 | crparam2bn(&kop->crk_param[kop->crk_iparams+1], s); | ||
616 | ret = 0; | 700 | ret = 0; |
617 | } | 701 | } |
702 | |||
618 | return (ret); | 703 | return (ret); |
619 | } | 704 | } |
620 | 705 | ||
@@ -623,38 +708,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) | 708 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) |
624 | { | 709 | { |
625 | struct crypt_kop kop; | 710 | struct crypt_kop kop; |
626 | int ret = 0; | 711 | int ret = 1; |
712 | |||
713 | /* Currently, we know we can do mod exp iff we can do any | ||
714 | * asymmetric operations at all. | ||
715 | */ | ||
716 | if (cryptodev_asymfeat == 0) { | ||
717 | ret = BN_mod_exp(r, a, p, m, ctx); | ||
718 | return (ret); | ||
719 | } | ||
627 | 720 | ||
628 | memset(&kop, 0, sizeof kop); | 721 | memset(&kop, 0, sizeof kop); |
629 | kop.crk_op = CRK_MOD_EXP; | 722 | kop.crk_op = CRK_MOD_EXP; |
630 | 723 | ||
631 | /* inputs: a m p */ | 724 | /* inputs: a^p % m */ |
632 | if (bn2crparam(a, &kop.crk_param[0])) | 725 | if (bn2crparam(a, &kop.crk_param[0])) |
633 | goto err; | 726 | goto err; |
634 | if (bn2crparam(m, &kop.crk_param[1])) | 727 | if (bn2crparam(p, &kop.crk_param[1])) |
635 | goto err; | 728 | goto err; |
636 | if (bn2crparam(p, &kop.crk_param[2])) | 729 | if (bn2crparam(m, &kop.crk_param[2])) |
637 | goto err; | 730 | goto err; |
638 | kop.crk_iparams = 3; | 731 | kop.crk_iparams = 3; |
639 | 732 | ||
640 | if (cryptodev_sym(&kop, r, NULL) == -1) { | 733 | if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL) == -1) { |
641 | ret = BN_mod_exp(r, a, p, m, ctx); | 734 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
735 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | ||
642 | } | 736 | } |
643 | err: | 737 | err: |
644 | zapparams(&kop); | 738 | zapparams(&kop); |
645 | return (ret); | 739 | return (ret); |
646 | } | 740 | } |
647 | 741 | ||
742 | static int | ||
743 | cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | ||
744 | { | ||
745 | int r; | ||
746 | BN_CTX *ctx; | ||
747 | |||
748 | ctx = BN_CTX_new(); | ||
749 | r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); | ||
750 | BN_CTX_free(ctx); | ||
751 | return (r); | ||
752 | } | ||
648 | 753 | ||
649 | static int | 754 | static int |
650 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | 755 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) |
651 | { | 756 | { |
652 | struct crypt_kop kop; | 757 | struct crypt_kop kop; |
653 | int ret = 0; | 758 | int ret = 1; |
654 | 759 | ||
655 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { | 760 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { |
656 | /* XXX 0 means failure?? */ | 761 | /* XXX 0 means failure?? */ |
657 | goto err; | 762 | return (0); |
658 | } | 763 | } |
659 | 764 | ||
660 | memset(&kop, 0, sizeof kop); | 765 | memset(&kop, 0, sizeof kop); |
@@ -674,9 +779,8 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) | |||
674 | goto err; | 779 | goto err; |
675 | kop.crk_iparams = 6; | 780 | kop.crk_iparams = 6; |
676 | 781 | ||
677 | if (cryptodev_sym(&kop, r0, NULL) == -1) { | 782 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { |
678 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); | 783 | const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); |
679 | |||
680 | ret = (*meth->rsa_mod_exp)(r0, I, rsa); | 784 | ret = (*meth->rsa_mod_exp)(r0, I, rsa); |
681 | } | 785 | } |
682 | err: | 786 | err: |
@@ -690,8 +794,8 @@ static RSA_METHOD cryptodev_rsa = { | |||
690 | NULL, /* rsa_pub_dec */ | 794 | NULL, /* rsa_pub_dec */ |
691 | NULL, /* rsa_priv_enc */ | 795 | NULL, /* rsa_priv_enc */ |
692 | NULL, /* rsa_priv_dec */ | 796 | NULL, /* rsa_priv_dec */ |
693 | cryptodev_rsa_mod_exp, /* rsa_mod_exp */ | 797 | NULL, |
694 | cryptodev_bn_mod_exp, /* bn_mod_exp */ | 798 | NULL, |
695 | NULL, /* init */ | 799 | NULL, /* init */ |
696 | NULL, /* finish */ | 800 | NULL, /* finish */ |
697 | 0, /* flags */ | 801 | 0, /* flags */ |
@@ -707,6 +811,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)); | 811 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); |
708 | } | 812 | } |
709 | 813 | ||
814 | static int | ||
815 | cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | ||
816 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, | ||
817 | BN_CTX *ctx, BN_MONT_CTX *mont) | ||
818 | { | ||
819 | BIGNUM t2; | ||
820 | int ret = 0; | ||
821 | |||
822 | BN_init(&t2); | ||
823 | |||
824 | /* v = ( g^u1 * y^u2 mod p ) mod q */ | ||
825 | /* let t1 = g ^ u1 mod p */ | ||
826 | ret = 0; | ||
827 | |||
828 | if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont)) | ||
829 | goto err; | ||
830 | |||
831 | /* let t2 = y ^ u2 mod p */ | ||
832 | if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont)) | ||
833 | goto err; | ||
834 | /* let u1 = t1 * t2 mod p */ | ||
835 | if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx)) | ||
836 | goto err; | ||
837 | |||
838 | BN_copy(t1,u1); | ||
839 | |||
840 | ret = 1; | ||
841 | err: | ||
842 | BN_free(&t2); | ||
843 | return(ret); | ||
844 | } | ||
845 | |||
710 | static DSA_SIG * | 846 | static DSA_SIG * |
711 | cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | 847 | cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) |
712 | { | 848 | { |
@@ -721,6 +857,7 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
721 | goto err; | 857 | goto err; |
722 | } | 858 | } |
723 | 859 | ||
860 | printf("bar\n"); | ||
724 | memset(&kop, 0, sizeof kop); | 861 | memset(&kop, 0, sizeof kop); |
725 | kop.crk_op = CRK_DSA_SIGN; | 862 | kop.crk_op = CRK_DSA_SIGN; |
726 | 863 | ||
@@ -737,13 +874,13 @@ cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |||
737 | goto err; | 874 | goto err; |
738 | kop.crk_iparams = 5; | 875 | kop.crk_iparams = 5; |
739 | 876 | ||
740 | if (cryptodev_sym(&kop, r, s) == 0) { | 877 | if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, |
878 | BN_num_bytes(dsa->q), s) == 0) { | ||
741 | dsaret = DSA_SIG_new(); | 879 | dsaret = DSA_SIG_new(); |
742 | dsaret->r = r; | 880 | dsaret->r = r; |
743 | dsaret->s = s; | 881 | dsaret->s = s; |
744 | } else { | 882 | } else { |
745 | const DSA_METHOD *meth = DSA_OpenSSL(); | 883 | const DSA_METHOD *meth = DSA_OpenSSL(); |
746 | |||
747 | BN_free(r); | 884 | BN_free(r); |
748 | BN_free(s); | 885 | BN_free(s); |
749 | dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); | 886 | dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa); |
@@ -759,7 +896,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
759 | DSA_SIG *sig, DSA *dsa) | 896 | DSA_SIG *sig, DSA *dsa) |
760 | { | 897 | { |
761 | struct crypt_kop kop; | 898 | struct crypt_kop kop; |
762 | int dsaret = 0; | 899 | int dsaret = 1; |
763 | 900 | ||
764 | memset(&kop, 0, sizeof kop); | 901 | memset(&kop, 0, sizeof kop); |
765 | kop.crk_op = CRK_DSA_VERIFY; | 902 | kop.crk_op = CRK_DSA_VERIFY; |
@@ -781,7 +918,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |||
781 | goto err; | 918 | goto err; |
782 | kop.crk_iparams = 7; | 919 | kop.crk_iparams = 7; |
783 | 920 | ||
784 | if (cryptodev_sym(&kop, NULL, NULL) == 0) { | 921 | if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { |
785 | dsaret = kop.crk_status; | 922 | dsaret = kop.crk_status; |
786 | } else { | 923 | } else { |
787 | const DSA_METHOD *meth = DSA_OpenSSL(); | 924 | const DSA_METHOD *meth = DSA_OpenSSL(); |
@@ -796,11 +933,11 @@ err: | |||
796 | 933 | ||
797 | static DSA_METHOD cryptodev_dsa = { | 934 | static DSA_METHOD cryptodev_dsa = { |
798 | "cryptodev DSA method", | 935 | "cryptodev DSA method", |
799 | cryptodev_dsa_do_sign, | 936 | NULL, |
800 | NULL, /* dsa_sign_setup */ | 937 | NULL, /* dsa_sign_setup */ |
801 | cryptodev_dsa_verify, | 938 | NULL, |
802 | NULL, /* dsa_mod_exp */ | 939 | NULL, /* dsa_mod_exp */ |
803 | cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */ | 940 | NULL, |
804 | NULL, /* init */ | 941 | NULL, /* init */ |
805 | NULL, /* finish */ | 942 | NULL, /* finish */ |
806 | 0, /* flags */ | 943 | 0, /* flags */ |
@@ -819,8 +956,14 @@ static int | |||
819 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | 956 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) |
820 | { | 957 | { |
821 | struct crypt_kop kop; | 958 | struct crypt_kop kop; |
822 | int dhret = 0; | 959 | int dhret = 1; |
823 | int keylen; | 960 | int fd, keylen; |
961 | |||
962 | if ((fd = get_asym_dev_crypto()) < 0) { | ||
963 | const DH_METHOD *meth = DH_OpenSSL(); | ||
964 | |||
965 | return ((meth->compute_key)(key, pub_key, dh)); | ||
966 | } | ||
824 | 967 | ||
825 | keylen = BN_num_bits(dh->p); | 968 | keylen = BN_num_bits(dh->p); |
826 | 969 | ||
@@ -840,7 +983,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |||
840 | kop.crk_param[3].crp_nbits = keylen * 8; | 983 | kop.crk_param[3].crp_nbits = keylen * 8; |
841 | kop.crk_oparams = 1; | 984 | kop.crk_oparams = 1; |
842 | 985 | ||
843 | if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) { | 986 | if (ioctl(fd, CIOCKEY, &kop) == -1) { |
844 | const DH_METHOD *meth = DH_OpenSSL(); | 987 | const DH_METHOD *meth = DH_OpenSSL(); |
845 | 988 | ||
846 | dhret = (meth->compute_key)(key, pub_key, dh); | 989 | dhret = (meth->compute_key)(key, pub_key, dh); |
@@ -854,8 +997,8 @@ err: | |||
854 | static DH_METHOD cryptodev_dh = { | 997 | static DH_METHOD cryptodev_dh = { |
855 | "cryptodev DH method", | 998 | "cryptodev DH method", |
856 | NULL, /* cryptodev_dh_generate_key */ | 999 | NULL, /* cryptodev_dh_generate_key */ |
857 | cryptodev_dh_compute_key, | 1000 | NULL, |
858 | cryptodev_mod_exp_dh, | 1001 | NULL, |
859 | NULL, | 1002 | NULL, |
860 | NULL, | 1003 | NULL, |
861 | 0, /* flags */ | 1004 | 0, /* flags */ |
@@ -884,11 +1027,21 @@ void | |||
884 | ENGINE_load_cryptodev(void) | 1027 | ENGINE_load_cryptodev(void) |
885 | { | 1028 | { |
886 | ENGINE *engine = ENGINE_new(); | 1029 | ENGINE *engine = ENGINE_new(); |
887 | const RSA_METHOD *rsa_meth; | 1030 | int fd; |
888 | const DH_METHOD *dh_meth; | ||
889 | 1031 | ||
890 | if (engine == NULL) | 1032 | if (engine == NULL) |
891 | return; | 1033 | return; |
1034 | if ((fd = get_dev_crypto()) < 0) | ||
1035 | return; | ||
1036 | |||
1037 | /* | ||
1038 | * find out what asymmetric crypto algorithms we support | ||
1039 | */ | ||
1040 | if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | ||
1041 | close(fd); | ||
1042 | return; | ||
1043 | } | ||
1044 | close(fd); | ||
892 | 1045 | ||
893 | if (!ENGINE_set_id(engine, "cryptodev") || | 1046 | if (!ENGINE_set_id(engine, "cryptodev") || |
894 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || | 1047 | !ENGINE_set_name(engine, "OpenBSD cryptodev engine") || |
@@ -900,24 +1053,52 @@ ENGINE_load_cryptodev(void) | |||
900 | return; | 1053 | return; |
901 | } | 1054 | } |
902 | 1055 | ||
903 | if ((cryptodev_symfeat & CRSFEAT_RSA) && | 1056 | if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { |
904 | ENGINE_set_RSA(engine, &cryptodev_rsa)) { | 1057 | const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); |
905 | rsa_meth = RSA_PKCS1_SSLeay(); | 1058 | |
1059 | cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; | ||
1060 | cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; | ||
906 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; | 1061 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; |
907 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; | 1062 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; |
908 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec; | 1063 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; |
909 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; | 1064 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; |
1065 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1066 | cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; | ||
1067 | if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) | ||
1068 | cryptodev_rsa.rsa_mod_exp = | ||
1069 | cryptodev_rsa_mod_exp; | ||
1070 | else | ||
1071 | cryptodev_rsa.rsa_mod_exp = | ||
1072 | cryptodev_rsa_nocrt_mod_exp; | ||
1073 | } | ||
910 | } | 1074 | } |
911 | 1075 | ||
912 | if ((cryptodev_symfeat & CRSFEAT_DSA) && | 1076 | if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { |
913 | ENGINE_set_DSA(engine, &cryptodev_dsa)) { | 1077 | const DSA_METHOD *meth = DSA_OpenSSL(); |
1078 | |||
1079 | memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); | ||
1080 | if (cryptodev_asymfeat & CRF_DSA_SIGN) | ||
1081 | cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; | ||
1082 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1083 | cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; | ||
1084 | cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; | ||
1085 | } | ||
1086 | if (cryptodev_asymfeat & CRF_DSA_VERIFY) | ||
1087 | cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; | ||
914 | } | 1088 | } |
915 | 1089 | ||
916 | if ((cryptodev_symfeat & CRSFEAT_DH) && | 1090 | if (ENGINE_set_DH(engine, &cryptodev_dh)){ |
917 | ENGINE_set_DH(engine, &cryptodev_dh)) { | 1091 | const DH_METHOD *dh_meth = DH_OpenSSL(); |
918 | dh_meth = DH_OpenSSL(); | 1092 | |
919 | cryptodev_dh.generate_key = dh_meth->generate_key; | 1093 | cryptodev_dh.generate_key = dh_meth->generate_key; |
920 | cryptodev_dh.compute_key = dh_meth->compute_key; | 1094 | cryptodev_dh.compute_key = dh_meth->compute_key; |
1095 | cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; | ||
1096 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | ||
1097 | cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; | ||
1098 | if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) | ||
1099 | cryptodev_dh.compute_key = | ||
1100 | cryptodev_dh_compute_key; | ||
1101 | } | ||
921 | } | 1102 | } |
922 | 1103 | ||
923 | ENGINE_add(engine); | 1104 | ENGINE_add(engine); |