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 2004 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 #include <security/cryptoki.h> 31 #include "softGlobal.h" 32 #include "softSession.h" 33 #include "softKeys.h" 34 #include "softOps.h" 35 36 37 CK_RV 38 C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 39 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) 40 { 41 42 CK_RV rv; 43 soft_session_t *session_p; 44 boolean_t lock_held = B_FALSE; 45 46 if (!softtoken_initialized) 47 return (CKR_CRYPTOKI_NOT_INITIALIZED); 48 49 /* Obtain the session pointer. */ 50 rv = handle2session(hSession, &session_p); 51 if (rv != CKR_OK) 52 return (rv); 53 54 if ((pMechanism == NULL) || (phKey == NULL)) { 55 rv = CKR_ARGUMENTS_BAD; 56 goto clean_exit; 57 } 58 59 if ((pTemplate == NULL) && (ulCount != 0)) { 60 rv = CKR_ARGUMENTS_BAD; 61 goto clean_exit; 62 } 63 64 rv = soft_genkey(session_p, pMechanism, pTemplate, 65 ulCount, phKey); 66 67 clean_exit: 68 SES_REFRELE(session_p, lock_held); 69 return (rv); 70 71 } 72 73 74 CK_RV 75 C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 76 CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, 77 CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, 78 CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) 79 { 80 81 CK_RV rv; 82 soft_session_t *session_p; 83 boolean_t lock_held = B_FALSE; 84 85 if (!softtoken_initialized) 86 return (CKR_CRYPTOKI_NOT_INITIALIZED); 87 88 /* Obtain the session pointer. */ 89 rv = handle2session(hSession, &session_p); 90 if (rv != CKR_OK) 91 return (rv); 92 93 if ((pMechanism == NULL) || (phPublicKey == NULL) || 94 (phPrivateKey == NULL)) { 95 rv = CKR_ARGUMENTS_BAD; 96 goto clean_exit; 97 } 98 99 if ((pPublicKeyTemplate == NULL) || 100 (ulPublicKeyAttributeCount == 0)) { 101 rv = CKR_ARGUMENTS_BAD; 102 goto clean_exit; 103 } 104 105 if ((pPrivateKeyTemplate == NULL) && 106 (ulPrivateKeyAttributeCount != 0)) { 107 rv = CKR_ARGUMENTS_BAD; 108 goto clean_exit; 109 } 110 111 rv = soft_genkey_pair(session_p, pMechanism, pPublicKeyTemplate, 112 ulPublicKeyAttributeCount, pPrivateKeyTemplate, 113 ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); 114 115 clean_exit: 116 SES_REFRELE(session_p, lock_held); 117 return (rv); 118 } 119 120 CK_RV 121 C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 122 CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, 123 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) 124 { 125 CK_RV rv; 126 soft_session_t *session_p; 127 soft_object_t *wrappingkey_p; 128 soft_object_t *hkey_p; 129 boolean_t lock_held = B_FALSE; 130 131 if (!softtoken_initialized) 132 return (CKR_CRYPTOKI_NOT_INITIALIZED); 133 134 /* Obtain the session pointer. */ 135 rv = handle2session(hSession, &session_p); 136 if (rv != CKR_OK) 137 return (rv); 138 139 if (pMechanism == NULL) { 140 rv = CKR_ARGUMENTS_BAD; 141 goto clean_exit; 142 } 143 144 if (pulWrappedKeyLen == NULL) { 145 rv = CKR_ARGUMENTS_BAD; 146 goto clean_exit; 147 } 148 149 /* Obtain the wrapping key object pointer. */ 150 HANDLE2OBJECT(hWrappingKey, wrappingkey_p, rv); 151 if (rv != CKR_OK) { 152 rv = CKR_WRAPPING_KEY_HANDLE_INVALID; 153 goto clean_exit; 154 } 155 156 /* Obtain the to-be-wrapped key object pointer. */ 157 HANDLE2OBJECT(hKey, hkey_p, rv); 158 if (rv != CKR_OK) 159 goto clean_exit1; 160 161 /* Check if given wrapping key may be used for wrapping. */ 162 if (!(wrappingkey_p->bool_attr_mask & WRAP_BOOL_ON)) { 163 rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 164 goto clean_exit2; 165 } 166 167 /* Check if given wrapping key may be used for encryption. */ 168 if (!(wrappingkey_p->bool_attr_mask & ENCRYPT_BOOL_ON)) { 169 rv = CKR_WRAPPING_KEY_TYPE_INCONSISTENT; 170 goto clean_exit2; 171 } 172 173 /* 174 * Check to see if key to be wrapped is extractable. 175 * Note: this should always be true for softtoken keys. 176 */ 177 if (!(hkey_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) { 178 rv = CKR_KEY_UNEXTRACTABLE; 179 goto clean_exit2; 180 } 181 182 (void) pthread_mutex_lock(&session_p->session_mutex); 183 lock_held = B_TRUE; 184 185 /* 186 * Wrapping key objects requires calling encrypt operations. 187 * Check to see if encrypt operation is already active. 188 */ 189 if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) { 190 /* free the memory to avoid memory leak */ 191 soft_crypt_cleanup(session_p, B_TRUE, lock_held); 192 } 193 194 /* This active flag will remain ON while wrapping the key. */ 195 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE; 196 197 (void) pthread_mutex_unlock(&session_p->session_mutex); 198 lock_held = B_FALSE; 199 200 rv = soft_wrapkey(session_p, pMechanism, wrappingkey_p, 201 hkey_p, pWrappedKey, pulWrappedKeyLen); 202 203 (void) pthread_mutex_lock(&session_p->session_mutex); 204 session_p->encrypt.flags = 0; 205 lock_held = B_TRUE; 206 207 clean_exit2: 208 OBJ_REFRELE(hkey_p); 209 clean_exit1: 210 OBJ_REFRELE(wrappingkey_p); 211 clean_exit: 212 SES_REFRELE(session_p, lock_held); 213 return (rv); 214 } 215 216 CK_RV 217 C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 218 CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, 219 CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, 220 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) 221 { 222 CK_RV rv; 223 soft_session_t *session_p; 224 soft_object_t *unwrappingkey_p; 225 boolean_t lock_held = B_FALSE; 226 227 if (!softtoken_initialized) 228 return (CKR_CRYPTOKI_NOT_INITIALIZED); 229 230 /* Obtain the session pointer. */ 231 rv = handle2session(hSession, &session_p); 232 if (rv != CKR_OK) 233 return (rv); 234 235 if (pMechanism == NULL) { 236 rv = CKR_ARGUMENTS_BAD; 237 goto clean_exit; 238 } 239 240 if ((pTemplate == NULL) || (ulAttributeCount == 0)) { 241 rv = CKR_ARGUMENTS_BAD; 242 goto clean_exit; 243 } 244 245 if ((pWrappedKey == NULL) || (ulWrappedKeyLen == 0)) { 246 rv = CKR_ARGUMENTS_BAD; 247 goto clean_exit; 248 } 249 250 if (phKey == NULL) { 251 rv = CKR_ARGUMENTS_BAD; 252 goto clean_exit; 253 } 254 255 /* Obtain the unwrapping key object pointer. */ 256 HANDLE2OBJECT(hUnwrappingKey, unwrappingkey_p, rv); 257 if (rv != CKR_OK) { 258 rv = CKR_UNWRAPPING_KEY_HANDLE_INVALID; 259 goto clean_exit; 260 } 261 262 /* Check if given unwrapping key may be used for unwrapping. */ 263 if (!(unwrappingkey_p->bool_attr_mask & UNWRAP_BOOL_ON)) { 264 rv = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 265 goto clean_exit1; 266 } 267 268 /* Check if given unwrapping key may be used to decrypt. */ 269 if (!(unwrappingkey_p->bool_attr_mask & DECRYPT_BOOL_ON)) { 270 rv = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; 271 goto clean_exit1; 272 } 273 274 (void) pthread_mutex_lock(&session_p->session_mutex); 275 lock_held = B_TRUE; 276 277 /* 278 * Unwrapping key objects requires calling decrypt operations. 279 * Check to see if decrypt operation is already active. 280 */ 281 if (session_p->decrypt.flags & CRYPTO_OPERATION_ACTIVE) { 282 /* free the memory to avoid memory leak */ 283 soft_crypt_cleanup(session_p, B_FALSE, lock_held); 284 } 285 286 /* 287 * This active flag will remain ON until application 288 * is done unwrapping the key. 289 */ 290 session_p->decrypt.flags = CRYPTO_OPERATION_ACTIVE; 291 292 (void) pthread_mutex_unlock(&session_p->session_mutex); 293 lock_held = B_FALSE; 294 295 rv = soft_unwrapkey(session_p, pMechanism, unwrappingkey_p, 296 pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, 297 phKey); 298 299 (void) pthread_mutex_lock(&session_p->session_mutex); 300 session_p->decrypt.flags = 0; 301 lock_held = B_TRUE; 302 303 clean_exit1: 304 OBJ_REFRELE(unwrappingkey_p); 305 clean_exit: 306 SES_REFRELE(session_p, lock_held); 307 return (rv); 308 } 309 310 311 CK_RV 312 C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 313 CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, 314 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) 315 { 316 317 CK_RV rv; 318 soft_session_t *session_p; 319 soft_object_t *basekey_p; 320 boolean_t lock_held = B_FALSE; 321 322 if (!softtoken_initialized) 323 return (CKR_CRYPTOKI_NOT_INITIALIZED); 324 325 /* Obtain the session pointer. */ 326 rv = handle2session(hSession, &session_p); 327 if (rv != CKR_OK) 328 return (rv); 329 330 if (pMechanism == NULL) { 331 rv = CKR_ARGUMENTS_BAD; 332 goto clean_exit; 333 } 334 335 if (((pTemplate != NULL) && (ulAttributeCount == 0)) || 336 ((pTemplate == NULL) && (ulAttributeCount != 0))) { 337 rv = CKR_ARGUMENTS_BAD; 338 goto clean_exit; 339 } 340 341 /* Obtain the private key object pointer. */ 342 HANDLE2OBJECT(hBaseKey, basekey_p, rv); 343 if (rv != CKR_OK) 344 goto clean_exit; 345 346 /* Check to see if key object allows for derivation. */ 347 if (!(basekey_p->bool_attr_mask & DERIVE_BOOL_ON)) { 348 rv = CKR_KEY_TYPE_INCONSISTENT; 349 goto clean_exit1; 350 } 351 352 rv = soft_derivekey(session_p, pMechanism, basekey_p, 353 pTemplate, ulAttributeCount, phKey); 354 355 clean_exit1: 356 OBJ_REFRELE(basekey_p); 357 clean_exit: 358 SES_REFRELE(session_p, lock_held); 359 return (rv); 360 } 361