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