(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/engines/e_ubsec.c

    1: /* crypto/engine/hw_ubsec.c */
    2: /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
    3:  * project 2000.
    4:  *
    5:  * Cloned shamelessly by Joe Tardo. 
    6:  */
    7: /* ====================================================================
    8:  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  *
   14:  * 1. Redistributions of source code must retain the above copyright
   15:  *    notice, this list of conditions and the following disclaimer. 
   16:  *
   17:  * 2. Redistributions in binary form must reproduce the above copyright
   18:  *    notice, this list of conditions and the following disclaimer in
   19:  *    the documentation and/or other materials provided with the
   20:  *    distribution.
   21:  *
   22:  * 3. All advertising materials mentioning features or use of this
   23:  *    software must display the following acknowledgment:
   24:  *    "This product includes software developed by the OpenSSL Project
   25:  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
   26:  *
   27:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   28:  *    endorse or promote products derived from this software without
   29:  *    prior written permission. For written permission, please contact
   30:  *    licensing@OpenSSL.org.
   31:  *
   32:  * 5. Products derived from this software may not be called "OpenSSL"
   33:  *    nor may "OpenSSL" appear in their names without prior written
   34:  *    permission of the OpenSSL Project.
   35:  *
   36:  * 6. Redistributions of any form whatsoever must retain the following
   37:  *    acknowledgment:
   38:  *    "This product includes software developed by the OpenSSL Project
   39:  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
   40:  *
   41:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   42:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   43:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   44:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   45:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   46:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   47:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   48:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   49:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   50:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   51:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   52:  * OF THE POSSIBILITY OF SUCH DAMAGE.
   53:  * ====================================================================
   54:  *
   55:  * This product includes cryptographic software written by Eric Young
   56:  * (eay@cryptsoft.com).  This product includes software written by Tim
   57:  * Hudson (tjh@cryptsoft.com).
   58:  *
   59:  */
   60: 
   61: #include <stdio.h>
   62: #include <string.h>
   63: #include <openssl/crypto.h>
   64: #include <openssl/buffer.h>
   65: #include <openssl/dso.h>
   66: #include <openssl/engine.h>
   67: #ifndef OPENSSL_NO_RSA
   68: #include <openssl/rsa.h>
   69: #endif
   70: #ifndef OPENSSL_NO_DSA
   71: #include <openssl/dsa.h>
   72: #endif
   73: #ifndef OPENSSL_NO_DH
   74: #include <openssl/dh.h>
   75: #endif
   76: #include <openssl/bn.h>
   77: 
   78: #ifndef OPENSSL_NO_HW
   79: #ifndef OPENSSL_NO_HW_UBSEC
   80: 
   81: #ifdef FLAT_INC
   82: #include "hw_ubsec.h"
   83: #else
   84: #include "vendor_defns/hw_ubsec.h"
   85: #endif
   86: 
   87: #define UBSEC_LIB_NAME "ubsec engine"
   88: #include "e_ubsec_err.c"
   89: 
   90: #define FAIL_TO_SOFTWARE -15
   91: 
   92: static int ubsec_destroy(ENGINE *e);
   93: static int ubsec_init(ENGINE *e);
   94: static int ubsec_finish(ENGINE *e);
   95: static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
   96: static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
   97:                 const BIGNUM *m, BN_CTX *ctx);
   98: static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
   99:                         const BIGNUM *q, const BIGNUM *dp,
  100:                         const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
  101: #ifndef OPENSSL_NO_RSA
  102: static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
  103: #endif
  104: static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  105:                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  106: #ifndef OPENSSL_NO_DSA
  107: #ifdef NOT_USED
  108: static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
  109:                 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
  110:                 BN_CTX *ctx, BN_MONT_CTX *in_mont);
  111: static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
  112:                 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  113:                 BN_MONT_CTX *m_ctx);
  114: #endif
  115: static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
  116: static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
  117:                                 DSA_SIG *sig, DSA *dsa);
  118: #endif
  119: #ifndef OPENSSL_NO_DH
  120: static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
  121:                 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
  122:                 BN_MONT_CTX *m_ctx);
  123: static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
  124: static int ubsec_dh_generate_key(DH *dh);
  125: #endif
  126: 
  127: #ifdef NOT_USED
  128: static int ubsec_rand_bytes(unsigned char *buf, int num);
  129: static int ubsec_rand_status(void);
  130: #endif
  131: 
  132: #define UBSEC_CMD_SO_PATH               ENGINE_CMD_BASE
  133: static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
  134:         {UBSEC_CMD_SO_PATH,
  135:                 "SO_PATH",
  136:                 "Specifies the path to the 'ubsec' shared library",
  137:                 ENGINE_CMD_FLAG_STRING},
  138:         {0, NULL, NULL, 0}
  139:         };
  140: 
  141: #ifndef OPENSSL_NO_RSA
  142: /* Our internal RSA_METHOD that we provide pointers to */
  143: static RSA_METHOD ubsec_rsa =
  144:         {
  145:         "UBSEC RSA method",
  146:         NULL,
  147:         NULL,
  148:         NULL,
  149:         NULL,
  150:         ubsec_rsa_mod_exp,
  151:         ubsec_mod_exp_mont,
  152:         NULL,
  153:         NULL,
  154:         0,
  155:         NULL,
  156:         NULL,
  157:         NULL,
  158:         NULL
  159:         };
  160: #endif
  161: 
  162: #ifndef OPENSSL_NO_DSA
  163: /* Our internal DSA_METHOD that we provide pointers to */
  164: static DSA_METHOD ubsec_dsa =
  165:         {
  166:         "UBSEC DSA method",
  167:         ubsec_dsa_do_sign, /* dsa_do_sign */
  168:         NULL, /* dsa_sign_setup */
  169:         ubsec_dsa_verify, /* dsa_do_verify */
  170:         NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
  171:         NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
  172:         NULL, /* init */
  173:         NULL, /* finish */
  174:         0, /* flags */
  175:         NULL, /* app_data */
  176:         NULL, /* dsa_paramgen */
  177:         NULL /* dsa_keygen */
  178:         };
  179: #endif
  180: 
  181: #ifndef OPENSSL_NO_DH
  182: /* Our internal DH_METHOD that we provide pointers to */
  183: static DH_METHOD ubsec_dh =
  184:         {
  185:         "UBSEC DH method",
  186:         ubsec_dh_generate_key,
  187:         ubsec_dh_compute_key,
  188:         ubsec_mod_exp_dh,
  189:         NULL,
  190:         NULL,
  191:         0,
  192:         NULL,
  193:         NULL
  194:         };
  195: #endif
  196: 
  197: /* Constants used when creating the ENGINE */
  198: static const char *engine_ubsec_id = "ubsec";
  199: static const char *engine_ubsec_name = "UBSEC hardware engine support";
  200: 
  201: /* This internal function is used by ENGINE_ubsec() and possibly by the
  202:  * "dynamic" ENGINE support too */
  203: static int bind_helper(ENGINE *e)
  204:         {
  205: #ifndef OPENSSL_NO_RSA
  206:         const RSA_METHOD *meth1;
  207: #endif
  208: #ifndef OPENSSL_NO_DH
  209: #ifndef HAVE_UBSEC_DH
  210:         const DH_METHOD *meth3;
  211: #endif /* HAVE_UBSEC_DH */
  212: #endif
  213:         if(!ENGINE_set_id(e, engine_ubsec_id) ||
  214:                         !ENGINE_set_name(e, engine_ubsec_name) ||
  215: #ifndef OPENSSL_NO_RSA
  216:                         !ENGINE_set_RSA(e, &ubsec_rsa) ||
  217: #endif
  218: #ifndef OPENSSL_NO_DSA
  219:                         !ENGINE_set_DSA(e, &ubsec_dsa) ||
  220: #endif
  221: #ifndef OPENSSL_NO_DH
  222:                         !ENGINE_set_DH(e, &ubsec_dh) ||
  223: #endif
  224:                         !ENGINE_set_destroy_function(e, ubsec_destroy) ||
  225:                         !ENGINE_set_init_function(e, ubsec_init) ||
  226:                         !ENGINE_set_finish_function(e, ubsec_finish) ||
  227:                         !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
  228:                         !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
  229:                 return 0;
  230: 
  231: #ifndef OPENSSL_NO_RSA
  232:         /* We know that the "PKCS1_SSLeay()" functions hook properly
  233:          * to the Broadcom-specific mod_exp and mod_exp_crt so we use
  234:          * those functions. NB: We don't use ENGINE_openssl() or
  235:          * anything "more generic" because something like the RSAref
  236:          * code may not hook properly, and if you own one of these
  237:          * cards then you have the right to do RSA operations on it
  238:          * anyway! */ 
  239:         meth1 = RSA_PKCS1_SSLeay();
  240:         ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
  241:         ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
  242:         ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
  243:         ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
  244: #endif
  245: 
  246: #ifndef OPENSSL_NO_DH
  247: #ifndef HAVE_UBSEC_DH
  248:         /* Much the same for Diffie-Hellman */
  249:         meth3 = DH_OpenSSL();
  250:         ubsec_dh.generate_key = meth3->generate_key;
  251:         ubsec_dh.compute_key = meth3->compute_key;
  252: #endif /* HAVE_UBSEC_DH */
  253: #endif
  254: 
  255:         /* Ensure the ubsec error handling is set up */
  256:         ERR_load_UBSEC_strings();
  257:         return 1;
  258:         }
  259: 
  260: #ifdef OPENSSL_NO_DYNAMIC_ENGINE
  261: static ENGINE *engine_ubsec(void)
  262:         {
  263:         ENGINE *ret = ENGINE_new();
  264:         if(!ret)
  265:                 return NULL;
  266:         if(!bind_helper(ret))
  267:                 {
  268:                 ENGINE_free(ret);
  269:                 return NULL;
  270:                 }
  271:         return ret;
  272:         }
  273: 
  274: void ENGINE_load_ubsec(void)
  275:         {
  276:         /* Copied from eng_[openssl|dyn].c */
  277:         ENGINE *toadd = engine_ubsec();
  278:         if(!toadd) return;
  279:         ENGINE_add(toadd);
  280:         ENGINE_free(toadd);
  281:         ERR_clear_error();
  282:         }
  283: #endif
  284: 
  285: /* This is a process-global DSO handle used for loading and unloading
  286:  * the UBSEC library. NB: This is only set (or unset) during an
  287:  * init() or finish() call (reference counts permitting) and they're
  288:  * operating with global locks, so this should be thread-safe
  289:  * implicitly. */
  290: 
  291: static DSO *ubsec_dso = NULL;
  292: 
  293: /* These are the function pointers that are (un)set when the library has
  294:  * successfully (un)loaded. */
  295: 
  296: static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
  297: static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
  298: static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
  299: static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
  300: #ifndef OPENSSL_NO_DH
  301: static t_UBSEC_diffie_hellman_generate_ioctl 
  302:         *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
  303: static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
  304: #endif
  305: /* #ifndef OPENSSL_NO_RSA */
  306: static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
  307: static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
  308: /* #endif */
  309: #ifndef OPENSSL_NO_DSA
  310: static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
  311: static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
  312: #endif
  313: static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
  314: static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
  315: static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
  316: 
  317: static int max_key_len = 1024;  /* ??? */
  318: 
  319: /* 
  320:  * These are the static string constants for the DSO file name and the function
  321:  * symbol names to bind to. 
  322:  */
  323: 
  324: static const char *UBSEC_LIBNAME = NULL;
  325: static const char *get_UBSEC_LIBNAME(void)
  326:         {
  327:         if(UBSEC_LIBNAME)
  328:                 return UBSEC_LIBNAME;
  329:         return "ubsec";
  330:         }
  331: static void free_UBSEC_LIBNAME(void)
  332:         {
  333:         if(UBSEC_LIBNAME)
  334:                 OPENSSL_free((void*)UBSEC_LIBNAME);
  335:         UBSEC_LIBNAME = NULL;
  336:         }
  337: static long set_UBSEC_LIBNAME(const char *name)
  338:         {
  339:         free_UBSEC_LIBNAME();
  340:         return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  341:         }
  342: static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
  343: static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
  344: static const char *UBSEC_F3 = "ubsec_open";
  345: static const char *UBSEC_F4 = "ubsec_close";
  346: #ifndef OPENSSL_NO_DH
  347: static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
  348: static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
  349: #endif
  350: /* #ifndef OPENSSL_NO_RSA */
  351: static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
  352: static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
  353: /* #endif */
  354: #ifndef OPENSSL_NO_DSA
  355: static const char *UBSEC_F9 = "dsa_sign_ioctl";
  356: static const char *UBSEC_F10 = "dsa_verify_ioctl";
  357: #endif
  358: static const char *UBSEC_F11 = "math_accelerate_ioctl";
  359: static const char *UBSEC_F12 = "rng_ioctl";
  360: static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
  361: 
  362: /* Destructor (complements the "ENGINE_ubsec()" constructor) */
  363: static int ubsec_destroy(ENGINE *e)
  364:         {
  365:         free_UBSEC_LIBNAME();
  366:         ERR_unload_UBSEC_strings();
  367:         return 1;
  368:         }
  369: 
  370: /* (de)initialisation functions. */
  371: static int ubsec_init(ENGINE *e)
  372:         {
  373:         t_UBSEC_ubsec_bytes_to_bits *p1;
  374:         t_UBSEC_ubsec_bits_to_bytes *p2;
  375:         t_UBSEC_ubsec_open *p3;
  376:         t_UBSEC_ubsec_close *p4;
  377: #ifndef OPENSSL_NO_DH
  378:         t_UBSEC_diffie_hellman_generate_ioctl *p5;
  379:         t_UBSEC_diffie_hellman_agree_ioctl *p6;
  380: #endif
  381: /* #ifndef OPENSSL_NO_RSA */
  382:         t_UBSEC_rsa_mod_exp_ioctl *p7;
  383:         t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
  384: /* #endif */
  385: #ifndef OPENSSL_NO_DSA
  386:         t_UBSEC_dsa_sign_ioctl *p9;
  387:         t_UBSEC_dsa_verify_ioctl *p10;
  388: #endif
  389:         t_UBSEC_math_accelerate_ioctl *p11;
  390:         t_UBSEC_rng_ioctl *p12;
  391:         t_UBSEC_max_key_len_ioctl *p13;
  392:         int fd = 0;
  393: 
  394:         if(ubsec_dso != NULL)
  395:                 {
  396:                 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
  397:                 goto err;
  398:                 }
  399:         /* 
  400:          * Attempt to load libubsec.so/ubsec.dll/whatever. 
  401:          */
  402:         ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
  403:         if(ubsec_dso == NULL)
  404:                 {
  405:                 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
  406:                 goto err;
  407:                 }
  408: 
  409:         if (
  410:         !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
  411:         !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
  412:         !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
  413:         !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
  414: #ifndef OPENSSL_NO_DH
  415:         !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) 
  416:                                 DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
  417:         !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) 
  418:                                 DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
  419: #endif
  420: /* #ifndef OPENSSL_NO_RSA */
  421:         !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
  422:         !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
  423: /* #endif */
  424: #ifndef OPENSSL_NO_DSA
  425:         !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
  426:         !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
  427: #endif
  428:         !(p11 = (t_UBSEC_math_accelerate_ioctl *) 
  429:                                 DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
  430:         !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
  431:         !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
  432:                 {
  433:                 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
  434:                 goto err;
  435:                 }
  436: 
  437:         /* Copy the pointers */
  438:         p_UBSEC_ubsec_bytes_to_bits = p1;
  439:         p_UBSEC_ubsec_bits_to_bytes = p2;
  440:         p_UBSEC_ubsec_open = p3;
  441:         p_UBSEC_ubsec_close = p4;
  442: #ifndef OPENSSL_NO_DH
  443:         p_UBSEC_diffie_hellman_generate_ioctl = p5;
  444:         p_UBSEC_diffie_hellman_agree_ioctl = p6;
  445: #endif
  446: #ifndef OPENSSL_NO_RSA
  447:         p_UBSEC_rsa_mod_exp_ioctl = p7;
  448:         p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
  449: #endif
  450: #ifndef OPENSSL_NO_DSA
  451:         p_UBSEC_dsa_sign_ioctl = p9;
  452:         p_UBSEC_dsa_verify_ioctl = p10;
  453: #endif
  454:         p_UBSEC_math_accelerate_ioctl = p11;
  455:         p_UBSEC_rng_ioctl = p12;
  456:         p_UBSEC_max_key_len_ioctl = p13;
  457: 
  458:         /* Perform an open to see if there's actually any unit running. */
  459:         if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
  460:         {
  461:            p_UBSEC_ubsec_close(fd);
  462:            return 1;
  463:         }
  464:         else
  465:         {
  466:           UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
  467:         }
  468: 
  469: err:
  470:         if(ubsec_dso)
  471:                 DSO_free(ubsec_dso);
  472:         ubsec_dso = NULL;
  473:         p_UBSEC_ubsec_bytes_to_bits = NULL;
  474:         p_UBSEC_ubsec_bits_to_bytes = NULL;
  475:         p_UBSEC_ubsec_open = NULL;
  476:         p_UBSEC_ubsec_close = NULL;
  477: #ifndef OPENSSL_NO_DH
  478:         p_UBSEC_diffie_hellman_generate_ioctl = NULL;
  479:         p_UBSEC_diffie_hellman_agree_ioctl = NULL;
  480: #endif
  481: #ifndef OPENSSL_NO_RSA
  482:         p_UBSEC_rsa_mod_exp_ioctl = NULL;
  483:         p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
  484: #endif
  485: #ifndef OPENSSL_NO_DSA
  486:         p_UBSEC_dsa_sign_ioctl = NULL;
  487:         p_UBSEC_dsa_verify_ioctl = NULL;
  488: #endif
  489:         p_UBSEC_math_accelerate_ioctl = NULL;
  490:         p_UBSEC_rng_ioctl = NULL;
  491:         p_UBSEC_max_key_len_ioctl = NULL;
  492: 
  493:         return 0;
  494:         }
  495: 
  496: static int ubsec_finish(ENGINE *e)
  497:         {
  498:         free_UBSEC_LIBNAME();
  499:         if(ubsec_dso == NULL)
  500:                 {
  501:                 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
  502:                 return 0;
  503:                 }
  504:         if(!DSO_free(ubsec_dso))
  505:                 {
  506:                 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
  507:                 return 0;
  508:                 }
  509:         ubsec_dso = NULL;
  510:         p_UBSEC_ubsec_bytes_to_bits = NULL;
  511:         p_UBSEC_ubsec_bits_to_bytes = NULL;
  512:         p_UBSEC_ubsec_open = NULL;
  513:         p_UBSEC_ubsec_close = NULL;
  514: #ifndef OPENSSL_NO_DH
  515:         p_UBSEC_diffie_hellman_generate_ioctl = NULL;
  516:         p_UBSEC_diffie_hellman_agree_ioctl = NULL;
  517: #endif
  518: #ifndef OPENSSL_NO_RSA
  519:         p_UBSEC_rsa_mod_exp_ioctl = NULL;
  520:         p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
  521: #endif
  522: #ifndef OPENSSL_NO_DSA
  523:         p_UBSEC_dsa_sign_ioctl = NULL;
  524:         p_UBSEC_dsa_verify_ioctl = NULL;
  525: #endif
  526:         p_UBSEC_math_accelerate_ioctl = NULL;
  527:         p_UBSEC_rng_ioctl = NULL;
  528:         p_UBSEC_max_key_len_ioctl = NULL;
  529:         return 1;
  530:         }
  531: 
  532: static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
  533:         {
  534:         int initialised = ((ubs