1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include "includes.h"
  27 #include "log.h"
  28 #include "engine.h"
  29 
  30 #define PKCS11_ENGINE   "pkcs11"
  31 
  32 /*
  33  * Loads the PKCS#11 engine if the UseOpenSSLEngine is set to yes which is the
  34  * default value.
  35  */
  36 ENGINE *
  37 pkcs11_engine_load(int use_engine)
  38 {
  39         ENGINE *e = NULL;
  40 
  41         debug("use_engine is '%s'", use_engine == 1 ? "yes" : "no");
  42         if (use_engine == 0)
  43                 return (NULL);
  44 
  45         ENGINE_load_pk11();
  46         /* get structural reference */
  47         if ((e = ENGINE_by_id(PKCS11_ENGINE)) == NULL) {
  48                 error("%s engine does not exist", PKCS11_ENGINE);
  49                 return (NULL);
  50         }
  51 
  52         /* get functional reference */
  53         if (ENGINE_init(e) == 0) {
  54                 error("can't initialize %s engine", PKCS11_ENGINE);
  55                 return (NULL);
  56         }
  57 
  58         debug("%s engine initialized, now setting it as default for "
  59             "RSA, DSA, and symmetric ciphers", PKCS11_ENGINE);
  60 
  61         /*
  62          * Offloading RSA, DSA and symmetric ciphers to the engine is all we
  63          * want. We don't offload Diffie-Helmann since we use longer DH keys
  64          * than supported in ncp/n2cp (2048 bits). And, we don't offload digest
  65          * operations since that would be beneficial if only big packets were
  66          * processed (~8K). However, that's not the case. For example,
  67          * SSH_MSG_CHANNEL_WINDOW_ADJUST messages are always small. Given the
  68          * fact that digest operations are fast in software and the inherent
  69          * overhead of offloading anything to HW is quite big, not offloading
  70          * digests to HW actually makes SSH data transfer faster.
  71          */
  72         if (!ENGINE_set_default_RSA(e)) {
  73                 error("can't use %s engine for RSA", PKCS11_ENGINE);
  74                 return (NULL);
  75         }
  76         if (!ENGINE_set_default_DSA(e)) {
  77                 error("can't use %s engine for DSA", PKCS11_ENGINE);
  78                 return (NULL);
  79         }
  80         if (!ENGINE_set_default_ciphers(e)) {
  81                 error("can't use %s engine for symmetric ciphers",
  82                     PKCS11_ENGINE);
  83                 return (NULL);
  84         }
  85 
  86         debug("%s engine initialization complete", PKCS11_ENGINE);
  87         return (e);
  88 }
  89 
  90 /*
  91  * Finishes the PKCS#11 engine after all remaining structural and functional
  92  * references to the ENGINE structure are freed.
  93  */
  94 void
  95 pkcs11_engine_finish(void *engine)
  96 {
  97         ENGINE *e = (ENGINE *)engine;
  98 
  99         debug("in pkcs11_engine_finish(), engine pointer is %p", e);
 100         /* UseOpenSSLEngine was 'no' */
 101         if (engine == NULL)
 102                 return;
 103 
 104         debug("unregistering RSA");
 105         ENGINE_unregister_RSA(e);
 106         debug("unregistering DSA");
 107         ENGINE_unregister_DSA(e);
 108         debug("unregistering ciphers");
 109         ENGINE_unregister_ciphers(e);
 110 
 111         debug("calling ENGINE_finish()");
 112         ENGINE_finish(engine);
 113         debug("calling ENGINE_remove()");
 114         ENGINE_remove(engine);
 115         debug("calling ENGINE_free()");
 116         ENGINE_free(engine);
 117         debug("%s engine finished", PKCS11_ENGINE);
 118 }