1160814Ssimon/* crypto/engine/hw_nuron.c */
2296341Sdelphij/*
3296341Sdelphij * Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
4160814Ssimon * Thorpe's Atalla implementation.
5160814Ssimon */
6160814Ssimon/* ====================================================================
7160814Ssimon * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
8160814Ssimon *
9160814Ssimon * Redistribution and use in source and binary forms, with or without
10160814Ssimon * modification, are permitted provided that the following conditions
11160814Ssimon * are met:
12160814Ssimon *
13160814Ssimon * 1. Redistributions of source code must retain the above copyright
14296341Sdelphij *    notice, this list of conditions and the following disclaimer.
15160814Ssimon *
16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright
17160814Ssimon *    notice, this list of conditions and the following disclaimer in
18160814Ssimon *    the documentation and/or other materials provided with the
19160814Ssimon *    distribution.
20160814Ssimon *
21160814Ssimon * 3. All advertising materials mentioning features or use of this
22160814Ssimon *    software must display the following acknowledgment:
23160814Ssimon *    "This product includes software developed by the OpenSSL Project
24160814Ssimon *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25160814Ssimon *
26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27160814Ssimon *    endorse or promote products derived from this software without
28160814Ssimon *    prior written permission. For written permission, please contact
29160814Ssimon *    licensing@OpenSSL.org.
30160814Ssimon *
31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL"
32160814Ssimon *    nor may "OpenSSL" appear in their names without prior written
33160814Ssimon *    permission of the OpenSSL Project.
34160814Ssimon *
35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following
36160814Ssimon *    acknowledgment:
37160814Ssimon *    "This product includes software developed by the OpenSSL Project
38160814Ssimon *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39160814Ssimon *
40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43160814Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
52160814Ssimon * ====================================================================
53160814Ssimon *
54160814Ssimon * This product includes cryptographic software written by Eric Young
55160814Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
56160814Ssimon * Hudson (tjh@cryptsoft.com).
57160814Ssimon *
58160814Ssimon */
59160814Ssimon
60160814Ssimon#include <stdio.h>
61160814Ssimon#include <string.h>
62160814Ssimon#include <openssl/crypto.h>
63160814Ssimon#include <openssl/buffer.h>
64160814Ssimon#include <openssl/dso.h>
65160814Ssimon#include <openssl/engine.h>
66160814Ssimon#ifndef OPENSSL_NO_RSA
67296341Sdelphij# include <openssl/rsa.h>
68160814Ssimon#endif
69160814Ssimon#ifndef OPENSSL_NO_DSA
70296341Sdelphij# include <openssl/dsa.h>
71160814Ssimon#endif
72160814Ssimon#ifndef OPENSSL_NO_DH
73296341Sdelphij# include <openssl/dh.h>
74160814Ssimon#endif
75160814Ssimon#include <openssl/bn.h>
76160814Ssimon
77160814Ssimon#ifndef OPENSSL_NO_HW
78296341Sdelphij# ifndef OPENSSL_NO_HW_NURON
79160814Ssimon
80296341Sdelphij#  define NURON_LIB_NAME "nuron engine"
81296341Sdelphij#  include "e_nuron_err.c"
82160814Ssimon
83160814Ssimonstatic const char *NURON_LIBNAME = NULL;
84160814Ssimonstatic const char *get_NURON_LIBNAME(void)
85296341Sdelphij{
86296341Sdelphij    if (NURON_LIBNAME)
87296341Sdelphij        return NURON_LIBNAME;
88296341Sdelphij    return "nuronssl";
89296341Sdelphij}
90296341Sdelphij
91160814Ssimonstatic void free_NURON_LIBNAME(void)
92296341Sdelphij{
93296341Sdelphij    if (NURON_LIBNAME)
94296341Sdelphij        OPENSSL_free((void *)NURON_LIBNAME);
95296341Sdelphij    NURON_LIBNAME = NULL;
96296341Sdelphij}
97296341Sdelphij
98160814Ssimonstatic long set_NURON_LIBNAME(const char *name)
99296341Sdelphij{
100296341Sdelphij    free_NURON_LIBNAME();
101296341Sdelphij    return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
102296341Sdelphij}
103296341Sdelphij
104160814Ssimonstatic const char *NURON_F1 = "nuron_mod_exp";
105160814Ssimon
106160814Ssimon/* The definitions for control commands specific to this engine */
107296341Sdelphij#  define NURON_CMD_SO_PATH               ENGINE_CMD_BASE
108160814Ssimonstatic const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
109296341Sdelphij    {NURON_CMD_SO_PATH,
110296341Sdelphij     "SO_PATH",
111296341Sdelphij     "Specifies the path to the 'nuronssl' shared library",
112296341Sdelphij     ENGINE_CMD_FLAG_STRING},
113296341Sdelphij    {0, NULL, NULL, 0}
114296341Sdelphij};
115160814Ssimon
116296341Sdelphijtypedef int tfnModExp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
117296341Sdelphij                      const BIGNUM *m);
118160814Ssimonstatic tfnModExp *pfnModExp = NULL;
119160814Ssimon
120160814Ssimonstatic DSO *pvDSOHandle = NULL;
121160814Ssimon
122160814Ssimonstatic int nuron_destroy(ENGINE *e)
123296341Sdelphij{
124296341Sdelphij    free_NURON_LIBNAME();
125296341Sdelphij    ERR_unload_NURON_strings();
126296341Sdelphij    return 1;
127296341Sdelphij}
128160814Ssimon
129160814Ssimonstatic int nuron_init(ENGINE *e)
130296341Sdelphij{
131296341Sdelphij    if (pvDSOHandle != NULL) {
132296341Sdelphij        NURONerr(NURON_F_NURON_INIT, NURON_R_ALREADY_LOADED);
133296341Sdelphij        return 0;
134296341Sdelphij    }
135160814Ssimon
136296341Sdelphij    pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL,
137296341Sdelphij                           DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
138296341Sdelphij    if (!pvDSOHandle) {
139296341Sdelphij        NURONerr(NURON_F_NURON_INIT, NURON_R_DSO_NOT_FOUND);
140296341Sdelphij        return 0;
141296341Sdelphij    }
142160814Ssimon
143296341Sdelphij    pfnModExp = (tfnModExp *) DSO_bind_func(pvDSOHandle, NURON_F1);
144296341Sdelphij    if (!pfnModExp) {
145296341Sdelphij        NURONerr(NURON_F_NURON_INIT, NURON_R_DSO_FUNCTION_NOT_FOUND);
146296341Sdelphij        return 0;
147296341Sdelphij    }
148160814Ssimon
149296341Sdelphij    return 1;
150296341Sdelphij}
151160814Ssimon
152160814Ssimonstatic int nuron_finish(ENGINE *e)
153296341Sdelphij{
154296341Sdelphij    free_NURON_LIBNAME();
155296341Sdelphij    if (pvDSOHandle == NULL) {
156296341Sdelphij        NURONerr(NURON_F_NURON_FINISH, NURON_R_NOT_LOADED);
157296341Sdelphij        return 0;
158296341Sdelphij    }
159296341Sdelphij    if (!DSO_free(pvDSOHandle)) {
160296341Sdelphij        NURONerr(NURON_F_NURON_FINISH, NURON_R_DSO_FAILURE);
161296341Sdelphij        return 0;
162296341Sdelphij    }
163296341Sdelphij    pvDSOHandle = NULL;
164296341Sdelphij    pfnModExp = NULL;
165296341Sdelphij    return 1;
166296341Sdelphij}
167160814Ssimon
168296341Sdelphijstatic int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
169296341Sdelphij{
170296341Sdelphij    int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
171296341Sdelphij    switch (cmd) {
172296341Sdelphij    case NURON_CMD_SO_PATH:
173296341Sdelphij        if (p == NULL) {
174296341Sdelphij            NURONerr(NURON_F_NURON_CTRL, ERR_R_PASSED_NULL_PARAMETER);
175296341Sdelphij            return 0;
176296341Sdelphij        }
177296341Sdelphij        if (initialised) {
178296341Sdelphij            NURONerr(NURON_F_NURON_CTRL, NURON_R_ALREADY_LOADED);
179296341Sdelphij            return 0;
180296341Sdelphij        }
181296341Sdelphij        return set_NURON_LIBNAME((const char *)p);
182296341Sdelphij    default:
183296341Sdelphij        break;
184296341Sdelphij    }
185296341Sdelphij    NURONerr(NURON_F_NURON_CTRL, NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
186296341Sdelphij    return 0;
187160814Ssimon}
188160814Ssimon
189296341Sdelphijstatic int nuron_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
190296341Sdelphij                         const BIGNUM *m, BN_CTX *ctx)
191296341Sdelphij{
192296341Sdelphij    if (!pvDSOHandle) {
193296341Sdelphij        NURONerr(NURON_F_NURON_MOD_EXP, NURON_R_NOT_LOADED);
194296341Sdelphij        return 0;
195296341Sdelphij    }
196296341Sdelphij    return pfnModExp(r, a, p, m);
197296341Sdelphij}
198160814Ssimon
199296341Sdelphij#  ifndef OPENSSL_NO_RSA
200296341Sdelphijstatic int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
201296341Sdelphij                             BN_CTX *ctx)
202296341Sdelphij{
203296341Sdelphij    return nuron_mod_exp(r0, I, rsa->d, rsa->n, ctx);
204296341Sdelphij}
205296341Sdelphij#  endif
206160814Ssimon
207296341Sdelphij#  ifndef OPENSSL_NO_DSA
208296341Sdelphij/*
209296341Sdelphij * This code was liberated and adapted from the commented-out code in
210296341Sdelphij * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration (it
211296341Sdelphij * doesn't have a CRT form for RSA), this function means that an Atalla
212296341Sdelphij * system running with a DSA server certificate can handshake around 5 or 6
213296341Sdelphij * times faster/more than an equivalent system running with RSA. Just check
214296341Sdelphij * out the "signs" statistics from the RSA and DSA parts of "openssl speed
215296341Sdelphij * -engine atalla dsa1024 rsa1024".
216296341Sdelphij */
217160814Ssimonstatic int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
218296341Sdelphij                             BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
219296341Sdelphij                             BN_CTX *ctx, BN_MONT_CTX *in_mont)
220296341Sdelphij{
221296341Sdelphij    BIGNUM t;
222296341Sdelphij    int to_return = 0;
223160814Ssimon
224296341Sdelphij    BN_init(&t);
225296341Sdelphij    /* let rr = a1 ^ p1 mod m */
226296341Sdelphij    if (!nuron_mod_exp(rr, a1, p1, m, ctx))
227296341Sdelphij        goto end;
228296341Sdelphij    /* let t = a2 ^ p2 mod m */
229296341Sdelphij    if (!nuron_mod_exp(&t, a2, p2, m, ctx))
230296341Sdelphij        goto end;
231296341Sdelphij    /* let rr = rr * t mod m */
232296341Sdelphij    if (!BN_mod_mul(rr, rr, &t, m, ctx))
233296341Sdelphij        goto end;
234296341Sdelphij    to_return = 1;
235296341Sdelphij end:
236296341Sdelphij    BN_free(&t);
237296341Sdelphij    return to_return;
238296341Sdelphij}
239160814Ssimon
240160814Ssimonstatic int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
241296341Sdelphij                             const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
242296341Sdelphij                             BN_MONT_CTX *m_ctx)
243296341Sdelphij{
244296341Sdelphij    return nuron_mod_exp(r, a, p, m, ctx);
245296341Sdelphij}
246296341Sdelphij#  endif
247160814Ssimon
248160814Ssimon/* This function is aliased to mod_exp (with the mont stuff dropped). */
249296341Sdelphij#  ifndef OPENSSL_NO_RSA
250160814Ssimonstatic int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
251296341Sdelphij                              const BIGNUM *m, BN_CTX *ctx,
252296341Sdelphij                              BN_MONT_CTX *m_ctx)
253296341Sdelphij{
254296341Sdelphij    return nuron_mod_exp(r, a, p, m, ctx);
255296341Sdelphij}
256296341Sdelphij#  endif
257160814Ssimon
258296341Sdelphij#  ifndef OPENSSL_NO_DH
259160814Ssimon/* This function is aliased to mod_exp (with the dh and mont dropped). */
260160814Ssimonstatic int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
261296341Sdelphij                            const BIGNUM *a, const BIGNUM *p,
262296341Sdelphij                            const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
263296341Sdelphij{
264296341Sdelphij    return nuron_mod_exp(r, a, p, m, ctx);
265296341Sdelphij}
266296341Sdelphij#  endif
267160814Ssimon
268296341Sdelphij#  ifndef OPENSSL_NO_RSA
269296341Sdelphijstatic RSA_METHOD nuron_rsa = {
270296341Sdelphij    "Nuron RSA method",
271296341Sdelphij    NULL,
272296341Sdelphij    NULL,
273296341Sdelphij    NULL,
274296341Sdelphij    NULL,
275296341Sdelphij    nuron_rsa_mod_exp,
276296341Sdelphij    nuron_mod_exp_mont,
277296341Sdelphij    NULL,
278296341Sdelphij    NULL,
279296341Sdelphij    0,
280296341Sdelphij    NULL,
281296341Sdelphij    NULL,
282296341Sdelphij    NULL,
283296341Sdelphij    NULL
284296341Sdelphij};
285296341Sdelphij#  endif
286160814Ssimon
287296341Sdelphij#  ifndef OPENSSL_NO_DSA
288296341Sdelphijstatic DSA_METHOD nuron_dsa = {
289296341Sdelphij    "Nuron DSA method",
290296341Sdelphij    NULL,                       /* dsa_do_sign */
291296341Sdelphij    NULL,                       /* dsa_sign_setup */
292296341Sdelphij    NULL,                       /* dsa_do_verify */
293296341Sdelphij    nuron_dsa_mod_exp,          /* dsa_mod_exp */
294296341Sdelphij    nuron_mod_exp_dsa,          /* bn_mod_exp */
295296341Sdelphij    NULL,                       /* init */
296296341Sdelphij    NULL,                       /* finish */
297296341Sdelphij    0,                          /* flags */
298296341Sdelphij    NULL,                       /* app_data */
299296341Sdelphij    NULL,                       /* dsa_paramgen */
300296341Sdelphij    NULL                        /* dsa_keygen */
301296341Sdelphij};
302296341Sdelphij#  endif
303160814Ssimon
304296341Sdelphij#  ifndef OPENSSL_NO_DH
305296341Sdelphijstatic DH_METHOD nuron_dh = {
306296341Sdelphij    "Nuron DH method",
307296341Sdelphij    NULL,
308296341Sdelphij    NULL,
309296341Sdelphij    nuron_mod_exp_dh,
310296341Sdelphij    NULL,
311296341Sdelphij    NULL,
312296341Sdelphij    0,
313296341Sdelphij    NULL,
314296341Sdelphij    NULL
315296341Sdelphij};
316296341Sdelphij#  endif
317160814Ssimon
318160814Ssimon/* Constants used when creating the ENGINE */
319160814Ssimonstatic const char *engine_nuron_id = "nuron";
320160814Ssimonstatic const char *engine_nuron_name = "Nuron hardware engine support";
321160814Ssimon
322296341Sdelphij/*
323296341Sdelphij * This internal function is used by ENGINE_nuron() and possibly by the
324296341Sdelphij * "dynamic" ENGINE support too
325296341Sdelphij */
326160814Ssimonstatic int bind_helper(ENGINE *e)
327296341Sdelphij{
328296341Sdelphij#  ifndef OPENSSL_NO_RSA
329296341Sdelphij    const RSA_METHOD *meth1;
330296341Sdelphij#  endif
331296341Sdelphij#  ifndef OPENSSL_NO_DSA
332296341Sdelphij    const DSA_METHOD *meth2;
333296341Sdelphij#  endif
334296341Sdelphij#  ifndef OPENSSL_NO_DH
335296341Sdelphij    const DH_METHOD *meth3;
336296341Sdelphij#  endif
337296341Sdelphij    if (!ENGINE_set_id(e, engine_nuron_id) ||
338296341Sdelphij        !ENGINE_set_name(e, engine_nuron_name) ||
339296341Sdelphij#  ifndef OPENSSL_NO_RSA
340296341Sdelphij        !ENGINE_set_RSA(e, &nuron_rsa) ||
341296341Sdelphij#  endif
342296341Sdelphij#  ifndef OPENSSL_NO_DSA
343296341Sdelphij        !ENGINE_set_DSA(e, &nuron_dsa) ||
344296341Sdelphij#  endif
345296341Sdelphij#  ifndef OPENSSL_NO_DH
346296341Sdelphij        !ENGINE_set_DH(e, &nuron_dh) ||
347296341Sdelphij#  endif
348296341Sdelphij        !ENGINE_set_destroy_function(e, nuron_destroy) ||
349296341Sdelphij        !ENGINE_set_init_function(e, nuron_init) ||
350296341Sdelphij        !ENGINE_set_finish_function(e, nuron_finish) ||
351296341Sdelphij        !ENGINE_set_ctrl_function(e, nuron_ctrl) ||
352296341Sdelphij        !ENGINE_set_cmd_defns(e, nuron_cmd_defns))
353296341Sdelphij        return 0;
354160814Ssimon
355296341Sdelphij#  ifndef OPENSSL_NO_RSA
356296341Sdelphij    /*
357296341Sdelphij     * We know that the "PKCS1_SSLeay()" functions hook properly to the
358296341Sdelphij     * nuron-specific mod_exp and mod_exp_crt so we use those functions. NB:
359296341Sdelphij     * We don't use ENGINE_openssl() or anything "more generic" because
360296341Sdelphij     * something like the RSAref code may not hook properly, and if you own
361296341Sdelphij     * one of these cards then you have the right to do RSA operations on it
362296341Sdelphij     * anyway!
363296341Sdelphij     */
364296341Sdelphij    meth1 = RSA_PKCS1_SSLeay();
365296341Sdelphij    nuron_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
366296341Sdelphij    nuron_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
367296341Sdelphij    nuron_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
368296341Sdelphij    nuron_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
369296341Sdelphij#  endif
370160814Ssimon
371296341Sdelphij#  ifndef OPENSSL_NO_DSA
372296341Sdelphij    /*
373296341Sdelphij     * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits.
374296341Sdelphij     */
375296341Sdelphij    meth2 = DSA_OpenSSL();
376296341Sdelphij    nuron_dsa.dsa_do_sign = meth2->dsa_do_sign;
377296341Sdelphij    nuron_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
378296341Sdelphij    nuron_dsa.dsa_do_verify = meth2->dsa_do_verify;
379296341Sdelphij#  endif
380160814Ssimon
381296341Sdelphij#  ifndef OPENSSL_NO_DH
382296341Sdelphij    /* Much the same for Diffie-Hellman */
383296341Sdelphij    meth3 = DH_OpenSSL();
384296341Sdelphij    nuron_dh.generate_key = meth3->generate_key;
385296341Sdelphij    nuron_dh.compute_key = meth3->compute_key;
386296341Sdelphij#  endif
387160814Ssimon
388296341Sdelphij    /* Ensure the nuron error handling is set up */
389296341Sdelphij    ERR_load_NURON_strings();
390296341Sdelphij    return 1;
391296341Sdelphij}
392160814Ssimon
393296341Sdelphij#  ifdef OPENSSL_NO_DYNAMIC_ENGINE
394160814Ssimonstatic ENGINE *engine_nuron(void)
395296341Sdelphij{
396296341Sdelphij    ENGINE *ret = ENGINE_new();
397296341Sdelphij    if (!ret)
398296341Sdelphij        return NULL;
399296341Sdelphij    if (!bind_helper(ret)) {
400296341Sdelphij        ENGINE_free(ret);
401296341Sdelphij        return NULL;
402296341Sdelphij    }
403296341Sdelphij    return ret;
404296341Sdelphij}
405160814Ssimon
406160814Ssimonvoid ENGINE_load_nuron(void)
407296341Sdelphij{
408296341Sdelphij    /* Copied from eng_[openssl|dyn].c */
409296341Sdelphij    ENGINE *toadd = engine_nuron();
410296341Sdelphij    if (!toadd)
411296341Sdelphij        return;
412296341Sdelphij    ENGINE_add(toadd);
413296341Sdelphij    ENGINE_free(toadd);
414296341Sdelphij    ERR_clear_error();
415296341Sdelphij}
416296341Sdelphij#  endif
417160814Ssimon
418296341Sdelphij/*
419296341Sdelphij * This stuff is needed if this ENGINE is being compiled into a
420296341Sdelphij * self-contained shared-library.
421296341Sdelphij */
422296341Sdelphij#  ifndef OPENSSL_NO_DYNAMIC_ENGINE
423160814Ssimonstatic int bind_fn(ENGINE *e, const char *id)
424296341Sdelphij{
425296341Sdelphij    if (id && (strcmp(id, engine_nuron_id) != 0))
426296341Sdelphij        return 0;
427296341Sdelphij    if (!bind_helper(e))
428296341Sdelphij        return 0;
429296341Sdelphij    return 1;
430296341Sdelphij}
431296341Sdelphij
432160814SsimonIMPLEMENT_DYNAMIC_CHECK_FN()
433296341Sdelphij    IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
434296341Sdelphij#  endif                        /* OPENSSL_NO_DYNAMIC_ENGINE */
435296341Sdelphij# endif                         /* !OPENSSL_NO_HW_NURON */
436296341Sdelphij#endif                          /* !OPENSSL_NO_HW */
437