fipstokn.c (70640B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * This file implements PKCS 11 on top of our existing security modules 6 * 7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. 8 * This implementation has two slots: 9 * slot 1 is our generic crypto support. It does not require login 10 * (unless you've enabled FIPS). It supports Public Key ops, and all they 11 * bulk ciphers and hashes. It can also support Private Key ops for imported 12 * Private keys. It does not have any token storage. 13 * slot 2 is our private key support. It requires a login before use. It 14 * can store Private Keys and Certs as token objects. Currently only private 15 * keys and their associated Certificates are saved on the token. 16 * 17 * In this implementation, session objects are only visible to the session 18 * that created or generated them. 19 */ 20 #include "seccomon.h" 21 #include "softoken.h" 22 #include "lowkeyi.h" 23 #include "pkcs11.h" 24 #include "pkcs11i.h" 25 #include "prenv.h" 26 #include "prprf.h" 27 28 #include <ctype.h> 29 30 #ifdef XP_UNIX 31 #define NSS_AUDIT_WITH_SYSLOG 1 32 #include <syslog.h> 33 #include <unistd.h> 34 #endif 35 36 #ifdef LINUX 37 #include <pthread.h> 38 #include <dlfcn.h> 39 #define LIBAUDIT_NAME "libaudit.so.1" 40 #ifndef AUDIT_CRYPTO_TEST_USER 41 #define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */ 42 #define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */ 43 #define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */ 44 #define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */ 45 #define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */ 46 #define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomize */ 47 #endif 48 static void *libaudit_handle; 49 static int (*audit_open_func)(void); 50 static void (*audit_close_func)(int fd); 51 static int (*audit_log_user_message_func)(int audit_fd, int type, 52 const char *message, const char *hostname, const char *addr, 53 const char *tty, int result); 54 static int (*audit_send_user_message_func)(int fd, int type, 55 const char *message); 56 57 static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT; 58 59 static void 60 libaudit_init(void) 61 { 62 libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY); 63 if (!libaudit_handle) { 64 return; 65 } 66 audit_open_func = dlsym(libaudit_handle, "audit_open"); 67 audit_close_func = dlsym(libaudit_handle, "audit_close"); 68 /* 69 * audit_send_user_message is the older function. 70 * audit_log_user_message, if available, is preferred. 71 */ 72 audit_log_user_message_func = dlsym(libaudit_handle, 73 "audit_log_user_message"); 74 if (!audit_log_user_message_func) { 75 audit_send_user_message_func = dlsym(libaudit_handle, 76 "audit_send_user_message"); 77 } 78 if (!audit_open_func || !audit_close_func || 79 (!audit_log_user_message_func && !audit_send_user_message_func)) { 80 dlclose(libaudit_handle); 81 libaudit_handle = NULL; 82 audit_open_func = NULL; 83 audit_close_func = NULL; 84 audit_log_user_message_func = NULL; 85 audit_send_user_message_func = NULL; 86 } 87 } 88 #endif /* LINUX */ 89 90 /* 91 * ******************** Password Utilities ******************************* 92 */ 93 static PRBool isLoggedIn = PR_FALSE; 94 static PRBool isLevel2 = PR_TRUE; 95 PRBool sftk_fatalError = PR_FALSE; 96 97 /* 98 * This function returns 99 * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string 100 * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not 101 * consist of characters from three or more character classes. 102 * - CKR_OK otherwise 103 * 104 * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters. 105 * We define five character classes: digits (0-9), ASCII lowercase letters, 106 * ASCII uppercase letters, ASCII non-alphanumeric characters (such as 107 * space and punctuation marks), and non-ASCII characters. If an ASCII 108 * uppercase letter is the first character of the password/PIN, the 109 * uppercase letter is not counted toward its character class. Similarly, 110 * if a digit is the last character of the password/PIN, the digit is not 111 * counted toward its character class. 112 * 113 * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum 114 * password/PIN length checks, they check the length in bytes as opposed 115 * to characters. To meet the minimum password/PIN guessing probability 116 * requirements in FIPS 140-2, we need to check the length in characters. 117 */ 118 static CK_RV 119 sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) 120 { 121 unsigned int i; 122 int nchar = 0; /* number of characters */ 123 int ntrail = 0; /* number of trailing bytes to follow */ 124 int ndigit = 0; /* number of decimal digits */ 125 int nlower = 0; /* number of ASCII lowercase letters */ 126 int nupper = 0; /* number of ASCII uppercase letters */ 127 int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */ 128 int nnonascii = 0; /* number of non-ASCII characters */ 129 int nclass; /* number of character classes */ 130 131 for (i = 0; i < ulPinLen; i++) { 132 unsigned int byte = pPin[i]; 133 134 if (ntrail) { 135 if ((byte & 0xc0) != 0x80) { 136 /* illegal */ 137 nchar = -1; 138 break; 139 } 140 if (--ntrail == 0) { 141 nchar++; 142 nnonascii++; 143 } 144 continue; 145 } 146 if ((byte & 0x80) == 0x00) { 147 /* single-byte (ASCII) character */ 148 nchar++; 149 if (isdigit(byte)) { 150 if (i < ulPinLen - 1) { 151 ndigit++; 152 } 153 } else if (islower(byte)) { 154 nlower++; 155 } else if (isupper(byte)) { 156 if (i > 0) { 157 nupper++; 158 } 159 } else { 160 nnonalnum++; 161 } 162 } else if ((byte & 0xe0) == 0xc0) { 163 /* leading byte of two-byte character */ 164 ntrail = 1; 165 } else if ((byte & 0xf0) == 0xe0) { 166 /* leading byte of three-byte character */ 167 ntrail = 2; 168 } else if ((byte & 0xf8) == 0xf0) { 169 /* leading byte of four-byte character */ 170 ntrail = 3; 171 } else { 172 /* illegal */ 173 nchar = -1; 174 break; 175 } 176 } 177 if (nchar == -1) { 178 /* illegal UTF8 string */ 179 return CKR_PIN_INVALID; 180 } 181 if (nchar < FIPS_MIN_PIN) { 182 return CKR_PIN_LEN_RANGE; 183 } 184 nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) + 185 (nnonalnum != 0) + (nnonascii != 0); 186 if (nclass < 3) { 187 return CKR_PIN_LEN_RANGE; 188 } 189 return CKR_OK; 190 } 191 192 /* FIPS required checks before any useful cryptographic services */ 193 static CK_RV 194 sftk_fipsCheck(void) 195 { 196 if (sftk_fatalError) 197 return CKR_DEVICE_ERROR; 198 if (isLevel2 && !isLoggedIn) 199 return CKR_USER_NOT_LOGGED_IN; 200 return CKR_OK; 201 } 202 203 #define SFTK_FIPSCHECK() \ 204 CK_RV rv; \ 205 if ((rv = sftk_fipsCheck()) != CKR_OK) \ 206 return rv; 207 208 #define SFTK_FIPSFATALCHECK() \ 209 if (sftk_fatalError) \ 210 return CKR_DEVICE_ERROR; 211 212 /* grab an attribute out of a raw template */ 213 void * 214 fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, 215 CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type) 216 { 217 int i; 218 219 for (i = 0; i < (int)ulCount; i++) { 220 if (pTemplate[i].type == type) { 221 return pTemplate[i].pValue; 222 } 223 } 224 return NULL; 225 } 226 227 #define __PASTE(x, y) x##y 228 229 /* ------------- forward declare all the NSC_ functions ------------- */ 230 #undef CK_NEED_ARG_LIST 231 #undef CK_PKCS11_FUNCTION_INFO 232 233 #define CK_PKCS11_3_2 1 234 #define CK_PKCS11_3_0 1 235 236 #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS, name) 237 #define CK_NEED_ARG_LIST 1 238 239 #include "pkcs11f.h" 240 241 /* ------------- forward declare all the FIPS functions ------------- */ 242 #undef CK_NEED_ARG_LIST 243 #undef CK_PKCS11_FUNCTION_INFO 244 245 #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name) 246 #define CK_NEED_ARG_LIST 1 247 248 #include "pkcs11f.h" 249 250 /* ------------- build the CK_CRYPTO_TABLE ------------------------- */ 251 static CK_FUNCTION_LIST_3_2 sftk_fipsTable_v32 = { 252 { 3, 2 }, 253 254 #undef CK_NEED_ARG_LIST 255 #undef CK_PKCS11_FUNCTION_INFO 256 257 #define CK_PKCS11_3_2_ONLY 1 258 #define CK_PKCS11_FUNCTION_INFO(name) \ 259 __PASTE(F, name) \ 260 , 261 262 #include "pkcs11f.h" 263 264 }; 265 #undef CK_PKCS11_3_2_ONLY 266 267 static CK_FUNCTION_LIST_3_0 sftk_fipsTable_v30 = { 268 { 3, 0 }, 269 270 #undef CK_NEED_ARG_LIST 271 #undef CK_PKCS11_FUNCTION_INFO 272 273 #define CK_PKCS11_3_0_ONLY 1 274 #define CK_PKCS11_FUNCTION_INFO(name) \ 275 __PASTE(F, name) \ 276 , 277 278 #include "pkcs11f.h" 279 280 }; 281 #undef CK_PKCS11_3_0_ONLY 282 283 /* forward declaration of special GetInfo functions */ 284 CK_RV FC_GetInfoV2(CK_INFO_PTR pInfo); 285 CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo); 286 CK_RV FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 287 CK_MECHANISM_INFO_PTR pInfo); 288 CK_RV NSC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 289 CK_MECHANISM_INFO_PTR pInfo); 290 291 static CK_FUNCTION_LIST sftk_fipsTable_v2 = { 292 { 2, 40 }, 293 294 #undef CK_PKCS11_3_0 295 #define CK_PKCS11_2_0_ONLY 1 296 #undef CK_NEED_ARG_LIST 297 #undef CK_PKCS11_FUNCTION_INFO 298 #define C_GetInfo C_GetInfoV2 299 #define C_GetMechanismInfo C_GetMechanismInfoV2 300 301 #define CK_PKCS11_FUNCTION_INFO(name) \ 302 __PASTE(F, name) \ 303 , 304 305 #include "pkcs11f.h" 306 307 }; 308 309 #undef C_GetInfo 310 #undef C_GetMechanismInfo 311 #undef CK_NEED_ARG_LIST 312 #undef CK_PKCS11_FUNCTION_INFO 313 #undef CK_PKCS11_2_0_ONLY 314 315 #undef __PASTE 316 317 /* 318 * Array is orderd by default first 319 */ 320 static CK_INTERFACE fips_interfaces[] = { 321 { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v32, NSS_INTERFACE_FLAGS }, 322 { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v30, NSS_INTERFACE_FLAGS }, 323 { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v2, NSS_INTERFACE_FLAGS }, 324 { (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS }, 325 { (CK_UTF8CHAR_PTR) "Vendor NSS FIPS Interface", &sftk_fips_funcList, NSS_INTERFACE_FLAGS } 326 }; 327 /* must match the count of interfaces in fips_interfaces above*/ 328 #define FIPS_INTERFACE_COUNT PR_ARRAY_SIZE(fips_interfaces) 329 330 /* CKO_NOT_A_KEY can be any object class that's not a key object. */ 331 #define CKO_NOT_A_KEY CKO_DATA 332 333 #define SFTK_IS_KEY_OBJECT(objClass) \ 334 (((objClass) == CKO_PUBLIC_KEY) || \ 335 ((objClass) == CKO_PRIVATE_KEY) || \ 336 ((objClass) == CKO_SECRET_KEY)) 337 338 #define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \ 339 (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY)) 340 341 static CK_RV 342 sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, 343 CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) 344 { 345 CK_RV rv; 346 CK_ATTRIBUTE class; 347 class.type = CKA_CLASS; 348 class.pValue = pObjClass; 349 class.ulValueLen = sizeof(*pObjClass); 350 rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); 351 if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { 352 rv = sftk_fipsCheck(); 353 } 354 return rv; 355 } 356 357 #ifdef LINUX 358 359 int 360 sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType) 361 { 362 switch (auditType) { 363 case NSS_AUDIT_ACCESS_KEY: 364 case NSS_AUDIT_CHANGE_KEY: 365 case NSS_AUDIT_COPY_KEY: 366 case NSS_AUDIT_DERIVE_KEY: 367 case NSS_AUDIT_DESTROY_KEY: 368 case NSS_AUDIT_DIGEST_KEY: 369 case NSS_AUDIT_GENERATE_KEY: 370 case NSS_AUDIT_LOAD_KEY: 371 case NSS_AUDIT_UNWRAP_KEY: 372 case NSS_AUDIT_WRAP_KEY: 373 case NSS_AUDIT_ENCAPSULATE_KEY: 374 case NSS_AUDIT_DECAPSULATE_KEY: 375 return AUDIT_CRYPTO_KEY_USER; 376 case NSS_AUDIT_CRYPT: 377 return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER : AUDIT_CRYPTO_KEY_USER; 378 case NSS_AUDIT_FIPS_STATE: 379 case NSS_AUDIT_INIT_PIN: 380 case NSS_AUDIT_INIT_TOKEN: 381 case NSS_AUDIT_SET_PIN: 382 return AUDIT_CRYPTO_PARAM_CHANGE_USER; 383 case NSS_AUDIT_SELF_TEST: 384 return AUDIT_CRYPTO_TEST_USER; 385 case NSS_AUDIT_LOGIN: 386 return AUDIT_CRYPTO_LOGIN; 387 case NSS_AUDIT_LOGOUT: 388 return AUDIT_CRYPTO_LOGOUT; 389 /* we skip the fault case here so we can get compiler 390 * warnings if new 'NSSAuditType's are added without 391 * added them to this list, defaults fall through */ 392 } 393 /* default */ 394 return AUDIT_CRYPTO_PARAM_CHANGE_USER; 395 } 396 #endif 397 398 /********************************************************************** 399 * 400 * FIPS 140 auditable event logging 401 * 402 **********************************************************************/ 403 404 PRBool sftk_audit_enabled = PR_FALSE; 405 406 /* 407 * Each audit record must have the following information: 408 * - Date and time of the event 409 * - Type of event 410 * - user (subject) identity 411 * - outcome (success or failure) of the event 412 * - process ID 413 * - name (ID) of the object 414 * - for changes to data (except for authentication data and CSPs), the new 415 * and old values of the data 416 * - for authentication attempts, the origin of the attempt (e.g., terminal 417 * identifier) 418 * - for assuming a role, the type of role, and the location of the request 419 */ 420 void 421 sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType, 422 const char *msg) 423 { 424 #ifdef NSS_AUDIT_WITH_SYSLOG 425 int level; 426 427 switch (severity) { 428 case NSS_AUDIT_ERROR: 429 level = LOG_ERR; 430 break; 431 case NSS_AUDIT_WARNING: 432 level = LOG_WARNING; 433 break; 434 default: 435 level = LOG_INFO; 436 break; 437 } 438 /* timestamp is provided by syslog in the message header */ 439 syslog(level | LOG_USER /* facility */, 440 "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s", 441 (int)getpid(), (int)getuid(), msg); 442 #ifdef LINUX 443 if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { 444 return; 445 } 446 if (libaudit_handle) { 447 int audit_fd; 448 int linuxAuditType; 449 int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ 450 char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); 451 if (!message) { 452 return; 453 } 454 audit_fd = audit_open_func(); 455 if (audit_fd < 0) { 456 PR_smprintf_free(message); 457 return; 458 } 459 linuxAuditType = sftk_mapLinuxAuditType(severity, auditType); 460 if (audit_log_user_message_func) { 461 audit_log_user_message_func(audit_fd, linuxAuditType, message, 462 NULL, NULL, NULL, result); 463 } else { 464 audit_send_user_message_func(audit_fd, linuxAuditType, message); 465 } 466 audit_close_func(audit_fd); 467 PR_smprintf_free(message); 468 } 469 #endif /* LINUX */ 470 #else 471 /* do nothing */ 472 #endif 473 } 474 475 /********************************************************************** 476 * 477 * Start of PKCS 11 functions 478 * 479 **********************************************************************/ 480 /* return the function list */ 481 CK_RV 482 FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) 483 { 484 485 CHECK_FORK(); 486 487 *pFunctionList = &sftk_fipsTable_v2; 488 return CKR_OK; 489 } 490 491 CK_RV 492 FC_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount) 493 { 494 CK_ULONG count = *pulCount; 495 *pulCount = FIPS_INTERFACE_COUNT; 496 if (interfaces == NULL) { 497 return CKR_OK; 498 } 499 if (count < FIPS_INTERFACE_COUNT) { 500 return CKR_BUFFER_TOO_SMALL; 501 } 502 PORT_Memcpy(interfaces, fips_interfaces, sizeof(fips_interfaces)); 503 return CKR_OK; 504 } 505 506 /* 507 * Get the requested interface, use the fips_interfaces array so we can 508 * easily add new interfaces as they occur. 509 */ 510 CK_RV 511 FC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, 512 CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags) 513 { 514 int i; 515 for (i = 0; i < FIPS_INTERFACE_COUNT; i++) { 516 CK_INTERFACE_PTR interface = &fips_interfaces[i]; 517 if (pInterfaceName && PORT_Strcmp((char *)pInterfaceName, (char *)interface->pInterfaceName) != 0) { 518 continue; 519 } 520 if (pVersion && PORT_Memcmp(pVersion, (CK_VERSION *)interface->pFunctionList, sizeof(CK_VERSION)) != 0) { 521 continue; 522 } 523 if (flags & ((interface->flags & flags) != flags)) { 524 continue; 525 } 526 *ppInterface = interface; 527 return CKR_OK; 528 } 529 return CKR_ARGUMENTS_BAD; 530 } 531 532 /* sigh global so pkcs11 can read it */ 533 PRBool nsf_init = PR_FALSE; 534 535 void 536 fc_log_init_error(CK_RV crv) 537 { 538 if (sftk_audit_enabled) { 539 char msg[128]; 540 PR_snprintf(msg, sizeof msg, 541 "C_Initialize()=0x%08lX " 542 "power-up self-tests failed", 543 (PRUint32)crv); 544 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); 545 } 546 } 547 548 /* FC_Initialize initializes the PKCS #11 library. */ 549 CK_RV 550 FC_Initialize(CK_VOID_PTR pReserved) 551 { 552 const char *envp; 553 CK_RV crv; 554 PRBool rerun; 555 556 if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { 557 sftk_audit_enabled = (atoi(envp) == 1); 558 } 559 560 /* if we have the forcePOST flag on, rerun the integrity checks */ 561 /* we need to know this before we fully parse the arguments in 562 * nsc_CommonInitialize, so read it now */ 563 rerun = sftk_RawArgHasFlag("flags", "forcePost", pReserved); 564 565 /* At this point we should have already done post and integrity checks. 566 * if we haven't, it probably means the FIPS product has not been installed 567 * or the tests failed. Don't let an application try to enter FIPS mode. This 568 * also forces the tests to be rerun if forcePOST is set. */ 569 crv = sftk_FIPSEntryOK(rerun); 570 if (crv != CKR_OK) { 571 sftk_fatalError = PR_TRUE; 572 fc_log_init_error(crv); 573 return crv; 574 } 575 576 sftk_ForkReset(pReserved, &crv); 577 578 if (nsf_init) { 579 return CKR_CRYPTOKI_ALREADY_INITIALIZED; 580 } 581 582 crv = nsc_CommonInitialize(pReserved, PR_TRUE); 583 584 /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ 585 if (crv != CKR_OK) { 586 sftk_fatalError = PR_TRUE; 587 return crv; 588 } 589 590 sftk_fatalError = PR_FALSE; /* any error has been reset */ 591 nsf_init = PR_TRUE; 592 isLevel2 = PR_TRUE; /* assume level 2 unless we learn otherwise */ 593 594 return CKR_OK; 595 } 596 597 /*FC_Finalize indicates that an application is done with the PKCS #11 library.*/ 598 CK_RV 599 FC_Finalize(CK_VOID_PTR pReserved) 600 { 601 CK_RV crv; 602 603 if (sftk_ForkReset(pReserved, &crv)) { 604 return crv; 605 } 606 607 if (!nsf_init) { 608 return CKR_OK; 609 } 610 611 crv = nsc_CommonFinalize(pReserved, PR_TRUE); 612 613 nsf_init = (PRBool) !(crv == CKR_OK); 614 return crv; 615 } 616 617 /* FC_GetInfo returns general information about PKCS #11. */ 618 CK_RV 619 FC_GetInfo(CK_INFO_PTR pInfo) 620 { 621 CHECK_FORK(); 622 623 return NSC_GetInfo(pInfo); 624 } 625 626 /* FC_GetInfo returns general information about PKCS #11. */ 627 CK_RV 628 FC_GetInfoV2(CK_INFO_PTR pInfo) 629 { 630 CHECK_FORK(); 631 632 return NSC_GetInfoV2(pInfo); 633 } 634 635 /* FC_GetSlotList obtains a list of slots in the system. */ 636 CK_RV 637 FC_GetSlotList(CK_BBOOL tokenPresent, 638 CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) 639 { 640 CHECK_FORK(); 641 642 return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount, 643 NSC_FIPS_MODULE); 644 } 645 646 /* FC_GetSlotInfo obtains information about a particular slot in the system. */ 647 CK_RV 648 FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) 649 { 650 CHECK_FORK(); 651 652 return NSC_GetSlotInfo(slotID, pInfo); 653 } 654 655 /*FC_GetTokenInfo obtains information about a particular token in the system.*/ 656 CK_RV 657 FC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) 658 { 659 CK_RV crv; 660 661 CHECK_FORK(); 662 663 crv = NSC_GetTokenInfo(slotID, pInfo); 664 if (crv == CKR_OK) { 665 /* use the global database to figure out if we are running in 666 * FIPS 140 Level 1 or Level 2 */ 667 if (slotID == FIPS_SLOT_ID && 668 (pInfo->flags & CKF_LOGIN_REQUIRED) == 0) { 669 isLevel2 = PR_FALSE; 670 } 671 } 672 return crv; 673 } 674 675 /*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/ 676 CK_RV 677 FC_GetMechanismList(CK_SLOT_ID slotID, 678 CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) 679 { 680 CHECK_FORK(); 681 682 SFTK_FIPSFATALCHECK(); 683 if (sftk_isFIPS(slotID)) { 684 slotID = NETSCAPE_SLOT_ID; 685 } 686 /* FIPS Slots support all functions */ 687 return NSC_GetMechanismList(slotID, pMechanismList, pusCount); 688 } 689 690 /* FC_GetMechanismInfo obtains information about a particular mechanism 691 * possibly supported by a token. */ 692 CK_RV 693 FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 694 CK_MECHANISM_INFO_PTR pInfo) 695 { 696 CHECK_FORK(); 697 698 SFTK_FIPSFATALCHECK(); 699 if (sftk_isFIPS(slotID)) { 700 slotID = NETSCAPE_SLOT_ID; 701 } 702 /* FIPS Slots support all functions */ 703 return NSC_GetMechanismInfo(slotID, type, pInfo); 704 } 705 706 /* FC_GetMechanismInfoV2 same as FC_GetMechanismInfo except the Message 707 * flags have been stripped out */ 708 CK_RV 709 FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 710 CK_MECHANISM_INFO_PTR pInfo) 711 { 712 CHECK_FORK(); 713 714 SFTK_FIPSFATALCHECK(); 715 if (sftk_isFIPS(slotID)) { 716 slotID = NETSCAPE_SLOT_ID; 717 } 718 /* FIPS Slots support all functions */ 719 return NSC_GetMechanismInfoV2(slotID, type, pInfo); 720 } 721 722 /* FC_InitToken initializes a token. */ 723 CK_RV 724 FC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, 725 CK_ULONG usPinLen, CK_CHAR_PTR pLabel) 726 { 727 CK_RV crv; 728 729 CHECK_FORK(); 730 731 crv = NSC_InitToken(slotID, pPin, usPinLen, pLabel); 732 if (sftk_audit_enabled) { 733 char msg[128]; 734 NSSAuditSeverity severity = (crv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 735 /* pLabel points to a 32-byte label, which is not null-terminated */ 736 PR_snprintf(msg, sizeof msg, 737 "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX", 738 (PRUint32)slotID, pLabel, (PRUint32)crv); 739 sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg); 740 } 741 return crv; 742 } 743 744 /* FC_InitPIN initializes the normal user's PIN. */ 745 CK_RV 746 FC_InitPIN(CK_SESSION_HANDLE hSession, 747 CK_CHAR_PTR pPin, CK_ULONG ulPinLen) 748 { 749 CK_RV rv; 750 751 CHECK_FORK(); 752 753 if (sftk_fatalError) 754 return CKR_DEVICE_ERROR; 755 /* NSC_InitPIN will only work once per database. We can either initialize 756 * it to level1 (pin len == 0) or level2. If we initialize to level 2, then 757 * we need to make sure the pin meets FIPS requirements */ 758 if ((ulPinLen == 0) || ((rv = sftk_newPinCheck(pPin, ulPinLen)) == CKR_OK)) { 759 rv = NSC_InitPIN(hSession, pPin, ulPinLen); 760 if ((rv == CKR_OK) && 761 (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) { 762 isLevel2 = (ulPinLen > 0) ? PR_TRUE : PR_FALSE; 763 } 764 } 765 if (sftk_audit_enabled) { 766 char msg[128]; 767 NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 768 PR_snprintf(msg, sizeof msg, 769 "C_InitPIN(hSession=0x%08lX)=0x%08lX", 770 (PRUint32)hSession, (PRUint32)rv); 771 sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg); 772 } 773 return rv; 774 } 775 776 /* FC_SetPIN modifies the PIN of user that is currently logged in. */ 777 /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */ 778 CK_RV 779 FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, 780 CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) 781 { 782 CK_RV rv; 783 784 CHECK_FORK(); 785 786 rv = sftk_fipsCheck(); 787 if (rv != CKR_OK) { 788 goto loser; 789 } 790 791 if (isLevel2 || usNewLen > 0) { 792 rv = sftk_newPinCheck(pNewPin, usNewLen); 793 if (rv != CKR_OK) { 794 goto loser; 795 } 796 rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); 797 if (rv != CKR_OK) { 798 goto loser; 799 } 800 if (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID) { 801 /* if we set the password in level1 we now go 802 * to level2. NOTE: we don't allow the user to 803 * go from level2 to level1 */ 804 isLevel2 = PR_TRUE; 805 } 806 } else { 807 /* here both old and new passwords are empty, but we need to 808 * call NSC_SetPIN to force rekey the database entries */ 809 PORT_Assert(usNewLen == 0); 810 rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); 811 if (rv != CKR_OK) { 812 goto loser; 813 } 814 } 815 816 loser: 817 if (sftk_audit_enabled) { 818 char msg[128]; 819 NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 820 PR_snprintf(msg, sizeof msg, 821 "C_SetPIN(hSession=0x%08lX)=0x%08lX", 822 (PRUint32)hSession, (PRUint32)rv); 823 sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg); 824 } 825 return rv; 826 } 827 828 /* FC_OpenSession opens a session between an application and a token. */ 829 CK_RV 830 FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, 831 CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession) 832 { 833 SFTK_FIPSFATALCHECK(); 834 835 CHECK_FORK(); 836 837 return NSC_OpenSession(slotID, flags, pApplication, Notify, phSession); 838 } 839 840 /* FC_CloseSession closes a session between an application and a token. */ 841 CK_RV 842 FC_CloseSession(CK_SESSION_HANDLE hSession) 843 { 844 CHECK_FORK(); 845 846 return NSC_CloseSession(hSession); 847 } 848 849 /* FC_CloseAllSessions closes all sessions with a token. */ 850 CK_RV 851 FC_CloseAllSessions(CK_SLOT_ID slotID) 852 { 853 854 CHECK_FORK(); 855 856 return NSC_CloseAllSessions(slotID); 857 } 858 859 CK_RV 860 FC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags) 861 { 862 SFTK_FIPSFATALCHECK(); 863 864 CHECK_FORK(); 865 866 return NSC_SessionCancel(hSession, flags); 867 } 868 869 /* FC_GetSessionInfo obtains information about the session. */ 870 CK_RV 871 FC_GetSessionInfo(CK_SESSION_HANDLE hSession, 872 CK_SESSION_INFO_PTR pInfo) 873 { 874 CK_RV rv; 875 SFTK_FIPSFATALCHECK(); 876 877 CHECK_FORK(); 878 879 rv = NSC_GetSessionInfo(hSession, pInfo); 880 if (rv == CKR_OK) { 881 /* handle the case where the auxilary slot doesn't require login. 882 * piggy back on the main token's login state */ 883 if (isLoggedIn && 884 ((pInfo->state == CKS_RO_PUBLIC_SESSION) || 885 (pInfo->state == CKS_RW_PUBLIC_SESSION))) { 886 CK_RV crv; 887 CK_TOKEN_INFO tInfo; 888 crv = NSC_GetTokenInfo(sftk_SlotIDFromSessionHandle(hSession), 889 &tInfo); 890 /* if the token doesn't login, use our global login state */ 891 if ((crv == CKR_OK) && ((tInfo.flags & CKF_LOGIN_REQUIRED) == 0)) { 892 if (pInfo->state == CKS_RO_PUBLIC_SESSION) { 893 pInfo->state = CKS_RO_USER_FUNCTIONS; 894 } else { 895 pInfo->state = CKS_RW_USER_FUNCTIONS; 896 } 897 } 898 } 899 } 900 return rv; 901 } 902 903 /* FC_Login logs a user into a token. */ 904 CK_RV 905 FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, 906 CK_CHAR_PTR pPin, CK_ULONG usPinLen) 907 { 908 CK_RV rv; 909 PRBool successful; 910 if (sftk_fatalError) 911 return CKR_DEVICE_ERROR; 912 rv = NSC_Login(hSession, userType, pPin, usPinLen); 913 successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); 914 if (successful) 915 isLoggedIn = PR_TRUE; 916 if (sftk_audit_enabled) { 917 char msg[128]; 918 NSSAuditSeverity severity; 919 severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 920 PR_snprintf(msg, sizeof msg, 921 "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", 922 (PRUint32)hSession, (PRUint32)userType, (PRUint32)rv); 923 sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg); 924 } 925 return rv; 926 } 927 928 CK_RV 929 FC_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, 930 CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername, 931 CK_ULONG ulUsernameLen) 932 { 933 CK_RV rv; 934 PRBool successful; 935 if (sftk_fatalError) 936 return CKR_DEVICE_ERROR; 937 rv = NSC_LoginUser(hSession, userType, pPin, ulPinLen, 938 pUsername, ulUsernameLen); 939 successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); 940 if (successful) 941 isLoggedIn = PR_TRUE; 942 if (sftk_audit_enabled) { 943 char msg[128]; 944 char user[61]; 945 int len = PR_MIN(ulUsernameLen, sizeof(user) - 1); 946 PORT_Memcpy(user, pUsername, len); 947 user[len] = 0; 948 NSSAuditSeverity severity; 949 severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 950 PR_snprintf(msg, sizeof msg, 951 "C_LoginUser(hSession=0x%08lX, userType=%lu username=%s)=0x%08lX", 952 (PRUint32)hSession, (PRUint32)userType, user, (PRUint32)rv); 953 sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg); 954 } 955 return rv; 956 } 957 958 /* FC_Logout logs a user out from a token. */ 959 CK_RV 960 FC_Logout(CK_SESSION_HANDLE hSession) 961 { 962 CK_RV rv; 963 964 CHECK_FORK(); 965 966 if ((rv = sftk_fipsCheck()) == CKR_OK) { 967 rv = NSC_Logout(hSession); 968 isLoggedIn = PR_FALSE; 969 } 970 if (sftk_audit_enabled) { 971 char msg[128]; 972 NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 973 PR_snprintf(msg, sizeof msg, 974 "C_Logout(hSession=0x%08lX)=0x%08lX", 975 (PRUint32)hSession, (PRUint32)rv); 976 sftk_LogAuditMessage(severity, NSS_AUDIT_LOGOUT, msg); 977 } 978 return rv; 979 } 980 981 /* FC_CreateObject creates a new object. */ 982 CK_RV 983 FC_CreateObject(CK_SESSION_HANDLE hSession, 984 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 985 CK_OBJECT_HANDLE_PTR phObject) 986 { 987 CK_OBJECT_CLASS *classptr; 988 CK_RV rv = CKR_OK; 989 990 CHECK_FORK(); 991 992 classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate, ulCount, CKA_CLASS); 993 if (classptr == NULL) 994 return CKR_TEMPLATE_INCOMPLETE; 995 996 if (*classptr == CKO_NSS_NEWSLOT || *classptr == CKO_NSS_DELSLOT) { 997 if (sftk_fatalError) 998 return CKR_DEVICE_ERROR; 999 } else { 1000 rv = sftk_fipsCheck(); 1001 if (rv != CKR_OK) 1002 return rv; 1003 } 1004 1005 /* FIPS can't create keys from raw key material */ 1006 if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { 1007 rv = CKR_ATTRIBUTE_VALUE_INVALID; 1008 } else { 1009 rv = NSC_CreateObject(hSession, pTemplate, ulCount, phObject); 1010 } 1011 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { 1012 sftk_AuditCreateObject(hSession, pTemplate, ulCount, phObject, rv); 1013 } 1014 return rv; 1015 } 1016 1017 /* FC_CopyObject copies an object, creating a new object for the copy. */ 1018 CK_RV 1019 FC_CopyObject(CK_SESSION_HANDLE hSession, 1020 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 1021 CK_OBJECT_HANDLE_PTR phNewObject) 1022 { 1023 CK_RV rv; 1024 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1025 1026 CHECK_FORK(); 1027 1028 SFTK_FIPSFATALCHECK(); 1029 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1030 if (rv == CKR_OK) { 1031 rv = NSC_CopyObject(hSession, hObject, pTemplate, ulCount, phNewObject); 1032 } 1033 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1034 sftk_AuditCopyObject(hSession, 1035 hObject, pTemplate, ulCount, phNewObject, rv); 1036 } 1037 return rv; 1038 } 1039 1040 /* FC_DestroyObject destroys an object. */ 1041 CK_RV 1042 FC_DestroyObject(CK_SESSION_HANDLE hSession, 1043 CK_OBJECT_HANDLE hObject) 1044 { 1045 CK_RV rv; 1046 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1047 1048 CHECK_FORK(); 1049 1050 SFTK_FIPSFATALCHECK(); 1051 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1052 if (rv == CKR_OK) { 1053 rv = NSC_DestroyObject(hSession, hObject); 1054 } 1055 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1056 sftk_AuditDestroyObject(hSession, hObject, rv); 1057 } 1058 return rv; 1059 } 1060 1061 /* FC_GetObjectSize gets the size of an object in bytes. */ 1062 CK_RV 1063 FC_GetObjectSize(CK_SESSION_HANDLE hSession, 1064 CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) 1065 { 1066 CK_RV rv; 1067 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1068 1069 CHECK_FORK(); 1070 1071 SFTK_FIPSFATALCHECK(); 1072 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1073 if (rv == CKR_OK) { 1074 rv = NSC_GetObjectSize(hSession, hObject, pulSize); 1075 } 1076 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1077 sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv); 1078 } 1079 return rv; 1080 } 1081 1082 /* FC_GetAttributeValue obtains the value of one or more object attributes. */ 1083 CK_RV 1084 FC_GetAttributeValue(CK_SESSION_HANDLE hSession, 1085 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) 1086 { 1087 CK_RV rv; 1088 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1089 1090 CHECK_FORK(); 1091 1092 SFTK_FIPSFATALCHECK(); 1093 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1094 if (rv == CKR_OK) { 1095 rv = NSC_GetAttributeValue(hSession, hObject, pTemplate, ulCount); 1096 } 1097 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1098 sftk_AuditGetAttributeValue(hSession, hObject, pTemplate, ulCount, rv); 1099 } 1100 return rv; 1101 } 1102 1103 /* FC_SetAttributeValue modifies the value of one or more object attributes */ 1104 CK_RV 1105 FC_SetAttributeValue(CK_SESSION_HANDLE hSession, 1106 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) 1107 { 1108 CK_RV rv; 1109 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1110 1111 CHECK_FORK(); 1112 1113 SFTK_FIPSFATALCHECK(); 1114 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1115 if (rv == CKR_OK) { 1116 rv = NSC_SetAttributeValue(hSession, hObject, pTemplate, ulCount); 1117 } 1118 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1119 sftk_AuditSetAttributeValue(hSession, hObject, pTemplate, ulCount, rv); 1120 } 1121 return rv; 1122 } 1123 1124 /* FC_FindObjectsInit initializes a search for token and session objects 1125 * that match a template. */ 1126 CK_RV 1127 FC_FindObjectsInit(CK_SESSION_HANDLE hSession, 1128 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) 1129 { 1130 /* let publically readable object be found */ 1131 unsigned int i; 1132 CK_RV rv; 1133 PRBool needLogin = PR_FALSE; 1134 1135 CHECK_FORK(); 1136 1137 SFTK_FIPSFATALCHECK(); 1138 1139 for (i = 0; i < usCount; i++) { 1140 CK_OBJECT_CLASS class; 1141 if (pTemplate[i].type != CKA_CLASS) { 1142 continue; 1143 } 1144 if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) { 1145 continue; 1146 } 1147 if (pTemplate[i].pValue == NULL) { 1148 continue; 1149 } 1150 class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; 1151 if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) { 1152 needLogin = PR_TRUE; 1153 break; 1154 } 1155 } 1156 if (needLogin) { 1157 if ((rv = sftk_fipsCheck()) != CKR_OK) 1158 return rv; 1159 } 1160 return NSC_FindObjectsInit(hSession, pTemplate, usCount); 1161 } 1162 1163 /* FC_FindObjects continues a search for token and session objects 1164 * that match a template, obtaining additional object handles. */ 1165 CK_RV 1166 FC_FindObjects(CK_SESSION_HANDLE hSession, 1167 CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, 1168 CK_ULONG_PTR pusObjectCount) 1169 { 1170 CHECK_FORK(); 1171 1172 /* let publically readable object be found */ 1173 SFTK_FIPSFATALCHECK(); 1174 return NSC_FindObjects(hSession, phObject, usMaxObjectCount, 1175 pusObjectCount); 1176 } 1177 1178 /* 1179 ************** Crypto Functions: Encrypt ************************ 1180 */ 1181 1182 /* FC_EncryptInit initializes an encryption operation. */ 1183 CK_RV 1184 FC_EncryptInit(CK_SESSION_HANDLE hSession, 1185 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1186 { 1187 SFTK_FIPSCHECK(); 1188 CHECK_FORK(); 1189 1190 rv = NSC_EncryptInit(hSession, pMechanism, hKey); 1191 if (sftk_audit_enabled) { 1192 sftk_AuditCryptInit("Encrypt", hSession, pMechanism, hKey, rv); 1193 } 1194 return rv; 1195 } 1196 1197 /* FC_Encrypt encrypts single-part data. */ 1198 CK_RV 1199 FC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1200 CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, 1201 CK_ULONG_PTR pusEncryptedDataLen) 1202 { 1203 SFTK_FIPSCHECK(); 1204 CHECK_FORK(); 1205 1206 return NSC_Encrypt(hSession, pData, usDataLen, pEncryptedData, 1207 pusEncryptedDataLen); 1208 } 1209 1210 /* FC_EncryptUpdate continues a multiple-part encryption operation. */ 1211 CK_RV 1212 FC_EncryptUpdate(CK_SESSION_HANDLE hSession, 1213 CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, 1214 CK_ULONG_PTR pusEncryptedPartLen) 1215 { 1216 SFTK_FIPSCHECK(); 1217 CHECK_FORK(); 1218 1219 return NSC_EncryptUpdate(hSession, pPart, usPartLen, pEncryptedPart, 1220 pusEncryptedPartLen); 1221 } 1222 1223 /* FC_EncryptFinal finishes a multiple-part encryption operation. */ 1224 CK_RV 1225 FC_EncryptFinal(CK_SESSION_HANDLE hSession, 1226 CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) 1227 { 1228 SFTK_FIPSCHECK(); 1229 CHECK_FORK(); 1230 1231 return NSC_EncryptFinal(hSession, pLastEncryptedPart, 1232 pusLastEncryptedPartLen); 1233 } 1234 1235 /* 1236 ************** Crypto Functions: Decrypt ************************ 1237 */ 1238 1239 /* FC_DecryptInit initializes a decryption operation. */ 1240 CK_RV 1241 FC_DecryptInit(CK_SESSION_HANDLE hSession, 1242 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1243 { 1244 SFTK_FIPSCHECK(); 1245 CHECK_FORK(); 1246 1247 rv = NSC_DecryptInit(hSession, pMechanism, hKey); 1248 if (sftk_audit_enabled) { 1249 sftk_AuditCryptInit("Decrypt", hSession, pMechanism, hKey, rv); 1250 } 1251 return rv; 1252 } 1253 1254 /* FC_Decrypt decrypts encrypted data in a single part. */ 1255 CK_RV 1256 FC_Decrypt(CK_SESSION_HANDLE hSession, 1257 CK_BYTE_PTR pEncryptedData, CK_ULONG usEncryptedDataLen, CK_BYTE_PTR pData, 1258 CK_ULONG_PTR pusDataLen) 1259 { 1260 SFTK_FIPSCHECK(); 1261 CHECK_FORK(); 1262 1263 return NSC_Decrypt(hSession, pEncryptedData, usEncryptedDataLen, pData, 1264 pusDataLen); 1265 } 1266 1267 /* FC_DecryptUpdate continues a multiple-part decryption operation. */ 1268 CK_RV 1269 FC_DecryptUpdate(CK_SESSION_HANDLE hSession, 1270 CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, 1271 CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) 1272 { 1273 SFTK_FIPSCHECK(); 1274 CHECK_FORK(); 1275 1276 return NSC_DecryptUpdate(hSession, pEncryptedPart, usEncryptedPartLen, 1277 pPart, pusPartLen); 1278 } 1279 1280 /* FC_DecryptFinal finishes a multiple-part decryption operation. */ 1281 CK_RV 1282 FC_DecryptFinal(CK_SESSION_HANDLE hSession, 1283 CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) 1284 { 1285 SFTK_FIPSCHECK(); 1286 CHECK_FORK(); 1287 1288 return NSC_DecryptFinal(hSession, pLastPart, pusLastPartLen); 1289 } 1290 1291 /* 1292 ************** Crypto Functions: Digest (HASH) ************************ 1293 */ 1294 1295 /* FC_DigestInit initializes a message-digesting operation. */ 1296 CK_RV 1297 FC_DigestInit(CK_SESSION_HANDLE hSession, 1298 CK_MECHANISM_PTR pMechanism) 1299 { 1300 SFTK_FIPSFATALCHECK(); 1301 CHECK_FORK(); 1302 1303 return NSC_DigestInit(hSession, pMechanism); 1304 } 1305 1306 /* FC_Digest digests data in a single part. */ 1307 CK_RV 1308 FC_Digest(CK_SESSION_HANDLE hSession, 1309 CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, 1310 CK_ULONG_PTR pusDigestLen) 1311 { 1312 SFTK_FIPSFATALCHECK(); 1313 CHECK_FORK(); 1314 1315 return NSC_Digest(hSession, pData, usDataLen, pDigest, pusDigestLen); 1316 } 1317 1318 /* FC_DigestUpdate continues a multiple-part message-digesting operation. */ 1319 CK_RV 1320 FC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1321 CK_ULONG usPartLen) 1322 { 1323 SFTK_FIPSFATALCHECK(); 1324 CHECK_FORK(); 1325 1326 return NSC_DigestUpdate(hSession, pPart, usPartLen); 1327 } 1328 1329 /* FC_DigestFinal finishes a multiple-part message-digesting operation. */ 1330 CK_RV 1331 FC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, 1332 CK_ULONG_PTR pusDigestLen) 1333 { 1334 SFTK_FIPSFATALCHECK(); 1335 CHECK_FORK(); 1336 1337 return NSC_DigestFinal(hSession, pDigest, pusDigestLen); 1338 } 1339 1340 /* 1341 ************** Crypto Functions: Sign ************************ 1342 */ 1343 1344 /* FC_SignInit initializes a signature (private key encryption) operation, 1345 * where the signature is (will be) an appendix to the data, 1346 * and plaintext cannot be recovered from the signature */ 1347 CK_RV 1348 FC_SignInit(CK_SESSION_HANDLE hSession, 1349 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1350 { 1351 SFTK_FIPSCHECK(); 1352 CHECK_FORK(); 1353 1354 rv = NSC_SignInit(hSession, pMechanism, hKey); 1355 if (sftk_audit_enabled) { 1356 sftk_AuditCryptInit("Sign", hSession, pMechanism, hKey, rv); 1357 } 1358 return rv; 1359 } 1360 1361 /* FC_Sign signs (encrypts with private key) data in a single part, 1362 * where the signature is (will be) an appendix to the data, 1363 * and plaintext cannot be recovered from the signature */ 1364 CK_RV 1365 FC_Sign(CK_SESSION_HANDLE hSession, 1366 CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, 1367 CK_ULONG_PTR pusSignatureLen) 1368 { 1369 SFTK_FIPSCHECK(); 1370 CHECK_FORK(); 1371 1372 return NSC_Sign(hSession, pData, usDataLen, pSignature, pusSignatureLen); 1373 } 1374 1375 /* FC_SignUpdate continues a multiple-part signature operation, 1376 * where the signature is (will be) an appendix to the data, 1377 * and plaintext cannot be recovered from the signature */ 1378 CK_RV 1379 FC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1380 CK_ULONG usPartLen) 1381 { 1382 SFTK_FIPSCHECK(); 1383 CHECK_FORK(); 1384 1385 return NSC_SignUpdate(hSession, pPart, usPartLen); 1386 } 1387 1388 /* FC_SignFinal finishes a multiple-part signature operation, 1389 * returning the signature. */ 1390 CK_RV 1391 FC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, 1392 CK_ULONG_PTR pusSignatureLen) 1393 { 1394 SFTK_FIPSCHECK(); 1395 CHECK_FORK(); 1396 1397 return NSC_SignFinal(hSession, pSignature, pusSignatureLen); 1398 } 1399 1400 /* 1401 ************** Crypto Functions: Sign Recover ************************ 1402 */ 1403 /* FC_SignRecoverInit initializes a signature operation, 1404 * where the (digest) data can be recovered from the signature. 1405 * E.g. encryption with the user's private key */ 1406 CK_RV 1407 FC_SignRecoverInit(CK_SESSION_HANDLE hSession, 1408 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1409 { 1410 SFTK_FIPSCHECK(); 1411 CHECK_FORK(); 1412 1413 rv = NSC_SignRecoverInit(hSession, pMechanism, hKey); 1414 if (sftk_audit_enabled) { 1415 sftk_AuditCryptInit("SignRecover", hSession, pMechanism, hKey, rv); 1416 } 1417 return rv; 1418 } 1419 1420 /* FC_SignRecover signs data in a single operation 1421 * where the (digest) data can be recovered from the signature. 1422 * E.g. encryption with the user's private key */ 1423 CK_RV 1424 FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1425 CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) 1426 { 1427 SFTK_FIPSCHECK(); 1428 CHECK_FORK(); 1429 1430 return NSC_SignRecover(hSession, pData, usDataLen, pSignature, pusSignatureLen); 1431 } 1432 1433 /* 1434 ************** Crypto Functions: verify ************************ 1435 */ 1436 1437 /* FC_VerifyInit initializes a verification operation, 1438 * where the signature is an appendix to the data, 1439 * and plaintext cannot be recovered from the signature (e.g. DSA) */ 1440 CK_RV 1441 FC_VerifyInit(CK_SESSION_HANDLE hSession, 1442 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1443 { 1444 SFTK_FIPSCHECK(); 1445 CHECK_FORK(); 1446 1447 rv = NSC_VerifyInit(hSession, pMechanism, hKey); 1448 if (sftk_audit_enabled) { 1449 sftk_AuditCryptInit("Verify", hSession, pMechanism, hKey, rv); 1450 } 1451 return rv; 1452 } 1453 1454 /* FC_Verify verifies a signature in a single-part operation, 1455 * where the signature is an appendix to the data, 1456 * and plaintext cannot be recovered from the signature */ 1457 CK_RV 1458 FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1459 CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) 1460 { 1461 /* make sure we're legal */ 1462 SFTK_FIPSCHECK(); 1463 CHECK_FORK(); 1464 1465 return NSC_Verify(hSession, pData, usDataLen, pSignature, usSignatureLen); 1466 } 1467 1468 /* FC_VerifyUpdate continues a multiple-part verification operation, 1469 * where the signature is an appendix to the data, 1470 * and plaintext cannot be recovered from the signature */ 1471 CK_RV 1472 FC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1473 CK_ULONG usPartLen) 1474 { 1475 SFTK_FIPSCHECK(); 1476 CHECK_FORK(); 1477 1478 return NSC_VerifyUpdate(hSession, pPart, usPartLen); 1479 } 1480 1481 /* FC_VerifyFinal finishes a multiple-part verification operation, 1482 * checking the signature. */ 1483 CK_RV 1484 FC_VerifyFinal(CK_SESSION_HANDLE hSession, 1485 CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) 1486 { 1487 SFTK_FIPSCHECK(); 1488 CHECK_FORK(); 1489 1490 return NSC_VerifyFinal(hSession, pSignature, usSignatureLen); 1491 } 1492 1493 /* 1494 ************** Crypto Functions: Verify Signature ************************ 1495 * some algorithms need the signature at the beginning of the verification, 1496 * VerifySignature provides such and API. For algorithms that don't need 1497 * the signature first, we stash the signature and just pass it to 1498 * NSC_VerifyXXX. 1499 */ 1500 CK_RV 1501 FC_VerifySignatureInit(CK_SESSION_HANDLE hSession, 1502 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, 1503 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) 1504 { 1505 SFTK_FIPSCHECK(); 1506 CHECK_FORK(); 1507 1508 rv = NSC_VerifySignatureInit(hSession, pMechanism, hKey, 1509 pSignature, ulSignatureLen); 1510 if (sftk_audit_enabled) { 1511 sftk_AuditCryptInit("VerifySignature", hSession, pMechanism, hKey, rv); 1512 } 1513 return rv; 1514 } 1515 1516 CK_RV 1517 FC_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1518 CK_ULONG ulDataLen) 1519 { 1520 SFTK_FIPSCHECK(); 1521 CHECK_FORK(); 1522 1523 return NSC_VerifySignature(hSession, pData, ulDataLen); 1524 } 1525 1526 CK_RV 1527 FC_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1528 CK_ULONG ulPartLen) 1529 { 1530 SFTK_FIPSCHECK(); 1531 CHECK_FORK(); 1532 1533 return NSC_VerifySignatureUpdate(hSession, pPart, ulPartLen); 1534 } 1535 1536 CK_RV 1537 FC_VerifySignatureFinal(CK_SESSION_HANDLE hSession) 1538 { 1539 SFTK_FIPSCHECK(); 1540 CHECK_FORK(); 1541 1542 return NSC_VerifySignatureFinal(hSession); 1543 } 1544 1545 /* 1546 ************** Crypto Functions: Verify Recover ************************ 1547 */ 1548 1549 /* FC_VerifyRecoverInit initializes a signature verification operation, 1550 * where the data is recovered from the signature. 1551 * E.g. Decryption with the user's public key */ 1552 CK_RV 1553 FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, 1554 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1555 { 1556 SFTK_FIPSCHECK(); 1557 CHECK_FORK(); 1558 1559 rv = NSC_VerifyRecoverInit(hSession, pMechanism, hKey); 1560 if (sftk_audit_enabled) { 1561 sftk_AuditCryptInit("VerifyRecover", hSession, pMechanism, hKey, rv); 1562 } 1563 return rv; 1564 } 1565 1566 /* FC_VerifyRecover verifies a signature in a single-part operation, 1567 * where the data is recovered from the signature. 1568 * E.g. Decryption with the user's public key */ 1569 CK_RV 1570 FC_VerifyRecover(CK_SESSION_HANDLE hSession, 1571 CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen, 1572 CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen) 1573 { 1574 SFTK_FIPSCHECK(); 1575 CHECK_FORK(); 1576 1577 return NSC_VerifyRecover(hSession, pSignature, usSignatureLen, pData, 1578 pusDataLen); 1579 } 1580 1581 /* 1582 **************************** Key Functions: ************************ 1583 */ 1584 1585 /* FC_GenerateKey generates a secret key, creating a new key object. */ 1586 CK_RV 1587 FC_GenerateKey(CK_SESSION_HANDLE hSession, 1588 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 1589 CK_OBJECT_HANDLE_PTR phKey) 1590 { 1591 CK_BBOOL *boolptr; 1592 1593 SFTK_FIPSCHECK(); 1594 CHECK_FORK(); 1595 1596 /* all secret keys must be sensitive, if the upper level code tries to say 1597 * otherwise, reject it. */ 1598 boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE); 1599 if (boolptr != NULL) { 1600 if (!(*boolptr)) { 1601 return CKR_ATTRIBUTE_VALUE_INVALID; 1602 } 1603 } 1604 1605 rv = NSC_GenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey); 1606 if (sftk_audit_enabled) { 1607 sftk_AuditGenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey, rv); 1608 } 1609 return rv; 1610 } 1611 1612 /* FC_GenerateKeyPair generates a public-key/private-key pair, 1613 * creating new key objects. */ 1614 CK_RV 1615 FC_GenerateKeyPair(CK_SESSION_HANDLE hSession, 1616 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, 1617 CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, 1618 CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, 1619 CK_OBJECT_HANDLE_PTR phPrivateKey) 1620 { 1621 CK_BBOOL *boolptr; 1622 CK_RV crv; 1623 1624 SFTK_FIPSCHECK(); 1625 CHECK_FORK(); 1626 1627 /* all private keys must be sensitive, if the upper level code tries to say 1628 * otherwise, reject it. */ 1629 boolptr = (CK_BBOOL *)fc_getAttribute(pPrivateKeyTemplate, 1630 usPrivateKeyAttributeCount, CKA_SENSITIVE); 1631 if (boolptr != NULL) { 1632 if (!(*boolptr)) { 1633 return CKR_ATTRIBUTE_VALUE_INVALID; 1634 } 1635 } 1636 crv = NSC_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate, 1637 usPublicKeyAttributeCount, pPrivateKeyTemplate, 1638 usPrivateKeyAttributeCount, phPublicKey, phPrivateKey); 1639 if (crv == CKR_GENERAL_ERROR) { 1640 /* pairwise consistency check failed. */ 1641 sftk_fatalError = PR_TRUE; 1642 } 1643 if (sftk_audit_enabled) { 1644 sftk_AuditGenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate, 1645 usPublicKeyAttributeCount, pPrivateKeyTemplate, 1646 usPrivateKeyAttributeCount, phPublicKey, phPrivateKey, crv); 1647 } 1648 return crv; 1649 } 1650 1651 /* FC_WrapKey wraps (i.e., encrypts) a key. */ 1652 CK_RV 1653 FC_WrapKey(CK_SESSION_HANDLE hSession, 1654 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, 1655 CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, 1656 CK_ULONG_PTR pulWrappedKeyLen) 1657 { 1658 SFTK_FIPSCHECK(); 1659 CHECK_FORK(); 1660 1661 rv = NSC_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, 1662 pulWrappedKeyLen); 1663 if (sftk_audit_enabled) { 1664 sftk_AuditWrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, 1665 pulWrappedKeyLen, rv); 1666 } 1667 return rv; 1668 } 1669 1670 /* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ 1671 CK_RV 1672 FC_UnwrapKey(CK_SESSION_HANDLE hSession, 1673 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, 1674 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, 1675 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 1676 CK_OBJECT_HANDLE_PTR phKey) 1677 { 1678 CK_BBOOL *boolptr; 1679 1680 SFTK_FIPSCHECK(); 1681 CHECK_FORK(); 1682 1683 /* all secret keys must be sensitive, if the upper level code tries to say 1684 * otherwise, reject it. */ 1685 boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, 1686 ulAttributeCount, CKA_SENSITIVE); 1687 if (boolptr != NULL) { 1688 if (!(*boolptr)) { 1689 return CKR_ATTRIBUTE_VALUE_INVALID; 1690 } 1691 } 1692 rv = NSC_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, 1693 ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey); 1694 if (sftk_audit_enabled) { 1695 sftk_AuditUnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, 1696 ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey, rv); 1697 } 1698 return rv; 1699 } 1700 1701 /* FC_DeriveKey derives a key from a base key, creating a new key object. */ 1702 CK_RV 1703 FC_DeriveKey(CK_SESSION_HANDLE hSession, 1704 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, 1705 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 1706 CK_OBJECT_HANDLE_PTR phKey) 1707 { 1708 CK_BBOOL *boolptr; 1709 1710 SFTK_FIPSCHECK(); 1711 CHECK_FORK(); 1712 1713 /* all secret keys must be sensitive, if the upper level code tries to say 1714 * otherwise, reject it. */ 1715 boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, 1716 ulAttributeCount, CKA_SENSITIVE); 1717 if (boolptr != NULL) { 1718 if (!(*boolptr)) { 1719 return CKR_ATTRIBUTE_VALUE_INVALID; 1720 } 1721 } 1722 rv = NSC_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, 1723 ulAttributeCount, phKey); 1724 if (sftk_audit_enabled) { 1725 sftk_AuditDeriveKey(hSession, pMechanism, hBaseKey, pTemplate, 1726 ulAttributeCount, phKey, rv); 1727 } 1728 return rv; 1729 } 1730 1731 /* 1732 **************************** Radom Functions: ************************ 1733 */ 1734 1735 /* FC_SeedRandom mixes additional seed material into the token's random number 1736 * generator. */ 1737 CK_RV 1738 FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, 1739 CK_ULONG usSeedLen) 1740 { 1741 CK_RV crv; 1742 1743 SFTK_FIPSFATALCHECK(); 1744 CHECK_FORK(); 1745 1746 crv = NSC_SeedRandom(hSession, pSeed, usSeedLen); 1747 if (crv != CKR_OK) { 1748 sftk_fatalError = PR_TRUE; 1749 } 1750 return crv; 1751 } 1752 1753 /* FC_GenerateRandom generates random data. */ 1754 CK_RV 1755 FC_GenerateRandom(CK_SESSION_HANDLE hSession, 1756 CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) 1757 { 1758 CK_RV crv; 1759 1760 CHECK_FORK(); 1761 1762 SFTK_FIPSFATALCHECK(); 1763 crv = NSC_GenerateRandom(hSession, pRandomData, ulRandomLen); 1764 if (crv != CKR_OK) { 1765 sftk_fatalError = PR_TRUE; 1766 if (sftk_audit_enabled) { 1767 char msg[128]; 1768 PR_snprintf(msg, sizeof msg, 1769 "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " 1770 "ulRandomLen=%lu)=0x%08lX " 1771 "self-test: continuous RNG test failed", 1772 (PRUint32)hSession, pRandomData, 1773 (PRUint32)ulRandomLen, (PRUint32)crv); 1774 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); 1775 } 1776 } 1777 return crv; 1778 } 1779 1780 /* FC_GetFunctionStatus obtains an updated status of a function running 1781 * in parallel with an application. */ 1782 CK_RV 1783 FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) 1784 { 1785 SFTK_FIPSCHECK(); 1786 CHECK_FORK(); 1787 1788 return NSC_GetFunctionStatus(hSession); 1789 } 1790 1791 /* FC_CancelFunction cancels a function running in parallel */ 1792 CK_RV 1793 FC_CancelFunction(CK_SESSION_HANDLE hSession) 1794 { 1795 SFTK_FIPSCHECK(); 1796 CHECK_FORK(); 1797 1798 return NSC_CancelFunction(hSession); 1799 } 1800 1801 /* 1802 **************************** Version 1.1 Functions: ************************ 1803 */ 1804 1805 /* FC_GetOperationState saves the state of the cryptographic 1806 *operation in a session. */ 1807 CK_RV 1808 FC_GetOperationState(CK_SESSION_HANDLE hSession, 1809 CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) 1810 { 1811 SFTK_FIPSFATALCHECK(); 1812 CHECK_FORK(); 1813 1814 return NSC_GetOperationState(hSession, pOperationState, pulOperationStateLen); 1815 } 1816 1817 /* FC_SetOperationState restores the state of the cryptographic operation 1818 * in a session. */ 1819 CK_RV 1820 FC_SetOperationState(CK_SESSION_HANDLE hSession, 1821 CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, 1822 CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) 1823 { 1824 SFTK_FIPSFATALCHECK(); 1825 CHECK_FORK(); 1826 1827 return NSC_SetOperationState(hSession, pOperationState, ulOperationStateLen, 1828 hEncryptionKey, hAuthenticationKey); 1829 } 1830 1831 /* FC_FindObjectsFinal finishes a search for token and session objects. */ 1832 CK_RV 1833 FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) 1834 { 1835 /* let publically readable object be found */ 1836 SFTK_FIPSFATALCHECK(); 1837 CHECK_FORK(); 1838 1839 return NSC_FindObjectsFinal(hSession); 1840 } 1841 1842 /* Dual-function cryptographic operations */ 1843 1844 /* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption 1845 * operation. */ 1846 CK_RV 1847 FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1848 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 1849 CK_ULONG_PTR pulEncryptedPartLen) 1850 { 1851 SFTK_FIPSCHECK(); 1852 CHECK_FORK(); 1853 1854 return NSC_DigestEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, 1855 pulEncryptedPartLen); 1856 } 1857 1858 /* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting 1859 * operation. */ 1860 CK_RV 1861 FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, 1862 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, 1863 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) 1864 { 1865 SFTK_FIPSCHECK(); 1866 CHECK_FORK(); 1867 1868 return NSC_DecryptDigestUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, 1869 pPart, pulPartLen); 1870 } 1871 1872 /* FC_SignEncryptUpdate continues a multiple-part signing and encryption 1873 * operation. */ 1874 CK_RV 1875 FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1876 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 1877 CK_ULONG_PTR pulEncryptedPartLen) 1878 { 1879 SFTK_FIPSCHECK(); 1880 CHECK_FORK(); 1881 1882 return NSC_SignEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, 1883 pulEncryptedPartLen); 1884 } 1885 1886 /* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify 1887 * operation. */ 1888 CK_RV 1889 FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, 1890 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, 1891 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) 1892 { 1893 SFTK_FIPSCHECK(); 1894 CHECK_FORK(); 1895 1896 return NSC_DecryptVerifyUpdate(hSession, pEncryptedData, ulEncryptedDataLen, 1897 pData, pulDataLen); 1898 } 1899 1900 /* FC_DigestKey continues a multi-part message-digesting operation, 1901 * by digesting the value of a secret key as part of the data already digested. 1902 */ 1903 CK_RV 1904 FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) 1905 { 1906 SFTK_FIPSCHECK(); 1907 CHECK_FORK(); 1908 1909 rv = NSC_DigestKey(hSession, hKey); 1910 if (sftk_audit_enabled) { 1911 sftk_AuditDigestKey(hSession, hKey, rv); 1912 } 1913 return rv; 1914 } 1915 1916 CK_RV 1917 FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, 1918 CK_VOID_PTR pReserved) 1919 { 1920 CHECK_FORK(); 1921 1922 return NSC_WaitForSlotEvent(flags, pSlot, pReserved); 1923 } 1924 1925 CK_RV 1926 FC_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 1927 CK_OBJECT_HANDLE hKey) 1928 { 1929 SFTK_FIPSCHECK(); 1930 CHECK_FORK(); 1931 1932 rv = NSC_MessageEncryptInit(hSession, pMechanism, hKey); 1933 if (sftk_audit_enabled) { 1934 sftk_AuditCryptInit("MessageEncrypt", hSession, pMechanism, hKey, rv); 1935 } 1936 return rv; 1937 } 1938 1939 CK_RV 1940 FC_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 1941 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 1942 CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, 1943 CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, 1944 CK_ULONG_PTR pulCiphertextLen) 1945 { 1946 SFTK_FIPSCHECK(); 1947 CHECK_FORK(); 1948 return NSC_EncryptMessage(hSession, pParameter, ulParameterLen, 1949 pAssociatedData, ulAssociatedDataLen, 1950 pPlaintext, ulPlaintextLen, pCiphertext, 1951 pulCiphertextLen); 1952 } 1953 1954 CK_RV 1955 FC_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 1956 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 1957 CK_ULONG ulAssociatedDataLen) 1958 { 1959 SFTK_FIPSCHECK(); 1960 CHECK_FORK(); 1961 return NSC_EncryptMessageBegin(hSession, pParameter, ulParameterLen, 1962 pAssociatedData, ulAssociatedDataLen); 1963 } 1964 1965 CK_RV 1966 FC_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 1967 CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, 1968 CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, 1969 CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags) 1970 { 1971 SFTK_FIPSCHECK(); 1972 CHECK_FORK(); 1973 return NSC_EncryptMessageNext(hSession, pParameter, ulParameterLen, 1974 pPlaintextPart, ulPlaintextPartLen, 1975 pCiphertextPart, pulCiphertextPartLen, flags); 1976 } 1977 1978 CK_RV 1979 FC_MessageEncryptFinal(CK_SESSION_HANDLE hSession) 1980 { 1981 SFTK_FIPSCHECK(); 1982 CHECK_FORK(); 1983 return NSC_MessageEncryptFinal(hSession); 1984 } 1985 1986 CK_RV 1987 FC_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 1988 CK_OBJECT_HANDLE hKey) 1989 { 1990 SFTK_FIPSCHECK(); 1991 CHECK_FORK(); 1992 1993 rv = NSC_MessageDecryptInit(hSession, pMechanism, hKey); 1994 if (sftk_audit_enabled) { 1995 sftk_AuditCryptInit("MessageDecrypt", hSession, pMechanism, hKey, rv); 1996 } 1997 return rv; 1998 } 1999 2000 CK_RV 2001 FC_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2002 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 2003 CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, 2004 CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, 2005 CK_ULONG_PTR pulPlaintextLen) 2006 { 2007 SFTK_FIPSCHECK(); 2008 CHECK_FORK(); 2009 return NSC_DecryptMessage(hSession, pParameter, ulParameterLen, 2010 pAssociatedData, ulAssociatedDataLen, 2011 pCiphertext, ulCiphertextLen, pPlaintext, 2012 pulPlaintextLen); 2013 } 2014 2015 CK_RV 2016 FC_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2017 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 2018 CK_ULONG ulAssociatedDataLen) 2019 { 2020 SFTK_FIPSCHECK(); 2021 CHECK_FORK(); 2022 return NSC_DecryptMessageBegin(hSession, pParameter, ulParameterLen, 2023 pAssociatedData, ulAssociatedDataLen); 2024 } 2025 2026 CK_RV 2027 FC_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2028 CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, 2029 CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, 2030 CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags) 2031 { 2032 SFTK_FIPSCHECK(); 2033 CHECK_FORK(); 2034 return NSC_DecryptMessageNext(hSession, pParameter, ulParameterLen, 2035 pCiphertextPart, ulCiphertextPartLen, 2036 pPlaintextPart, pulPlaintextPartLen, flags); 2037 } 2038 2039 CK_RV 2040 FC_MessageDecryptFinal(CK_SESSION_HANDLE hSession) 2041 { 2042 SFTK_FIPSCHECK(); 2043 CHECK_FORK(); 2044 return NSC_MessageDecryptFinal(hSession); 2045 } 2046 2047 CK_RV 2048 FC_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 2049 CK_OBJECT_HANDLE hKey) 2050 { 2051 SFTK_FIPSCHECK(); 2052 CHECK_FORK(); 2053 2054 rv = NSC_MessageSignInit(hSession, pMechanism, hKey); 2055 if (sftk_audit_enabled) { 2056 sftk_AuditCryptInit("MessageSign", hSession, pMechanism, hKey, rv); 2057 } 2058 return rv; 2059 } 2060 2061 CK_RV 2062 FC_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2063 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, 2064 CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 2065 { 2066 SFTK_FIPSCHECK(); 2067 CHECK_FORK(); 2068 return NSC_SignMessage(hSession, pParameter, ulParameterLen, pData, 2069 ulDataLen, pSignature, pulSignatureLen); 2070 } 2071 2072 CK_RV 2073 FC_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2074 CK_ULONG ulParameterLen) 2075 { 2076 SFTK_FIPSCHECK(); 2077 CHECK_FORK(); 2078 return NSC_SignMessageBegin(hSession, pParameter, ulParameterLen); 2079 } 2080 2081 CK_RV 2082 FC_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2083 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, 2084 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 2085 CK_ULONG_PTR pulSignatureLen) 2086 { 2087 SFTK_FIPSCHECK(); 2088 CHECK_FORK(); 2089 return NSC_SignMessageNext(hSession, pParameter, ulParameterLen, pData, 2090 ulDataLen, pSignature, pulSignatureLen); 2091 } 2092 2093 CK_RV 2094 FC_MessageSignFinal(CK_SESSION_HANDLE hSession) 2095 { 2096 SFTK_FIPSCHECK(); 2097 CHECK_FORK(); 2098 return NSC_MessageSignFinal(hSession); 2099 } 2100 2101 CK_RV 2102 FC_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 2103 CK_OBJECT_HANDLE hKey) 2104 { 2105 SFTK_FIPSCHECK(); 2106 CHECK_FORK(); 2107 2108 rv = NSC_MessageVerifyInit(hSession, pMechanism, hKey); 2109 if (sftk_audit_enabled) { 2110 sftk_AuditCryptInit("MessageVerify", hSession, pMechanism, hKey, rv); 2111 } 2112 return rv; 2113 } 2114 2115 CK_RV 2116 FC_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2117 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, 2118 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 2119 CK_ULONG ulSignatureLen) 2120 { 2121 SFTK_FIPSCHECK(); 2122 CHECK_FORK(); 2123 return NSC_VerifyMessage(hSession, pParameter, ulParameterLen, pData, 2124 ulDataLen, pSignature, ulSignatureLen); 2125 } 2126 2127 CK_RV 2128 FC_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2129 CK_ULONG ulParameterLen) 2130 { 2131 SFTK_FIPSCHECK(); 2132 CHECK_FORK(); 2133 return NSC_VerifyMessageBegin(hSession, pParameter, ulParameterLen); 2134 } 2135 2136 CK_RV 2137 FC_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 2138 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, 2139 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 2140 CK_ULONG ulSignatureLen) 2141 { 2142 SFTK_FIPSCHECK(); 2143 CHECK_FORK(); 2144 return NSC_VerifyMessageNext(hSession, pParameter, ulParameterLen, 2145 pData, ulDataLen, pSignature, ulSignatureLen); 2146 } 2147 2148 CK_RV 2149 FC_MessageVerifyFinal(CK_SESSION_HANDLE hSession) 2150 { 2151 SFTK_FIPSCHECK(); 2152 CHECK_FORK(); 2153 return NSC_MessageVerifyFinal(hSession); 2154 } 2155 2156 CK_RV 2157 FC_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 2158 CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, 2159 CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, 2160 CK_ULONG_PTR pulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey) 2161 { 2162 CK_BBOOL *boolptr; 2163 2164 SFTK_FIPSCHECK(); 2165 CHECK_FORK(); 2166 2167 /* all secret keys must be sensitive, if the upper level code tries to say 2168 * otherwise, reject it. */ 2169 boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, 2170 ulAttributeCount, CKA_SENSITIVE); 2171 if (boolptr != NULL) { 2172 if (!(*boolptr)) { 2173 return CKR_ATTRIBUTE_VALUE_INVALID; 2174 } 2175 } 2176 rv = NSC_EncapsulateKey(hSession, pMechanism, hPublicKey, 2177 pTemplate, ulAttributeCount, 2178 pCiphertext, pulCiphertextLen, phKey); 2179 if (sftk_audit_enabled) { 2180 sftk_AuditEncapsulateKey(hSession, pMechanism, hPublicKey, 2181 pTemplate, ulAttributeCount, 2182 pCiphertext, pulCiphertextLen, phKey, rv); 2183 } 2184 return rv; 2185 } 2186 2187 CK_RV 2188 FC_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 2189 CK_OBJECT_HANDLE hPrivateKey, CK_ATTRIBUTE_PTR pTemplate, 2190 CK_ULONG ulAttributeCount, CK_BYTE_PTR pCiphertext, 2191 CK_ULONG ulCiphertextLen, CK_OBJECT_HANDLE_PTR phKey) 2192 { 2193 CK_BBOOL *boolptr; 2194 2195 SFTK_FIPSCHECK(); 2196 CHECK_FORK(); 2197 2198 /* all secret keys must be sensitive, if the upper level code tries to say 2199 * otherwise, reject it. */ 2200 boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, 2201 ulAttributeCount, CKA_SENSITIVE); 2202 if (boolptr != NULL) { 2203 if (!(*boolptr)) { 2204 return CKR_ATTRIBUTE_VALUE_INVALID; 2205 } 2206 } 2207 rv = NSC_DecapsulateKey(hSession, pMechanism, hPrivateKey, 2208 pTemplate, ulAttributeCount, 2209 pCiphertext, ulCiphertextLen, phKey); 2210 if (sftk_audit_enabled) { 2211 sftk_AuditDecapsulateKey(hSession, pMechanism, hPrivateKey, 2212 pTemplate, ulAttributeCount, 2213 pCiphertext, ulCiphertextLen, phKey, rv); 2214 } 2215 return rv; 2216 } 2217 2218 CK_RV 2219 FC_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, 2220 CK_SESSION_VALIDATION_FLAGS_TYPE type, 2221 CK_FLAGS_PTR pFlags) 2222 { 2223 SFTK_FIPSCHECK(); 2224 CHECK_FORK(); 2225 2226 return NSC_GetSessionValidationFlags(hSession, type, pFlags); 2227 } 2228 2229 CK_RV 2230 FC_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, 2231 CK_ASYNC_DATA_PTR pResult) 2232 { 2233 SFTK_FIPSCHECK(); 2234 CHECK_FORK(); 2235 2236 return NSC_AsyncComplete(hSession, pFunctionName, pResult); 2237 } 2238 2239 CK_RV 2240 FC_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, 2241 CK_ULONG_PTR pulID) 2242 { 2243 SFTK_FIPSCHECK(); 2244 CHECK_FORK(); 2245 2246 return NSC_AsyncGetID(hSession, pFunctionName, pulID); 2247 } 2248 2249 CK_RV 2250 FC_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, 2251 CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData) 2252 { 2253 SFTK_FIPSCHECK(); 2254 CHECK_FORK(); 2255 2256 return FC_AsyncJoin(hSession, pFunctionName, ulID, pData, ulData); 2257 } 2258 2259 CK_RV 2260 FC_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession, 2261 CK_MECHANISM_PTR pMechanism, 2262 CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, 2263 CK_BYTE_PTR pAssociatedData, 2264 CK_ULONG ulAssociatedDataLen, 2265 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) 2266 { 2267 SFTK_FIPSCHECK(); 2268 CHECK_FORK(); 2269 2270 /* Before we support FC_WrapKeyAuthenticated, we'll have to add 2271 * logging here, so just return CKR_FUNCTION_NOT_SUPPORTED until logging 2272 * is added */ 2273 return CKR_FUNCTION_NOT_SUPPORTED; 2274 } 2275 2276 CK_RV 2277 FC_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession, 2278 CK_MECHANISM_PTR pMechanism, 2279 CK_OBJECT_HANDLE hUnwrappingKey, 2280 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, 2281 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 2282 CK_BYTE_PTR pAssociatedData, 2283 CK_ULONG ulAssociatedDataLen, 2284 CK_OBJECT_HANDLE_PTR phKey) 2285 { 2286 SFTK_FIPSCHECK(); 2287 CHECK_FORK(); 2288 2289 /* Before we support FC_UnwrapKeyAuthenticated, we'll have to add 2290 * logging here, so just return CKR_FUNCTION_NOT_SUPPORTED until logging 2291 * is added */ 2292 return CKR_FUNCTION_NOT_SUPPORTED; 2293 }