xref: /illumos-gate/usr/src/uts/common/crypto/core/kcf.c (revision 06e1a714)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Core KCF (Kernel Cryptographic Framework). This file implements
31  * the loadable module entry points and module verification routines.
32  */
33 
34 #include <sys/systm.h>
35 #include <sys/cmn_err.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/modctl.h>
39 #include <sys/errno.h>
40 #include <sys/rwlock.h>
41 #include <sys/kmem.h>
42 #include <sys/door.h>
43 #include <sys/kobj.h>
44 
45 #include <sys/crypto/common.h>
46 #include <sys/crypto/api.h>
47 #include <sys/crypto/spi.h>
48 #include <sys/crypto/impl.h>
49 #include <sys/crypto/sched_impl.h>
50 #include <sys/crypto/elfsign.h>
51 
52 #ifdef DEBUG
53 int kcf_frmwrk_debug = 0;
54 
55 #define	KCF_FRMWRK_DEBUG(l, x)	if (kcf_frmwrk_debug >= l) printf x
56 #else	/* DEBUG */
57 #define	KCF_FRMWRK_DEBUG(l, x)
58 #endif	/* DEBUG */
59 
60 /*
61  * Door to make upcalls to kcfd. kcfd will send us this
62  * handle when it is coming up.
63  */
64 kmutex_t kcf_dh_lock;
65 door_handle_t kcf_dh = NULL;
66 
67 
68 static struct modlmisc modlmisc = {
69 	&mod_miscops, "Kernel Crypto Framework %I%"
70 };
71 
72 static struct modlinkage modlinkage = {
73 	MODREV_1, (void *)&modlmisc, NULL
74 };
75 
76 static int rngtimer_started;
77 
78 
79 int
80 _init()
81 {
82 	/* initialize the mechanisms tables supported out-of-the-box */
83 	kcf_init_mech_tabs();
84 
85 	/* initialize the providers tables */
86 	kcf_prov_tab_init();
87 
88 	/* initialize the policy table */
89 	kcf_policy_tab_init();
90 
91 	/* initialize soft_config_list */
92 	kcf_soft_config_init();
93 
94 	/*
95 	 * Initialize scheduling structures. Note that this does NOT
96 	 * start any threads since it might not be safe to do so.
97 	 */
98 	kcf_sched_init();
99 
100 	/* initialize the RNG support structures */
101 	rngtimer_started = 0;
102 	kcf_rnd_init();
103 
104 	return (mod_install(&modlinkage));
105 }
106 
107 int
108 _info(struct modinfo *modinfop)
109 {
110 	return (mod_info(&modlinkage, modinfop));
111 }
112 
113 /*
114  * We do not allow kcf to unload.
115  */
116 int
117 _fini(void)
118 {
119 	return (EBUSY);
120 }
121 
122 /*
123  * Return a pointer to the modctl structure of the
124  * provider's module.
125  */
126 struct modctl *
127 kcf_get_modctl(crypto_provider_info_t *pinfo)
128 {
129 	struct modctl *mctlp;
130 
131 	/* Get the modctl struct for this module */
132 	if (pinfo->pi_provider_type == CRYPTO_SW_PROVIDER)
133 		mctlp = mod_getctl(pinfo->pi_provider_dev.pd_sw);
134 	else {
135 		major_t major;
136 		char *drvmod;
137 
138 		if ((major =
139 		    ddi_driver_major(pinfo->pi_provider_dev.pd_hw)) != -1) {
140 			drvmod = ddi_major_to_name(major);
141 			mctlp = mod_find_by_filename("drv", drvmod);
142 		} else
143 			return (NULL);
144 	}
145 
146 	return (mctlp);
147 }
148 
149 /*
150  * Verify the signature of the module of the passed in provider.
151  *
152  * Returns 0 if the signature is verified successfully. Returns -1,
153  * if the signature can not be verified now since kcfd is not up.
154  * In this case, we delay the verification till kcfd is up. Returns
155  * CRYPTO_MODVERIFICATION_FAILED if the verification has failed.
156  *
157  * This function can be called from process context only.
158  *
159  * We call kcfd with the full pathname of the module to be
160  * verified. kcfd will return success/restricted/fail, signature length
161  * and the actual signature in the ELF section of the module. If kcfd
162  * returns success or restricted, we compare the signature and the length
163  * with the values that krtld stored in the module structure. We log an
164  * error message in case of a failure.
165  */
166 int
167 kcf_verify_signature(kcf_provider_desc_t *pd)
168 {
169 	int rv;
170 	int error = CRYPTO_MODVERIFICATION_FAILED;
171 	door_arg_t darg;
172 	kcf_door_arg_t *kda;
173 	char *filename;
174 	struct module *mp;
175 	struct modctl *mctlp = pd->pd_mctlp;
176 	crypto_ops_t *prov_ops = pd->pd_ops_vector;
177 
178 	/*
179 	 * mctlp->mod_filename does not give us the full pathname.
180 	 * So, we have to access the module structure to get it.
181 	 */
182 	if (mctlp == NULL || mctlp->mod_mp == NULL)
183 		return (error);
184 
185 	mp = (struct module *)mctlp->mod_mp;
186 	filename = mp->filename;
187 
188 	KCF_FRMWRK_DEBUG(2, ("Verifying module: %s\n", filename));
189 
190 	/*
191 	 * Check if this provider needs to be verified. We always verify
192 	 * the module if it carries a signature. Any operation set which has
193 	 * a encryption/decryption component is a candidate for verification.
194 	 */
195 	if (prov_ops->co_cipher_ops == NULL && prov_ops->co_dual_ops == NULL &&
196 	    prov_ops->co_dual_cipher_mac_ops == NULL &&
197 	    prov_ops->co_key_ops == NULL && prov_ops->co_sign_ops == NULL &&
198 	    prov_ops->co_verify_ops == NULL && mp->sigdata == NULL) {
199 		return (0);
200 	}
201 
202 	/*
203 	 * See if this module has a proper signature section.
204 	 */
205 	if (mp->sigdata == NULL) {
206 		return (error);
207 	}
208 
209 	/*
210 	 * Check if the door is set up yet. This will be set when kcfd
211 	 * comes up. If not, we return -1 to indicate unverified. This
212 	 * will trigger the verification of the module later when kcfd
213 	 * is up. This is safe as we NEVER use a provider that has not
214 	 * been verified yet (assuming the provider needs to be verified).
215 	 */
216 	mutex_enter(&kcf_dh_lock);
217 	if (kcf_dh == NULL) {
218 		mutex_exit(&kcf_dh_lock);
219 		return (-1);
220 	}
221 	mutex_exit(&kcf_dh_lock);
222 
223 	kda = kmem_alloc(sizeof (kcf_door_arg_t) + mp->sigsize, KM_SLEEP);
224 	kda->da_version = KCF_KCFD_VERSION1;
225 	kda->da_iskernel = B_TRUE;
226 	bcopy(filename, kda->da_u.filename, strlen(filename) + 1);
227 
228 	darg.data_ptr = (char *)kda;
229 	darg.data_size = sizeof (kcf_door_arg_t) + mp->sigsize;
230 	darg.desc_ptr = NULL;
231 	darg.desc_num = 0;
232 	darg.rbuf = (char *)kda;
233 	darg.rsize = sizeof (kcf_door_arg_t);
234 
235 	/*
236 	 * Make door upcall. door_ki_upcall() checks for validity of the handle.
237 	 */
238 	rv = door_ki_upcall(kcf_dh, &darg);
239 
240 	if (rv == 0) {
241 		kcf_door_arg_t *rkda =  (kcf_door_arg_t *)darg.rbuf;
242 
243 		KCF_FRMWRK_DEBUG(2,
244 		    ("passed: %d\n", rkda->da_u.result.status));
245 		KCF_FRMWRK_DEBUG(2,
246 		    ("signature length: %d\n", rkda->da_u.result.siglen));
247 		KCF_FRMWRK_DEBUG(2,
248 		    ("signature: %p\n", (void*)rkda->da_u.result.signature));
249 
250 
251 		/* Check kcfd result and compare against module struct fields */
252 		if (((rkda->da_u.result.status != ELFSIGN_SUCCESS) &&
253 			(rkda->da_u.result.status != ELFSIGN_RESTRICTED)) ||
254 		    !(rkda->da_u.result.siglen == mp->sigsize) ||
255 		    (bcmp(rkda->da_u.result.signature, mp->sigdata,
256 			mp->sigsize))) {
257 			cmn_err(CE_WARN, "Module verification failed for %s.",
258 			    mp->filename);
259 		} else {
260 			error = 0;
261 		}
262 
263 		pd->pd_restricted =
264 		    (rkda->da_u.result.status == ELFSIGN_RESTRICTED);
265 
266 		if (pd->pd_restricted) {
267 			KCF_FRMWRK_DEBUG(2,
268 			    ("provider is restricted\n"));
269 		}
270 
271 		if (rkda != kda)
272 			kmem_free(rkda, darg.rsize);
273 
274 	} else {
275 		cmn_err(CE_WARN, "Module verification failed for %s.",
276 		    mp->filename);
277 	}
278 
279 	kmem_free(kda, sizeof (kcf_door_arg_t) + mp->sigsize);
280 	return (error);
281 }
282 
283 /* called from the CRYPTO_LOAD_DOOR ioctl */
284 int
285 crypto_load_door(uint_t did)
286 {
287 	mutex_enter(&kcf_dh_lock);
288 	kcf_dh = door_ki_lookup(did);
289 	mutex_exit(&kcf_dh_lock);
290 
291 	verify_unverified_providers();
292 
293 	/* Start the timeout handler to get random numbers */
294 	if (rngtimer_started == 0) {
295 		kcf_rnd_schedule_timeout(B_TRUE);
296 		rngtimer_started = 1;
297 	}
298 
299 	return (0);
300 }
301