Some more tweaks to ENGINE code.
[openssl.git] / crypto / engine / hw_ncipher.c
index f6b06e468fa4852f12214b5256b6778d481dc8d0..dc645d554b3d0cd8f5a6fb3725533c6fdfb3936f 100644 (file)
 #include <openssl/pem.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
-#include "engine_int.h"
 #include <openssl/engine.h>
 
-#ifndef NO_HW
-#ifndef NO_HW_NCIPHER
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_NCIPHER
 
 /* Attribution notice: nCipher have said several times that it's OK for
  * us to implement a general interface to their boxes, and recently declared
@@ -82,9 +81,9 @@
 #include "vendor_defns/hwcryptohook.h"
 #endif
 
-static int hwcrhk_init(void);
-static int hwcrhk_finish(void);
-static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); 
+static int hwcrhk_init(ENGINE *e);
+static int hwcrhk_finish(ENGINE *e);
+static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 
 
 /* Functions to handle mutexes */
 static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
@@ -93,28 +92,29 @@ static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
 static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
 
 /* BIGNUM stuff */
-static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *m, BN_CTX *ctx);
 
 /* RSA stuff */
-static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa);
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa);
 /* This function is aliased to mod_exp (with the mont stuff dropped). */
-static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
 
 /* DH stuff */
 /* This function is alised to mod_exp (with the DH and mont dropped). */
-static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
-               const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
+       const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
 
 /* RAND stuff */
 static int hwcrhk_rand_bytes(unsigned char *buf, int num);
 static int hwcrhk_rand_status(void);
 
 /* KM stuff */
-static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
+static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
        const char *passphrase);
-static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id,
+static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
        const char *passphrase);
 static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
        int ind,long argl, void *argp);
@@ -126,6 +126,26 @@ static int hwcrhk_get_pass(const char *prompt_info,
        HWCryptoHook_CallerContext *cactx);
 static void hwcrhk_log_message(void *logstr, const char *message);
 
+/* The definitions for control commands specific to this engine */
+#define HWCRHK_CMD_SO_PATH             ENGINE_CMD_BASE
+#define HWCRHK_CMD_FORK_CHECK          (ENGINE_CMD_BASE + 1)
+#define HWCRHK_CMD_THREAD_LOCKING      (ENGINE_CMD_BASE + 2)
+static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
+       {HWCRHK_CMD_SO_PATH,
+               "SO_PATH",
+               "Specifies the path to the 'hwcrhk' shared library",
+               ENGINE_CMD_FLAG_STRING},
+       {HWCRHK_CMD_FORK_CHECK,
+               "FORK_CHECK",
+               "Turns fork() checking on or off (boolean)",
+               ENGINE_CMD_FLAG_NUMERIC},
+       {HWCRHK_CMD_THREAD_LOCKING,
+               "THREAD_LOCKING",
+               "Turns thread-safe locking on or off (boolean)",
+               ENGINE_CMD_FLAG_NUMERIC},
+       {0, NULL, NULL, 0}
+       };
+
 /* Our internal RSA_METHOD that we provide pointers to */
 static RSA_METHOD hwcrhk_rsa =
        {
@@ -168,26 +188,9 @@ static RAND_METHOD hwcrhk_rand =
        hwcrhk_rand_status,
        };
 
-/* Our ENGINE structure. */
-static ENGINE engine_hwcrhk =
-        {
-       "chil",
-       "nCipher hardware engine support",
-       &hwcrhk_rsa,
-       NULL,
-       &hwcrhk_dh,
-       &hwcrhk_rand,
-       hwcrhk_mod_exp,
-       NULL,
-       hwcrhk_init,
-       hwcrhk_finish,
-       hwcrhk_ctrl,
-       hwcrhk_load_privkey,
-       hwcrhk_load_pubkey,
-       0, /* no flags */
-       0, 0, /* no references */
-       NULL, NULL /* unlinked */
-        };
+/* Constants used when creating the ENGINE */
+static const char *engine_hwcrhk_id = "chil";
+static const char *engine_hwcrhk_name = "nCipher hardware engine support";
 
 /* Internal stuff for HWCryptoHook */
 
@@ -291,8 +294,27 @@ static HWCryptoHook_InitInfo hwcrhk_globals = {
  * (indeed - the lock will already be held by our caller!!!) */
 ENGINE *ENGINE_ncipher()
        {
-       RSA_METHOD *meth1;
-       DH_METHOD *meth2;
+       const RSA_METHOD *meth1;
+       const DH_METHOD *meth2;
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_hwcrhk_id) ||
+                       !ENGINE_set_name(ret, engine_hwcrhk_name) ||
+                       !ENGINE_set_RSA(ret, &hwcrhk_rsa) ||
+                       !ENGINE_set_DH(ret, &hwcrhk_dh) ||
+                       !ENGINE_set_RAND(ret, &hwcrhk_rand) ||
+                       !ENGINE_set_BN_mod_exp(ret, hwcrhk_mod_exp) ||
+                       !ENGINE_set_init_function(ret, hwcrhk_init) ||
+                       !ENGINE_set_finish_function(ret, hwcrhk_finish) ||
+                       !ENGINE_set_ctrl_function(ret, hwcrhk_ctrl) ||
+                       !ENGINE_set_load_privkey_function(ret, hwcrhk_load_privkey) ||
+                       !ENGINE_set_load_pubkey_function(ret, hwcrhk_load_pubkey) ||
+                       !ENGINE_set_cmd_defns(ret, hwcrhk_cmd_defns))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
 
        /* We know that the "PKCS1_SSLeay()" functions hook properly
         * to the cswift-specific mod_exp and mod_exp_crt so we use
@@ -311,7 +333,7 @@ ENGINE *ENGINE_ncipher()
        meth2 = DH_OpenSSL();
        hwcrhk_dh.generate_key = meth2->generate_key;
        hwcrhk_dh.compute_key = meth2->compute_key;
-       return &engine_hwcrhk;
+       return ret;
        }
 
 /* This is a process-global DSO handle used for loading and unloading
@@ -336,7 +358,8 @@ static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
 static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
 
 /* Used in the DSO operations. */
-static const char *HWCRHK_LIBNAME = "nfhwcrhk";
+static const char def_HWCRHK_LIBNAME[] = "nfhwcrhk";
+static const char *HWCRHK_LIBNAME = def_HWCRHK_LIBNAME;
 static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
 static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
 static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
@@ -375,7 +398,7 @@ static void release_context(HWCryptoHook_ContextHandle hac)
        }
 
 /* (de)initialisation functions. */
-static int hwcrhk_init()
+static int hwcrhk_init(ENGINE *e)
        {
        HWCryptoHook_Init_t *p1;
        HWCryptoHook_Finish_t *p2;
@@ -474,7 +497,7 @@ err:
        return 0;
        }
 
-static int hwcrhk_finish()
+static int hwcrhk_finish(ENGINE *e)
        {
        int to_return = 1;
        if(hwcrhk_dso == NULL)
@@ -506,12 +529,25 @@ static int hwcrhk_finish()
        return to_return;
        }
 
-static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
+static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
        {
        int to_return = 1;
 
        switch(cmd)
                {
+       case HWCRHK_CMD_SO_PATH:
+               if(hwcrhk_dso)
+                       {
+                       ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_ALREADY_LOADED);
+                       return 0;
+                       }
+               if(p == NULL)
+                       {
+                       ENGINEerr(ENGINE_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+                       return 0;
+                       }
+               HWCRHK_LIBNAME = (const char *)p;
+               return 1;
        case ENGINE_CTRL_SET_LOGSTREAM:
                {
                BIO *bio = (BIO *)p;
@@ -537,6 +573,7 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
        /* this enables or disables the "SimpleForkCheck" flag used in the
         * initialisation structure. */
        case ENGINE_CTRL_CHIL_SET_FORKCHECK:
+       case HWCRHK_CMD_FORK_CHECK:
                CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
                if(i)
                        hwcrhk_globals.flags |=
@@ -556,6 +593,11 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
                disable_mutex_callbacks = 1;
                CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
                break;
+       case HWCRHK_CMD_THREAD_LOCKING:
+               CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+               disable_mutex_callbacks = ((i == 0) ? 0 : 1);
+               CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+               break;
 
        /* The command isn't understood by this engine */
        default:
@@ -568,7 +610,7 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
        return to_return;
        }
 
-static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
+static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
        const char *passphrase)
        {
        RSA *rtmp = NULL;
@@ -604,7 +646,7 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
                        ENGINE_R_NO_KEY);
                goto err;
                }
-       rtmp = RSA_new_method(&engine_hwcrhk);
+       rtmp = RSA_new_method(eng);
        RSA_set_ex_data(rtmp, hndidx, (char *)hptr);
        rtmp->e = BN_new();
        rtmp->n = BN_new();
@@ -648,9 +690,10 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
        return NULL;
        }
 
-static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
+static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
+       const char *passphrase)
        {
-       EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase);
+       EVP_PKEY *res = hwcrhk_load_privkey(eng, key_id, passphrase);
 
        if (res)
                switch(res->type)
@@ -681,7 +724,7 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
        }
 
 /* A little mod_exp */
-static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                        const BIGNUM *m, BN_CTX *ctx)
        {
        char tempbuf[1024];
@@ -737,7 +780,7 @@ err:
        return to_return;
        }
  
-static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa)
        {
        char tempbuf[1024];
        HWCryptoHook_ErrMsgBuf rmsg;
@@ -853,14 +896,15 @@ err:
        }
 
 /* This function is aliased to mod_exp (with the mont stuff dropped). */
-static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        {
        return hwcrhk_mod_exp(r, a, p, m, ctx);
        }
 
 /* This function is aliased to mod_exp (with the dh and mont dropped). */
-static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
+               const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        {
        return hwcrhk_mod_exp(r, a, p, m, ctx);
@@ -1014,5 +1058,5 @@ static void hwcrhk_log_message(void *logstr, const char *message)
        CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
        }
 
-#endif /* !NO_HW_NCIPHER */
-#endif /* !NO_HW */
+#endif /* !OPENSSL_NO_HW_NCIPHER */
+#endif /* !OPENSSL_NO_HW */