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