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