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 
80 static int cluster_labs_destroy(ENGINE *e);
81 static int cluster_labs_init(ENGINE *e);
82 static int cluster_labs_finish(ENGINE *e);
83 static 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). */
88 static 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
93 static int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
94 	     unsigned char *to, RSA *rsa, int padding);
95 static int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
96 	     unsigned char *to, RSA *rsa, int padding);
97 static int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from,
98 		unsigned char *to, RSA *rsa, int padding);
99 static int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from,
100 		unsigned char *to, RSA *rsa, int padding);
101 static int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
102 #endif
103 
104 /* DSA stuff */
105 #ifndef OPENSSL_NO_DSA
106 static DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
107 static int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
108 				DSA_SIG *sig, DSA *dsa);
109 static 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);
112 static 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). */
120 static 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 */
125 static 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
129 static 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
141 static 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
161 static 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
178 static 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 
191 static 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 
202 static const char *engine_cluster_labs_id = "cluster_labs";
203 static const char *engine_cluster_labs_name = "Cluster Labs hardware engine support";
204 
205 /* engine implementation */
206 /*-----------------------*/
207 static 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
234 static 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
249 static
250 #endif
251 void 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 
263 static 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. */
277 static DSO *cluster_labs_dso = NULL;
278 
279 /* These are the function pointers that are (un)set when the library has
280  * successfully (un)loaded. */
281 static cl_engine_init	  	*p_cl_engine_init 		 = NULL;
282 static cl_mod_exp	 	*p_cl_mod_exp 			 = NULL;
283 static cl_mod_exp_crt		*p_cl_mod_exp_crt 		 = NULL;
284 static cl_rsa_mod_exp		*p_cl_rsa_mod_exp 		 = NULL;
285 static cl_rsa_priv_enc		*p_cl_rsa_priv_enc 		 = NULL;
286 static cl_rsa_priv_dec		*p_cl_rsa_priv_dec 		 = NULL;
287 static cl_rsa_pub_enc		*p_cl_rsa_pub_enc 		 = NULL;
288 static cl_rsa_pub_dec		*p_cl_rsa_pub_dec 		 = NULL;
289 static cl_rand_bytes		*p_cl_rand_bytes	 	 = NULL;
290 static cl_dsa_sign		*p_cl_dsa_sign		 	 = NULL;
291 static cl_dsa_verify		*p_cl_dsa_verify	 	 = NULL;
292 
293 
294 int 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 
373 err:
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 
395 static 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 
426 static 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 
453 static 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 
472 static 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 
492 static 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 
510 static 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 
528 static 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 
548 static 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;
563 end:
564 	BN_free(&t);
565 
566 	return(1);
567 
568 	}
569 
570 static 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). */
578 static 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). */
586 static 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 
593 static 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 
612 static 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 
632 static 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 
652 static 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 
680 static 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
701 static 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 	}
715 IMPLEMENT_DYNAMIC_CHECK_FN()
716 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
717 #endif /* ENGINE_DYNAMIC_SUPPORT */
718 
719 #endif /* !NO_HW_CLUSTER_LABS */
720 #endif /* !NO_HW */
721 
722