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