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