1109998Smarkm/* crypto/engine/hw_cluster_labs.c */
2296465Sdelphij/*
3296465Sdelphij * Written by Jan Tschirschwitz (jan.tschirschwitz@cluster-labs.com for the
4296465Sdelphij * OpenSSL project 2000.
5109998Smarkm */
6109998Smarkm/* ====================================================================
7109998Smarkm * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
8109998Smarkm *
9109998Smarkm * Redistribution and use in source and binary forms, with or without
10109998Smarkm * modification, are permitted provided that the following conditions
11109998Smarkm * are met:
12109998Smarkm *
13109998Smarkm * 1. Redistributions of source code must retain the above copyright
14296465Sdelphij *    notice, this list of conditions and the following disclaimer.
15109998Smarkm *
16109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
17109998Smarkm *    notice, this list of conditions and the following disclaimer in
18109998Smarkm *    the documentation and/or other materials provided with the
19109998Smarkm *    distribution.
20109998Smarkm *
21109998Smarkm * 3. All advertising materials mentioning features or use of this
22109998Smarkm *    software must display the following acknowledgment:
23109998Smarkm *    "This product includes software developed by the OpenSSL Project
24109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25109998Smarkm *
26109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27109998Smarkm *    endorse or promote products derived from this software without
28109998Smarkm *    prior written permission. For written permission, please contact
29109998Smarkm *    licensing@OpenSSL.org.
30109998Smarkm *
31109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
32109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
33109998Smarkm *    permission of the OpenSSL Project.
34109998Smarkm *
35109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
36109998Smarkm *    acknowledgment:
37109998Smarkm *    "This product includes software developed by the OpenSSL Project
38109998Smarkm *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39109998Smarkm *
40109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
52109998Smarkm * ====================================================================
53109998Smarkm *
54109998Smarkm * This product includes cryptographic software written by Eric Young
55109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
56109998Smarkm * Hudson (tjh@cryptsoft.com).
57109998Smarkm *
58109998Smarkm */
59109998Smarkm
60296465Sdelphij#define MSC_VER                 /* only used cryptic.h */
61109998Smarkm
62109998Smarkm#include <stdio.h>
63109998Smarkm#include <openssl/crypto.h>
64109998Smarkm#include <openssl/dso.h>
65109998Smarkm#include <openssl/des.h>
66109998Smarkm#include <openssl/engine.h>
67109998Smarkm
68109998Smarkm#ifndef NO_HW
69296465Sdelphij# ifndef NO_HW_CLUSTER_LABS
70109998Smarkm
71296465Sdelphij#  ifdef FLAT_INC
72296465Sdelphij#   include "cluster_labs.h"
73296465Sdelphij#  else
74296465Sdelphij#   include "vendor_defns/cluster_labs.h"
75296465Sdelphij#  endif
76109998Smarkm
77296465Sdelphij#  define CL_LIB_NAME "cluster_labs engine"
78296465Sdelphij#  include "hw_cluster_labs_err.c"
79109998Smarkm
80109998Smarkmstatic int cluster_labs_destroy(ENGINE *e);
81109998Smarkmstatic int cluster_labs_init(ENGINE *e);
82109998Smarkmstatic int cluster_labs_finish(ENGINE *e);
83296465Sdelphijstatic int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p,
84296465Sdelphij                             void (*f) ());
85109998Smarkm
86109998Smarkm/* BIGNUM stuff */
87109998Smarkm/* This function is aliased to mod_exp (with the mont stuff dropped). */
88296465Sdelphijstatic int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a,
89296465Sdelphij                                     const BIGNUM *p, const BIGNUM *m,
90296465Sdelphij                                     BN_CTX *ctx, BN_MONT_CTX *m_ctx);
91296465Sdelphij
92109998Smarkm/* RSA stuff */
93296465Sdelphij#  ifndef OPENSSL_NO_RSA
94109998Smarkmstatic int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
95296465Sdelphij                                    unsigned char *to, RSA *rsa, int padding);
96109998Smarkmstatic int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
97296465Sdelphij                                    unsigned char *to, RSA *rsa, int padding);
98296465Sdelphijstatic int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from,
99296465Sdelphij                                     unsigned char *to, RSA *rsa,
100296465Sdelphij                                     int padding);
101296465Sdelphijstatic int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from,
102296465Sdelphij                                     unsigned char *to, RSA *rsa,
103296465Sdelphij                                     int padding);
104109998Smarkmstatic int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
105296465Sdelphij#  endif
106109998Smarkm
107109998Smarkm/* DSA stuff */
108296465Sdelphij#  ifndef OPENSSL_NO_DSA
109296465Sdelphijstatic DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen,
110296465Sdelphij                                      DSA *dsa);
111109998Smarkmstatic int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
112296465Sdelphij                                   DSA_SIG *sig, DSA *dsa);
113109998Smarkmstatic int cluster_labs_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
114296465Sdelphij                                    BIGNUM *p1, BIGNUM *a2, BIGNUM *p2,
115296465Sdelphij                                    BIGNUM *m, BN_CTX *ctx,
116296465Sdelphij                                    BN_MONT_CTX *in_mont);
117109998Smarkmstatic int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
118296465Sdelphij                                    const BIGNUM *p, const BIGNUM *m,
119296465Sdelphij                                    BN_CTX *ctx, BN_MONT_CTX *m_ctx);
120296465Sdelphij#  endif
121296465Sdelphij
122109998Smarkm/* DH stuff */
123296465Sdelphij#  ifndef OPENSSL_NO_DH
124109998Smarkm/* This function is alised to mod_exp (with the DH and mont dropped). */
125296465Sdelphijstatic int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
126296465Sdelphij                                   const BIGNUM *p, const BIGNUM *m,
127296465Sdelphij                                   BN_CTX *ctx, BN_MONT_CTX *m_ctx);
128296465Sdelphij#  endif
129296465Sdelphij
130296465Sdelphij/* RANDOM stuff */
131109998Smarkmstatic int cluster_labs_rand_bytes(unsigned char *buf, int num);
132109998Smarkm
133109998Smarkm/* The definitions for control commands specific to this engine */
134296465Sdelphij#  define CLUSTER_LABS_CMD_SO_PATH                ENGINE_CMD_BASE
135296465Sdelphijstatic const ENGINE_CMD_DEFN cluster_labs_cmd_defns[] = {
136296465Sdelphij    {CLUSTER_LABS_CMD_SO_PATH,
137296465Sdelphij     "SO_PATH",
138296465Sdelphij     "Specifies the path to the 'cluster labs' shared library",
139296465Sdelphij     ENGINE_CMD_FLAG_STRING},
140296465Sdelphij    {0, NULL, NULL, 0}
141296465Sdelphij};
142109998Smarkm
143109998Smarkm/* Our internal RSA_METHOD that we provide pointers to */
144296465Sdelphij#  ifndef OPENSSL_NO_RSA
145296465Sdelphijstatic RSA_METHOD cluster_labs_rsa = {
146296465Sdelphij    "Cluster Labs RSA method",
147296465Sdelphij    cluster_labs_rsa_pub_enc,   /* rsa_pub_enc */
148296465Sdelphij    cluster_labs_rsa_pub_dec,   /* rsa_pub_dec */
149296465Sdelphij    cluster_labs_rsa_priv_enc,  /* rsa_priv_enc */
150296465Sdelphij    cluster_labs_rsa_priv_dec,  /* rsa_priv_dec */
151296465Sdelphij    cluster_labs_rsa_mod_exp,   /* rsa_mod_exp */
152296465Sdelphij    cluster_labs_mod_exp_mont,  /* bn_mod_exp */
153296465Sdelphij    NULL,                       /* init */
154296465Sdelphij    NULL,                       /* finish */
155296465Sdelphij    0,                          /* flags */
156296465Sdelphij    NULL,                       /* apps_data */
157296465Sdelphij    NULL,                       /* rsa_sign */
158296465Sdelphij    NULL                        /* rsa_verify */
159296465Sdelphij};
160296465Sdelphij#  endif
161109998Smarkm
162109998Smarkm/* Our internal DSA_METHOD that we provide pointers to */
163296465Sdelphij#  ifndef OPENSSL_NO_DSA
164296465Sdelphijstatic DSA_METHOD cluster_labs_dsa = {
165296465Sdelphij    "Cluster Labs DSA method",
166296465Sdelphij    cluster_labs_dsa_sign,      /* dsa_do_sign */
167296465Sdelphij    NULL,                       /* dsa_sign_setup */
168296465Sdelphij    cluster_labs_dsa_verify,    /* dsa_do_verify */
169296465Sdelphij    cluster_labs_dsa_mod_exp,   /* dsa_mod_exp */
170296465Sdelphij    cluster_labs_mod_exp_dsa,   /* bn_mod_exp */
171296465Sdelphij    NULL,                       /* init */
172296465Sdelphij    NULL,                       /* finish */
173296465Sdelphij    0,                          /* flags */
174296465Sdelphij    NULL                        /* app_data */
175296465Sdelphij};
176296465Sdelphij#  endif
177109998Smarkm
178109998Smarkm/* Our internal DH_METHOD that we provide pointers to */
179296465Sdelphij#  ifndef OPENSSL_NO_DH
180296465Sdelphijstatic DH_METHOD cluster_labs_dh = {
181296465Sdelphij    "Cluster Labs DH method",
182296465Sdelphij    NULL,                       /* generate key */
183296465Sdelphij    NULL,                       /* compute key */
184296465Sdelphij    cluster_labs_mod_exp_dh,    /* bn_mod_exp */
185296465Sdelphij    NULL,                       /* init */
186296465Sdelphij    NULL,                       /* finish */
187296465Sdelphij    0,                          /* flags */
188296465Sdelphij    NULL                        /* app_data */
189296465Sdelphij};
190296465Sdelphij#  endif
191109998Smarkm
192296465Sdelphijstatic RAND_METHOD cluster_labs_rand = {
193296465Sdelphij    /* "Cluster Labs RAND method", */
194296465Sdelphij    NULL,                       /* seed */
195296465Sdelphij    cluster_labs_rand_bytes,    /* bytes */
196296465Sdelphij    NULL,                       /* cleanup */
197296465Sdelphij    NULL,                       /* add */
198296465Sdelphij    cluster_labs_rand_bytes,    /* pseudorand */
199296465Sdelphij    NULL,                       /* status */
200296465Sdelphij};
201296465Sdelphij
202109998Smarkmstatic const char *engine_cluster_labs_id = "cluster_labs";
203296465Sdelphijstatic const char *engine_cluster_labs_name =
204296465Sdelphij    "Cluster Labs hardware engine support";
205109998Smarkm
206109998Smarkm/* engine implementation */
207296465Sdelphij/* ---------------------*/
208109998Smarkmstatic int bind_helper(ENGINE *e)
209296465Sdelphij{
210296465Sdelphij
211296465Sdelphij    if (!ENGINE_set_id(e, engine_cluster_labs_id) ||
212296465Sdelphij        !ENGINE_set_name(e, engine_cluster_labs_name) ||
213296465Sdelphij#  ifndef OPENSSL_NO_RSA
214296465Sdelphij        !ENGINE_set_RSA(e, &cluster_labs_rsa) ||
215296465Sdelphij#  endif
216296465Sdelphij#  ifndef OPENSSL_NO_DSA
217296465Sdelphij        !ENGINE_set_DSA(e, &cluster_labs_dsa) ||
218296465Sdelphij#  endif
219296465Sdelphij#  ifndef OPENSSL_NO_DH
220296465Sdelphij        !ENGINE_set_DH(e, &cluster_labs_dh) ||
221296465Sdelphij#  endif
222296465Sdelphij        !ENGINE_set_RAND(e, &cluster_labs_rand) ||
223296465Sdelphij        !ENGINE_set_destroy_function(e, cluster_labs_destroy) ||
224296465Sdelphij        !ENGINE_set_init_function(e, cluster_labs_init) ||
225296465Sdelphij        !ENGINE_set_finish_function(e, cluster_labs_finish) ||
226296465Sdelphij        !ENGINE_set_ctrl_function(e, cluster_labs_ctrl) ||
227296465Sdelphij        !ENGINE_set_cmd_defns(e, cluster_labs_cmd_defns))
228296465Sdelphij        return 0;
229296465Sdelphij    /* Ensure the error handling is set up */
230296465Sdelphij    ERR_load_CL_strings();
231296465Sdelphij    return 1;
232296465Sdelphij}
233296465Sdelphij
234296465Sdelphij#  ifndef ENGINE_DYNAMIC_SUPPORT
235109998Smarkmstatic ENGINE *engine_cluster_labs(void)
236296465Sdelphij{
237296465Sdelphij    ENGINE *ret = ENGINE_new();
238109998Smarkm
239296465Sdelphij    if (!ret)
240296465Sdelphij        return NULL;
241296465Sdelphij    if (!bind_helper(ret)) {
242296465Sdelphij        ENGINE_free(ret);
243296465Sdelphij        return NULL;
244296465Sdelphij    }
245296465Sdelphij    return ret;
246296465Sdelphij}
247109998Smarkm
248296465Sdelphij#   ifdef ENGINE_DYNAMIC_SUPPORT
249109998Smarkmstatic
250296465Sdelphij#   endif
251109998Smarkmvoid ENGINE_load_cluster_labs(void)
252296465Sdelphij{
253109998Smarkm
254296465Sdelphij    ENGINE *cluster_labs = engine_cluster_labs();
255109998Smarkm
256296465Sdelphij    if (!cluster_labs)
257296465Sdelphij        return;
258296465Sdelphij    ENGINE_add(cluster_labs);
259296465Sdelphij    ENGINE_free(cluster_labs);
260296465Sdelphij    ERR_clear_error();
261296465Sdelphij}
262296465Sdelphij#  endif                        /* !ENGINE_DYNAMIC_SUPPORT */
263296465Sdelphij
264109998Smarkmstatic int cluster_labs_destroy(ENGINE *e)
265296465Sdelphij{
266109998Smarkm
267296465Sdelphij    ERR_unload_CL_strings();
268296465Sdelphij    return 1;
269296465Sdelphij}
270109998Smarkm
271296465Sdelphij/*
272296465Sdelphij * This is a process-global DSO handle used for loading and unloading the
273296465Sdelphij * Cluster Labs library. NB: This is only set (or unset) during an init() or
274296465Sdelphij * finish() call (reference counts permitting) and they're operating with
275296465Sdelphij * global locks, so this should be thread-safe implicitly.
276296465Sdelphij */
277109998Smarkmstatic DSO *cluster_labs_dso = NULL;
278109998Smarkm
279296465Sdelphij/*
280296465Sdelphij * These are the function pointers that are (un)set when the library has
281296465Sdelphij * successfully (un)loaded.
282296465Sdelphij */
283296465Sdelphijstatic cl_engine_init *p_cl_engine_init = NULL;
284296465Sdelphijstatic cl_mod_exp *p_cl_mod_exp = NULL;
285296465Sdelphijstatic cl_mod_exp_crt *p_cl_mod_exp_crt = NULL;
286296465Sdelphijstatic cl_rsa_mod_exp *p_cl_rsa_mod_exp = NULL;
287296465Sdelphijstatic cl_rsa_priv_enc *p_cl_rsa_priv_enc = NULL;
288296465Sdelphijstatic cl_rsa_priv_dec *p_cl_rsa_priv_dec = NULL;
289296465Sdelphijstatic cl_rsa_pub_enc *p_cl_rsa_pub_enc = NULL;
290296465Sdelphijstatic cl_rsa_pub_dec *p_cl_rsa_pub_dec = NULL;
291296465Sdelphijstatic cl_rand_bytes *p_cl_rand_bytes = NULL;
292296465Sdelphijstatic cl_dsa_sign *p_cl_dsa_sign = NULL;
293296465Sdelphijstatic cl_dsa_verify *p_cl_dsa_verify = NULL;
294109998Smarkm
295109998Smarkmint cluster_labs_init(ENGINE *e)
296296465Sdelphij{
297109998Smarkm
298296465Sdelphij    cl_engine_init *p1;
299296465Sdelphij    cl_mod_exp *p2;
300296465Sdelphij    cl_mod_exp_crt *p3;
301296465Sdelphij    cl_rsa_mod_exp *p4;
302296465Sdelphij    cl_rsa_priv_enc *p5;
303296465Sdelphij    cl_rsa_priv_dec *p6;
304296465Sdelphij    cl_rsa_pub_enc *p7;
305296465Sdelphij    cl_rsa_pub_dec *p8;
306296465Sdelphij    cl_rand_bytes *p20;
307296465Sdelphij    cl_dsa_sign *p30;
308296465Sdelphij    cl_dsa_verify *p31;
309109998Smarkm
310296465Sdelphij    /* engine already loaded */
311296465Sdelphij    if (cluster_labs_dso != NULL) {
312296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_INIT, CL_R_ALREADY_LOADED);
313296465Sdelphij        goto err;
314296465Sdelphij    }
315296465Sdelphij    /* try to load engine    */
316296465Sdelphij    cluster_labs_dso = DSO_load(NULL, CLUSTER_LABS_LIB_NAME, NULL, 0);
317296465Sdelphij    if (cluster_labs_dso == NULL) {
318296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_INIT, CL_R_DSO_FAILURE);
319296465Sdelphij        goto err;
320296465Sdelphij    }
321296465Sdelphij    /* bind functions */
322296465Sdelphij    if (!
323296465Sdelphij        (p1 =
324296465Sdelphij         (cl_engine_init *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F1))
325296465Sdelphij|| !(p2 = (cl_mod_exp *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F2))
326296465Sdelphij|| !(p3 = (cl_mod_exp_crt *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F3))
327296465Sdelphij|| !(p4 = (cl_rsa_mod_exp *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F4))
328296465Sdelphij|| !(p5 =
329296465Sdelphij     (cl_rsa_priv_enc *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F5))
330296465Sdelphij|| !(p6 =
331296465Sdelphij     (cl_rsa_priv_dec *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F6))
332296465Sdelphij|| !(p7 = (cl_rsa_pub_enc *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F7))
333296465Sdelphij|| !(p8 = (cl_rsa_pub_dec *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F8))
334296465Sdelphij|| !(p20 =
335296465Sdelphij     (cl_rand_bytes *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F20))
336296465Sdelphij|| !(p30 = (cl_dsa_sign *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F30))
337296465Sdelphij|| !(p31 =
338296465Sdelphij     (cl_dsa_verify *) DSO_bind_func(cluster_labs_dso, CLUSTER_LABS_F31))) {
339296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_INIT, CL_R_DSO_FAILURE);
340296465Sdelphij        goto err;
341296465Sdelphij    }
342109998Smarkm
343296465Sdelphij    /* copy function pointers */
344296465Sdelphij    p_cl_engine_init = p1;
345296465Sdelphij    p_cl_mod_exp = p2;
346296465Sdelphij    p_cl_mod_exp_crt = p3;
347296465Sdelphij    p_cl_rsa_mod_exp = p4;
348296465Sdelphij    p_cl_rsa_priv_enc = p5;
349296465Sdelphij    p_cl_rsa_priv_dec = p6;
350296465Sdelphij    p_cl_rsa_pub_enc = p7;
351296465Sdelphij    p_cl_rsa_pub_dec = p8;
352296465Sdelphij    p_cl_rand_bytes = p20;
353296465Sdelphij    p_cl_dsa_sign = p30;
354296465Sdelphij    p_cl_dsa_verify = p31;
355109998Smarkm
356296465Sdelphij    /* cluster labs engine init */
357296465Sdelphij    if (p_cl_engine_init() == 0) {
358296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_INIT, CL_R_INIT_FAILED);
359296465Sdelphij        goto err;
360296465Sdelphij    }
361109998Smarkm
362296465Sdelphij    return (1);
363296465Sdelphij
364296465Sdelphij err:
365296465Sdelphij    /* reset all pointers */
366296465Sdelphij    if (cluster_labs_dso)
367296465Sdelphij        DSO_free(cluster_labs_dso);
368296465Sdelphij
369296465Sdelphij    cluster_labs_dso = NULL;
370296465Sdelphij    p_cl_engine_init = NULL;
371296465Sdelphij    p_cl_mod_exp = NULL;
372296465Sdelphij    p_cl_mod_exp_crt = NULL;
373296465Sdelphij    p_cl_rsa_mod_exp = NULL;
374296465Sdelphij    p_cl_rsa_priv_enc = NULL;
375296465Sdelphij    p_cl_rsa_priv_dec = NULL;
376296465Sdelphij    p_cl_rsa_pub_enc = NULL;
377296465Sdelphij    p_cl_rsa_pub_dec = NULL;
378296465Sdelphij    p_cl_rand_bytes = NULL;
379296465Sdelphij    p_cl_dsa_sign = NULL;
380296465Sdelphij    p_cl_dsa_verify = NULL;
381296465Sdelphij
382296465Sdelphij    return (0);
383296465Sdelphij}
384296465Sdelphij
385109998Smarkmstatic int cluster_labs_finish(ENGINE *e)
386296465Sdelphij{
387109998Smarkm
388296465Sdelphij    if (cluster_labs_dso == NULL) {
389296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_FINISH, CL_R_NOT_LOADED);
390296465Sdelphij        return 0;
391296465Sdelphij    }
392296465Sdelphij    if (!DSO_free(cluster_labs_dso)) {
393296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_FINISH, CL_R_DSO_FAILURE);
394296465Sdelphij        return 0;
395296465Sdelphij    }
396109998Smarkm
397296465Sdelphij    cluster_labs_dso = NULL;
398296465Sdelphij    p_cl_engine_init = NULL;
399296465Sdelphij    p_cl_mod_exp = NULL;
400296465Sdelphij    p_cl_rsa_mod_exp = NULL;
401296465Sdelphij    p_cl_mod_exp_crt = NULL;
402296465Sdelphij    p_cl_rsa_priv_enc = NULL;
403296465Sdelphij    p_cl_rsa_priv_dec = NULL;
404296465Sdelphij    p_cl_rsa_pub_enc = NULL;
405296465Sdelphij    p_cl_rsa_pub_dec = NULL;
406296465Sdelphij    p_cl_rand_bytes = NULL;
407296465Sdelphij    p_cl_dsa_sign = NULL;
408296465Sdelphij    p_cl_dsa_verify = NULL;
409109998Smarkm
410296465Sdelphij    return (1);
411296465Sdelphij
412296465Sdelphij}
413296465Sdelphij
414296465Sdelphijstatic int cluster_labs_ctrl(ENGINE *e, int cmd, long i, void *p,
415296465Sdelphij                             void (*f) ())
416296465Sdelphij{
417296465Sdelphij    int initialised = ((cluster_labs_dso == NULL) ? 0 : 1);
418296465Sdelphij
419296465Sdelphij    switch (cmd) {
420296465Sdelphij    case CLUSTER_LABS_CMD_SO_PATH:
421296465Sdelphij        if (p == NULL) {
422296465Sdelphij            CLerr(CL_F_CLUSTER_LABS_CTRL, ERR_R_PASSED_NULL_PARAMETER);
423296465Sdelphij            return 0;
424296465Sdelphij        }
425296465Sdelphij        if (initialised) {
426296465Sdelphij            CLerr(CL_F_CLUSTER_LABS_CTRL, CL_R_ALREADY_LOADED);
427296465Sdelphij            return 0;
428296465Sdelphij        }
429296465Sdelphij        CLUSTER_LABS_LIB_NAME = (const char *)p;
430296465Sdelphij        return 1;
431296465Sdelphij    default:
432296465Sdelphij        break;
433296465Sdelphij    }
434296465Sdelphij    CLerr(CL_F_CLUSTER_LABS_CTRL, CL_R_COMMAND_NOT_IMPLEMENTED);
435296465Sdelphij    return 0;
436296465Sdelphij}
437296465Sdelphij
438109998Smarkmstatic int cluster_labs_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
439296465Sdelphij                                const BIGNUM *m, BN_CTX *ctx)
440296465Sdelphij{
441109998Smarkm
442296465Sdelphij    if (cluster_labs_dso == NULL) {
443296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_MOD_EXP, CL_R_NOT_LOADED);
444296465Sdelphij        return 0;
445296465Sdelphij    }
446296465Sdelphij    if (p_cl_mod_exp == NULL) {
447296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_MOD_EXP, CL_R_FUNCTION_NOT_BINDED);
448296465Sdelphij        return 0;
449296465Sdelphij    }
450109998Smarkm
451296465Sdelphij    return p_cl_mod_exp(r, a, p, m, ctx);
452109998Smarkm
453296465Sdelphij}
454296465Sdelphij
455109998Smarkmstatic int cluster_labs_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
456296465Sdelphij                                    const BIGNUM *q, const BIGNUM *dmp1,
457296465Sdelphij                                    const BIGNUM *dmq1, const BIGNUM *iqmp,
458296465Sdelphij                                    BN_CTX *ctx)
459296465Sdelphij{
460109998Smarkm
461296465Sdelphij    if (cluster_labs_dso == NULL) {
462296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT, CL_R_NOT_LOADED);
463296465Sdelphij        return 0;
464296465Sdelphij    }
465296465Sdelphij    if (p_cl_mod_exp_crt == NULL) {
466296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_MOD_EXP_CRT, CL_R_FUNCTION_NOT_BINDED);
467296465Sdelphij        return 0;
468296465Sdelphij    }
469296465Sdelphij
470296465Sdelphij    return p_cl_mod_exp_crt(r, a, p, q, dmp1, dmq1, iqmp, ctx);
471296465Sdelphij
472296465Sdelphij}
473296465Sdelphij
474109998Smarkmstatic int cluster_labs_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
475296465Sdelphij{
476109998Smarkm
477296465Sdelphij    if (cluster_labs_dso == NULL) {
478296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP, CL_R_NOT_LOADED);
479296465Sdelphij        return 0;
480296465Sdelphij    }
481296465Sdelphij    if (p_cl_rsa_mod_exp == NULL) {
482296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_MOD_EXP, CL_R_FUNCTION_NOT_BINDED);
483296465Sdelphij        return 0;
484296465Sdelphij    }
485109998Smarkm
486296465Sdelphij    return p_cl_rsa_mod_exp(r0, I, rsa);
487109998Smarkm
488296465Sdelphij}
489109998Smarkm
490296465Sdelphijstatic DSA_SIG *cluster_labs_dsa_sign(const unsigned char *dgst, int dlen,
491296465Sdelphij                                      DSA *dsa)
492296465Sdelphij{
493109998Smarkm
494296465Sdelphij    if (cluster_labs_dso == NULL) {
495296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_DSA_SIGN, CL_R_NOT_LOADED);
496296465Sdelphij        return 0;
497296465Sdelphij    }
498296465Sdelphij    if (p_cl_dsa_sign == NULL) {
499296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_DSA_SIGN, CL_R_FUNCTION_NOT_BINDED);
500296465Sdelphij        return 0;
501296465Sdelphij    }
502296465Sdelphij
503296465Sdelphij    return p_cl_dsa_sign(dgst, dlen, dsa);
504296465Sdelphij
505296465Sdelphij}
506296465Sdelphij
507109998Smarkmstatic int cluster_labs_dsa_verify(const unsigned char *dgst, int dgst_len,
508296465Sdelphij                                   DSA_SIG *sig, DSA *dsa)
509296465Sdelphij{
510109998Smarkm
511296465Sdelphij    if (cluster_labs_dso == NULL) {
512296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY, CL_R_NOT_LOADED);
513296465Sdelphij        return 0;
514296465Sdelphij    }
515109998Smarkm
516296465Sdelphij    if (p_cl_dsa_verify == NULL) {
517296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_DSA_VERIFY, CL_R_FUNCTION_NOT_BINDED);
518296465Sdelphij        return 0;
519296465Sdelphij    }
520109998Smarkm
521296465Sdelphij    return p_cl_dsa_verify(dgst, dgst_len, sig, dsa);
522296465Sdelphij
523296465Sdelphij}
524296465Sdelphij
525109998Smarkmstatic int cluster_labs_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
526296465Sdelphij                                    BIGNUM *p1, BIGNUM *a2, BIGNUM *p2,
527296465Sdelphij                                    BIGNUM *m, BN_CTX *ctx,
528296465Sdelphij                                    BN_MONT_CTX *in_mont)
529296465Sdelphij{
530296465Sdelphij    BIGNUM t;
531296465Sdelphij    int status = 0;
532109998Smarkm
533296465Sdelphij    BN_init(&t);
534296465Sdelphij    /* let rr = a1 ^ p1 mod m */
535296465Sdelphij    if (!cluster_labs_mod_exp(rr, a1, p1, m, ctx))
536296465Sdelphij        goto end;
537296465Sdelphij    /* let t = a2 ^ p2 mod m */
538296465Sdelphij    if (!cluster_labs_mod_exp(&t, a2, p2, m, ctx))
539296465Sdelphij        goto end;
540296465Sdelphij    /* let rr = rr * t mod m */
541296465Sdelphij    if (!BN_mod_mul(rr, rr, &t, m, ctx))
542296465Sdelphij        goto end;
543296465Sdelphij    status = 1;
544296465Sdelphij end:
545296465Sdelphij    BN_free(&t);
546109998Smarkm
547296465Sdelphij    return (1);
548296465Sdelphij
549296465Sdelphij}
550296465Sdelphij
551109998Smarkmstatic int cluster_labs_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
552296465Sdelphij                                    const BIGNUM *p, const BIGNUM *m,
553296465Sdelphij                                    BN_CTX *ctx, BN_MONT_CTX *m_ctx)
554296465Sdelphij{
555296465Sdelphij    return cluster_labs_mod_exp(r, a, p, m, ctx);
556296465Sdelphij}
557296465Sdelphij
558109998Smarkm/* This function is aliased to mod_exp (with the mont stuff dropped). */
559296465Sdelphijstatic int cluster_labs_mod_exp_mont(BIGNUM *r, const BIGNUM *a,
560296465Sdelphij                                     const BIGNUM *p, const BIGNUM *m,
561296465Sdelphij                                     BN_CTX *ctx, BN_MONT_CTX *m_ctx)
562296465Sdelphij{
563296465Sdelphij    return cluster_labs_mod_exp(r, a, p, m, ctx);
564296465Sdelphij}
565109998Smarkm
566109998Smarkm/* This function is aliased to mod_exp (with the dh and mont dropped). */
567296465Sdelphijstatic int cluster_labs_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
568296465Sdelphij                                   const BIGNUM *p, const BIGNUM *m,
569296465Sdelphij                                   BN_CTX *ctx, BN_MONT_CTX *m_ctx)
570296465Sdelphij{
571296465Sdelphij    return cluster_labs_mod_exp(r, a, p, m, ctx);
572296465Sdelphij}
573109998Smarkm
574109998Smarkmstatic int cluster_labs_rsa_pub_enc(int flen, const unsigned char *from,
575296465Sdelphij                                    unsigned char *to, RSA *rsa, int padding)
576296465Sdelphij{
577109998Smarkm
578296465Sdelphij    if (cluster_labs_dso == NULL) {
579296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC, CL_R_NOT_LOADED);
580296465Sdelphij        return 0;
581296465Sdelphij    }
582296465Sdelphij    if (p_cl_rsa_priv_enc == NULL) {
583296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PUB_ENC, CL_R_FUNCTION_NOT_BINDED);
584296465Sdelphij        return 0;
585296465Sdelphij    }
586296465Sdelphij
587296465Sdelphij    return p_cl_rsa_pub_enc(flen, from, to, rsa, padding);
588296465Sdelphij
589296465Sdelphij}
590296465Sdelphij
591109998Smarkmstatic int cluster_labs_rsa_pub_dec(int flen, const unsigned char *from,
592296465Sdelphij                                    unsigned char *to, RSA *rsa, int padding)
593296465Sdelphij{
594109998Smarkm
595296465Sdelphij    if (cluster_labs_dso == NULL) {
596296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC, CL_R_NOT_LOADED);
597296465Sdelphij        return 0;
598296465Sdelphij    }
599296465Sdelphij    if (p_cl_rsa_priv_enc == NULL) {
600296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PUB_DEC, CL_R_FUNCTION_NOT_BINDED);
601296465Sdelphij        return 0;
602296465Sdelphij    }
603109998Smarkm
604296465Sdelphij    return p_cl_rsa_pub_dec(flen, from, to, rsa, padding);
605109998Smarkm
606296465Sdelphij}
607109998Smarkm
608296465Sdelphijstatic int cluster_labs_rsa_priv_enc(int flen, const unsigned char *from,
609296465Sdelphij                                     unsigned char *to, RSA *rsa, int padding)
610296465Sdelphij{
611109998Smarkm
612296465Sdelphij    if (cluster_labs_dso == NULL) {
613296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC, CL_R_NOT_LOADED);
614296465Sdelphij        return 0;
615296465Sdelphij    }
616109998Smarkm
617296465Sdelphij    if (p_cl_rsa_priv_enc == NULL) {
618296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_ENC, CL_R_FUNCTION_NOT_BINDED);
619296465Sdelphij        return 0;
620296465Sdelphij    }
621109998Smarkm
622296465Sdelphij    return p_cl_rsa_priv_enc(flen, from, to, rsa, padding);
623109998Smarkm
624296465Sdelphij}
625296465Sdelphij
626296465Sdelphijstatic int cluster_labs_rsa_priv_dec(int flen, const unsigned char *from,
627296465Sdelphij                                     unsigned char *to, RSA *rsa, int padding)
628296465Sdelphij{
629296465Sdelphij
630296465Sdelphij    if (cluster_labs_dso == NULL) {
631296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC, CL_R_NOT_LOADED);
632296465Sdelphij        return 0;
633296465Sdelphij    }
634296465Sdelphij    if (p_cl_rsa_priv_dec == NULL) {
635296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RSA_PRIV_DEC, CL_R_FUNCTION_NOT_BINDED);
636296465Sdelphij        return 0;
637296465Sdelphij    }
638296465Sdelphij
639296465Sdelphij    return p_cl_rsa_priv_dec(flen, from, to, rsa, padding);
640296465Sdelphij
641296465Sdelphij}
642296465Sdelphij
643109998Smarkm/************************************************************************************
644109998Smarkm* Symmetric algorithms
645109998Smarkm************************************************************************************/
646109998Smarkm/* this will be come soon! */
647109998Smarkm
648109998Smarkm/************************************************************************************
649109998Smarkm* Random generator
650109998Smarkm************************************************************************************/
651109998Smarkm
652296465Sdelphijstatic int cluster_labs_rand_bytes(unsigned char *buf, int num)
653296465Sdelphij{
654109998Smarkm
655296465Sdelphij    if (cluster_labs_dso == NULL) {
656296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RAND_BYTES, CL_R_NOT_LOADED);
657296465Sdelphij        return 0;
658296465Sdelphij    }
659296465Sdelphij    if (p_cl_mod_exp_crt == NULL) {
660296465Sdelphij        CLerr(CL_F_CLUSTER_LABS_RAND_BYTES, CL_R_FUNCTION_NOT_BINDED);
661296465Sdelphij        return 0;
662296465Sdelphij    }
663109998Smarkm
664296465Sdelphij    return p_cl_rand_bytes(buf, num);
665109998Smarkm
666109998Smarkm}
667109998Smarkm
668296465Sdelphij/*
669296465Sdelphij * This stuff is needed if this ENGINE is being compiled into a
670296465Sdelphij * self-contained shared-library.
671296465Sdelphij */
672296465Sdelphij#  ifdef ENGINE_DYNAMIC_SUPPORT
673296465Sdelphijstatic int bind_fn(ENGINE *e, const char *id)
674296465Sdelphij{
675296465Sdelphij    fprintf(stderr, "bind_fn CLUSTER_LABS\n");
676296465Sdelphij    if (id && (strcmp(id, engine_cluster_labs_id) != 0)) {
677296465Sdelphij        fprintf(stderr, "bind_fn return(0) first\n");
678296465Sdelphij        return 0;
679296465Sdelphij    }
680296465Sdelphij    if (!bind_helper(e)) {
681296465Sdelphij        fprintf(stderr, "bind_fn return(1) first\n");
682296465Sdelphij        return 0;
683296465Sdelphij    }
684296465Sdelphij    fprintf(stderr, "bind_fn return(1)\n");
685296465Sdelphij    return 1;
686296465Sdelphij}
687109998Smarkm
688109998SmarkmIMPLEMENT_DYNAMIC_CHECK_FN()
689296465Sdelphij    IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
690296465Sdelphij#  endif                        /* ENGINE_DYNAMIC_SUPPORT */
691296465Sdelphij# endif                         /* !NO_HW_CLUSTER_LABS */
692296465Sdelphij#endif                          /* !NO_HW */
693