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 #include <strings.h> 30 #include <cryptoutil.h> 31 #include <security/cryptoki.h> 32 #include <arcfour.h> 33 #include "softGlobal.h" 34 #include "softSession.h" 35 #include <des_impl.h> 36 #include <aes_impl.h> 37 #include "softDH.h" 38 #include "softObject.h" 39 #include "softKeystore.h" 40 #include "softKeystoreUtil.h" 41 42 43 static CK_MECHANISM_TYPE soft_mechanisms[] = { 44 CKM_DES_CBC, 45 CKM_DES_CBC_PAD, 46 CKM_DES_ECB, 47 CKM_DES_KEY_GEN, 48 CKM_DES_MAC_GENERAL, 49 CKM_DES_MAC, 50 CKM_DES3_CBC, 51 CKM_DES3_CBC_PAD, 52 CKM_DES3_ECB, 53 CKM_DES3_KEY_GEN, 54 CKM_AES_CBC, 55 CKM_AES_CBC_PAD, 56 CKM_AES_ECB, 57 CKM_AES_KEY_GEN, 58 CKM_SHA_1, 59 CKM_SHA_1_HMAC, 60 CKM_SHA_1_HMAC_GENERAL, 61 CKM_SSL3_SHA1_MAC, 62 CKM_MD5, 63 CKM_MD5_HMAC, 64 CKM_MD5_HMAC_GENERAL, 65 CKM_SSL3_MD5_MAC, 66 CKM_RC4, 67 CKM_RC4_KEY_GEN, 68 CKM_DSA, 69 CKM_DSA_SHA1, 70 CKM_DSA_KEY_PAIR_GEN, 71 CKM_RSA_PKCS, 72 CKM_RSA_PKCS_KEY_PAIR_GEN, 73 CKM_RSA_X_509, 74 CKM_MD5_RSA_PKCS, 75 CKM_SHA1_RSA_PKCS, 76 CKM_DH_PKCS_KEY_PAIR_GEN, 77 CKM_DH_PKCS_DERIVE, 78 CKM_MD5_KEY_DERIVATION, 79 CKM_SHA1_KEY_DERIVATION, 80 CKM_PBE_SHA1_RC4_128, 81 CKM_PKCS5_PBKD2, 82 CKM_SSL3_PRE_MASTER_KEY_GEN, 83 CKM_TLS_PRE_MASTER_KEY_GEN, 84 CKM_SSL3_MASTER_KEY_DERIVE, 85 CKM_TLS_MASTER_KEY_DERIVE, 86 CKM_SSL3_MASTER_KEY_DERIVE_DH, 87 CKM_TLS_MASTER_KEY_DERIVE_DH, 88 CKM_SSL3_KEY_AND_MAC_DERIVE, 89 CKM_TLS_KEY_AND_MAC_DERIVE 90 }; 91 92 /* 93 * This is the table of CK_MECHANISM_INFO structs for the supported mechanisms. 94 * The index for this table is the same as the one above for the same 95 * mechanism. 96 * The minimum and maximum sizes of the key for the mechanism can be measured 97 * in bits or in bytes (i.e. mechanism-dependent). This table specifies the 98 * supported range of key sizes in bytes; unless noted as in bits. 99 */ 100 static CK_MECHANISM_INFO soft_mechanism_info[] = { 101 {DES_MINBYTES, DES_MAXBYTES, 102 CKF_ENCRYPT|CKF_DECRYPT| 103 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_CBC */ 104 {DES_MINBYTES, DES_MAXBYTES, 105 CKF_ENCRYPT|CKF_DECRYPT| 106 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_CBC_PAD */ 107 {DES_MINBYTES, DES_MAXBYTES, 108 CKF_ENCRYPT|CKF_DECRYPT| 109 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES_ECB */ 110 {DES_MINBYTES, DES_MAXBYTES, 111 CKF_GENERATE}, /* CKM_DES_KEY_GEN */ 112 {DES_MINBYTES, DES_MAXBYTES, 113 CKF_SIGN|CKF_VERIFY}, /* CKM_DES_MAC_GENERAL */ 114 {DES_MINBYTES, DES_MAXBYTES, 115 CKF_SIGN|CKF_VERIFY}, /* CKM_DES_MAC */ 116 /* 117 * Note that DES3 is allowed even if CRYPTO_UNLIMITED is not specified. 118 * This is because 3DES has an exception to the Solaris PAC enforced 119 * no crypto greater than 128 bit in core Solaris rule. 120 * The actual key length of 3DES is 192, but most cryptographers regard 121 * it to be effectively 112. 122 */ 123 {DES3_MINBYTES, DES3_MAXBYTES, 124 CKF_ENCRYPT|CKF_DECRYPT| 125 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_CBC */ 126 {DES3_MINBYTES, DES3_MAXBYTES, 127 CKF_ENCRYPT|CKF_DECRYPT| 128 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_CBC_PAD */ 129 {DES3_MINBYTES, DES3_MAXBYTES, 130 CKF_ENCRYPT|CKF_DECRYPT| 131 CKF_WRAP|CKF_UNWRAP}, /* CKM_DES3_ECB */ 132 {DES3_MINBYTES, DES3_MAXBYTES, 133 CKF_GENERATE}, /* CKM_DES3_KEY_GEN */ 134 {AES_MINBYTES, AES_MAXBYTES, 135 CKF_ENCRYPT|CKF_DECRYPT| 136 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC */ 137 {AES_MINBYTES, AES_MAXBYTES, 138 CKF_ENCRYPT|CKF_DECRYPT| 139 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_CBC_PAD */ 140 {AES_MINBYTES, AES_MAXBYTES, 141 CKF_ENCRYPT|CKF_DECRYPT| 142 CKF_WRAP|CKF_UNWRAP}, /* CKM_AES_ECB */ 143 {AES_MINBYTES, AES_MAXBYTES, 144 CKF_GENERATE}, /* CKM_AES_KEY_GEN */ 145 {0, 0, CKF_DIGEST}, /* CKM_SHA_1 */ 146 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA_1_HMAC */ 147 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA_1_HMAC_GENERAL */ 148 {1, 512, CKF_SIGN|CKF_VERIFY}, /* CKM_SSL3_SHA1_MAC */ 149 {0, 0, CKF_DIGEST}, /* CKM_MD5 */ 150 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_HMAC */ 151 {1, 64, CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_HMAC_GENERAL */ 152 {1, 512, CKF_SIGN|CKF_VERIFY}, /* CKM_SSL3_MD5_MAC */ 153 {8, ARCFOUR_MAX_KEY_BITS, CKF_ENCRYPT|CKF_DECRYPT}, /* CKM_RC4; */ 154 /* in bits */ 155 {8, ARCFOUR_MAX_KEY_BITS, CKF_GENERATE }, /* CKM_RC4_KEY_GEN; in bits */ 156 {512, 1024, CKF_SIGN|CKF_VERIFY}, /* CKM_DSA; in bits */ 157 {512, 1024, CKF_SIGN|CKF_VERIFY}, /* CKM_DSA_SHA1; in bits */ 158 {512, 1024, CKF_GENERATE_KEY_PAIR}, /* CKM_DSA_KEY_PAIR_GEN; */ 159 /* in bits */ 160 {256, 4096, CKF_ENCRYPT|CKF_DECRYPT| 161 CKF_SIGN|CKF_SIGN_RECOVER| 162 CKF_WRAP|CKF_UNWRAP| 163 CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_PKCS; in bits */ 164 {256, 4096, CKF_GENERATE_KEY_PAIR}, /* CKM_RSA_PKCS_KEY_PAIR_GEN; */ 165 /* in bits */ 166 {256, 4096, CKF_ENCRYPT|CKF_DECRYPT| 167 CKF_SIGN|CKF_SIGN_RECOVER| 168 CKF_WRAP|CKF_UNWRAP| 169 CKF_VERIFY|CKF_VERIFY_RECOVER}, /* CKM_RSA_X_509 in bits */ 170 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_MD5_RSA_PKCS in bits */ 171 {256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA1_RSA_PKCS in bits */ 172 {MIN_DH_KEYLENGTH, MAX_DH_KEYLENGTH, CKF_GENERATE_KEY_PAIR}, 173 /* CKM_DH_PKCS_KEY_PAIR_GEN */ 174 /* in bits */ 175 {MIN_DH_KEYLENGTH, MAX_DH_KEYLENGTH, CKF_DERIVE}, 176 /* CKM_DH_PKCS_DERIVE; */ 177 /* in bits */ 178 {1, 16, CKF_DERIVE}, /* CKM_MD5_KEY_DERIVATION */ 179 {1, 20, CKF_DERIVE}, /* CKM_SHA1_KEY_DERIVATION */ 180 {0, 0, CKF_GENERATE}, /* CKM_PBE_SHA1_RC4_128 */ 181 {0, 0, CKF_GENERATE}, /* CKM_PKCS5_PBKD2 */ 182 {48, 48, CKF_GENERATE}, /* CKM_SSL3_PRE_MASTER_KEY_GEN */ 183 {48, 48, CKF_GENERATE}, /* CKM_TLS_PRE_MASTER_KEY_GEN */ 184 {48, 48, CKF_DERIVE}, /* CKM_SSL3_MASTER_KEY_DERIVE */ 185 {48, 48, CKF_DERIVE}, /* CKM_TLS_MASTER_KEY_DERIVE */ 186 {48, 48, CKF_DERIVE}, /* CKM_SSL3_MASTER_KEY_DERIVE_DH */ 187 {48, 48, CKF_DERIVE}, /* CKM_TLS_MASTER_KEY_DERIVE_DH */ 188 {0, 0, CKF_DERIVE}, /* CKM_SSL3_KEY_AND_MAC_DERIVE */ 189 {0, 0, CKF_DERIVE} /* CKM_TLS_KEY_AND_MAC_DERIVE */ 190 }; 191 192 /* 193 * Slot ID for softtoken is always 1. tokenPresent is ignored. 194 * Also, only one slot is used. 195 */ 196 /*ARGSUSED*/ 197 CK_RV 198 C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, 199 CK_ULONG_PTR pulCount) 200 { 201 202 CK_RV rv; 203 204 if (!softtoken_initialized) 205 return (CKR_CRYPTOKI_NOT_INITIALIZED); 206 207 if (pulCount == NULL) { 208 return (CKR_ARGUMENTS_BAD); 209 } 210 211 if (pSlotList == NULL) { 212 /* 213 * Application only wants to know the number of slots. 214 */ 215 *pulCount = 1; 216 return (CKR_OK); 217 } 218 219 if ((*pulCount < 1) && (pSlotList != NULL)) { 220 rv = CKR_BUFFER_TOO_SMALL; 221 } else { 222 pSlotList[0] = SOFTTOKEN_SLOTID; 223 rv = CKR_OK; 224 } 225 226 *pulCount = 1; 227 return (rv); 228 } 229 230 231 CK_RV 232 C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) 233 { 234 235 if (!softtoken_initialized) 236 return (CKR_CRYPTOKI_NOT_INITIALIZED); 237 238 if (pInfo == NULL) 239 return (CKR_ARGUMENTS_BAD); 240 241 /* Make sure the slot ID is valid */ 242 if (slotID != SOFTTOKEN_SLOTID) 243 return (CKR_SLOT_ID_INVALID); 244 245 /* Provide information about the slot in the provided buffer */ 246 (void) strncpy((char *)pInfo->slotDescription, SOFT_SLOT_DESCRIPTION, 247 64); 248 (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32); 249 pInfo->flags = 0; 250 if (soft_token_present) { 251 pInfo->flags |= CKF_TOKEN_PRESENT; 252 } 253 pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR; 254 pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR; 255 pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR; 256 pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR; 257 258 return (CKR_OK); 259 } 260 261 262 CK_RV 263 C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) 264 { 265 266 ulong_t token_flag = 0; 267 boolean_t pin_initialized = B_FALSE; 268 char *ks_cryptpin = NULL; 269 CK_RV rv = CKR_OK; 270 271 if (!softtoken_initialized) 272 return (CKR_CRYPTOKI_NOT_INITIALIZED); 273 274 /* Make sure the slot ID is valid */ 275 if (slotID != SOFTTOKEN_SLOTID) 276 return (CKR_SLOT_ID_INVALID); 277 278 if (pInfo == NULL) 279 return (CKR_ARGUMENTS_BAD); 280 281 if (!soft_token_present) 282 return (CKR_DEVICE_REMOVED); 283 284 /* Provide information about a token in the provided buffer */ 285 (void) strncpy((char *)pInfo->label, SOFT_TOKEN_LABEL, 32); 286 (void) strncpy((char *)pInfo->manufacturerID, SOFT_MANUFACTURER_ID, 32); 287 (void) strncpy((char *)pInfo->model, TOKEN_MODEL, 16); 288 (void) strncpy((char *)pInfo->serialNumber, SOFT_TOKEN_SERIAL, 16); 289 290 rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin, 291 B_FALSE); 292 if (rv != CKR_OK) 293 return (rv); 294 if (!pin_initialized) 295 token_flag = CKF_USER_PIN_TO_BE_CHANGED; 296 if (ks_cryptpin) 297 free(ks_cryptpin); 298 299 pInfo->flags = SOFT_TOKEN_FLAGS | token_flag; 300 pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE; 301 pInfo->ulSessionCount = soft_session_cnt; 302 pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE; 303 pInfo->ulRwSessionCount = soft_session_rw_cnt; 304 pInfo->ulMaxPinLen = MAX_PIN_LEN; 305 pInfo->ulMinPinLen = MIN_PIN_LEN; 306 pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; 307 pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; 308 pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; 309 pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; 310 pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR; 311 pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR; 312 pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR; 313 pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR; 314 (void) memset(pInfo->utcTime, ' ', 16); 315 316 return (CKR_OK); 317 } 318 319 /*ARGSUSED*/ 320 CK_RV 321 C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved) 322 { 323 if (!softtoken_initialized) 324 return (CKR_CRYPTOKI_NOT_INITIALIZED); 325 326 /* 327 * This is currently not implemented, however we could cause this 328 * to wait for the token files to appear if soft_token_present is 329 * false. 330 * However there is currently no polite and portable way to do that 331 * because we might not even be able to get to an fd to the 332 * parent directory, so instead we don't support any slot events. 333 */ 334 return (CKR_FUNCTION_NOT_SUPPORTED); 335 } 336 337 338 CK_RV 339 C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, 340 CK_ULONG_PTR pulCount) 341 { 342 343 ulong_t i; 344 ulong_t mechnum; 345 346 if (!softtoken_initialized) 347 return (CKR_CRYPTOKI_NOT_INITIALIZED); 348 349 if (slotID != SOFTTOKEN_SLOTID) 350 return (CKR_SLOT_ID_INVALID); 351 352 mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE); 353 354 if (pMechanismList == NULL) { 355 /* 356 * Application only wants to know the number of 357 * supported mechanism types. 358 */ 359 *pulCount = mechnum; 360 return (CKR_OK); 361 } 362 363 if (*pulCount < mechnum) { 364 *pulCount = mechnum; 365 return (CKR_BUFFER_TOO_SMALL); 366 } 367 368 for (i = 0; i < mechnum; i++) { 369 pMechanismList[i] = soft_mechanisms[i]; 370 } 371 372 *pulCount = mechnum; 373 374 return (CKR_OK); 375 } 376 377 378 CK_RV 379 C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 380 CK_MECHANISM_INFO_PTR pInfo) 381 { 382 383 ulong_t i; 384 ulong_t mechnum; 385 386 if (!softtoken_initialized) 387 return (CKR_CRYPTOKI_NOT_INITIALIZED); 388 389 if (slotID != SOFTTOKEN_SLOTID) 390 return (CKR_SLOT_ID_INVALID); 391 392 if (pInfo == NULL) { 393 return (CKR_ARGUMENTS_BAD); 394 } 395 396 mechnum = sizeof (soft_mechanisms) / sizeof (CK_MECHANISM_TYPE); 397 for (i = 0; i < mechnum; i++) { 398 if (soft_mechanisms[i] == type) 399 break; 400 } 401 402 if (i == mechnum) 403 /* unsupported mechanism */ 404 return (CKR_MECHANISM_INVALID); 405 406 pInfo->ulMinKeySize = soft_mechanism_info[i].ulMinKeySize; 407 pInfo->ulMaxKeySize = soft_mechanism_info[i].ulMaxKeySize; 408 pInfo->flags = soft_mechanism_info[i].flags; 409 410 return (CKR_OK); 411 } 412 413 414 /*ARGSUSED*/ 415 CK_RV 416 C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, 417 CK_UTF8CHAR_PTR pLabel) 418 { 419 if (!softtoken_initialized) 420 return (CKR_CRYPTOKI_NOT_INITIALIZED); 421 422 return (CKR_FUNCTION_NOT_SUPPORTED); 423 } 424 425 /*ARGSUSED*/ 426 CK_RV 427 C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) 428 { 429 if (!softtoken_initialized) 430 return (CKR_CRYPTOKI_NOT_INITIALIZED); 431 432 return (CKR_FUNCTION_NOT_SUPPORTED); 433 } 434 435 436 CK_RV 437 C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, 438 CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) 439 { 440 441 soft_session_t *session_p; 442 CK_RV rv; 443 boolean_t lock_held = B_FALSE; 444 445 if (!softtoken_initialized) 446 return (CKR_CRYPTOKI_NOT_INITIALIZED); 447 448 /* 449 * Obtain the session pointer. Also, increment the session 450 * reference count. 451 */ 452 rv = handle2session(hSession, &session_p); 453 if (rv != CKR_OK) 454 return (rv); 455 456 if (!soft_token_present) { 457 SES_REFRELE(session_p, lock_held); 458 return (CKR_DEVICE_REMOVED); 459 } 460 461 if ((ulOldPinLen < MIN_PIN_LEN) || (ulOldPinLen > MAX_PIN_LEN) || 462 (ulNewPinLen < MIN_PIN_LEN) ||(ulNewPinLen > MAX_PIN_LEN)) { 463 SES_REFRELE(session_p, lock_held); 464 return (CKR_PIN_LEN_RANGE); 465 } 466 467 if ((pOldPin == NULL_PTR) || (pNewPin == NULL_PTR)) { 468 /* 469 * We don't support CKF_PROTECTED_AUTHENTICATION_PATH 470 */ 471 SES_REFRELE(session_p, lock_held); 472 return (CKR_ARGUMENTS_BAD); 473 } 474 475 /* check the state of the session */ 476 if ((session_p->state != CKS_RW_PUBLIC_SESSION) && 477 (session_p->state != CKS_RW_USER_FUNCTIONS)) { 478 SES_REFRELE(session_p, lock_held); 479 return (CKR_SESSION_READ_ONLY); 480 } 481 482 rv = soft_setpin(pOldPin, ulOldPinLen, pNewPin, ulNewPinLen); 483 484 SES_REFRELE(session_p, lock_held); 485 return (rv); 486 } 487