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