1/* crypto/engine/hw_zencod.c */
2 /* Written by Fred Donnat (frederic.donnat@zencod.com) for "zencod"
3 * engine integration in order to redirect crypto computing on a crypto
4 * hardware accelerator zenssl32  ;-)
5 *
6 * Date : 25 jun 2002
7 * Revision : 17 Ju7 2002
8 * Version : zencod_engine-0.9.7
9 */
10
11/* ====================================================================
12 * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in
23 *    the documentation and/or other materials provided with the
24 *    distribution.
25 *
26 * 3. All advertising materials mentioning features or use of this
27 *    software must display the following acknowledgment:
28 *    "This product includes software developed by the OpenSSL Project
29 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
30 *
31 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
32 *    endorse or promote products derived from this software without
33 *    prior written permission. For written permission, please contact
34 *    licensing@OpenSSL.org.
35 *
36 * 5. Products derived from this software may not be called "OpenSSL"
37 *    nor may "OpenSSL" appear in their names without prior written
38 *    permission of the OpenSSL Project.
39 *
40 * 6. Redistributions of any form whatsoever must retain the following
41 *    acknowledgment:
42 *    "This product includes software developed by the OpenSSL Project
43 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
46 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56 * OF THE POSSIBILITY OF SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This product includes cryptographic software written by Eric Young
60 * (eay@cryptsoft.com).  This product includes software written by Tim
61 * Hudson (tjh@cryptsoft.com).
62 *
63 */
64
65
66/* ENGINE general include */
67#include <stdio.h>
68#include <openssl/crypto.h>
69#include <openssl/dso.h>
70#include <openssl/engine.h>
71
72#ifndef OPENSSL_NO_HW
73#ifndef OPENSSL_NO_HW_ZENCOD
74
75#ifdef FLAT_INC
76#  include "hw_zencod.h"
77#else
78#  include "vendor_defns/hw_zencod.h"
79#endif
80
81#define ZENCOD_LIB_NAME "zencod engine"
82#include "hw_zencod_err.c"
83
84#define FAIL_TO_SOFTWARE		-15
85
86#define	ZEN_LIBRARY	"zenbridge"
87
88#if 0
89#  define PERROR(s)	perror(s)
90#  define CHEESE()	fputs("## [ZenEngine] ## " __FUNCTION__ "\n", stderr)
91#else
92#  define PERROR(s)
93#  define CHEESE()
94#endif
95
96
97/* Sorry ;) */
98#ifndef WIN32
99static inline void esrever ( unsigned char *d, int l )
100{
101	for(;--l>0;--l,d++){*d^=*(d+l);*(d+l)^=*d;*d^=*(d+l);}
102}
103
104static inline void ypcmem ( unsigned char *d, const unsigned char *s, int l )
105{
106	for(d+=l;l--;)*--d=*s++;
107}
108#else
109static __inline void esrever ( unsigned char *d, int l )
110{
111	for(;--l>0;--l,d++){*d^=*(d+l);*(d+l)^=*d;*d^=*(d+l);}
112}
113
114static __inline void ypcmem ( unsigned char *d, const unsigned char *s, int l )
115{
116	for(d+=l;l--;)*--d=*s++;
117}
118#endif
119
120
121#define BIGNUM2ZEN(n, bn)	(ptr_zencod_init_number((n), \
122					(unsigned long) ((bn)->top * BN_BITS2), \
123					(unsigned char *) ((bn)->d)))
124
125#define ZEN_BITS(n, bytes)	(ptr_zencod_bytes2bits((unsigned char *) (n), (unsigned long) (bytes)))
126#define ZEN_BYTES(bits)	(ptr_zencod_bits2bytes((unsigned long) (bits)))
127
128
129/* Function for ENGINE detection and control */
130static int zencod_destroy ( ENGINE *e ) ;
131static int zencod_init ( ENGINE *e ) ;
132static int zencod_finish ( ENGINE *e ) ;
133static int zencod_ctrl ( ENGINE *e, int cmd, long i, void *p, void (*f) () ) ;
134
135/* BIGNUM stuff */
136static int zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx ) ;
137
138/* RSA stuff */
139#ifndef OPENSSL_NO_RSA
140static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *I, RSA *rsa ) ;
141static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
142		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx ) ;
143#endif
144
145/* DSA stuff */
146#ifndef OPENSSL_NO_DSA
147static int DSA_zencod_bn_mod_exp ( DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
148		BN_MONT_CTX *m_ctx ) ;
149
150static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa ) ;
151static int DSA_zencod_do_verify ( const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
152		DSA *dsa ) ;
153#endif
154
155/* DH stuff */
156#ifndef OPENSSL_NO_DH
157static int DH_zencod_bn_mod_exp ( const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
158		BN_MONT_CTX *m_ctx ) ;
159static int DH_zencod_generate_key ( DH *dh ) ;
160static int DH_zencod_compute_key ( unsigned char *key, const BIGNUM *pub_key, DH *dh ) ;
161#endif
162
163/* Rand stuff */
164static void RAND_zencod_seed ( const void *buf, int num ) ;
165static int RAND_zencod_rand_bytes ( unsigned char *buf, int num ) ;
166static int RAND_zencod_rand_status ( void ) ;
167
168/* Digest Stuff */
169static int engine_digests ( ENGINE *e, const EVP_MD **digest, const int **nids, int nid ) ;
170
171/* Cipher Stuff */
172static int engine_ciphers ( ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid ) ;
173
174
175#define ZENCOD_CMD_SO_PATH			ENGINE_CMD_BASE
176static const ENGINE_CMD_DEFN zencod_cmd_defns [ ] =
177{
178	{ ZENCOD_CMD_SO_PATH,
179	  "SO_PATH",
180	  "Specifies the path to the 'zenbridge' shared library",
181	  ENGINE_CMD_FLAG_STRING},
182	{ 0, NULL, NULL, 0 }
183} ;
184
185
186#ifndef OPENSSL_NO_RSA
187/* Our internal RSA_METHOD specific to zencod ENGINE providing pointers to our function */
188static RSA_METHOD zencod_rsa =
189{
190	"ZENCOD RSA method",
191	NULL,
192	NULL,
193	NULL,
194	NULL,
195	RSA_zencod_rsa_mod_exp,
196	RSA_zencod_bn_mod_exp,
197	NULL,
198	NULL,
199	0,
200	NULL,
201	NULL,
202	NULL
203} ;
204#endif
205
206#ifndef OPENSSL_NO_DSA
207/* Our internal DSA_METHOD specific to zencod ENGINE providing pointers to our function */
208static DSA_METHOD zencod_dsa =
209{
210	"ZENCOD DSA method",
211	DSA_zencod_do_sign,
212	NULL,
213	DSA_zencod_do_verify,
214	NULL,
215	DSA_zencod_bn_mod_exp,
216	NULL,
217	NULL,
218	0,
219	NULL
220} ;
221#endif
222
223#ifndef OPENSSL_NO_DH
224/* Our internal DH_METHOD specific to zencod ENGINE providing pointers to our function */
225static DH_METHOD zencod_dh =
226{
227	"ZENCOD DH method",
228	DH_zencod_generate_key,
229	DH_zencod_compute_key,
230	DH_zencod_bn_mod_exp,
231	NULL,
232	NULL,
233	0,
234	NULL
235} ;
236#endif
237
238/* Our internal RAND_meth specific to zencod ZNGINE providing pointers to  our function */
239static RAND_METHOD zencod_rand =
240{
241	RAND_zencod_seed,
242	RAND_zencod_rand_bytes,
243	NULL,
244	NULL,
245	RAND_zencod_rand_bytes,
246	RAND_zencod_rand_status
247} ;
248
249
250/* Constants used when creating the ENGINE */
251static const char *engine_zencod_id = "zencod";
252static const char *engine_zencod_name = "ZENCOD hardware engine support";
253
254
255/* This internal function is used by ENGINE_zencod () and possibly by the
256 * "dynamic" ENGINE support too   ;-)
257 */
258static int bind_helper ( ENGINE *e )
259{
260
261#ifndef OPENSSL_NO_RSA
262	const RSA_METHOD *meth_rsa ;
263#endif
264#ifndef OPENSSL_NO_DSA
265	const DSA_METHOD *meth_dsa ;
266#endif
267#ifndef OPENSSL_NO_DH
268	const DH_METHOD *meth_dh ;
269#endif
270
271	const RAND_METHOD *meth_rand ;
272
273
274	if ( !ENGINE_set_id ( e, engine_zencod_id ) ||
275			!ENGINE_set_name ( e, engine_zencod_name ) ||
276#ifndef OPENSSL_NO_RSA
277			!ENGINE_set_RSA ( e, &zencod_rsa ) ||
278#endif
279#ifndef OPENSSL_NO_DSA
280			!ENGINE_set_DSA ( e, &zencod_dsa ) ||
281#endif
282#ifndef OPENSSL_NO_DH
283			!ENGINE_set_DH ( e, &zencod_dh ) ||
284#endif
285			!ENGINE_set_RAND ( e, &zencod_rand ) ||
286
287			!ENGINE_set_destroy_function ( e, zencod_destroy ) ||
288			!ENGINE_set_init_function ( e, zencod_init ) ||
289			!ENGINE_set_finish_function ( e, zencod_finish ) ||
290			!ENGINE_set_ctrl_function ( e, zencod_ctrl ) ||
291			!ENGINE_set_cmd_defns ( e, zencod_cmd_defns ) ||
292			!ENGINE_set_digests ( e, engine_digests ) ||
293			!ENGINE_set_ciphers ( e, engine_ciphers ) ) {
294		return 0 ;
295	}
296
297#ifndef OPENSSL_NO_RSA
298	/* We know that the "PKCS1_SSLeay()" functions hook properly
299	 * to the Zencod-specific mod_exp and mod_exp_crt so we use
300	 * those functions. NB: We don't use ENGINE_openssl() or
301	 * anything "more generic" because something like the RSAref
302	 * code may not hook properly, and if you own one of these
303	 * cards then you have the right to do RSA operations on it
304	 * anyway!
305	 */
306	meth_rsa = RSA_PKCS1_SSLeay () ;
307
308	zencod_rsa.rsa_pub_enc = meth_rsa->rsa_pub_enc ;
309	zencod_rsa.rsa_pub_dec = meth_rsa->rsa_pub_dec ;
310	zencod_rsa.rsa_priv_enc = meth_rsa->rsa_priv_enc ;
311	zencod_rsa.rsa_priv_dec = meth_rsa->rsa_priv_dec ;
312	/* meth_rsa->rsa_mod_exp */
313	/* meth_rsa->bn_mod_exp */
314	zencod_rsa.init = meth_rsa->init ;
315	zencod_rsa.finish = meth_rsa->finish ;
316#endif
317
318#ifndef OPENSSL_NO_DSA
319	/* We use OpenSSL meth to supply what we don't provide ;-*)
320	 */
321	meth_dsa = DSA_OpenSSL () ;
322
323	/* meth_dsa->dsa_do_sign */
324	zencod_dsa.dsa_sign_setup = meth_dsa->dsa_sign_setup ;
325	/* meth_dsa->dsa_do_verify */
326	zencod_dsa.dsa_mod_exp = meth_dsa->dsa_mod_exp ;
327	/* zencod_dsa.bn_mod_exp = meth_dsa->bn_mod_exp ; */
328	zencod_dsa.init = meth_dsa->init ;
329	zencod_dsa.finish = meth_dsa->finish ;
330#endif
331
332#ifndef OPENSSL_NO_DH
333	/* We use OpenSSL meth to supply what we don't provide ;-*)
334	 */
335	meth_dh = DH_OpenSSL () ;
336
337	/* zencod_dh.generate_key = meth_dh->generate_key ; */
338	/* zencod_dh.compute_key = meth_dh->compute_key ; */
339	/* zencod_dh.bn_mod_exp = meth_dh->bn_mod_exp ; */
340	zencod_dh.init = meth_dh->init ;
341	zencod_dh.finish = meth_dh->finish ;
342
343#endif
344
345	/* We use OpenSSL (SSLeay) meth to supply what we don't provide ;-*)
346	 */
347	meth_rand = RAND_SSLeay () ;
348
349	/* meth_rand->seed ; */
350	/* zencod_rand.seed = meth_rand->seed ; */
351	/* meth_rand->bytes ; */
352	/* zencod_rand.bytes = meth_rand->bytes ; */
353	zencod_rand.cleanup = meth_rand->cleanup ;
354	zencod_rand.add = meth_rand->add ;
355	/* meth_rand->pseudorand ; */
356	/* zencod_rand.pseudorand = meth_rand->pseudorand ; */
357	/* zencod_rand.status = meth_rand->status ; */
358	/* meth_rand->status ; */
359
360	/* Ensure the zencod error handling is set up */
361	ERR_load_ZENCOD_strings () ;
362	return 1 ;
363}
364
365
366/* As this is only ever called once, there's no need for locking
367 * (indeed - the lock will already be held by our caller!!!)
368 */
369static ENGINE *ENGINE_zencod ( void )
370{
371
372	ENGINE *eng = ENGINE_new () ;
373
374	if ( !eng ) {
375		return NULL ;
376	}
377	if ( !bind_helper ( eng ) ) {
378		ENGINE_free ( eng ) ;
379		return NULL ;
380	}
381
382	return eng ;
383}
384
385
386#ifdef ENGINE_DYNAMIC_SUPPORT
387static
388#endif
389void ENGINE_load_zencod ( void )
390{
391	/* Copied from eng_[openssl|dyn].c */
392	ENGINE *toadd = ENGINE_zencod ( ) ;
393	if ( !toadd ) return ;
394	ENGINE_add ( toadd ) ;
395	ENGINE_free ( toadd ) ;
396	ERR_clear_error ( ) ;
397}
398
399
400/* This is a process-global DSO handle used for loading and unloading
401 * the ZENBRIDGE library.
402 * NB: This is only set (or unset) during an * init () or finish () call
403 * (reference counts permitting) and they're  * operating with global locks,
404 * so this should be thread-safe * implicitly.
405 */
406static DSO *zencod_dso = NULL ;
407
408static t_zencod_test *ptr_zencod_test = NULL ;
409static t_zencod_bytes2bits *ptr_zencod_bytes2bits = NULL ;
410static t_zencod_bits2bytes *ptr_zencod_bits2bytes = NULL ;
411static t_zencod_new_number *ptr_zencod_new_number = NULL ;
412static t_zencod_init_number *ptr_zencod_init_number = NULL ;
413
414static t_zencod_rsa_mod_exp *ptr_zencod_rsa_mod_exp = NULL ;
415static t_zencod_rsa_mod_exp_crt *ptr_zencod_rsa_mod_exp_crt = NULL ;
416static t_zencod_dsa_do_sign *ptr_zencod_dsa_do_sign = NULL ;
417static t_zencod_dsa_do_verify *ptr_zencod_dsa_do_verify = NULL ;
418static t_zencod_dh_generate_key *ptr_zencod_dh_generate_key = NULL ;
419static t_zencod_dh_compute_key *ptr_zencod_dh_compute_key = NULL ;
420static t_zencod_rand_bytes *ptr_zencod_rand_bytes = NULL ;
421static t_zencod_math_mod_exp *ptr_zencod_math_mod_exp = NULL ;
422
423static t_zencod_md5_init *ptr_zencod_md5_init = NULL ;
424static t_zencod_md5_update *ptr_zencod_md5_update = NULL ;
425static t_zencod_md5_do_final *ptr_zencod_md5_do_final = NULL ;
426static t_zencod_sha1_init *ptr_zencod_sha1_init = NULL ;
427static t_zencod_sha1_update *ptr_zencod_sha1_update = NULL ;
428static t_zencod_sha1_do_final *ptr_zencod_sha1_do_final = NULL ;
429
430static t_zencod_xdes_cipher *ptr_zencod_xdes_cipher = NULL ;
431static t_zencod_rc4_cipher *ptr_zencod_rc4_cipher = NULL ;
432
433/* These are the static string constants for the DSO file name and the function
434 * symbol names to bind to.
435 */
436static const char *ZENCOD_LIBNAME = ZEN_LIBRARY ;
437
438static const char *ZENCOD_Fct_0 = "test_device" ;
439static const char *ZENCOD_Fct_1 = "zenbridge_bytes2bits" ;
440static const char *ZENCOD_Fct_2 = "zenbridge_bits2bytes" ;
441static const char *ZENCOD_Fct_3 = "zenbridge_new_number" ;
442static const char *ZENCOD_Fct_4 = "zenbridge_init_number" ;
443
444static const char *ZENCOD_Fct_exp_1 = "zenbridge_rsa_mod_exp" ;
445static const char *ZENCOD_Fct_exp_2 = "zenbridge_rsa_mod_exp_crt" ;
446static const char *ZENCOD_Fct_dsa_1 = "zenbridge_dsa_do_sign" ;
447static const char *ZENCOD_Fct_dsa_2 = "zenbridge_dsa_do_verify" ;
448static const char *ZENCOD_Fct_dh_1 = "zenbridge_dh_generate_key" ;
449static const char *ZENCOD_Fct_dh_2 = "zenbridge_dh_compute_key" ;
450static const char *ZENCOD_Fct_rand_1 = "zenbridge_rand_bytes" ;
451static const char *ZENCOD_Fct_math_1 = "zenbridge_math_mod_exp" ;
452
453static const char *ZENCOD_Fct_md5_1 = "zenbridge_md5_init" ;
454static const char *ZENCOD_Fct_md5_2 = "zenbridge_md5_update" ;
455static const char *ZENCOD_Fct_md5_3 = "zenbridge_md5_do_final" ;
456static const char *ZENCOD_Fct_sha1_1 = "zenbridge_sha1_init" ;
457static const char *ZENCOD_Fct_sha1_2 = "zenbridge_sha1_update" ;
458static const char *ZENCOD_Fct_sha1_3 = "zenbridge_sha1_do_final" ;
459
460static const char *ZENCOD_Fct_xdes_1 = "zenbridge_xdes_cipher" ;
461static const char *ZENCOD_Fct_rc4_1 = "zenbridge_rc4_cipher" ;
462
463/* Destructor (complements the "ENGINE_zencod ()" constructor)
464 */
465static int zencod_destroy (ENGINE *e )
466{
467
468	ERR_unload_ZENCOD_strings () ;
469
470	return 1 ;
471}
472
473
474/* (de)initialisation functions. Control Function
475 */
476static int zencod_init ( ENGINE *e )
477{
478
479	t_zencod_test *ptr_0 ;
480	t_zencod_bytes2bits *ptr_1 ;
481	t_zencod_bits2bytes *ptr_2 ;
482	t_zencod_new_number *ptr_3 ;
483	t_zencod_init_number *ptr_4 ;
484	t_zencod_rsa_mod_exp *ptr_exp_1 ;
485	t_zencod_rsa_mod_exp_crt *ptr_exp_2 ;
486	t_zencod_dsa_do_sign *ptr_dsa_1 ;
487	t_zencod_dsa_do_verify *ptr_dsa_2 ;
488	t_zencod_dh_generate_key *ptr_dh_1 ;
489	t_zencod_dh_compute_key *ptr_dh_2 ;
490	t_zencod_rand_bytes *ptr_rand_1 ;
491	t_zencod_math_mod_exp *ptr_math_1 ;
492	t_zencod_md5_init *ptr_md5_1 ;
493	t_zencod_md5_update *ptr_md5_2 ;
494	t_zencod_md5_do_final *ptr_md5_3 ;
495	t_zencod_sha1_init *ptr_sha1_1 ;
496	t_zencod_sha1_update *ptr_sha1_2 ;
497	t_zencod_sha1_do_final *ptr_sha1_3 ;
498	t_zencod_xdes_cipher *ptr_xdes_1 ;
499	t_zencod_rc4_cipher *ptr_rc4_1 ;
500
501	CHEESE () ;
502
503	/*
504	 * We Should add some tests for non NULL parameters or bad value !!
505	 * Stuff to be done ...
506	 */
507
508	if ( zencod_dso != NULL ) {
509		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_ALREADY_LOADED ) ;
510		goto err ;
511	}
512	/* Trying to load the Library "cryptozen"
513	 */
514	zencod_dso = DSO_load ( NULL, ZENCOD_LIBNAME, NULL, 0 ) ;
515	if ( zencod_dso == NULL ) {
516		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE ) ;
517		goto err ;
518	}
519
520	/* Trying to load Function from the Library
521	 */
522	if ( ! ( ptr_1 = (t_zencod_bytes2bits*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_1 ) ) ||
523			! ( ptr_2 = (t_zencod_bits2bytes*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_2 ) ) ||
524			! ( ptr_3 = (t_zencod_new_number*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_3 ) ) ||
525			! ( ptr_4 = (t_zencod_init_number*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_4 ) ) ||
526			! ( ptr_exp_1 = (t_zencod_rsa_mod_exp*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_exp_1 ) ) ||
527			! ( ptr_exp_2 = (t_zencod_rsa_mod_exp_crt*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_exp_2 ) ) ||
528			! ( ptr_dsa_1 = (t_zencod_dsa_do_sign*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dsa_1 ) ) ||
529			! ( ptr_dsa_2 = (t_zencod_dsa_do_verify*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dsa_2 ) ) ||
530			! ( ptr_dh_1 = (t_zencod_dh_generate_key*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dh_1 ) ) ||
531			! ( ptr_dh_2 = (t_zencod_dh_compute_key*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_dh_2 ) ) ||
532			! ( ptr_rand_1 = (t_zencod_rand_bytes*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_rand_1 ) ) ||
533			! ( ptr_math_1 = (t_zencod_math_mod_exp*) DSO_bind_func ( zencod_dso, ZENCOD_Fct_math_1 ) ) ||
534			! ( ptr_0 = (t_zencod_test *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_0 ) ) ||
535			! ( ptr_md5_1 = (t_zencod_md5_init *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_1 ) ) ||
536			! ( ptr_md5_2 = (t_zencod_md5_update *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_2 ) ) ||
537			! ( ptr_md5_3 = (t_zencod_md5_do_final *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_md5_3 ) ) ||
538			! ( ptr_sha1_1 = (t_zencod_sha1_init *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_1 ) ) ||
539			! ( ptr_sha1_2 = (t_zencod_sha1_update *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_2 ) ) ||
540			! ( ptr_sha1_3 = (t_zencod_sha1_do_final *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_sha1_3 ) ) ||
541			! ( ptr_xdes_1 = (t_zencod_xdes_cipher *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_xdes_1 ) ) ||
542			! ( ptr_rc4_1 = (t_zencod_rc4_cipher *) DSO_bind_func ( zencod_dso, ZENCOD_Fct_rc4_1 ) ) ) {
543
544		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE ) ;
545		goto err ;
546	}
547
548	/* The function from "cryptozen" Library have been correctly loaded so copy them
549	 */
550	ptr_zencod_test = ptr_0 ;
551	ptr_zencod_bytes2bits = ptr_1 ;
552	ptr_zencod_bits2bytes = ptr_2 ;
553	ptr_zencod_new_number = ptr_3 ;
554	ptr_zencod_init_number = ptr_4 ;
555	ptr_zencod_rsa_mod_exp = ptr_exp_1 ;
556	ptr_zencod_rsa_mod_exp_crt = ptr_exp_2 ;
557	ptr_zencod_dsa_do_sign = ptr_dsa_1 ;
558	ptr_zencod_dsa_do_verify = ptr_dsa_2 ;
559	ptr_zencod_dh_generate_key = ptr_dh_1 ;
560	ptr_zencod_dh_compute_key = ptr_dh_2 ;
561	ptr_zencod_rand_bytes = ptr_rand_1 ;
562	ptr_zencod_math_mod_exp = ptr_math_1 ;
563	ptr_zencod_test = ptr_0 ;
564	ptr_zencod_md5_init = ptr_md5_1 ;
565	ptr_zencod_md5_update = ptr_md5_2 ;
566	ptr_zencod_md5_do_final = ptr_md5_3 ;
567	ptr_zencod_sha1_init = ptr_sha1_1 ;
568	ptr_zencod_sha1_update = ptr_sha1_2 ;
569	ptr_zencod_sha1_do_final = ptr_sha1_3 ;
570	ptr_zencod_xdes_cipher = ptr_xdes_1 ;
571	ptr_zencod_rc4_cipher = ptr_rc4_1 ;
572
573	/* We should peform a test to see if there is actually any unit runnig on the system ...
574	 * Even if the cryptozen library is loaded the module coul not be loaded on the system ...
575	 * For now we may just open and close the device !!
576	 */
577
578	if ( ptr_zencod_test () != 0 ) {
579		ZENCODerr ( ZENCOD_F_ZENCOD_INIT, ZENCOD_R_UNIT_FAILURE ) ;
580		goto err ;
581	}
582
583	return 1 ;
584err :
585	if ( zencod_dso ) {
586		DSO_free ( zencod_dso ) ;
587	}
588	zencod_dso = NULL ;
589	ptr_zencod_bytes2bits = NULL ;
590	ptr_zencod_bits2bytes = NULL ;
591	ptr_zencod_new_number = NULL ;
592	ptr_zencod_init_number = NULL ;
593	ptr_zencod_rsa_mod_exp = NULL ;
594	ptr_zencod_rsa_mod_exp_crt = NULL ;
595	ptr_zencod_dsa_do_sign = NULL ;
596	ptr_zencod_dsa_do_verify = NULL ;
597	ptr_zencod_dh_generate_key = NULL ;
598	ptr_zencod_dh_compute_key = NULL ;
599	ptr_zencod_rand_bytes = NULL ;
600	ptr_zencod_math_mod_exp = NULL ;
601	ptr_zencod_test = NULL ;
602	ptr_zencod_md5_init = NULL ;
603	ptr_zencod_md5_update = NULL ;
604	ptr_zencod_md5_do_final = NULL ;
605	ptr_zencod_sha1_init = NULL ;
606	ptr_zencod_sha1_update = NULL ;
607	ptr_zencod_sha1_do_final = NULL ;
608	ptr_zencod_xdes_cipher = NULL ;
609	ptr_zencod_rc4_cipher = NULL ;
610
611	return 0 ;
612}
613
614
615static int zencod_finish ( ENGINE *e )
616{
617
618	CHEESE () ;
619
620	/*
621	 * We Should add some tests for non NULL parameters or bad value !!
622	 * Stuff to be done ...
623	 */
624	if ( zencod_dso == NULL ) {
625		ZENCODerr ( ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_NOT_LOADED ) ;
626		return 0 ;
627	}
628	if ( !DSO_free ( zencod_dso ) ) {
629		ZENCODerr ( ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_DSO_FAILURE ) ;
630		return 0 ;
631	}
632
633	zencod_dso = NULL ;
634
635	ptr_zencod_bytes2bits = NULL ;
636	ptr_zencod_bits2bytes = NULL ;
637	ptr_zencod_new_number = NULL ;
638	ptr_zencod_init_number = NULL ;
639	ptr_zencod_rsa_mod_exp = NULL ;
640	ptr_zencod_rsa_mod_exp_crt = NULL ;
641	ptr_zencod_dsa_do_sign = NULL ;
642	ptr_zencod_dsa_do_verify = NULL ;
643	ptr_zencod_dh_generate_key = NULL ;
644	ptr_zencod_dh_compute_key = NULL ;
645	ptr_zencod_rand_bytes = NULL ;
646	ptr_zencod_math_mod_exp = NULL ;
647	ptr_zencod_test = NULL ;
648	ptr_zencod_md5_init = NULL ;
649	ptr_zencod_md5_update = NULL ;
650	ptr_zencod_md5_do_final = NULL ;
651	ptr_zencod_sha1_init = NULL ;
652	ptr_zencod_sha1_update = NULL ;
653	ptr_zencod_sha1_do_final = NULL ;
654	ptr_zencod_xdes_cipher = NULL ;
655	ptr_zencod_rc4_cipher = NULL ;
656
657	return 1 ;
658}
659
660
661static int zencod_ctrl ( ENGINE *e, int cmd, long i, void *p, void (*f) () )
662{
663
664	int initialised = ( ( zencod_dso == NULL ) ? 0 : 1 ) ;
665
666	CHEESE () ;
667
668	/*
669	 * We Should add some tests for non NULL parameters or bad value !!
670	 * Stuff to be done ...
671	 */
672	switch ( cmd ) {
673	case ZENCOD_CMD_SO_PATH :
674		if ( p == NULL ) {
675			ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ERR_R_PASSED_NULL_PARAMETER ) ;
676			return 0 ;
677		}
678		if ( initialised ) {
679			ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_ALREADY_LOADED ) ;
680			return 0 ;
681		}
682		ZENCOD_LIBNAME = (const char *) p ;
683		return 1 ;
684	default :
685		break ;
686	}
687
688	ZENCODerr ( ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED ) ;
689
690	return 0 ;
691}
692
693
694/* BIGNUM stuff Functions
695 */
696static int zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx )
697{
698	zen_nb_t y, x, e, n;
699	int ret;
700
701	CHEESE () ;
702
703	if ( !zencod_dso ) {
704		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_NOT_LOADED);
705		return 0;
706	}
707
708	if ( !bn_wexpand(r, m->top + 1) ) {
709		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
710		return 0;
711	}
712
713	memset(r->d, 0, BN_num_bytes(m));
714
715	ptr_zencod_init_number ( &y, (r->dmax - 1) * sizeof (BN_ULONG) * 8, (unsigned char *) r->d ) ;
716	BIGNUM2ZEN ( &x, a ) ;
717	BIGNUM2ZEN ( &e, p ) ;
718	BIGNUM2ZEN ( &n, m ) ;
719
720	/* Must invert x and e parameter due to BN mod exp prototype ... */
721	ret = ptr_zencod_math_mod_exp ( &y, &e, &x, &n ) ;
722
723	if ( ret )  {
724		PERROR("zenbridge_math_mod_exp");
725		ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
726		return 0;
727	}
728
729	r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;
730
731	return 1;
732}
733
734
735/* RSA stuff Functions
736 */
737#ifndef OPENSSL_NO_RSA
738static int RSA_zencod_rsa_mod_exp ( BIGNUM *r0, const BIGNUM *i, RSA *rsa )
739{
740
741	CHEESE () ;
742
743	if ( !zencod_dso ) {
744		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_NOT_LOADED);
745		return 0;
746	}
747
748	if ( !rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp ) {
749		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BAD_KEY_COMPONENTS);
750		return 0;
751	}
752
753	/* Do in software if argument is too large for hardware */
754	if ( RSA_size(rsa) * 8 > ZENBRIDGE_MAX_KEYSIZE_RSA_CRT ) {
755		const RSA_METHOD *meth;
756
757		meth = RSA_PKCS1_SSLeay();
758		return meth->rsa_mod_exp(r0, i, rsa);
759	} else {
760		zen_nb_t y, x, p, q, dmp1, dmq1, iqmp;
761
762		if ( !bn_expand(r0, RSA_size(rsa) * 8) ) {
763			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_BN_EXPAND_FAIL);
764			return 0;
765		}
766		r0->top = (RSA_size(rsa) * 8 + BN_BITS2 - 1) / BN_BITS2;
767
768		BIGNUM2ZEN ( &x, i ) ;
769		BIGNUM2ZEN ( &y, r0 ) ;
770		BIGNUM2ZEN ( &p, rsa->p ) ;
771		BIGNUM2ZEN ( &q, rsa->q ) ;
772		BIGNUM2ZEN ( &dmp1, rsa->dmp1 ) ;
773		BIGNUM2ZEN ( &dmq1, rsa->dmq1 ) ;
774		BIGNUM2ZEN ( &iqmp, rsa->iqmp ) ;
775
776		if ( ptr_zencod_rsa_mod_exp_crt ( &y, &x, &p, &q, &dmp1, &dmq1, &iqmp ) < 0 ) {
777			PERROR("zenbridge_rsa_mod_exp_crt");
778			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_REQUEST_FAILED);
779			return 0;
780		}
781
782		return 1;
783	}
784}
785
786
787/* This function is aliased to RSA_mod_exp (with the mont stuff dropped).
788 */
789static int RSA_zencod_bn_mod_exp ( BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
790		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx )
791{
792
793	CHEESE () ;
794
795	if ( !zencod_dso ) {
796		ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_NOT_LOADED);
797		return 0;
798	}
799
800	/* Do in software if argument is too large for hardware */
801	if ( BN_num_bits(m) > ZENBRIDGE_MAX_KEYSIZE_RSA ) {
802		const RSA_METHOD *meth;
803
804		meth = RSA_PKCS1_SSLeay();
805		return meth->bn_mod_exp(r, a, p, m, ctx, m_ctx);
806	} else {
807		zen_nb_t y, x, e, n;
808
809		if ( !bn_expand(r, BN_num_bits(m)) ) {
810			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
811			return 0;
812		}
813		r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;
814
815		BIGNUM2ZEN ( &x, a ) ;
816		BIGNUM2ZEN ( &y, r ) ;
817		BIGNUM2ZEN ( &e, p ) ;
818		BIGNUM2ZEN ( &n, m ) ;
819
820		if ( ptr_zencod_rsa_mod_exp ( &y, &x, &n, &e ) < 0 ) {
821			PERROR("zenbridge_rsa_mod_exp");
822			ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
823			return 0;
824		}
825
826		return 1;
827	}
828}
829#endif /* !OPENSSL_NO_RSA */
830
831
832#ifndef OPENSSL_NO_DSA
833/* DSA stuff Functions
834 */
835static DSA_SIG *DSA_zencod_do_sign ( const unsigned char *dgst, int dlen, DSA *dsa )
836{
837	zen_nb_t p, q, g, x, y, r, s, data;
838	DSA_SIG *sig;
839	BIGNUM *bn_r = NULL;
840	BIGNUM *bn_s = NULL;
841	char msg[20];
842
843	CHEESE();
844
845	if ( !zencod_dso ) {
846		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_NOT_LOADED);
847		goto FAILED;
848	}
849
850	if ( dlen > 160 ) {
851		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
852		goto FAILED;
853	}
854
855	/* Do in software if argument is too large for hardware */
856	if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
857		BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) {
858		const DSA_METHOD *meth;
859		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
860		meth = DSA_OpenSSL();
861		return meth->dsa_do_sign(dgst, dlen, dsa);
862	}
863
864	if ( !(bn_s = BN_new()) || !(bn_r = BN_new()) ) {
865		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
866		goto FAILED;
867	}
868
869	if ( !bn_expand(bn_r, 160) || !bn_expand(bn_s, 160) ) {
870		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BN_EXPAND_FAIL);
871		goto FAILED;
872	}
873
874	bn_r->top = bn_s->top = (160 + BN_BITS2 - 1) / BN_BITS2;
875	BIGNUM2ZEN ( &p, dsa->p ) ;
876	BIGNUM2ZEN ( &q, dsa->q ) ;
877	BIGNUM2ZEN ( &g, dsa->g ) ;
878	BIGNUM2ZEN ( &x, dsa->priv_key ) ;
879	BIGNUM2ZEN ( &y, dsa->pub_key ) ;
880	BIGNUM2ZEN ( &r, bn_r ) ;
881	BIGNUM2ZEN ( &s, bn_s ) ;
882	q.len = x.len = 160;
883
884	ypcmem(msg, dgst, 20);
885	ptr_zencod_init_number ( &data, 160, msg ) ;
886
887	if ( ptr_zencod_dsa_do_sign ( 0, &data, &y, &p, &q, &g, &x, &r, &s ) < 0 ) {
888		PERROR("zenbridge_dsa_do_sign");
889		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
890		goto FAILED;
891	}
892
893	if ( !( sig = DSA_SIG_new () ) ) {
894		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
895		goto FAILED;
896	}
897	sig->r = bn_r;
898	sig->s = bn_s;
899	return sig;
900
901 FAILED:
902	if (bn_r)
903		BN_free(bn_r);
904	if (bn_s)
905		BN_free(bn_s);
906	return NULL;
907}
908
909
910static int DSA_zencod_do_verify ( const unsigned char *dgst, int dlen, DSA_SIG *sig, DSA *dsa )
911{
912	zen_nb_t data, p, q, g, y, r, s, v;
913	char msg[20];
914	char v_data[20];
915	int ret;
916
917	CHEESE();
918
919	if ( !zencod_dso ) {
920		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_NOT_LOADED);
921		return 0;
922	}
923
924	if ( dlen > 160 ) {
925		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
926		return 0;
927	}
928
929	/* Do in software if argument is too large for hardware */
930	if ( BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
931		BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ) {
932		const DSA_METHOD *meth;
933		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
934		meth = DSA_OpenSSL();
935		return meth->dsa_do_verify(dgst, dlen, sig, dsa);
936	}
937
938	BIGNUM2ZEN ( &p, dsa->p ) ;
939	BIGNUM2ZEN ( &q, dsa->q ) ;
940	BIGNUM2ZEN ( &g, dsa->g ) ;
941	BIGNUM2ZEN ( &y, dsa->pub_key ) ;
942	BIGNUM2ZEN ( &r, sig->r ) ;
943	BIGNUM2ZEN ( &s, sig->s ) ;
944	ptr_zencod_init_number ( &v, 160, v_data ) ;
945	ypcmem(msg, dgst, 20);
946	ptr_zencod_init_number ( &data, 160, msg ) ;
947
948	if ( ( ret = ptr_zencod_dsa_do_verify ( 0, &data, &p, &q, &g, &y, &r, &s, &v ) ) < 0 ) {
949		PERROR("zenbridge_dsa_do_verify");
950		ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_REQUEST_FAILED);
951		return 0;
952	}
953
954	return ( ( ret == 0 ) ? 1 : ret ) ;
955}
956
957
958static int DSA_zencod_bn_mod_exp ( DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
959			     BN_CTX *ctx, BN_MONT_CTX *m_ctx )
960{
961	CHEESE () ;
962
963	return zencod_bn_mod_exp ( r, a, p, m, ctx ) ;
964}
965#endif /* !OPENSSL_NO_DSA */
966
967
968#ifndef OPENSSl_NO_DH
969/* DH stuff Functions
970 */
971static int DH_zencod_generate_key ( DH *dh )
972{
973	BIGNUM *bn_prv = NULL;
974	BIGNUM *bn_pub = NULL;
975	zen_nb_t y, x, g, p;
976	int generate_x;
977
978	CHEESE();
979
980	if ( !zencod_dso ) {
981		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_NOT_LOADED);
982		return 0;
983	}
984
985	/* Private key */
986	if ( dh->priv_key ) {
987		bn_prv = dh->priv_key;
988		generate_x = 0;
989	} else {
990		if (!(bn_prv = BN_new())) {
991			ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
992			goto FAILED;
993		}
994		generate_x = 1;
995	}
996
997	/* Public key */
998	if ( dh->pub_key )
999		bn_pub = dh->pub_key;
1000	else
1001		if ( !( bn_pub = BN_new () ) ) {
1002			ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
1003			goto FAILED;
1004		}
1005
1006	/* Expand */
1007	if ( !bn_wexpand ( bn_prv, dh->p->dmax ) ||
1008	    !bn_wexpand ( bn_pub, dh->p->dmax ) ) {
1009		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
1010		goto FAILED;
1011	}
1012	bn_prv->top = dh->p->top;
1013	bn_pub->top = dh->p->top;
1014
1015	/* Convert all keys */
1016	BIGNUM2ZEN ( &p, dh->p ) ;
1017	BIGNUM2ZEN ( &g, dh->g ) ;
1018	BIGNUM2ZEN ( &y, bn_pub ) ;
1019	BIGNUM2ZEN ( &x, bn_prv ) ;
1020	x.len = DH_size(dh) * 8;
1021
1022	/* Adjust the lengths of P and G */
1023	p.len = ptr_zencod_bytes2bits ( p.data, ZEN_BYTES ( p.len ) ) ;
1024	g.len = ptr_zencod_bytes2bits ( g.data, ZEN_BYTES ( g.len ) ) ;
1025
1026	/* Send the request to the driver */
1027	if ( ptr_zencod_dh_generate_key ( &y, &x, &g, &p, generate_x ) < 0 ) {
1028		perror("zenbridge_dh_generate_key");
1029		ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_REQUEST_FAILED);
1030		goto FAILED;
1031	}
1032
1033	dh->priv_key = bn_prv;
1034	dh->pub_key  = bn_pub;
1035
1036	return 1;
1037
1038 FAILED:
1039	if (!dh->priv_key && bn_prv)
1040		BN_free(bn_prv);
1041	if (!dh->pub_key && bn_pub)
1042		BN_free(bn_pub);
1043
1044	return 0;
1045}
1046
1047
1048static int DH_zencod_compute_key ( unsigned char *key, const BIGNUM *pub_key, DH *dh )
1049{
1050	zen_nb_t y, x, p, k;
1051
1052	CHEESE();
1053
1054	if ( !zencod_dso ) {
1055		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_NOT_LOADED);
1056		return 0;
1057	}
1058
1059	if ( !dh->priv_key ) {
1060		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_BAD_KEY_COMPONENTS);
1061		return 0;
1062	}
1063
1064	/* Convert all keys */
1065	BIGNUM2ZEN ( &y, pub_key ) ;
1066	BIGNUM2ZEN ( &x, dh->priv_key ) ;
1067	BIGNUM2ZEN ( &p, dh->p ) ;
1068	ptr_zencod_init_number ( &k, p.len, key ) ;
1069
1070	/* Adjust the lengths */
1071	p.len = ptr_zencod_bytes2bits ( p.data, ZEN_BYTES ( p.len ) ) ;
1072	y.len = ptr_zencod_bytes2bits ( y.data, ZEN_BYTES ( y.len ) ) ;
1073	x.len = ptr_zencod_bytes2bits ( x.data, ZEN_BYTES ( x.len ) ) ;
1074
1075	/* Call the hardware */
1076	if ( ptr_zencod_dh_compute_key ( &k, &y, &x, &p ) < 0 ) {
1077		ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_REQUEST_FAILED);
1078		return 0;
1079	}
1080
1081	/* The key must be written MSB -> LSB */
1082	k.len = ptr_zencod_bytes2bits ( k.data, ZEN_BYTES ( k.len ) ) ;
1083	esrever ( key, ZEN_BYTES ( k.len ) ) ;
1084
1085	return ZEN_BYTES ( k.len ) ;
1086}
1087
1088
1089static int DH_zencod_bn_mod_exp ( const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1090		BN_MONT_CTX *m_ctx )
1091{
1092	CHEESE () ;
1093
1094	return zencod_bn_mod_exp ( r, a, p, m, ctx ) ;
1095}
1096#endif	/* !OPENSSL_NO_DH */
1097
1098
1099/* RAND stuff Functions
1100 */
1101static void RAND_zencod_seed ( const void *buf, int num )
1102{
1103	/* Nothing to do cause our crypto accelerator provide a true random generator */
1104}
1105
1106
1107static int RAND_zencod_rand_bytes ( unsigned char *buf, int num )
1108{
1109	zen_nb_t r;
1110
1111	CHEESE();
1112
1113	if ( !zencod_dso ) {
1114		ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_NOT_LOADED);
1115		return 0;
1116	}
1117
1118	ptr_zencod_init_number ( &r, num * 8, buf ) ;
1119
1120	if ( ptr_zencod_rand_bytes ( &r, ZENBRIDGE_RNG_DIRECT ) < 0 ) {
1121		PERROR("zenbridge_rand_bytes");
1122		ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_REQUEST_FAILED);
1123		return 0;
1124	}
1125
1126	return 1;
1127}
1128
1129
1130static int RAND_zencod_rand_status ( void )
1131{
1132	CHEESE () ;
1133
1134	return 1;
1135}
1136
1137
1138/* This stuff is needed if this ENGINE is being compiled into a self-contained
1139 * shared-library.
1140 */
1141#ifdef ENGINE_DYNAMIC_SUPPORT
1142static int bind_fn ( ENGINE *e, const char *id )
1143{
1144
1145	if ( id && ( strcmp ( id, engine_zencod_id ) != 0 ) ) {
1146		return 0 ;
1147	}
1148	if ( !bind_helper ( e ) )  {
1149		return 0 ;
1150	}
1151
1152	return 1 ;
1153}
1154
1155IMPLEMENT_DYNAMIC_CHECK_FN ()
1156IMPLEMENT_DYNAMIC_BIND_FN ( bind_fn )
1157#endif /* ENGINE_DYNAMIC_SUPPORT */
1158
1159
1160
1161
1162/*
1163 * Adding "Digest" and "Cipher" tools ...
1164 * This is in development ... ;-)
1165 * In orfer to code this, i refer to hw_openbsd_dev_crypto and openssl engine made by Geoff Thorpe (if i'm rigth),
1166 * and evp, sha md5 definitions etc ...
1167 */
1168/* First add some include ... */
1169#include <openssl/evp.h>
1170#include <openssl/sha.h>
1171#include <openssl/md5.h>
1172#include <openssl/rc4.h>
1173#include <openssl/des.h>
1174
1175
1176/* Some variables declaration ... */
1177/* DONS:
1178 * Disable symetric computation except DES and 3DES, but let part of the code
1179 */
1180/* static int engine_digest_nids [ ] = { NID_sha1, NID_md5 } ; */
1181static int engine_digest_nids [ ] = {  } ;
1182static int engine_digest_nids_num = 0 ;
1183/* static int engine_cipher_nids [ ] = { NID_rc4, NID_rc4_40, NID_des_cbc, NID_des_ede3_cbc } ; */
1184static int engine_cipher_nids [ ] = { NID_des_cbc, NID_des_ede3_cbc } ;
1185static int engine_cipher_nids_num = 2 ;
1186
1187
1188/* Function prototype ... */
1189/*  SHA stuff */
1190static int engine_sha1_init ( EVP_MD_CTX *ctx ) ;
1191static int engine_sha1_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count ) ;
1192static int engine_sha1_final ( EVP_MD_CTX *ctx, unsigned char *md ) ;
1193
1194/*  MD5 stuff */
1195static int engine_md5_init ( EVP_MD_CTX *ctx ) ;
1196static int engine_md5_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count ) ;
1197static int engine_md5_final ( EVP_MD_CTX *ctx, unsigned char *md ) ;
1198
1199static int engine_md_cleanup ( EVP_MD_CTX *ctx ) ;
1200static int engine_md_copy ( EVP_MD_CTX *to, const EVP_MD_CTX *from ) ;
1201
1202
1203/* RC4 Stuff */
1204static int engine_rc4_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
1205static int engine_rc4_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl ) ;
1206
1207/* DES Stuff */
1208static int engine_des_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
1209static int engine_des_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl ) ;
1210
1211/*  3DES Stuff */
1212static int engine_des_ede3_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc ) ;
1213static int engine_des_ede3_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out,const unsigned char *in, unsigned int inl ) ;
1214
1215static int engine_cipher_cleanup ( EVP_CIPHER_CTX *ctx ) ;	/* cleanup ctx */
1216
1217
1218/* The one for SHA ... */
1219static const EVP_MD engine_sha1_md =
1220{
1221	NID_sha1,
1222	NID_sha1WithRSAEncryption,
1223	SHA_DIGEST_LENGTH,
1224	EVP_MD_FLAG_ONESHOT,
1225	/* 0, */			/* EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block
1226				* XXX: set according to device info ... */
1227	engine_sha1_init,
1228	engine_sha1_update,
1229	engine_sha1_final,
1230	engine_md_copy,		/* dev_crypto_sha_copy */
1231	engine_md_cleanup,		/* dev_crypto_sha_cleanup */
1232	EVP_PKEY_RSA_method,
1233	SHA_CBLOCK,
1234	/* sizeof ( EVP_MD * ) + sizeof ( SHA_CTX ) */
1235	sizeof ( ZEN_MD_DATA )
1236	/* sizeof ( MD_CTX_DATA )	The message digest data structure ... */
1237} ;
1238
1239/* The one for MD5 ... */
1240static const EVP_MD engine_md5_md =
1241{
1242	NID_md5,
1243	NID_md5WithRSAEncryption,
1244	MD5_DIGEST_LENGTH,
1245	EVP_MD_FLAG_ONESHOT,
1246	/* 0, */			/* EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block
1247				* XXX: set according to device info ... */
1248	engine_md5_init,
1249	engine_md5_update,
1250	engine_md5_final,
1251	engine_md_copy,		/* dev_crypto_md5_copy */
1252	engine_md_cleanup,		/* dev_crypto_md5_cleanup */
1253	EVP_PKEY_RSA_method,
1254	MD5_CBLOCK,
1255	/* sizeof ( EVP_MD * ) + sizeof ( MD5_CTX ) */
1256	sizeof ( ZEN_MD_DATA )
1257	/* sizeof ( MD_CTX_DATA )	The message digest data structure ... */
1258} ;
1259
1260
1261/* The one for RC4 ... */
1262#define EVP_RC4_KEY_SIZE			16
1263
1264/* Try something static ... */
1265typedef struct
1266{
1267	unsigned int len ;
1268	unsigned int first ;
1269	unsigned char rc4_state [ 260 ] ;
1270} NEW_ZEN_RC4_KEY ;
1271
1272#define rc4_data(ctx)				( (EVP_RC4_KEY *) ( ctx )->cipher_data )
1273
1274static const EVP_CIPHER engine_rc4 =
1275{
1276	NID_rc4,
1277	1,
1278	16,				/* EVP_RC4_KEY_SIZE should be 128 bits */
1279	0,				/* FIXME: key should be up to 256 bytes */
1280	EVP_CIPH_VARIABLE_LENGTH,
1281	engine_rc4_init_key,
1282	engine_rc4_cipher,
1283	engine_cipher_cleanup,
1284	sizeof ( NEW_ZEN_RC4_KEY ),
1285	NULL,
1286	NULL,
1287	NULL
1288} ;
1289
1290/* The one for RC4_40 ... */
1291static const EVP_CIPHER engine_rc4_40 =
1292{
1293	NID_rc4_40,
1294	1,
1295	5,				/* 40 bits */
1296	0,
1297	EVP_CIPH_VARIABLE_LENGTH,
1298	engine_rc4_init_key,
1299	engine_rc4_cipher,
1300	engine_cipher_cleanup,
1301	sizeof ( NEW_ZEN_RC4_KEY ),
1302	NULL,
1303	NULL,
1304	NULL
1305} ;
1306
1307/* The one for DES ... */
1308
1309/* Try something static ... */
1310typedef struct
1311{
1312	unsigned char des_key [ 24 ] ;
1313	unsigned char des_iv [ 8 ] ;
1314} ZEN_DES_KEY ;
1315
1316static const EVP_CIPHER engine_des_cbc =
1317	{
1318	NID_des_cbc,
1319	8, 8, 8,
1320	0 | EVP_CIPH_CBC_MODE,
1321	engine_des_init_key,
1322	engine_des_cbc_cipher,
1323	engine_cipher_cleanup,
1324	sizeof(ZEN_DES_KEY),
1325	EVP_CIPHER_set_asn1_iv,
1326	EVP_CIPHER_get_asn1_iv,
1327	NULL,
1328	NULL
1329	};
1330
1331/* The one for 3DES ... */
1332
1333/* Try something static ... */
1334typedef struct
1335{
1336	unsigned char des3_key [ 24 ] ;
1337	unsigned char des3_iv [ 8 ] ;
1338} ZEN_3DES_KEY ;
1339
1340#define des_data(ctx)				 ( (DES_EDE_KEY *) ( ctx )->cipher_data )
1341
1342static const EVP_CIPHER engine_des_ede3_cbc =
1343	{
1344	NID_des_ede3_cbc,
1345	8, 8, 8,
1346	0 | EVP_CIPH_CBC_MODE,
1347	engine_des_ede3_init_key,
1348	engine_des_ede3_cbc_cipher,
1349	engine_cipher_cleanup,
1350	sizeof(ZEN_3DES_KEY),
1351	EVP_CIPHER_set_asn1_iv,
1352	EVP_CIPHER_get_asn1_iv,
1353	NULL,
1354	NULL
1355	};
1356
1357
1358/* General function cloned on hw_openbsd_dev_crypto one ... */
1359static int engine_digests ( ENGINE *e, const EVP_MD **digest, const int **nids, int nid )
1360{
1361
1362#ifdef DEBUG_ZENCOD_MD
1363	fprintf ( stderr, "\t=>Function : static int engine_digests () called !\n" ) ;
1364#endif
1365
1366	if ( !digest ) {
1367		/* We are returning a list of supported nids */
1368		*nids = engine_digest_nids ;
1369		return engine_digest_nids_num ;
1370	}
1371	/* We are being asked for a specific digest */
1372	if ( nid == NID_md5 ) {
1373		*digest = &engine_md5_md ;
1374	}
1375	else if ( nid == NID_sha1 ) {
1376		*digest = &engine_sha1_md ;
1377	}
1378	else {
1379		*digest = NULL ;
1380		return 0 ;
1381	}
1382	return 1 ;
1383}
1384
1385
1386/* SHA stuff Functions
1387 */
1388static int engine_sha1_init ( EVP_MD_CTX *ctx )
1389{
1390
1391	int to_return = 0 ;
1392
1393	/* Test with zenbridge library ... */
1394	to_return = ptr_zencod_sha1_init ( (ZEN_MD_DATA *) ctx->md_data ) ;
1395	to_return = !to_return ;
1396
1397	return to_return ;
1398}
1399
1400
1401static int engine_sha1_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count )
1402{
1403
1404	zen_nb_t input ;
1405	int to_return = 0 ;
1406
1407	/* Convert parameters ... */
1408	input.len = count ;
1409	input.data = (unsigned char *) data ;
1410
1411	/* Test with zenbridge library ... */
1412	to_return = ptr_zencod_sha1_update ( (ZEN_MD_DATA *) ctx->md_data, (const zen_nb_t *) &input ) ;
1413	to_return = !to_return ;
1414
1415	return to_return ;
1416}
1417
1418
1419static int engine_sha1_final ( EVP_MD_CTX *ctx, unsigned char *md )
1420{
1421
1422	zen_nb_t output ;
1423	int to_return = 0 ;
1424
1425	/* Convert parameters ... */
1426	output.len = SHA_DIGEST_LENGTH ;
1427	output.data = md ;
1428
1429	/* Test with zenbridge library ... */
1430	to_return = ptr_zencod_sha1_do_final ( (ZEN_MD_DATA *) ctx->md_data, (zen_nb_t *) &output ) ;
1431	to_return = !to_return ;
1432
1433	return to_return ;
1434}
1435
1436
1437
1438/* MD5 stuff Functions
1439 */
1440static int engine_md5_init ( EVP_MD_CTX *ctx )
1441{
1442
1443	int to_return = 0 ;
1444
1445	/* Test with zenbridge library ... */
1446	to_return = ptr_zencod_md5_init ( (ZEN_MD_DATA *) ctx->md_data ) ;
1447	to_return = !to_return ;
1448
1449	return to_return ;
1450}
1451
1452
1453static int engine_md5_update ( EVP_MD_CTX *ctx, const void *data, unsigned long count )
1454{
1455
1456	zen_nb_t input ;
1457	int to_return = 0 ;
1458
1459	/* Convert parameters ... */
1460	input.len = count ;
1461	input.data = (unsigned char *) data ;
1462
1463	/* Test with zenbridge library ... */
1464	to_return = ptr_zencod_md5_update ( (ZEN_MD_DATA *) ctx->md_data, (const zen_nb_t *) &input ) ;
1465	to_return = !to_return ;
1466
1467	return to_return ;
1468}
1469
1470
1471static int engine_md5_final ( EVP_MD_CTX *ctx, unsigned char *md )
1472{
1473
1474	zen_nb_t output ;
1475	int to_return = 0 ;
1476
1477	/* Convert parameters ... */
1478	output.len = MD5_DIGEST_LENGTH ;
1479	output.data = md ;
1480
1481	/* Test with zenbridge library ... */
1482	to_return = ptr_zencod_md5_do_final ( (ZEN_MD_DATA *) ctx->md_data, (zen_nb_t *) &output ) ;
1483	to_return = !to_return ;
1484
1485	return to_return ;
1486}
1487
1488
1489static int engine_md_cleanup ( EVP_MD_CTX *ctx )
1490{
1491
1492	ZEN_MD_DATA *zen_md_data = (ZEN_MD_DATA *) ctx->md_data ;
1493
1494	if ( zen_md_data->HashBuffer != NULL ) {
1495		OPENSSL_free ( zen_md_data->HashBuffer ) ;
1496		zen_md_data->HashBufferSize = 0 ;
1497		ctx->md_data = NULL ;
1498	}
1499
1500	return 1 ;
1501}
1502
1503
1504static int engine_md_copy ( EVP_MD_CTX *to, const EVP_MD_CTX *from )
1505{
1506	const ZEN_MD_DATA *from_md = (ZEN_MD_DATA *) from->md_data ;
1507	ZEN_MD_DATA *to_md = (ZEN_MD_DATA *) to->md_data ;
1508
1509	to_md->HashBuffer = OPENSSL_malloc ( from_md->HashBufferSize ) ;
1510	memcpy ( to_md->HashBuffer, from_md->HashBuffer, from_md->HashBufferSize ) ;
1511
1512	return 1;
1513}
1514
1515
1516/* General function cloned on hw_openbsd_dev_crypto one ... */
1517static int engine_ciphers ( ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid )
1518{
1519
1520	if ( !cipher ) {
1521		/* We are returning a list of supported nids */
1522		*nids = engine_cipher_nids ;
1523		return engine_cipher_nids_num ;
1524	}
1525	/* We are being asked for a specific cipher */
1526	if ( nid == NID_rc4 ) {
1527		*cipher = &engine_rc4 ;
1528	}
1529	else if ( nid == NID_rc4_40 ) {
1530		*cipher = &engine_rc4_40 ;
1531	}
1532	else if ( nid == NID_des_cbc ) {
1533		*cipher = &engine_des_cbc ;
1534	}
1535	else if ( nid == NID_des_ede3_cbc ) {
1536		*cipher = &engine_des_ede3_cbc ;
1537	}
1538	else {
1539		*cipher = NULL ;
1540		return 0 ;
1541	}
1542
1543	return 1 ;
1544}
1545
1546
1547static int engine_rc4_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
1548{
1549	int to_return = 0 ;
1550	int i = 0 ;
1551	int nb = 0 ;
1552	NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL ;
1553
1554	tmp_rc4_key = (NEW_ZEN_RC4_KEY *) ( ctx->cipher_data ) ;
1555	tmp_rc4_key->first = 0 ;
1556	tmp_rc4_key->len = ctx->key_len ;
1557	tmp_rc4_key->rc4_state [ 0 ] = 0x00 ;
1558	tmp_rc4_key->rc4_state [ 2 ] = 0x00 ;
1559	nb = 256 / ctx->key_len ;
1560	for ( i = 0; i < nb ; i++ ) {
1561		memcpy ( &( tmp_rc4_key->rc4_state [ 4 + i*ctx->key_len ] ), key, ctx->key_len ) ;
1562	}
1563
1564	to_return = 1 ;
1565
1566	return to_return ;
1567}
1568
1569
1570static int engine_rc4_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int in_len )
1571{
1572
1573	zen_nb_t output, input ;
1574	zen_nb_t rc4key ;
1575	int to_return = 0 ;
1576	NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL ;
1577
1578	/* Convert parameters ... */
1579	input.len = in_len ;
1580	input.data = (unsigned char *) in ;
1581	output.len = in_len ;
1582	output.data = (unsigned char *) out ;
1583
1584	tmp_rc4_key = ( (NEW_ZEN_RC4_KEY *) ( ctx->cipher_data ) ) ;
1585	rc4key.len = 260 ;
1586	rc4key.data = &( tmp_rc4_key->rc4_state [ 0 ] ) ;
1587
1588	/* Test with zenbridge library ... */
1589	to_return = ptr_zencod_rc4_cipher ( &output, &input, (const zen_nb_t *) &rc4key, &( tmp_rc4_key->rc4_state [0] ), &( tmp_rc4_key->rc4_state [3] ), !tmp_rc4_key->first ) ;
1590	to_return = !to_return ;
1591
1592	/* Update encryption state ... */
1593	tmp_rc4_key->first = 1 ;
1594	tmp_rc4_key = NULL ;
1595
1596	return to_return ;
1597}
1598
1599
1600static int engine_des_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
1601{
1602
1603	ZEN_DES_KEY *tmp_des_key = NULL ;
1604	int to_return = 0 ;
1605
1606	tmp_des_key = (ZEN_DES_KEY *) ( ctx->cipher_data ) ;
1607	memcpy ( &( tmp_des_key->des_key [ 0 ] ), key, 8 ) ;
1608	memcpy ( &( tmp_des_key->des_key [ 8 ] ), key, 8 ) ;
1609	memcpy ( &( tmp_des_key->des_key [ 16 ] ), key, 8 ) ;
1610	memcpy ( &( tmp_des_key->des_iv [ 0 ] ), iv, 8 ) ;
1611
1612	to_return = 1 ;
1613
1614	return to_return ;
1615}
1616
1617
1618static int engine_des_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl )
1619{
1620
1621	zen_nb_t output, input ;
1622	zen_nb_t deskey_1, deskey_2, deskey_3, iv ;
1623	int to_return = 0 ;
1624
1625	/* Convert parameters ... */
1626	input.len = inl ;
1627	input.data = (unsigned char *) in ;
1628	output.len = inl ;
1629	output.data = out ;
1630
1631	/* Set key parameters ... */
1632	deskey_1.len = 8 ;
1633	deskey_2.len = 8 ;
1634	deskey_3.len = 8 ;
1635	deskey_1.data = (unsigned char *) ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key ;
1636	deskey_2.data =  (unsigned char *) &( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key [ 8 ] ;
1637	deskey_3.data =  (unsigned char *) &( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_key [ 16 ] ;
1638
1639	/* Key correct iv ... */
1640	memcpy ( ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_iv, ctx->iv, 8 ) ;
1641	iv.len = 8 ;
1642	iv.data = (unsigned char *) ( (ZEN_DES_KEY *) ( ctx->cipher_data ) )->des_iv ;
1643
1644	if ( ctx->encrypt == 0 ) {
1645		memcpy ( ctx->iv, &( input.data [ input.len - 8 ] ), 8 ) ;
1646	}
1647
1648	/* Test with zenbridge library ... */
1649	to_return = ptr_zencod_xdes_cipher ( &output, &input,
1650			(zen_nb_t *) &deskey_1, (zen_nb_t *) &deskey_2, (zen_nb_t *) &deskey_3, &iv, ctx->encrypt ) ;
1651	to_return = !to_return ;
1652
1653	/* But we need to set up the rigth iv ...
1654	 * Test ENCRYPT or DECRYPT mode to set iv ... */
1655	if ( ctx->encrypt == 1 ) {
1656		memcpy ( ctx->iv, &( output.data [ output.len - 8 ] ), 8 ) ;
1657	}
1658
1659	return to_return ;
1660}
1661
1662
1663static int engine_des_ede3_init_key ( EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc )
1664{
1665
1666	ZEN_3DES_KEY *tmp_3des_key = NULL ;
1667	int to_return = 0 ;
1668
1669	tmp_3des_key = (ZEN_3DES_KEY *) ( ctx->cipher_data ) ;
1670	memcpy ( &( tmp_3des_key->des3_key [ 0 ] ), key, 24 ) ;
1671	memcpy ( &( tmp_3des_key->des3_iv [ 0 ] ), iv, 8 ) ;
1672
1673	to_return = 1;
1674
1675	return to_return ;
1676}
1677
1678
1679static int engine_des_ede3_cbc_cipher ( EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
1680	unsigned int in_len )
1681{
1682
1683	zen_nb_t output, input ;
1684	zen_nb_t deskey_1, deskey_2, deskey_3, iv ;
1685	int to_return = 0 ;
1686
1687	/* Convert parameters ... */
1688	input.len = in_len ;
1689	input.data = (unsigned char *) in ;
1690	output.len = in_len ;
1691	output.data = out ;
1692
1693	/* Set key ... */
1694	deskey_1.len = 8 ;
1695	deskey_2.len = 8 ;
1696	deskey_3.len = 8 ;
1697	deskey_1.data =  (unsigned char *) ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key ;
1698	deskey_2.data =  (unsigned char *) &( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key [ 8 ] ;
1699	deskey_3.data =  (unsigned char *) &( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_key [ 16 ] ;
1700
1701	/* Key correct iv ... */
1702	memcpy ( ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_iv, ctx->iv, 8 ) ;
1703	iv.len = 8 ;
1704	iv.data = (unsigned char *) ( (ZEN_3DES_KEY *) ( ctx->cipher_data ) )->des3_iv ;
1705
1706	if ( ctx->encrypt == 0 ) {
1707		memcpy ( ctx->iv, &( input.data [ input.len - 8 ] ), 8 ) ;
1708	}
1709
1710	/* Test with zenbridge library ... */
1711	to_return = ptr_zencod_xdes_cipher ( &output, &input,
1712			(zen_nb_t *) &deskey_1, (zen_nb_t *) &deskey_2, (zen_nb_t *) &deskey_3, &iv, ctx->encrypt ) ;
1713	to_return = !to_return ;
1714
1715	if ( ctx->encrypt == 1 ) {
1716		memcpy ( ctx->iv, &( output.data [ output.len - 8 ] ), 8 ) ;
1717	}
1718
1719	return to_return ;
1720}
1721
1722
1723static int engine_cipher_cleanup ( EVP_CIPHER_CTX *ctx )
1724{
1725
1726	/* Set the key pointer ... */
1727	if ( ctx->cipher->nid == NID_rc4 || ctx->cipher->nid == NID_rc4_40 ) {
1728	}
1729	else if ( ctx->cipher->nid == NID_des_cbc ) {
1730	}
1731	else if ( ctx->cipher->nid == NID_des_ede3_cbc ) {
1732	}
1733
1734	return 1 ;
1735}
1736
1737
1738#endif /* !OPENSSL_NO_HW_ZENCOD */
1739#endif /* !OPENSSL_NO_HW */
1740