1/* crypto/engine/hw_cluster_labs.c */
2/* Written by Jan Tschirschwitz (jan.tschirschwitz@cluster-labs.com
3 * for the OpenSSL project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 *    software must display the following acknowledgment:
22 *    "This product includes software developed by the OpenSSL Project
23 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 *    endorse or promote products derived from this software without
27 *    prior written permission. For written permission, please contact
28 *    licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 *    nor may "OpenSSL" appear in their names without prior written
32 *    permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 *    acknowledgment:
36 *    "This product includes software developed by the OpenSSL Project
37 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com).  This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#define MSC_VER   /* only used cryptic.h */
60
61#include <stdio.h>
62#include <openssl/crypto.h>
63#include <openssl/dso.h>
64#include <openssl/des.h>
65#include <openssl/engine.h>
66
67#ifndef NO_HW
68#ifndef NO_HW_CLUSTER_LABS
69
70#ifdef FLAT_INC
71#include "cluster_labs.h"
72#else
73#include "vendor_defns/cluster_labs.h"
74#endif
75
76#define CL_LIB_NAME "cluster_labs engine"
77#include "hw_cluster_labs_err.c"
78
79
80static int cluster_labs_destroy(ENGINE *e);
81static int cluster_labs_init(ENGINE *e);
82static int cluster_labs_finish(ENGINE *e);
83static int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
84
85
86/* BIGNUM stuff */
87/* This function is aliased to mod_exp (with the mont stuff dropped). */
88static int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
89		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
90
91/* RSA stuff */
92#ifndef OPENSSL_NO_RSA
93static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
94	     unsigned char *to, RSA *rsa, int padding);
95static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
96	     unsigned char *to, RSA *rsa, int padding);
97static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from,
98		unsigned char *to, RSA *rsa, int padding);
99static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from,
100		unsigned char *to, RSA *rsa, int padding);
101static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
102#endif
103
104/* DSA stuff */
105#ifndef OPENSSL_NO_DSA
106static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
107static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
108				DSA_SIG *sig, DSA *dsa);
109static int cluster_labs_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
110		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
111		BN_CTX *ctx, BN_MONT_CTX *in_mont);
112static int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
113		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
114		BN_MONT_CTX *m_ctx);
115#endif
116
117/* DH stuff */
118#ifndef OPENSSL_NO_DH
119/* This function is alised to mod_exp (with the DH and mont dropped). */
120static int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
121		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
122#endif
123
124/* RANDOM stuff */
125static int cluster_labs_rand_bytes(unsigned char *buf, int num);
126
127/* The definitions for control commands specific to this engine */
128#define CLUSTER_LABS_CMD_SO_PATH		ENGINE_CMD_BASE
129static const ENGINE_CMD_DEFN cluster_labs_cmd_defns[] =
130	{
131	{ CLUSTER_LABS_CMD_SO_PATH,
132	  "SO_PATH",
133	  "Specifies the path to the 'cluster labs' shared library",
134	  ENGINE_CMD_FLAG_STRING
135	},
136	{0, NULL, NULL, 0}
137	};
138
139/* Our internal RSA_METHOD that we provide pointers to */
140#ifndef OPENSSL_NO_RSA
141static RSA_METHOD cluster_labs_rsa =
142	{
143	"Cluster Labs RSA method",
144	cluster_labs_rsa_pub_enc,	/* rsa_pub_enc */
145	cluster_labs_rsa_pub_dec,	/* rsa_pub_dec */
146	cluster_labs_rsa_priv_enc,	/* rsa_priv_enc */
147	cluster_labs_rsa_priv_dec,	/* rsa_priv_dec */
148	cluster_labs_rsa_mod_exp,	/* rsa_mod_exp */
149	cluster_labs_mod_exp_mont,	/* bn_mod_exp */
150	NULL,				/* init */
151	NULL,				/* finish */
152	0, 				/* flags */
153	NULL,				/* apps_data */
154	NULL,				/* rsa_sign */
155	NULL				/* rsa_verify */
156	};
157#endif
158
159/* Our internal DSA_METHOD that we provide pointers to */
160#ifndef OPENSSL_NO_DSA
161static DSA_METHOD cluster_labs_dsa =
162	{
163	"Cluster Labs DSA method",
164	cluster_labs_dsa_sign,  	/* dsa_do_sign */
165	NULL, 				/* dsa_sign_setup */
166	cluster_labs_dsa_verify,	/* dsa_do_verify */
167	cluster_labs_dsa_mod_exp, 	/* dsa_mod_exp */
168	cluster_labs_mod_exp_dsa, 	/* bn_mod_exp */
169	NULL, 				/* init */
170	NULL, 				/* finish */
171	0, 				/* flags */
172	NULL 				/* app_data */
173	};
174#endif
175
176/* Our internal DH_METHOD that we provide pointers to */
177#ifndef OPENSSL_NO_DH
178static DH_METHOD cluster_labs_dh =
179	{
180	"Cluster Labs DH method",
181	NULL,				/* generate key */
182	NULL,				/* compute key */
183	cluster_labs_mod_exp_dh,	/* bn_mod_exp */
184	NULL,				/* init */
185	NULL,				/* finish */
186	0,				/* flags */
187	NULL				/* app_data */
188	};
189#endif
190
191static RAND_METHOD cluster_labs_rand =
192	{
193	/* "Cluster Labs RAND method", */
194	NULL,				/* seed */
195	cluster_labs_rand_bytes,	/* bytes */
196	NULL,				/* cleanup */
197	NULL,				/* add */
198	cluster_labs_rand_bytes,	/* pseudorand */
199	NULL,				/* status */
200	};
201
202static const char *engine_cluster_labs_id = "cluster_labs";
203static const char *engine_cluster_labs_name = "Cluster Labs hardware engine support";
204
205/* engine implementation */
206/*-----------------------*/
207static int bind_helper(ENGINE *e)
208	{
209
210	if(!ENGINE_set_id(e, engine_cluster_labs_id) ||
211			!ENGINE_set_name(e, engine_cluster_labs_name) ||
212#ifndef OPENSSL_NO_RSA
213			!ENGINE_set_RSA(e, &cluster_labs_rsa) ||
214#endif
215#ifndef OPENSSL_NO_DSA
216			!ENGINE_set_DSA(e, &cluster_labs_dsa) ||
217#endif
218#ifndef OPENSSL_NO_DH
219			!ENGINE_set_DH(e, &cluster_labs_dh) ||
220#endif
221			!ENGINE_set_RAND(e, &cluster_labs_rand) ||
222			!ENGINE_set_destroy_function(e, cluster_labs_destroy) ||
223			!ENGINE_set_init_function(e, cluster_labs_init) ||
224			!ENGINE_set_finish_function(e, cluster_labs_finish) ||
225			!ENGINE_set_ctrl_function(e, cluster_labs_ctrl) ||
226			!ENGINE_set_cmd_defns(e, cluster_labs_cmd_defns))
227		return 0;
228	/* Ensure the error handling is set up */
229	ERR_load_CL_strings();
230	return 1;
231	}
232
233#ifndef ENGINE_DYNAMIC_SUPPORT
234static ENGINE *engine_cluster_labs(void)
235	{
236	ENGINE *ret = ENGINE_new();
237
238	if(!ret)
239		return NULL;
240	if(!bind_helper(ret))
241		{
242		ENGINE_free(ret);
243		return NULL;
244		}
245	return ret;
246	}
247
248#ifdef ENGINE_DYNAMIC_SUPPORT
249static
250#endif
251void ENGINE_load_cluster_labs(void)
252	{
253
254	ENGINE *cluster_labs = engine_cluster_labs();
255
256	if(!cluster_labs) return;
257	ENGINE_add(cluster_labs);
258	ENGINE_free(cluster_labs);
259	ERR_clear_error();
260	}
261#endif /* !ENGINE_DYNAMIC_SUPPORT */
262
263static int cluster_labs_destroy(ENGINE *e)
264	{
265
266	ERR_unload_CL_strings();
267	return 1;
268	}
269
270
271
272/* This is a process-global DSO handle used for loading and unloading
273 * the Cluster Labs library. NB: This is only set (or unset) during an
274 * init() or finish() call (reference counts permitting) and they're
275 * operating with global locks, so this should be thread-safe
276 * implicitly. */
277static DSO *cluster_labs_dso = NULL;
278
279/* These are the function pointers that are (un)set when the library has
280 * successfully (un)loaded. */
281static cl_engine_init	  	*p_cl_engine_init 		 = NULL;
282static cl_mod_exp	 	*p_cl_mod_exp 			 = NULL;
283static cl_mod_exp_crt		*p_cl_mod_exp_crt 		 = NULL;
284static cl_rsa_mod_exp		*p_cl_rsa_mod_exp 		 = NULL;
285static cl_rsa_priv_enc		*p_cl_rsa_priv_enc 		 = NULL;
286static cl_rsa_priv_dec		*p_cl_rsa_priv_dec 		 = NULL;
287static cl_rsa_pub_enc		*p_cl_rsa_pub_enc 		 = NULL;
288static cl_rsa_pub_dec		*p_cl_rsa_pub_dec 		 = NULL;
289static cl_rand_bytes		*p_cl_rand_bytes	 	 = NULL;
290static cl_dsa_sign		*p_cl_dsa_sign		 	 = NULL;
291static cl_dsa_verify		*p_cl_dsa_verify	 	 = NULL;
292
293
294int cluster_labs_init(ENGINE *e)
295	{
296
297	cl_engine_init			*p1;
298	cl_mod_exp			*p2;
299	cl_mod_exp_crt			*p3;
300	cl_rsa_mod_exp			*p4;
301	cl_rsa_priv_enc			*p5;
302	cl_rsa_priv_dec			*p6;
303	cl_rsa_pub_enc			*p7;
304	cl_rsa_pub_dec			*p8;
305	cl_rand_bytes			*p20;
306	cl_dsa_sign			*p30;
307	cl_dsa_verify			*p31;
308
309	/* engine already loaded */
310	if(cluster_labs_dso != NULL)
311		{
312		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_ALREADY_LOADED);
313		goto err;
314		}
315	/* try to load engine	 */
316	cluster_labs_dso = DSO_load(NULL, CLUSTER_LABS_LIB_NAME, NULL,0);
317	if(cluster_labs_dso == NULL)
318		{
319		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_DSO_FAILURE);
320		goto err;
321		}
322	/* bind functions */
323	if(	!(p1 = (cl_engine_init *)DSO_bind_func(
324				cluster_labs_dso, CLUSTER_LABS_F1)) ||
325		!(p2 = (cl_mod_exp *)DSO_bind_func(
326				cluster_labs_dso, CLUSTER_LABS_F2)) ||
327		!(p3 = (cl_mod_exp_crt *)DSO_bind_func(
328				cluster_labs_dso, CLUSTER_LABS_F3)) ||
329		!(p4 = (cl_rsa_mod_exp *)DSO_bind_func(
330				cluster_labs_dso, CLUSTER_LABS_F4)) ||
331		!(p5 = (cl_rsa_priv_enc *)DSO_bind_func(
332				cluster_labs_dso, CLUSTER_LABS_F5)) ||
333		!(p6 = (cl_rsa_priv_dec *)DSO_bind_func(
334				cluster_labs_dso, CLUSTER_LABS_F6)) ||
335		!(p7 = (cl_rsa_pub_enc *)DSO_bind_func(
336				cluster_labs_dso, CLUSTER_LABS_F7)) ||
337		!(p8 = (cl_rsa_pub_dec *)DSO_bind_func(
338				cluster_labs_dso, CLUSTER_LABS_F8)) ||
339		!(p20= (cl_rand_bytes *)DSO_bind_func(
340				cluster_labs_dso, CLUSTER_LABS_F20)) ||
341		!(p30= (cl_dsa_sign *)DSO_bind_func(
342				cluster_labs_dso, CLUSTER_LABS_F30)) ||
343		!(p31= (cl_dsa_verify *)DSO_bind_func(
344				cluster_labs_dso, CLUSTER_LABS_F31)))
345		{
346		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_DSO_FAILURE);
347		goto err;
348		}
349
350	/* copy function pointers */
351	p_cl_engine_init		= p1;
352	p_cl_mod_exp			= p2;
353	p_cl_mod_exp_crt		= p3;
354	p_cl_rsa_mod_exp 		= p4;
355	p_cl_rsa_priv_enc	 	= p5;
356	p_cl_rsa_priv_dec	 	= p6;
357	p_cl_rsa_pub_enc	 	= p7;
358	p_cl_rsa_pub_dec	 	= p8;
359	p_cl_rand_bytes			= p20;
360	p_cl_dsa_sign			= p30;
361	p_cl_dsa_verify			= p31;
362
363
364
365	/* cluster labs engine init */
366	if(p_cl_engine_init()== 0){
367		CLerr(CL_F_CLUSTER_LABS_INIT,CL_R_INIT_FAILED);
368		goto err;
369	}
370
371	return(1);
372
373err:
374	/* reset all pointers */
375	if(cluster_labs_dso)
376		DSO_free(cluster_labs_dso);
377
378	cluster_labs_dso		= NULL;
379	p_cl_engine_init		= NULL;
380	p_cl_mod_exp			= NULL;
381	p_cl_mod_exp_crt		= NULL;
382	p_cl_rsa_mod_exp		= NULL;
383	p_cl_rsa_priv_enc		= NULL;
384	p_cl_rsa_priv_dec		= NULL;
385	p_cl_rsa_pub_enc		= NULL;
386	p_cl_rsa_pub_dec		= NULL;
387	p_cl_rand_bytes			= NULL;
388	p_cl_dsa_sign			= NULL;
389	p_cl_dsa_verify			= NULL;
390
391	return(0);
392	}
393
394
395static int cluster_labs_finish(ENGINE *e)
396	{
397
398	if(cluster_labs_dso == NULL)
399		{
400		CLerr(CL_F_CLUSTER_LABS_FINISH,CL_R_NOT_LOADED);
401		return 0;
402		}
403	if(!DSO_free(cluster_labs_dso))
404		{
405		CLerr(CL_F_CLUSTER_LABS_FINISH,CL_R_DSO_FAILURE);
406		return 0;
407		}
408
409	cluster_labs_dso 		= NULL;
410	p_cl_engine_init		= NULL;
411	p_cl_mod_exp			= NULL;
412	p_cl_rsa_mod_exp		= NULL;
413	p_cl_mod_exp_crt		= NULL;
414	p_cl_rsa_priv_enc		= NULL;
415	p_cl_rsa_priv_dec		= NULL;
416	p_cl_rsa_pub_enc		= NULL;
417	p_cl_rsa_pub_dec		= NULL;
418	p_cl_rand_bytes			= NULL;
419	p_cl_dsa_sign			= NULL;
420	p_cl_dsa_verify			= NULL;
421
422	return(1);
423
424	}
425
426static int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
427	{
428	int initialised = ((cluster_labs_dso == NULL) ? 0 : 1);
429
430	switch(cmd)
431		{
432	case CLUSTER_LABS_CMD_SO_PATH:
433		if(p == NULL)
434			{
435			CLerr(CL_F_CLUSTER_LABS_CTRL,ERR_R_PASSED_NULL_PARAMETER);
436			return 0;
437			}
438		if(initialised)
439			{
440			CLerr(CL_F_CLUSTER_LABS_CTRL,CL_R_ALREADY_LOADED);
441			return 0;
442			}
443		CLUSTER_LABS_LIB_NAME = (const char *)p;
444		return 1;
445	default:
446		break;
447		}
448	CLerr(CL_F_CLUSTER_LABS_CTRL,CL_R_COMMAND_NOT_IMPLEMENTED);
449	return 0;
450	}
451
452
453static int cluster_labs_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
454		const BIGNUM *m, BN_CTX *ctx)
455	{
456
457	if(cluster_labs_dso == NULL)
458		{
459		CLerr(CL_F_CLUSTER_LABS_MOD_EXP,CL_R_NOT_LOADED);
460		return 0;
461		}
462	if(p_cl_mod_exp == NULL)
463		{
464		CLerr(CL_F_CLUSTER_LABS_MOD_EXP,CL_R_FUNCTION_NOT_BINDED);
465		return 0;
466		}
467
468	return	p_cl_mod_exp(r, a, p, m, ctx);
469
470	}
471
472static int cluster_labs_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
473		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
474		const BIGNUM *iqmp, BN_CTX *ctx)
475	{
476
477	if(cluster_labs_dso == NULL)
478		{
479		CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT,CL_R_NOT_LOADED);
480		return 0;
481		}
482	if(p_cl_mod_exp_crt == NULL)
483		{
484		CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT,CL_R_FUNCTION_NOT_BINDED);
485		return 0;
486		}
487
488	return	p_cl_mod_exp_crt(r, a, p, q,dmp1, dmq1, iqmp, ctx);
489
490	}
491
492static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
493	{
494
495	if(cluster_labs_dso == NULL)
496		{
497		CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP,CL_R_NOT_LOADED);
498		return 0;
499		}
500	if(p_cl_rsa_mod_exp == NULL)
501		{
502		CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP,CL_R_FUNCTION_NOT_BINDED);
503		return 0;
504		}
505
506	return p_cl_rsa_mod_exp(r0, I, rsa);
507
508	}
509
510static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
511	{
512
513	if(cluster_labs_dso == NULL)
514		{
515		CLerr(CL_F_CLUSTER_LABS_DSA_SIGN,CL_R_NOT_LOADED);
516		return 0;
517		}
518	if(p_cl_dsa_sign == NULL)
519		{
520		CLerr(CL_F_CLUSTER_LABS_DSA_SIGN,CL_R_FUNCTION_NOT_BINDED);
521		return 0;
522		}
523
524	return p_cl_dsa_sign(dgst, dlen, dsa);
525
526	}
527
528static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
529				DSA_SIG *sig, DSA *dsa)
530	{
531
532	if(cluster_labs_dso == NULL)
533		{
534		CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY,CL_R_NOT_LOADED);
535		return 0;
536		}
537
538	if(p_cl_dsa_verify == NULL)
539		{
540		CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY,CL_R_FUNCTION_NOT_BINDED);
541		return 0;
542		}
543
544	return p_cl_dsa_verify(dgst, dgst_len, sig, dsa);
545
546	}
547
548static int cluster_labs_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
549		BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
550		BN_CTX *ctx, BN_MONT_CTX *in_mont)
551	{
552	BIGNUM t;
553	int status = 0;
554
555	BN_init(&t);
556	/* let rr = a1 ^ p1 mod m */
557	if (!cluster_labs_mod_exp(rr,a1,p1,m,ctx)) goto end;
558	/* let t = a2 ^ p2 mod m */
559	if (!cluster_labs_mod_exp(&t,a2,p2,m,ctx)) goto end;
560	/* let rr = rr * t mod m */
561	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
562	status = 1;
563end:
564	BN_free(&t);
565
566	return(1);
567
568	}
569
570static int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
571		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
572		BN_MONT_CTX *m_ctx)
573	{
574	return 	cluster_labs_mod_exp(r, a, p, m, ctx);
575	}
576
577/* This function is aliased to mod_exp (with the mont stuff dropped). */
578static int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
579		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
580	{
581	return	cluster_labs_mod_exp(r, a, p, m, ctx);
582	}
583
584
585/* This function is aliased to mod_exp (with the dh and mont dropped). */
586static int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
587		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
588	{
589	return 	cluster_labs_mod_exp(r, a, p, m, ctx);
590	}
591
592
593static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
594	     unsigned char *to, RSA *rsa, int padding)
595	{
596
597	if(cluster_labs_dso == NULL)
598		{
599		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC,CL_R_NOT_LOADED);
600		return 0;
601		}
602	if(p_cl_rsa_priv_enc == NULL)
603		{
604		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC,CL_R_FUNCTION_NOT_BINDED);
605		return 0;
606		}
607
608	return 	p_cl_rsa_pub_enc(flen, from, to, rsa, padding);
609
610	}
611
612static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
613	     unsigned char *to, RSA *rsa, int padding)
614	{
615
616	if(cluster_labs_dso == NULL)
617		{
618		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC,CL_R_NOT_LOADED);
619		return 0;
620		}
621	if(p_cl_rsa_priv_enc == NULL)
622		{
623		CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC,CL_R_FUNCTION_NOT_BINDED);
624		return 0;
625		}
626
627	return 	p_cl_rsa_pub_dec(flen, from, to, rsa, padding);
628
629	}
630
631
632static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from,
633		unsigned char *to, RSA *rsa, int padding)
634	{
635
636	if(cluster_labs_dso == NULL)
637		{
638		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC,CL_R_NOT_LOADED);
639		return 0;
640		}
641
642	if(p_cl_rsa_priv_enc == NULL)
643		{
644		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC,CL_R_FUNCTION_NOT_BINDED);
645		return 0;
646		}
647
648	return 	p_cl_rsa_priv_enc(flen, from, to, rsa, padding);
649
650	}
651
652static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from,
653		unsigned char *to, RSA *rsa, int padding)
654	{
655
656	if(cluster_labs_dso == NULL)
657		{
658		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC,CL_R_NOT_LOADED);
659		return 0;
660		}
661	if(p_cl_rsa_priv_dec == NULL)
662		{
663		CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC,CL_R_FUNCTION_NOT_BINDED);
664		return 0;
665		}
666
667	return 	p_cl_rsa_priv_dec(flen, from, to, rsa, padding);
668
669	}
670
671/************************************************************************************
672* Symmetric algorithms
673************************************************************************************/
674/* this will be come soon! */
675
676/************************************************************************************
677* Random generator
678************************************************************************************/
679
680static int cluster_labs_rand_bytes(unsigned char *buf, int num){
681
682	if(cluster_labs_dso == NULL)
683		{
684		CLerr(CL_F_CLUSTER_LABS_RAND_BYTES,CL_R_NOT_LOADED);
685		return 0;
686		}
687	if(p_cl_mod_exp_crt == NULL)
688		{
689		CLerr(CL_F_CLUSTER_LABS_RAND_BYTES,CL_R_FUNCTION_NOT_BINDED);
690		return 0;
691		}
692
693	return 	p_cl_rand_bytes(buf, num);
694
695}
696
697
698/* This stuff is needed if this ENGINE is being compiled into a self-contained
699 * shared-library. */
700#ifdef ENGINE_DYNAMIC_SUPPORT
701static int bind_fn(ENGINE *e, const char *id)
702	{
703	fprintf(stderr, "bind_fn CLUSTER_LABS\n");
704	if(id && (strcmp(id, engine_cluster_labs_id) != 0)) {
705		fprintf(stderr, "bind_fn return(0) first\n");
706		return 0;
707		}
708	if(!bind_helper(e)) {
709		fprintf(stderr, "bind_fn return(1) first\n");
710		return 0;
711		}
712	fprintf(stderr, "bind_fn return(1)\n");
713	return 1;
714	}
715IMPLEMENT_DYNAMIC_CHECK_FN()
716IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
717#endif /* ENGINE_DYNAMIC_SUPPORT */
718
719#endif /* !NO_HW_CLUSTER_LABS */
720#endif /* !NO_HW */
721
722