diff options
author | beck <> | 2002-05-15 02:29:21 +0000 |
---|---|---|
committer | beck <> | 2002-05-15 02:29:21 +0000 |
commit | b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9 (patch) | |
tree | fa27cf82a1250b64ed3bf5f4a18c7354d470bbcc /src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c | |
parent | e471e1ea98d673597b182ea85f29e30c97cd08b5 (diff) | |
download | openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.tar.gz openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.tar.bz2 openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.zip |
OpenSSL 0.9.7 stable 2002 05 08 merge
Diffstat (limited to 'src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c')
-rw-r--r-- | src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c | 594 |
1 files changed, 594 insertions, 0 deletions
diff --git a/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c b/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c new file mode 100644 index 0000000000..f946389b8a --- /dev/null +++ b/src/lib/libcrypto/engine/hw_openbsd_dev_crypto.c | |||
@@ -0,0 +1,594 @@ | |||
1 | /* Written by Ben Laurie <ben@algroup.co.uk> August 2001 */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * licensing@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include <openssl/engine.h> | ||
57 | #include <openssl/evp.h> | ||
58 | #include "eng_int.h" | ||
59 | /* Maybe this is needed? ... */ | ||
60 | #ifdef FLAT_INC | ||
61 | #include "evp_locl.h" | ||
62 | #else | ||
63 | #include "../evp/evp_locl.h" | ||
64 | #endif | ||
65 | #include <openssl/conf.h> | ||
66 | |||
67 | #ifndef OPENSSL_OPENBSD_DEV_CRYPTO | ||
68 | |||
69 | void ENGINE_load_openbsd_dev_crypto(void) | ||
70 | { | ||
71 | /* This is a NOP unless OPENSSL_OPENBSD_DEV_CRYPTO is defined */ | ||
72 | return; | ||
73 | } | ||
74 | |||
75 | #else /* OPENSSL_OPENBSD_DEV_CRYPTO */ | ||
76 | |||
77 | #include <fcntl.h> | ||
78 | #include <stdio.h> | ||
79 | #include <errno.h> | ||
80 | #include <assert.h> | ||
81 | #include <unistd.h> | ||
82 | #include <sys/ioctl.h> | ||
83 | |||
84 | #include <crypto/cryptodev.h> | ||
85 | |||
86 | /****************************************************/ | ||
87 | /* Declare the normal generic ENGINE stuff here ... */ | ||
88 | |||
89 | static int dev_crypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
90 | const int **nids, int nid); | ||
91 | static int dev_crypto_digests(ENGINE *e, const EVP_MD **digest, | ||
92 | const int **nids, int nid); | ||
93 | |||
94 | static const char dev_crypto_id[] = "openbsd_dev_crypto"; | ||
95 | static const char dev_crypto_name[] = "OpenBSD /dev/crypto"; | ||
96 | |||
97 | static long allow_misaligned; | ||
98 | |||
99 | #define DEV_CRYPTO_CMD_ALLOW_MISALIGNED ENGINE_CMD_BASE | ||
100 | static const ENGINE_CMD_DEFN dev_crypto_cmd_defns[]= | ||
101 | { | ||
102 | { DEV_CRYPTO_CMD_ALLOW_MISALIGNED, | ||
103 | "allow_misaligned", | ||
104 | "Permit misaligned data to be used", | ||
105 | ENGINE_CMD_FLAG_NUMERIC }, | ||
106 | { 0, NULL, NULL, 0 } | ||
107 | }; | ||
108 | |||
109 | static int dev_crypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | ||
110 | { | ||
111 | switch(cmd) | ||
112 | { | ||
113 | case DEV_CRYPTO_CMD_ALLOW_MISALIGNED: | ||
114 | allow_misaligned=i; | ||
115 | printf("allow misaligned=%ld\n",allow_misaligned); | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | static ENGINE *engine_openbsd_dev_crypto(void) | ||
123 | { | ||
124 | ENGINE *engine=ENGINE_new(); | ||
125 | |||
126 | if(!ENGINE_set_id(engine, dev_crypto_id) || | ||
127 | !ENGINE_set_name(engine, dev_crypto_name) || | ||
128 | !ENGINE_set_ciphers(engine, dev_crypto_ciphers) || | ||
129 | !ENGINE_set_digests(engine, dev_crypto_digests) || | ||
130 | !ENGINE_set_ctrl_function(engine, dev_crypto_ctrl) || | ||
131 | !ENGINE_set_cmd_defns(engine, dev_crypto_cmd_defns)) | ||
132 | { | ||
133 | ENGINE_free(engine); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | return engine; | ||
138 | } | ||
139 | |||
140 | void ENGINE_load_openbsd_dev_crypto(void) | ||
141 | { | ||
142 | /* Copied from eng_[openssl|dyn].c */ | ||
143 | ENGINE *toadd = engine_openbsd_dev_crypto(); | ||
144 | if(!toadd) return; | ||
145 | ENGINE_add(toadd); | ||
146 | ENGINE_free(toadd); | ||
147 | ERR_clear_error(); | ||
148 | } | ||
149 | |||
150 | /******************************************************************************/ | ||
151 | /* Clip in the stuff from crypto/evp/openbsd_hw.c here. NB: What has changed? */ | ||
152 | /* I've removed the exposed EVP_*** functions, they're accessed through the */ | ||
153 | /* "dev_crypto_[ciphers|digests]" handlers. I've also moved the EVP_CIPHER */ | ||
154 | /* and EVP_MD structures to the bottom where they are close to the handlers */ | ||
155 | /* that expose them. What should be done? The global data (file-descriptors, */ | ||
156 | /* etc) should be put into ENGINE's ex_data support, and per-context data */ | ||
157 | /* (also file-descriptors perhaps) should be put into the contexts. Also code */ | ||
158 | /* formatting, fprintf statements, and OpenSSL-style error handling should be */ | ||
159 | /* added (dynamically, like the other ENGINEs). Also, "dynamic" support */ | ||
160 | /* be added to this ENGINE once it's up and running so that it could be built */ | ||
161 | /* as a shared-library. What else? device initialisation should take place */ | ||
162 | /* inside an ENGINE 'init()' handler (and likewise 'finish()'). ciphers and */ | ||
163 | /* digests won't be used by the framework unless the ENGINE has been */ | ||
164 | /* successfully initialised (that's one of the things you get for free) so */ | ||
165 | /* initialisation, including returning failure if device setup fails, can be */ | ||
166 | /* handled quite cleanly. This could presumably handle the opening (and then */ | ||
167 | /* closing inside 'finish()') of the 'cryptodev_fd' file-descriptor). */ | ||
168 | |||
169 | /* longest key supported in hardware */ | ||
170 | #define MAX_HW_KEY 24 | ||
171 | #define MAX_HW_IV 8 | ||
172 | |||
173 | #define MD5_DIGEST_LENGTH 16 | ||
174 | #define MD5_CBLOCK 64 | ||
175 | |||
176 | static int fd; | ||
177 | static int dev_failed; | ||
178 | |||
179 | typedef struct session_op session_op; | ||
180 | |||
181 | #define CDATA(ctx) EVP_C_DATA(session_op,ctx) | ||
182 | |||
183 | static void err(const char *str) | ||
184 | { | ||
185 | fprintf(stderr,"%s: errno %d\n",str,errno); | ||
186 | } | ||
187 | |||
188 | static int dev_crypto_init(session_op *ses) | ||
189 | { | ||
190 | if(dev_failed) | ||
191 | return 0; | ||
192 | if(!fd) | ||
193 | { | ||
194 | int cryptodev_fd; | ||
195 | |||
196 | if ((cryptodev_fd=open("/dev/crypto",O_RDWR,0)) < 0) | ||
197 | { | ||
198 | err("/dev/crypto"); | ||
199 | dev_failed=1; | ||
200 | return 0; | ||
201 | } | ||
202 | if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1) | ||
203 | { | ||
204 | err("CRIOGET failed"); | ||
205 | close(cryptodev_fd); | ||
206 | dev_failed=1; | ||
207 | return 0; | ||
208 | } | ||
209 | close(cryptodev_fd); | ||
210 | } | ||
211 | assert(ses); | ||
212 | memset(ses,'\0',sizeof *ses); | ||
213 | |||
214 | return 1; | ||
215 | } | ||
216 | |||
217 | static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx) | ||
218 | { | ||
219 | fprintf(stderr,"cleanup %d\n",CDATA(ctx)->ses); | ||
220 | if(ioctl(fd,CIOCFSESSION,&CDATA(ctx)->ses) == -1) | ||
221 | err("CIOCFSESSION failed"); | ||
222 | |||
223 | OPENSSL_free(CDATA(ctx)->key); | ||
224 | |||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx,int cipher, | ||
229 | const unsigned char *key,int klen) | ||
230 | { | ||
231 | if(!dev_crypto_init(CDATA(ctx))) | ||
232 | return 0; | ||
233 | |||
234 | CDATA(ctx)->key=OPENSSL_malloc(MAX_HW_KEY); | ||
235 | |||
236 | assert(ctx->cipher->iv_len <= MAX_HW_IV); | ||
237 | |||
238 | memcpy(CDATA(ctx)->key,key,klen); | ||
239 | |||
240 | CDATA(ctx)->cipher=cipher; | ||
241 | CDATA(ctx)->keylen=klen; | ||
242 | |||
243 | if (ioctl(fd,CIOCGSESSION,CDATA(ctx)) == -1) | ||
244 | { | ||
245 | err("CIOCGSESSION failed"); | ||
246 | return 0; | ||
247 | } | ||
248 | return 1; | ||
249 | } | ||
250 | |||
251 | static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, | ||
252 | const unsigned char *in,unsigned int inl) | ||
253 | { | ||
254 | struct crypt_op cryp; | ||
255 | unsigned char lb[MAX_HW_IV]; | ||
256 | |||
257 | if(!inl) | ||
258 | return 1; | ||
259 | |||
260 | assert(CDATA(ctx)); | ||
261 | assert(!dev_failed); | ||
262 | |||
263 | memset(&cryp,'\0',sizeof cryp); | ||
264 | cryp.ses=CDATA(ctx)->ses; | ||
265 | cryp.op=ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; | ||
266 | cryp.flags=0; | ||
267 | cryp.len=inl; | ||
268 | assert((inl&(ctx->cipher->block_size-1)) == 0); | ||
269 | cryp.src=(caddr_t)in; | ||
270 | cryp.dst=(caddr_t)out; | ||
271 | cryp.mac=0; | ||
272 | if(ctx->cipher->iv_len) | ||
273 | cryp.iv=(caddr_t)ctx->iv; | ||
274 | |||
275 | if(!ctx->encrypt) | ||
276 | memcpy(lb,&in[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len); | ||
277 | |||
278 | if(ioctl(fd, CIOCCRYPT, &cryp) == -1) | ||
279 | { | ||
280 | if(errno == EINVAL) /* buffers are misaligned */ | ||
281 | { | ||
282 | unsigned int cinl=0; | ||
283 | char *cin=NULL; | ||
284 | char *cout=NULL; | ||
285 | |||
286 | /* NB: this can only make cinl != inl with stream ciphers */ | ||
287 | cinl=(inl+3)/4*4; | ||
288 | |||
289 | if(((unsigned long)in&3) || cinl != inl) | ||
290 | { | ||
291 | cin=OPENSSL_malloc(cinl); | ||
292 | memcpy(cin,in,inl); | ||
293 | cryp.src=cin; | ||
294 | } | ||
295 | |||
296 | if(((unsigned long)out&3) || cinl != inl) | ||
297 | { | ||
298 | cout=OPENSSL_malloc(cinl); | ||
299 | cryp.dst=cout; | ||
300 | } | ||
301 | |||
302 | cryp.len=cinl; | ||
303 | |||
304 | if(ioctl(fd, CIOCCRYPT, &cryp) == -1) | ||
305 | { | ||
306 | err("CIOCCRYPT(2) failed"); | ||
307 | printf("src=%p dst=%p\n",cryp.src,cryp.dst); | ||
308 | abort(); | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | if(cout) | ||
313 | { | ||
314 | memcpy(out,cout,inl); | ||
315 | OPENSSL_free(cout); | ||
316 | } | ||
317 | if(cin) | ||
318 | OPENSSL_free(cin); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | err("CIOCCRYPT failed"); | ||
323 | abort(); | ||
324 | return 0; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | if(ctx->encrypt) | ||
329 | memcpy(ctx->iv,&out[cryp.len-ctx->cipher->iv_len],ctx->cipher->iv_len); | ||
330 | else | ||
331 | memcpy(ctx->iv,lb,ctx->cipher->iv_len); | ||
332 | |||
333 | return 1; | ||
334 | } | ||
335 | |||
336 | static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx, | ||
337 | const unsigned char *key, | ||
338 | const unsigned char *iv, int enc) | ||
339 | { return dev_crypto_init_key(ctx,CRYPTO_3DES_CBC,key,24); } | ||
340 | |||
341 | static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx, | ||
342 | const unsigned char *key, | ||
343 | const unsigned char *iv, int enc) | ||
344 | { return dev_crypto_init_key(ctx,CRYPTO_ARC4,key,16); } | ||
345 | |||
346 | typedef struct | ||
347 | { | ||
348 | session_op sess; | ||
349 | char *data; | ||
350 | int len; | ||
351 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
352 | } MD_DATA; | ||
353 | |||
354 | static int dev_crypto_init_digest(MD_DATA *md_data,int mac) | ||
355 | { | ||
356 | if(!dev_crypto_init(&md_data->sess)) | ||
357 | return 0; | ||
358 | |||
359 | md_data->len=0; | ||
360 | md_data->data=NULL; | ||
361 | |||
362 | md_data->sess.mac=mac; | ||
363 | |||
364 | if (ioctl(fd,CIOCGSESSION,&md_data->sess) == -1) | ||
365 | { | ||
366 | err("CIOCGSESSION failed"); | ||
367 | return 0; | ||
368 | } | ||
369 | fprintf(stderr,"opened %d\n",md_data->sess.ses); | ||
370 | return 1; | ||
371 | } | ||
372 | |||
373 | static int dev_crypto_cleanup_digest(MD_DATA *md_data) | ||
374 | { | ||
375 | fprintf(stderr,"cleanup %d\n",md_data->sess.ses); | ||
376 | if (ioctl(fd,CIOCFSESSION,&md_data->sess.ses) == -1) | ||
377 | { | ||
378 | err("CIOCFSESSION failed"); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | return 1; | ||
383 | } | ||
384 | |||
385 | /* FIXME: if device can do chained MACs, then don't accumulate */ | ||
386 | /* FIXME: move accumulation to the framework */ | ||
387 | static int dev_crypto_md5_init(EVP_MD_CTX *ctx) | ||
388 | { return dev_crypto_init_digest(ctx->md_data,CRYPTO_MD5); } | ||
389 | |||
390 | static int do_digest(int ses,unsigned char *md,const void *data,int len) | ||
391 | { | ||
392 | struct crypt_op cryp; | ||
393 | static unsigned char md5zero[16]= | ||
394 | { | ||
395 | 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04, | ||
396 | 0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e | ||
397 | }; | ||
398 | |||
399 | /* some cards can't do zero length */ | ||
400 | if(!len) | ||
401 | { | ||
402 | memcpy(md,md5zero,16); | ||
403 | return 1; | ||
404 | } | ||
405 | |||
406 | memset(&cryp,'\0',sizeof cryp); | ||
407 | cryp.ses=ses; | ||
408 | cryp.op=COP_ENCRYPT;/* required to do the MAC rather than check it */ | ||
409 | cryp.len=len; | ||
410 | cryp.src=(caddr_t)data; | ||
411 | cryp.dst=(caddr_t)data; // FIXME!!! | ||
412 | cryp.mac=(caddr_t)md; | ||
413 | |||
414 | if(ioctl(fd, CIOCCRYPT, &cryp) == -1) | ||
415 | { | ||
416 | if(errno == EINVAL && allow_misaligned) /* buffer is misaligned */ | ||
417 | { | ||
418 | char *dcopy; | ||
419 | |||
420 | dcopy=OPENSSL_malloc(len); | ||
421 | memcpy(dcopy,data,len); | ||
422 | cryp.src=dcopy; | ||
423 | cryp.dst=cryp.src; // FIXME!!! | ||
424 | |||
425 | if(ioctl(fd, CIOCCRYPT, &cryp) == -1) | ||
426 | { | ||
427 | err("CIOCCRYPT(MAC2) failed"); | ||
428 | abort(); | ||
429 | return 0; | ||
430 | } | ||
431 | OPENSSL_free(dcopy); | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | err("CIOCCRYPT(MAC) failed"); | ||
436 | abort(); | ||
437 | return 0; | ||
438 | } | ||
439 | } | ||
440 | // printf("done\n"); | ||
441 | |||
442 | return 1; | ||
443 | } | ||
444 | |||
445 | static int dev_crypto_md5_update(EVP_MD_CTX *ctx,const void *data, | ||
446 | unsigned long len) | ||
447 | { | ||
448 | MD_DATA *md_data=ctx->md_data; | ||
449 | |||
450 | if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT) | ||
451 | return do_digest(md_data->sess.ses,md_data->md,data,len); | ||
452 | |||
453 | md_data->data=OPENSSL_realloc(md_data->data,md_data->len+len); | ||
454 | memcpy(md_data->data+md_data->len,data,len); | ||
455 | md_data->len+=len; | ||
456 | |||
457 | return 1; | ||
458 | } | ||
459 | |||
460 | static int dev_crypto_md5_final(EVP_MD_CTX *ctx,unsigned char *md) | ||
461 | { | ||
462 | int ret; | ||
463 | MD_DATA *md_data=ctx->md_data; | ||
464 | |||
465 | if(ctx->flags&EVP_MD_CTX_FLAG_ONESHOT) | ||
466 | { | ||
467 | memcpy(md,md_data->md,MD5_DIGEST_LENGTH); | ||
468 | ret=1; | ||
469 | } | ||
470 | else | ||
471 | { | ||
472 | ret=do_digest(md_data->sess.ses,md,md_data->data,md_data->len); | ||
473 | OPENSSL_free(md_data->data); | ||
474 | md_data->data=NULL; | ||
475 | md_data->len=0; | ||
476 | } | ||
477 | |||
478 | return ret; | ||
479 | } | ||
480 | |||
481 | static int dev_crypto_md5_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) | ||
482 | { | ||
483 | const MD_DATA *from_md=from->md_data; | ||
484 | MD_DATA *to_md=to->md_data; | ||
485 | |||
486 | // How do we copy sessions? | ||
487 | assert(from->digest->flags&EVP_MD_FLAG_ONESHOT); | ||
488 | |||
489 | to_md->data=OPENSSL_malloc(from_md->len); | ||
490 | memcpy(to_md->data,from_md->data,from_md->len); | ||
491 | |||
492 | return 1; | ||
493 | } | ||
494 | |||
495 | static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx) | ||
496 | { | ||
497 | return dev_crypto_cleanup_digest(ctx->md_data); | ||
498 | } | ||
499 | |||
500 | /**************************************************************************/ | ||
501 | /* Here are the moved declarations of the EVP_CIPHER and EVP_MD */ | ||
502 | /* implementations. They're down here to be within easy editor-distance */ | ||
503 | /* of the digests and ciphers handler functions. */ | ||
504 | |||
505 | #define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher | ||
506 | |||
507 | BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8, | ||
508 | 0, dev_crypto_des_ede3_init_key, | ||
509 | dev_crypto_cleanup, | ||
510 | EVP_CIPHER_set_asn1_iv, | ||
511 | EVP_CIPHER_get_asn1_iv, | ||
512 | NULL) | ||
513 | |||
514 | static const EVP_CIPHER r4_cipher= | ||
515 | { | ||
516 | NID_rc4, | ||
517 | 1,16,0, /* FIXME: key should be up to 256 bytes */ | ||
518 | EVP_CIPH_VARIABLE_LENGTH, | ||
519 | dev_crypto_rc4_init_key, | ||
520 | dev_crypto_cipher, | ||
521 | dev_crypto_cleanup, | ||
522 | sizeof(session_op), | ||
523 | NULL, | ||
524 | NULL, | ||
525 | NULL | ||
526 | }; | ||
527 | |||
528 | static const EVP_MD md5_md= | ||
529 | { | ||
530 | NID_md5, | ||
531 | NID_md5WithRSAEncryption, | ||
532 | MD5_DIGEST_LENGTH, | ||
533 | EVP_MD_FLAG_ONESHOT, // XXX: set according to device info... | ||
534 | dev_crypto_md5_init, | ||
535 | dev_crypto_md5_update, | ||
536 | dev_crypto_md5_final, | ||
537 | dev_crypto_md5_copy, | ||
538 | dev_crypto_md5_cleanup, | ||
539 | EVP_PKEY_RSA_method, | ||
540 | MD5_CBLOCK, | ||
541 | sizeof(MD_DATA), | ||
542 | }; | ||
543 | |||
544 | /****************************************************************/ | ||
545 | /* Implement the dev_crypto_[ciphers|digests] handlers here ... */ | ||
546 | |||
547 | static int cipher_nids[] = {NID_des_ede3_cbc, NID_rc4}; | ||
548 | static int cipher_nids_num = 2; | ||
549 | static int digest_nids[] = {NID_md5}; | ||
550 | static int digest_nids_num = 1; | ||
551 | |||
552 | static int dev_crypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
553 | const int **nids, int nid) | ||
554 | { | ||
555 | if(!cipher) | ||
556 | { | ||
557 | /* We are returning a list of supported nids */ | ||
558 | *nids = cipher_nids; | ||
559 | return cipher_nids_num; | ||
560 | } | ||
561 | /* We are being asked for a specific cipher */ | ||
562 | if(nid == NID_rc4) | ||
563 | *cipher = &r4_cipher; | ||
564 | else if(nid == NID_des_ede3_cbc) | ||
565 | *cipher = &dev_crypto_des_ede3_cbc; | ||
566 | else | ||
567 | { | ||
568 | *cipher = NULL; | ||
569 | return 0; | ||
570 | } | ||
571 | return 1; | ||
572 | } | ||
573 | |||
574 | static int dev_crypto_digests(ENGINE *e, const EVP_MD **digest, | ||
575 | const int **nids, int nid) | ||
576 | { | ||
577 | if(!digest) | ||
578 | { | ||
579 | /* We are returning a list of supported nids */ | ||
580 | *nids = digest_nids; | ||
581 | return digest_nids_num; | ||
582 | } | ||
583 | /* We are being asked for a specific digest */ | ||
584 | if(nid == NID_md5) | ||
585 | *digest = &md5_md; | ||
586 | else | ||
587 | { | ||
588 | *digest = NULL; | ||
589 | return 0; | ||
590 | } | ||
591 | return 1; | ||
592 | } | ||
593 | |||
594 | #endif /* OPENSSL_OPENBSD_DEV_CRYPTO */ | ||