1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/softoken/fipstokn.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1542 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * This file implements PKCS 11 on top of our existing security modules 1.9 + * 1.10 + * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. 1.11 + * This implementation has two slots: 1.12 + * slot 1 is our generic crypto support. It does not require login 1.13 + * (unless you've enabled FIPS). It supports Public Key ops, and all they 1.14 + * bulk ciphers and hashes. It can also support Private Key ops for imported 1.15 + * Private keys. It does not have any token storage. 1.16 + * slot 2 is our private key support. It requires a login before use. It 1.17 + * can store Private Keys and Certs as token objects. Currently only private 1.18 + * keys and their associated Certificates are saved on the token. 1.19 + * 1.20 + * In this implementation, session objects are only visible to the session 1.21 + * that created or generated them. 1.22 + */ 1.23 +#include "seccomon.h" 1.24 +#include "softoken.h" 1.25 +#include "lowkeyi.h" 1.26 +#include "pkcs11.h" 1.27 +#include "pkcs11i.h" 1.28 +#include "prenv.h" 1.29 +#include "prprf.h" 1.30 + 1.31 +#include <ctype.h> 1.32 + 1.33 +#ifdef XP_UNIX 1.34 +#define NSS_AUDIT_WITH_SYSLOG 1 1.35 +#include <syslog.h> 1.36 +#include <unistd.h> 1.37 +#endif 1.38 + 1.39 +#ifdef LINUX 1.40 +#include <pthread.h> 1.41 +#include <dlfcn.h> 1.42 +#define LIBAUDIT_NAME "libaudit.so.0" 1.43 +#ifndef AUDIT_CRYPTO_TEST_USER 1.44 +#define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */ 1.45 +#define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */ 1.46 +#define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */ 1.47 +#define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */ 1.48 +#define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */ 1.49 +#define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomize */ 1.50 +#endif 1.51 +static void *libaudit_handle; 1.52 +static int (*audit_open_func)(void); 1.53 +static void (*audit_close_func)(int fd); 1.54 +static int (*audit_log_user_message_func)(int audit_fd, int type, 1.55 + const char *message, const char *hostname, const char *addr, 1.56 + const char *tty, int result); 1.57 +static int (*audit_send_user_message_func)(int fd, int type, 1.58 + const char *message); 1.59 + 1.60 +static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT; 1.61 + 1.62 +static void 1.63 +libaudit_init(void) 1.64 +{ 1.65 + libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY); 1.66 + if (!libaudit_handle) { 1.67 + return; 1.68 + } 1.69 + audit_open_func = dlsym(libaudit_handle, "audit_open"); 1.70 + audit_close_func = dlsym(libaudit_handle, "audit_close"); 1.71 + /* 1.72 + * audit_send_user_message is the older function. 1.73 + * audit_log_user_message, if available, is preferred. 1.74 + */ 1.75 + audit_log_user_message_func = dlsym(libaudit_handle, 1.76 + "audit_log_user_message"); 1.77 + if (!audit_log_user_message_func) { 1.78 + audit_send_user_message_func = dlsym(libaudit_handle, 1.79 + "audit_send_user_message"); 1.80 + } 1.81 + if (!audit_open_func || !audit_close_func || 1.82 + (!audit_log_user_message_func && !audit_send_user_message_func)) { 1.83 + dlclose(libaudit_handle); 1.84 + libaudit_handle = NULL; 1.85 + audit_open_func = NULL; 1.86 + audit_close_func = NULL; 1.87 + audit_log_user_message_func = NULL; 1.88 + audit_send_user_message_func = NULL; 1.89 + } 1.90 +} 1.91 +#endif /* LINUX */ 1.92 + 1.93 + 1.94 +/* 1.95 + * ******************** Password Utilities ******************************* 1.96 + */ 1.97 +static PRBool isLoggedIn = PR_FALSE; 1.98 +PRBool sftk_fatalError = PR_FALSE; 1.99 + 1.100 +/* 1.101 + * This function returns 1.102 + * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string 1.103 + * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not 1.104 + * consist of characters from three or more character classes. 1.105 + * - CKR_OK otherwise 1.106 + * 1.107 + * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters. 1.108 + * We define five character classes: digits (0-9), ASCII lowercase letters, 1.109 + * ASCII uppercase letters, ASCII non-alphanumeric characters (such as 1.110 + * space and punctuation marks), and non-ASCII characters. If an ASCII 1.111 + * uppercase letter is the first character of the password/PIN, the 1.112 + * uppercase letter is not counted toward its character class. Similarly, 1.113 + * if a digit is the last character of the password/PIN, the digit is not 1.114 + * counted toward its character class. 1.115 + * 1.116 + * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum 1.117 + * password/PIN length checks, they check the length in bytes as opposed 1.118 + * to characters. To meet the minimum password/PIN guessing probability 1.119 + * requirements in FIPS 140-2, we need to check the length in characters. 1.120 + */ 1.121 +static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { 1.122 + unsigned int i; 1.123 + int nchar = 0; /* number of characters */ 1.124 + int ntrail = 0; /* number of trailing bytes to follow */ 1.125 + int ndigit = 0; /* number of decimal digits */ 1.126 + int nlower = 0; /* number of ASCII lowercase letters */ 1.127 + int nupper = 0; /* number of ASCII uppercase letters */ 1.128 + int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */ 1.129 + int nnonascii = 0; /* number of non-ASCII characters */ 1.130 + int nclass; /* number of character classes */ 1.131 + 1.132 + for (i = 0; i < ulPinLen; i++) { 1.133 + unsigned int byte = pPin[i]; 1.134 + 1.135 + if (ntrail) { 1.136 + if ((byte & 0xc0) != 0x80) { 1.137 + /* illegal */ 1.138 + nchar = -1; 1.139 + break; 1.140 + } 1.141 + if (--ntrail == 0) { 1.142 + nchar++; 1.143 + nnonascii++; 1.144 + } 1.145 + continue; 1.146 + } 1.147 + if ((byte & 0x80) == 0x00) { 1.148 + /* single-byte (ASCII) character */ 1.149 + nchar++; 1.150 + if (isdigit(byte)) { 1.151 + if (i < ulPinLen - 1) { 1.152 + ndigit++; 1.153 + } 1.154 + } else if (islower(byte)) { 1.155 + nlower++; 1.156 + } else if (isupper(byte)) { 1.157 + if (i > 0) { 1.158 + nupper++; 1.159 + } 1.160 + } else { 1.161 + nnonalnum++; 1.162 + } 1.163 + } else if ((byte & 0xe0) == 0xc0) { 1.164 + /* leading byte of two-byte character */ 1.165 + ntrail = 1; 1.166 + } else if ((byte & 0xf0) == 0xe0) { 1.167 + /* leading byte of three-byte character */ 1.168 + ntrail = 2; 1.169 + } else if ((byte & 0xf8) == 0xf0) { 1.170 + /* leading byte of four-byte character */ 1.171 + ntrail = 3; 1.172 + } else { 1.173 + /* illegal */ 1.174 + nchar = -1; 1.175 + break; 1.176 + } 1.177 + } 1.178 + if (nchar == -1) { 1.179 + /* illegal UTF8 string */ 1.180 + return CKR_PIN_INVALID; 1.181 + } 1.182 + if (nchar < FIPS_MIN_PIN) { 1.183 + return CKR_PIN_LEN_RANGE; 1.184 + } 1.185 + nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) + 1.186 + (nnonalnum != 0) + (nnonascii != 0); 1.187 + if (nclass < 3) { 1.188 + return CKR_PIN_LEN_RANGE; 1.189 + } 1.190 + return CKR_OK; 1.191 +} 1.192 + 1.193 + 1.194 +/* FIPS required checks before any useful cryptographic services */ 1.195 +static CK_RV sftk_fipsCheck(void) { 1.196 + if (sftk_fatalError) 1.197 + return CKR_DEVICE_ERROR; 1.198 + if (!isLoggedIn) 1.199 + return CKR_USER_NOT_LOGGED_IN; 1.200 + return CKR_OK; 1.201 +} 1.202 + 1.203 + 1.204 +#define SFTK_FIPSCHECK() \ 1.205 + CK_RV rv; \ 1.206 + if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; 1.207 + 1.208 +#define SFTK_FIPSFATALCHECK() \ 1.209 + if (sftk_fatalError) return CKR_DEVICE_ERROR; 1.210 + 1.211 + 1.212 +/* grab an attribute out of a raw template */ 1.213 +void * 1.214 +fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, 1.215 + CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type) 1.216 +{ 1.217 + int i; 1.218 + 1.219 + for (i=0; i < (int) ulCount; i++) { 1.220 + if (pTemplate[i].type == type) { 1.221 + return pTemplate[i].pValue; 1.222 + } 1.223 + } 1.224 + return NULL; 1.225 +} 1.226 + 1.227 + 1.228 +#define __PASTE(x,y) x##y 1.229 + 1.230 +/* ------------- forward declare all the NSC_ functions ------------- */ 1.231 +#undef CK_NEED_ARG_LIST 1.232 +#undef CK_PKCS11_FUNCTION_INFO 1.233 + 1.234 +#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name) 1.235 +#define CK_NEED_ARG_LIST 1 1.236 + 1.237 +#include "pkcs11f.h" 1.238 + 1.239 +/* ------------- forward declare all the FIPS functions ------------- */ 1.240 +#undef CK_NEED_ARG_LIST 1.241 +#undef CK_PKCS11_FUNCTION_INFO 1.242 + 1.243 +#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name) 1.244 +#define CK_NEED_ARG_LIST 1 1.245 + 1.246 +#include "pkcs11f.h" 1.247 + 1.248 +/* ------------- build the CK_CRYPTO_TABLE ------------------------- */ 1.249 +static CK_FUNCTION_LIST sftk_fipsTable = { 1.250 + { 1, 10 }, 1.251 + 1.252 +#undef CK_NEED_ARG_LIST 1.253 +#undef CK_PKCS11_FUNCTION_INFO 1.254 + 1.255 +#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name), 1.256 + 1.257 + 1.258 +#include "pkcs11f.h" 1.259 + 1.260 +}; 1.261 + 1.262 +#undef CK_NEED_ARG_LIST 1.263 +#undef CK_PKCS11_FUNCTION_INFO 1.264 + 1.265 + 1.266 +#undef __PASTE 1.267 + 1.268 +/* CKO_NOT_A_KEY can be any object class that's not a key object. */ 1.269 +#define CKO_NOT_A_KEY CKO_DATA 1.270 + 1.271 +#define SFTK_IS_KEY_OBJECT(objClass) \ 1.272 + (((objClass) == CKO_PUBLIC_KEY) || \ 1.273 + ((objClass) == CKO_PRIVATE_KEY) || \ 1.274 + ((objClass) == CKO_SECRET_KEY)) 1.275 + 1.276 +#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \ 1.277 + (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY)) 1.278 + 1.279 +static CK_RV 1.280 +sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, 1.281 + CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) 1.282 +{ 1.283 + CK_RV rv; 1.284 + CK_ATTRIBUTE class; 1.285 + class.type = CKA_CLASS; 1.286 + class.pValue = pObjClass; 1.287 + class.ulValueLen = sizeof(*pObjClass); 1.288 + rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); 1.289 + if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { 1.290 + rv = sftk_fipsCheck(); 1.291 + } 1.292 + return rv; 1.293 +} 1.294 + 1.295 +#ifdef LINUX 1.296 + 1.297 +int 1.298 +sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType) 1.299 +{ 1.300 + switch (auditType) { 1.301 + case NSS_AUDIT_ACCESS_KEY: 1.302 + case NSS_AUDIT_CHANGE_KEY: 1.303 + case NSS_AUDIT_COPY_KEY: 1.304 + case NSS_AUDIT_DERIVE_KEY: 1.305 + case NSS_AUDIT_DESTROY_KEY: 1.306 + case NSS_AUDIT_DIGEST_KEY: 1.307 + case NSS_AUDIT_GENERATE_KEY: 1.308 + case NSS_AUDIT_LOAD_KEY: 1.309 + case NSS_AUDIT_UNWRAP_KEY: 1.310 + case NSS_AUDIT_WRAP_KEY: 1.311 + return AUDIT_CRYPTO_KEY_USER; 1.312 + case NSS_AUDIT_CRYPT: 1.313 + return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER : 1.314 + AUDIT_CRYPTO_KEY_USER; 1.315 + case NSS_AUDIT_FIPS_STATE: 1.316 + case NSS_AUDIT_INIT_PIN: 1.317 + case NSS_AUDIT_INIT_TOKEN: 1.318 + case NSS_AUDIT_SET_PIN: 1.319 + return AUDIT_CRYPTO_PARAM_CHANGE_USER; 1.320 + case NSS_AUDIT_SELF_TEST: 1.321 + return AUDIT_CRYPTO_TEST_USER; 1.322 + case NSS_AUDIT_LOGIN: 1.323 + return AUDIT_CRYPTO_LOGIN; 1.324 + case NSS_AUDIT_LOGOUT: 1.325 + return AUDIT_CRYPTO_LOGOUT; 1.326 + /* we skip the fault case here so we can get compiler 1.327 + * warnings if new 'NSSAuditType's are added without 1.328 + * added them to this list, defaults fall through */ 1.329 + } 1.330 + /* default */ 1.331 + return AUDIT_CRYPTO_PARAM_CHANGE_USER; 1.332 +} 1.333 +#endif 1.334 + 1.335 + 1.336 +/********************************************************************** 1.337 + * 1.338 + * FIPS 140 auditable event logging 1.339 + * 1.340 + **********************************************************************/ 1.341 + 1.342 +PRBool sftk_audit_enabled = PR_FALSE; 1.343 + 1.344 +/* 1.345 + * Each audit record must have the following information: 1.346 + * - Date and time of the event 1.347 + * - Type of event 1.348 + * - user (subject) identity 1.349 + * - outcome (success or failure) of the event 1.350 + * - process ID 1.351 + * - name (ID) of the object 1.352 + * - for changes to data (except for authentication data and CSPs), the new 1.353 + * and old values of the data 1.354 + * - for authentication attempts, the origin of the attempt (e.g., terminal 1.355 + * identifier) 1.356 + * - for assuming a role, the type of role, and the location of the request 1.357 + */ 1.358 +void 1.359 +sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType, 1.360 + const char *msg) 1.361 +{ 1.362 +#ifdef NSS_AUDIT_WITH_SYSLOG 1.363 + int level; 1.364 + 1.365 + switch (severity) { 1.366 + case NSS_AUDIT_ERROR: 1.367 + level = LOG_ERR; 1.368 + break; 1.369 + case NSS_AUDIT_WARNING: 1.370 + level = LOG_WARNING; 1.371 + break; 1.372 + default: 1.373 + level = LOG_INFO; 1.374 + break; 1.375 + } 1.376 + /* timestamp is provided by syslog in the message header */ 1.377 + syslog(level | LOG_USER /* facility */, 1.378 + "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s", 1.379 + (int)getpid(), (int)getuid(), msg); 1.380 +#ifdef LINUX 1.381 + if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { 1.382 + return; 1.383 + } 1.384 + if (libaudit_handle) { 1.385 + int audit_fd; 1.386 + int linuxAuditType; 1.387 + int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ 1.388 + char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); 1.389 + if (!message) { 1.390 + return; 1.391 + } 1.392 + audit_fd = audit_open_func(); 1.393 + if (audit_fd < 0) { 1.394 + PR_smprintf_free(message); 1.395 + return; 1.396 + } 1.397 + linuxAuditType = sftk_mapLinuxAuditType(severity, auditType); 1.398 + if (audit_log_user_message_func) { 1.399 + audit_log_user_message_func(audit_fd, linuxAuditType, message, 1.400 + NULL, NULL, NULL, result); 1.401 + } else { 1.402 + audit_send_user_message_func(audit_fd, linuxAuditType, message); 1.403 + } 1.404 + audit_close_func(audit_fd); 1.405 + PR_smprintf_free(message); 1.406 + } 1.407 +#endif /* LINUX */ 1.408 +#else 1.409 + /* do nothing */ 1.410 +#endif 1.411 +} 1.412 + 1.413 + 1.414 +/********************************************************************** 1.415 + * 1.416 + * Start of PKCS 11 functions 1.417 + * 1.418 + **********************************************************************/ 1.419 +/* return the function list */ 1.420 +CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) { 1.421 + 1.422 + CHECK_FORK(); 1.423 + 1.424 + *pFunctionList = &sftk_fipsTable; 1.425 + return CKR_OK; 1.426 +} 1.427 + 1.428 +/* sigh global so pkcs11 can read it */ 1.429 +PRBool nsf_init = PR_FALSE; 1.430 + 1.431 +/* FC_Initialize initializes the PKCS #11 library. */ 1.432 +CK_RV FC_Initialize(CK_VOID_PTR pReserved) { 1.433 + const char *envp; 1.434 + CK_RV crv; 1.435 + 1.436 + sftk_ForkReset(pReserved, &crv); 1.437 + 1.438 + if (nsf_init) { 1.439 + return CKR_CRYPTOKI_ALREADY_INITIALIZED; 1.440 + } 1.441 + 1.442 + if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { 1.443 + sftk_audit_enabled = (atoi(envp) == 1); 1.444 + } 1.445 + 1.446 + crv = nsc_CommonInitialize(pReserved, PR_TRUE); 1.447 + 1.448 + /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ 1.449 + if (crv != CKR_OK) { 1.450 + sftk_fatalError = PR_TRUE; 1.451 + return crv; 1.452 + } 1.453 + 1.454 + sftk_fatalError = PR_FALSE; /* any error has been reset */ 1.455 + 1.456 + crv = sftk_fipsPowerUpSelfTest(); 1.457 + if (crv != CKR_OK) { 1.458 + nsc_CommonFinalize(NULL, PR_TRUE); 1.459 + sftk_fatalError = PR_TRUE; 1.460 + if (sftk_audit_enabled) { 1.461 + char msg[128]; 1.462 + PR_snprintf(msg,sizeof msg, 1.463 + "C_Initialize()=0x%08lX " 1.464 + "power-up self-tests failed", 1.465 + (PRUint32)crv); 1.466 + sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); 1.467 + } 1.468 + return crv; 1.469 + } 1.470 + nsf_init = PR_TRUE; 1.471 + 1.472 + return CKR_OK; 1.473 +} 1.474 + 1.475 +/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/ 1.476 +CK_RV FC_Finalize (CK_VOID_PTR pReserved) { 1.477 + CK_RV crv; 1.478 + 1.479 + if (sftk_ForkReset(pReserved, &crv)) { 1.480 + return crv; 1.481 + } 1.482 + 1.483 + if (!nsf_init) { 1.484 + return CKR_OK; 1.485 + } 1.486 + 1.487 + crv = nsc_CommonFinalize (pReserved, PR_TRUE); 1.488 + 1.489 + nsf_init = (PRBool) !(crv == CKR_OK); 1.490 + return crv; 1.491 +} 1.492 + 1.493 + 1.494 +/* FC_GetInfo returns general information about PKCS #11. */ 1.495 +CK_RV FC_GetInfo(CK_INFO_PTR pInfo) { 1.496 + CHECK_FORK(); 1.497 + 1.498 + return NSC_GetInfo(pInfo); 1.499 +} 1.500 + 1.501 +/* FC_GetSlotList obtains a list of slots in the system. */ 1.502 +CK_RV FC_GetSlotList(CK_BBOOL tokenPresent, 1.503 + CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { 1.504 + CHECK_FORK(); 1.505 + 1.506 + return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount, 1.507 + NSC_FIPS_MODULE); 1.508 +} 1.509 + 1.510 +/* FC_GetSlotInfo obtains information about a particular slot in the system. */ 1.511 +CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { 1.512 + CHECK_FORK(); 1.513 + 1.514 + return NSC_GetSlotInfo(slotID,pInfo); 1.515 +} 1.516 + 1.517 + 1.518 +/*FC_GetTokenInfo obtains information about a particular token in the system.*/ 1.519 + CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) { 1.520 + CK_RV crv; 1.521 + 1.522 + CHECK_FORK(); 1.523 + 1.524 + crv = NSC_GetTokenInfo(slotID,pInfo); 1.525 + if (crv == CKR_OK) 1.526 + pInfo->flags |= CKF_LOGIN_REQUIRED; 1.527 + return crv; 1.528 + 1.529 +} 1.530 + 1.531 + 1.532 + 1.533 +/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/ 1.534 + CK_RV FC_GetMechanismList(CK_SLOT_ID slotID, 1.535 + CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) { 1.536 + CHECK_FORK(); 1.537 + 1.538 + SFTK_FIPSFATALCHECK(); 1.539 + if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID; 1.540 + /* FIPS Slot supports all functions */ 1.541 + return NSC_GetMechanismList(slotID,pMechanismList,pusCount); 1.542 +} 1.543 + 1.544 + 1.545 +/* FC_GetMechanismInfo obtains information about a particular mechanism 1.546 + * possibly supported by a token. */ 1.547 + CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 1.548 + CK_MECHANISM_INFO_PTR pInfo) { 1.549 + CHECK_FORK(); 1.550 + 1.551 + SFTK_FIPSFATALCHECK(); 1.552 + if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID; 1.553 + /* FIPS Slot supports all functions */ 1.554 + return NSC_GetMechanismInfo(slotID,type,pInfo); 1.555 +} 1.556 + 1.557 + 1.558 +/* FC_InitToken initializes a token. */ 1.559 + CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin, 1.560 + CK_ULONG usPinLen,CK_CHAR_PTR pLabel) { 1.561 + CK_RV crv; 1.562 + 1.563 + CHECK_FORK(); 1.564 + 1.565 + crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel); 1.566 + if (sftk_audit_enabled) { 1.567 + char msg[128]; 1.568 + NSSAuditSeverity severity = (crv == CKR_OK) ? 1.569 + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 1.570 + /* pLabel points to a 32-byte label, which is not null-terminated */ 1.571 + PR_snprintf(msg,sizeof msg, 1.572 + "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX", 1.573 + (PRUint32)slotID,pLabel,(PRUint32)crv); 1.574 + sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg); 1.575 + } 1.576 + return crv; 1.577 +} 1.578 + 1.579 + 1.580 +/* FC_InitPIN initializes the normal user's PIN. */ 1.581 + CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession, 1.582 + CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { 1.583 + CK_RV rv; 1.584 + 1.585 + CHECK_FORK(); 1.586 + 1.587 + if (sftk_fatalError) return CKR_DEVICE_ERROR; 1.588 + if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) { 1.589 + rv = NSC_InitPIN(hSession,pPin,ulPinLen); 1.590 + } 1.591 + if (sftk_audit_enabled) { 1.592 + char msg[128]; 1.593 + NSSAuditSeverity severity = (rv == CKR_OK) ? 1.594 + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 1.595 + PR_snprintf(msg,sizeof msg, 1.596 + "C_InitPIN(hSession=0x%08lX)=0x%08lX", 1.597 + (PRUint32)hSession,(PRUint32)rv); 1.598 + sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg); 1.599 + } 1.600 + return rv; 1.601 +} 1.602 + 1.603 + 1.604 +/* FC_SetPIN modifies the PIN of user that is currently logged in. */ 1.605 +/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */ 1.606 + CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, 1.607 + CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) { 1.608 + CK_RV rv; 1.609 + 1.610 + CHECK_FORK(); 1.611 + 1.612 + if ((rv = sftk_fipsCheck()) == CKR_OK && 1.613 + (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) { 1.614 + rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen); 1.615 + } 1.616 + if (sftk_audit_enabled) { 1.617 + char msg[128]; 1.618 + NSSAuditSeverity severity = (rv == CKR_OK) ? 1.619 + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 1.620 + PR_snprintf(msg,sizeof msg, 1.621 + "C_SetPIN(hSession=0x%08lX)=0x%08lX", 1.622 + (PRUint32)hSession,(PRUint32)rv); 1.623 + sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg); 1.624 + } 1.625 + return rv; 1.626 +} 1.627 + 1.628 +/* FC_OpenSession opens a session between an application and a token. */ 1.629 + CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, 1.630 + CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) { 1.631 + SFTK_FIPSFATALCHECK(); 1.632 + 1.633 + CHECK_FORK(); 1.634 + 1.635 + return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession); 1.636 +} 1.637 + 1.638 + 1.639 +/* FC_CloseSession closes a session between an application and a token. */ 1.640 + CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) { 1.641 + CHECK_FORK(); 1.642 + 1.643 + return NSC_CloseSession(hSession); 1.644 +} 1.645 + 1.646 + 1.647 +/* FC_CloseAllSessions closes all sessions with a token. */ 1.648 + CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) { 1.649 + 1.650 + CHECK_FORK(); 1.651 + 1.652 + return NSC_CloseAllSessions (slotID); 1.653 +} 1.654 + 1.655 + 1.656 +/* FC_GetSessionInfo obtains information about the session. */ 1.657 + CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession, 1.658 + CK_SESSION_INFO_PTR pInfo) { 1.659 + CK_RV rv; 1.660 + SFTK_FIPSFATALCHECK(); 1.661 + 1.662 + CHECK_FORK(); 1.663 + 1.664 + rv = NSC_GetSessionInfo(hSession,pInfo); 1.665 + if (rv == CKR_OK) { 1.666 + if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) { 1.667 + pInfo->state = CKS_RO_USER_FUNCTIONS; 1.668 + } 1.669 + if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) { 1.670 + pInfo->state = CKS_RW_USER_FUNCTIONS; 1.671 + } 1.672 + } 1.673 + return rv; 1.674 +} 1.675 + 1.676 +/* FC_Login logs a user into a token. */ 1.677 + CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, 1.678 + CK_CHAR_PTR pPin, CK_ULONG usPinLen) { 1.679 + CK_RV rv; 1.680 + PRBool successful; 1.681 + if (sftk_fatalError) return CKR_DEVICE_ERROR; 1.682 + rv = NSC_Login(hSession,userType,pPin,usPinLen); 1.683 + successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); 1.684 + if (successful) 1.685 + isLoggedIn = PR_TRUE; 1.686 + if (sftk_audit_enabled) { 1.687 + char msg[128]; 1.688 + NSSAuditSeverity severity; 1.689 + severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 1.690 + PR_snprintf(msg,sizeof msg, 1.691 + "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", 1.692 + (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv); 1.693 + sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg); 1.694 + } 1.695 + return rv; 1.696 +} 1.697 + 1.698 +/* FC_Logout logs a user out from a token. */ 1.699 + CK_RV FC_Logout(CK_SESSION_HANDLE hSession) { 1.700 + CK_RV rv; 1.701 + 1.702 + CHECK_FORK(); 1.703 + 1.704 + if ((rv = sftk_fipsCheck()) == CKR_OK) { 1.705 + rv = NSC_Logout(hSession); 1.706 + isLoggedIn = PR_FALSE; 1.707 + } 1.708 + if (sftk_audit_enabled) { 1.709 + char msg[128]; 1.710 + NSSAuditSeverity severity = (rv == CKR_OK) ? 1.711 + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; 1.712 + PR_snprintf(msg,sizeof msg, 1.713 + "C_Logout(hSession=0x%08lX)=0x%08lX", 1.714 + (PRUint32)hSession,(PRUint32)rv); 1.715 + sftk_LogAuditMessage(severity, NSS_AUDIT_LOGOUT, msg); 1.716 + } 1.717 + return rv; 1.718 +} 1.719 + 1.720 + 1.721 +/* FC_CreateObject creates a new object. */ 1.722 + CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession, 1.723 + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 1.724 + CK_OBJECT_HANDLE_PTR phObject) { 1.725 + CK_OBJECT_CLASS * classptr; 1.726 + 1.727 + SFTK_FIPSCHECK(); 1.728 + CHECK_FORK(); 1.729 + 1.730 + classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS); 1.731 + if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE; 1.732 + 1.733 + /* FIPS can't create keys from raw key material */ 1.734 + if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { 1.735 + rv = CKR_ATTRIBUTE_VALUE_INVALID; 1.736 + } else { 1.737 + rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject); 1.738 + } 1.739 + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { 1.740 + sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv); 1.741 + } 1.742 + return rv; 1.743 +} 1.744 + 1.745 + 1.746 + 1.747 + 1.748 + 1.749 +/* FC_CopyObject copies an object, creating a new object for the copy. */ 1.750 + CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession, 1.751 + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 1.752 + CK_OBJECT_HANDLE_PTR phNewObject) { 1.753 + CK_RV rv; 1.754 + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1.755 + 1.756 + CHECK_FORK(); 1.757 + 1.758 + SFTK_FIPSFATALCHECK(); 1.759 + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1.760 + if (rv == CKR_OK) { 1.761 + rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject); 1.762 + } 1.763 + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1.764 + sftk_AuditCopyObject(hSession, 1.765 + hObject,pTemplate,ulCount,phNewObject,rv); 1.766 + } 1.767 + return rv; 1.768 +} 1.769 + 1.770 + 1.771 +/* FC_DestroyObject destroys an object. */ 1.772 + CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession, 1.773 + CK_OBJECT_HANDLE hObject) { 1.774 + CK_RV rv; 1.775 + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1.776 + 1.777 + CHECK_FORK(); 1.778 + 1.779 + SFTK_FIPSFATALCHECK(); 1.780 + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1.781 + if (rv == CKR_OK) { 1.782 + rv = NSC_DestroyObject(hSession,hObject); 1.783 + } 1.784 + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1.785 + sftk_AuditDestroyObject(hSession,hObject,rv); 1.786 + } 1.787 + return rv; 1.788 +} 1.789 + 1.790 + 1.791 +/* FC_GetObjectSize gets the size of an object in bytes. */ 1.792 + CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession, 1.793 + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { 1.794 + CK_RV rv; 1.795 + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1.796 + 1.797 + CHECK_FORK(); 1.798 + 1.799 + SFTK_FIPSFATALCHECK(); 1.800 + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1.801 + if (rv == CKR_OK) { 1.802 + rv = NSC_GetObjectSize(hSession, hObject, pulSize); 1.803 + } 1.804 + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1.805 + sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv); 1.806 + } 1.807 + return rv; 1.808 +} 1.809 + 1.810 + 1.811 +/* FC_GetAttributeValue obtains the value of one or more object attributes. */ 1.812 + CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession, 1.813 + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { 1.814 + CK_RV rv; 1.815 + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1.816 + 1.817 + CHECK_FORK(); 1.818 + 1.819 + SFTK_FIPSFATALCHECK(); 1.820 + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1.821 + if (rv == CKR_OK) { 1.822 + rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount); 1.823 + } 1.824 + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1.825 + sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); 1.826 + } 1.827 + return rv; 1.828 +} 1.829 + 1.830 + 1.831 +/* FC_SetAttributeValue modifies the value of one or more object attributes */ 1.832 + CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession, 1.833 + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { 1.834 + CK_RV rv; 1.835 + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; 1.836 + 1.837 + CHECK_FORK(); 1.838 + 1.839 + SFTK_FIPSFATALCHECK(); 1.840 + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); 1.841 + if (rv == CKR_OK) { 1.842 + rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount); 1.843 + } 1.844 + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { 1.845 + sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); 1.846 + } 1.847 + return rv; 1.848 +} 1.849 + 1.850 + 1.851 + 1.852 +/* FC_FindObjectsInit initializes a search for token and session objects 1.853 + * that match a template. */ 1.854 + CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession, 1.855 + CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) { 1.856 + /* let publically readable object be found */ 1.857 + unsigned int i; 1.858 + CK_RV rv; 1.859 + PRBool needLogin = PR_FALSE; 1.860 + 1.861 + 1.862 + CHECK_FORK(); 1.863 + 1.864 + SFTK_FIPSFATALCHECK(); 1.865 + 1.866 + for (i=0; i < usCount; i++) { 1.867 + CK_OBJECT_CLASS class; 1.868 + if (pTemplate[i].type != CKA_CLASS) { 1.869 + continue; 1.870 + } 1.871 + if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) { 1.872 + continue; 1.873 + } 1.874 + if (pTemplate[i].pValue == NULL) { 1.875 + continue; 1.876 + } 1.877 + class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; 1.878 + if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) { 1.879 + needLogin = PR_TRUE; 1.880 + break; 1.881 + } 1.882 + } 1.883 + if (needLogin) { 1.884 + if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; 1.885 + } 1.886 + return NSC_FindObjectsInit(hSession,pTemplate,usCount); 1.887 +} 1.888 + 1.889 + 1.890 +/* FC_FindObjects continues a search for token and session objects 1.891 + * that match a template, obtaining additional object handles. */ 1.892 + CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession, 1.893 + CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount, 1.894 + CK_ULONG_PTR pusObjectCount) { 1.895 + CHECK_FORK(); 1.896 + 1.897 + /* let publically readable object be found */ 1.898 + SFTK_FIPSFATALCHECK(); 1.899 + return NSC_FindObjects(hSession,phObject,usMaxObjectCount, 1.900 + pusObjectCount); 1.901 +} 1.902 + 1.903 + 1.904 +/* 1.905 + ************** Crypto Functions: Encrypt ************************ 1.906 + */ 1.907 + 1.908 +/* FC_EncryptInit initializes an encryption operation. */ 1.909 + CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession, 1.910 + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { 1.911 + SFTK_FIPSCHECK(); 1.912 + CHECK_FORK(); 1.913 + 1.914 + rv = NSC_EncryptInit(hSession,pMechanism,hKey); 1.915 + if (sftk_audit_enabled) { 1.916 + sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv); 1.917 + } 1.918 + return rv; 1.919 +} 1.920 + 1.921 +/* FC_Encrypt encrypts single-part data. */ 1.922 + CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1.923 + CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, 1.924 + CK_ULONG_PTR pusEncryptedDataLen) { 1.925 + SFTK_FIPSCHECK(); 1.926 + CHECK_FORK(); 1.927 + 1.928 + return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData, 1.929 + pusEncryptedDataLen); 1.930 +} 1.931 + 1.932 + 1.933 +/* FC_EncryptUpdate continues a multiple-part encryption operation. */ 1.934 + CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession, 1.935 + CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, 1.936 + CK_ULONG_PTR pusEncryptedPartLen) { 1.937 + SFTK_FIPSCHECK(); 1.938 + CHECK_FORK(); 1.939 + 1.940 + return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart, 1.941 + pusEncryptedPartLen); 1.942 +} 1.943 + 1.944 + 1.945 +/* FC_EncryptFinal finishes a multiple-part encryption operation. */ 1.946 + CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession, 1.947 + CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) { 1.948 + SFTK_FIPSCHECK(); 1.949 + CHECK_FORK(); 1.950 + 1.951 + return NSC_EncryptFinal(hSession,pLastEncryptedPart, 1.952 + pusLastEncryptedPartLen); 1.953 +} 1.954 + 1.955 +/* 1.956 + ************** Crypto Functions: Decrypt ************************ 1.957 + */ 1.958 + 1.959 + 1.960 +/* FC_DecryptInit initializes a decryption operation. */ 1.961 + CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession, 1.962 + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { 1.963 + SFTK_FIPSCHECK(); 1.964 + CHECK_FORK(); 1.965 + 1.966 + rv = NSC_DecryptInit(hSession,pMechanism,hKey); 1.967 + if (sftk_audit_enabled) { 1.968 + sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv); 1.969 + } 1.970 + return rv; 1.971 +} 1.972 + 1.973 +/* FC_Decrypt decrypts encrypted data in a single part. */ 1.974 + CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession, 1.975 + CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData, 1.976 + CK_ULONG_PTR pusDataLen) { 1.977 + SFTK_FIPSCHECK(); 1.978 + CHECK_FORK(); 1.979 + 1.980 + return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData, 1.981 + pusDataLen); 1.982 +} 1.983 + 1.984 + 1.985 +/* FC_DecryptUpdate continues a multiple-part decryption operation. */ 1.986 + CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession, 1.987 + CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, 1.988 + CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) { 1.989 + SFTK_FIPSCHECK(); 1.990 + CHECK_FORK(); 1.991 + 1.992 + return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen, 1.993 + pPart,pusPartLen); 1.994 +} 1.995 + 1.996 + 1.997 +/* FC_DecryptFinal finishes a multiple-part decryption operation. */ 1.998 + CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession, 1.999 + CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) { 1.1000 + SFTK_FIPSCHECK(); 1.1001 + CHECK_FORK(); 1.1002 + 1.1003 + return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen); 1.1004 +} 1.1005 + 1.1006 + 1.1007 +/* 1.1008 + ************** Crypto Functions: Digest (HASH) ************************ 1.1009 + */ 1.1010 + 1.1011 +/* FC_DigestInit initializes a message-digesting operation. */ 1.1012 + CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession, 1.1013 + CK_MECHANISM_PTR pMechanism) { 1.1014 + SFTK_FIPSFATALCHECK(); 1.1015 + CHECK_FORK(); 1.1016 + 1.1017 + return NSC_DigestInit(hSession, pMechanism); 1.1018 +} 1.1019 + 1.1020 + 1.1021 +/* FC_Digest digests data in a single part. */ 1.1022 + CK_RV FC_Digest(CK_SESSION_HANDLE hSession, 1.1023 + CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, 1.1024 + CK_ULONG_PTR pusDigestLen) { 1.1025 + SFTK_FIPSFATALCHECK(); 1.1026 + CHECK_FORK(); 1.1027 + 1.1028 + return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen); 1.1029 +} 1.1030 + 1.1031 + 1.1032 +/* FC_DigestUpdate continues a multiple-part message-digesting operation. */ 1.1033 + CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, 1.1034 + CK_ULONG usPartLen) { 1.1035 + SFTK_FIPSFATALCHECK(); 1.1036 + CHECK_FORK(); 1.1037 + 1.1038 + return NSC_DigestUpdate(hSession,pPart,usPartLen); 1.1039 +} 1.1040 + 1.1041 + 1.1042 +/* FC_DigestFinal finishes a multiple-part message-digesting operation. */ 1.1043 + CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest, 1.1044 + CK_ULONG_PTR pusDigestLen) { 1.1045 + SFTK_FIPSFATALCHECK(); 1.1046 + CHECK_FORK(); 1.1047 + 1.1048 + return NSC_DigestFinal(hSession,pDigest,pusDigestLen); 1.1049 +} 1.1050 + 1.1051 + 1.1052 +/* 1.1053 + ************** Crypto Functions: Sign ************************ 1.1054 + */ 1.1055 + 1.1056 +/* FC_SignInit initializes a signature (private key encryption) operation, 1.1057 + * where the signature is (will be) an appendix to the data, 1.1058 + * and plaintext cannot be recovered from the signature */ 1.1059 + CK_RV FC_SignInit(CK_SESSION_HANDLE hSession, 1.1060 + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { 1.1061 + SFTK_FIPSCHECK(); 1.1062 + CHECK_FORK(); 1.1063 + 1.1064 + rv = NSC_SignInit(hSession,pMechanism,hKey); 1.1065 + if (sftk_audit_enabled) { 1.1066 + sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv); 1.1067 + } 1.1068 + return rv; 1.1069 +} 1.1070 + 1.1071 + 1.1072 +/* FC_Sign signs (encrypts with private key) data in a single part, 1.1073 + * where the signature is (will be) an appendix to the data, 1.1074 + * and plaintext cannot be recovered from the signature */ 1.1075 + CK_RV FC_Sign(CK_SESSION_HANDLE hSession, 1.1076 + CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature, 1.1077 + CK_ULONG_PTR pusSignatureLen) { 1.1078 + SFTK_FIPSCHECK(); 1.1079 + CHECK_FORK(); 1.1080 + 1.1081 + return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen); 1.1082 +} 1.1083 + 1.1084 + 1.1085 +/* FC_SignUpdate continues a multiple-part signature operation, 1.1086 + * where the signature is (will be) an appendix to the data, 1.1087 + * and plaintext cannot be recovered from the signature */ 1.1088 + CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, 1.1089 + CK_ULONG usPartLen) { 1.1090 + SFTK_FIPSCHECK(); 1.1091 + CHECK_FORK(); 1.1092 + 1.1093 + return NSC_SignUpdate(hSession,pPart,usPartLen); 1.1094 +} 1.1095 + 1.1096 + 1.1097 +/* FC_SignFinal finishes a multiple-part signature operation, 1.1098 + * returning the signature. */ 1.1099 + CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature, 1.1100 + CK_ULONG_PTR pusSignatureLen) { 1.1101 + SFTK_FIPSCHECK(); 1.1102 + CHECK_FORK(); 1.1103 + 1.1104 + return NSC_SignFinal(hSession,pSignature,pusSignatureLen); 1.1105 +} 1.1106 + 1.1107 +/* 1.1108 + ************** Crypto Functions: Sign Recover ************************ 1.1109 + */ 1.1110 +/* FC_SignRecoverInit initializes a signature operation, 1.1111 + * where the (digest) data can be recovered from the signature. 1.1112 + * E.g. encryption with the user's private key */ 1.1113 + CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession, 1.1114 + CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { 1.1115 + SFTK_FIPSCHECK(); 1.1116 + CHECK_FORK(); 1.1117 + 1.1118 + rv = NSC_SignRecoverInit(hSession,pMechanism,hKey); 1.1119 + if (sftk_audit_enabled) { 1.1120 + sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv); 1.1121 + } 1.1122 + return rv; 1.1123 +} 1.1124 + 1.1125 + 1.1126 +/* FC_SignRecover signs data in a single operation 1.1127 + * where the (digest) data can be recovered from the signature. 1.1128 + * E.g. encryption with the user's private key */ 1.1129 + CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1.1130 + CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) { 1.1131 + SFTK_FIPSCHECK(); 1.1132 + CHECK_FORK(); 1.1133 + 1.1134 + return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen); 1.1135 +} 1.1136 + 1.1137 +/* 1.1138 + ************** Crypto Functions: verify ************************ 1.1139 + */ 1.1140 + 1.1141 +/* FC_VerifyInit initializes a verification operation, 1.1142 + * where the signature is an appendix to the data, 1.1143 + * and plaintext cannot be recovered from the signature (e.g. DSA) */ 1.1144 + CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession, 1.1145 + CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { 1.1146 + SFTK_FIPSCHECK(); 1.1147 + CHECK_FORK(); 1.1148 + 1.1149 + rv = NSC_VerifyInit(hSession,pMechanism,hKey); 1.1150 + if (sftk_audit_enabled) { 1.1151 + sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv); 1.1152 + } 1.1153 + return rv; 1.1154 +} 1.1155 + 1.1156 + 1.1157 +/* FC_Verify verifies a signature in a single-part operation, 1.1158 + * where the signature is an appendix to the data, 1.1159 + * and plaintext cannot be recovered from the signature */ 1.1160 + CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1.1161 + CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) { 1.1162 + /* make sure we're legal */ 1.1163 + SFTK_FIPSCHECK(); 1.1164 + CHECK_FORK(); 1.1165 + 1.1166 + return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen); 1.1167 +} 1.1168 + 1.1169 + 1.1170 +/* FC_VerifyUpdate continues a multiple-part verification operation, 1.1171 + * where the signature is an appendix to the data, 1.1172 + * and plaintext cannot be recovered from the signature */ 1.1173 + CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1.1174 + CK_ULONG usPartLen) { 1.1175 + SFTK_FIPSCHECK(); 1.1176 + CHECK_FORK(); 1.1177 + 1.1178 + return NSC_VerifyUpdate(hSession,pPart,usPartLen); 1.1179 +} 1.1180 + 1.1181 + 1.1182 +/* FC_VerifyFinal finishes a multiple-part verification operation, 1.1183 + * checking the signature. */ 1.1184 + CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession, 1.1185 + CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) { 1.1186 + SFTK_FIPSCHECK(); 1.1187 + CHECK_FORK(); 1.1188 + 1.1189 + return NSC_VerifyFinal(hSession,pSignature,usSignatureLen); 1.1190 +} 1.1191 + 1.1192 +/* 1.1193 + ************** Crypto Functions: Verify Recover ************************ 1.1194 + */ 1.1195 + 1.1196 +/* FC_VerifyRecoverInit initializes a signature verification operation, 1.1197 + * where the data is recovered from the signature. 1.1198 + * E.g. Decryption with the user's public key */ 1.1199 + CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, 1.1200 + CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { 1.1201 + SFTK_FIPSCHECK(); 1.1202 + CHECK_FORK(); 1.1203 + 1.1204 + rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey); 1.1205 + if (sftk_audit_enabled) { 1.1206 + sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv); 1.1207 + } 1.1208 + return rv; 1.1209 +} 1.1210 + 1.1211 + 1.1212 +/* FC_VerifyRecover verifies a signature in a single-part operation, 1.1213 + * where the data is recovered from the signature. 1.1214 + * E.g. Decryption with the user's public key */ 1.1215 + CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession, 1.1216 + CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen, 1.1217 + CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) { 1.1218 + SFTK_FIPSCHECK(); 1.1219 + CHECK_FORK(); 1.1220 + 1.1221 + return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData, 1.1222 + pusDataLen); 1.1223 +} 1.1224 + 1.1225 +/* 1.1226 + **************************** Key Functions: ************************ 1.1227 + */ 1.1228 + 1.1229 +/* FC_GenerateKey generates a secret key, creating a new key object. */ 1.1230 + CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession, 1.1231 + CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, 1.1232 + CK_OBJECT_HANDLE_PTR phKey) { 1.1233 + CK_BBOOL *boolptr; 1.1234 + 1.1235 + SFTK_FIPSCHECK(); 1.1236 + CHECK_FORK(); 1.1237 + 1.1238 + /* all secret keys must be sensitive, if the upper level code tries to say 1.1239 + * otherwise, reject it. */ 1.1240 + boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE); 1.1241 + if (boolptr != NULL) { 1.1242 + if (!(*boolptr)) { 1.1243 + return CKR_ATTRIBUTE_VALUE_INVALID; 1.1244 + } 1.1245 + } 1.1246 + 1.1247 + rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); 1.1248 + if (sftk_audit_enabled) { 1.1249 + sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv); 1.1250 + } 1.1251 + return rv; 1.1252 +} 1.1253 + 1.1254 + 1.1255 +/* FC_GenerateKeyPair generates a public-key/private-key pair, 1.1256 + * creating new key objects. */ 1.1257 + CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession, 1.1258 + CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, 1.1259 + CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, 1.1260 + CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, 1.1261 + CK_OBJECT_HANDLE_PTR phPrivateKey) { 1.1262 + CK_BBOOL *boolptr; 1.1263 + CK_RV crv; 1.1264 + 1.1265 + SFTK_FIPSCHECK(); 1.1266 + CHECK_FORK(); 1.1267 + 1.1268 + 1.1269 + /* all private keys must be sensitive, if the upper level code tries to say 1.1270 + * otherwise, reject it. */ 1.1271 + boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate, 1.1272 + usPrivateKeyAttributeCount, CKA_SENSITIVE); 1.1273 + if (boolptr != NULL) { 1.1274 + if (!(*boolptr)) { 1.1275 + return CKR_ATTRIBUTE_VALUE_INVALID; 1.1276 + } 1.1277 + } 1.1278 + crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate, 1.1279 + usPublicKeyAttributeCount,pPrivateKeyTemplate, 1.1280 + usPrivateKeyAttributeCount,phPublicKey,phPrivateKey); 1.1281 + if (crv == CKR_GENERAL_ERROR) { 1.1282 + /* pairwise consistency check failed. */ 1.1283 + sftk_fatalError = PR_TRUE; 1.1284 + } 1.1285 + if (sftk_audit_enabled) { 1.1286 + sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate, 1.1287 + usPublicKeyAttributeCount,pPrivateKeyTemplate, 1.1288 + usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv); 1.1289 + } 1.1290 + return crv; 1.1291 +} 1.1292 + 1.1293 + 1.1294 +/* FC_WrapKey wraps (i.e., encrypts) a key. */ 1.1295 + CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession, 1.1296 + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, 1.1297 + CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, 1.1298 + CK_ULONG_PTR pulWrappedKeyLen) { 1.1299 + SFTK_FIPSCHECK(); 1.1300 + CHECK_FORK(); 1.1301 + 1.1302 + rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, 1.1303 + pulWrappedKeyLen); 1.1304 + if (sftk_audit_enabled) { 1.1305 + sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, 1.1306 + pulWrappedKeyLen,rv); 1.1307 + } 1.1308 + return rv; 1.1309 +} 1.1310 + 1.1311 + 1.1312 +/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ 1.1313 + CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession, 1.1314 + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, 1.1315 + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, 1.1316 + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 1.1317 + CK_OBJECT_HANDLE_PTR phKey) { 1.1318 + CK_BBOOL *boolptr; 1.1319 + 1.1320 + SFTK_FIPSCHECK(); 1.1321 + CHECK_FORK(); 1.1322 + 1.1323 + /* all secret keys must be sensitive, if the upper level code tries to say 1.1324 + * otherwise, reject it. */ 1.1325 + boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, 1.1326 + ulAttributeCount, CKA_SENSITIVE); 1.1327 + if (boolptr != NULL) { 1.1328 + if (!(*boolptr)) { 1.1329 + return CKR_ATTRIBUTE_VALUE_INVALID; 1.1330 + } 1.1331 + } 1.1332 + rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, 1.1333 + ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey); 1.1334 + if (sftk_audit_enabled) { 1.1335 + sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, 1.1336 + ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv); 1.1337 + } 1.1338 + return rv; 1.1339 +} 1.1340 + 1.1341 + 1.1342 +/* FC_DeriveKey derives a key from a base key, creating a new key object. */ 1.1343 + CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession, 1.1344 + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, 1.1345 + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 1.1346 + CK_OBJECT_HANDLE_PTR phKey) { 1.1347 + CK_BBOOL *boolptr; 1.1348 + 1.1349 + SFTK_FIPSCHECK(); 1.1350 + CHECK_FORK(); 1.1351 + 1.1352 + /* all secret keys must be sensitive, if the upper level code tries to say 1.1353 + * otherwise, reject it. */ 1.1354 + boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, 1.1355 + ulAttributeCount, CKA_SENSITIVE); 1.1356 + if (boolptr != NULL) { 1.1357 + if (!(*boolptr)) { 1.1358 + return CKR_ATTRIBUTE_VALUE_INVALID; 1.1359 + } 1.1360 + } 1.1361 + rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, 1.1362 + ulAttributeCount, phKey); 1.1363 + if (sftk_audit_enabled) { 1.1364 + sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate, 1.1365 + ulAttributeCount,phKey,rv); 1.1366 + } 1.1367 + return rv; 1.1368 +} 1.1369 + 1.1370 +/* 1.1371 + **************************** Radom Functions: ************************ 1.1372 + */ 1.1373 + 1.1374 +/* FC_SeedRandom mixes additional seed material into the token's random number 1.1375 + * generator. */ 1.1376 + CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, 1.1377 + CK_ULONG usSeedLen) { 1.1378 + CK_RV crv; 1.1379 + 1.1380 + SFTK_FIPSFATALCHECK(); 1.1381 + CHECK_FORK(); 1.1382 + 1.1383 + crv = NSC_SeedRandom(hSession,pSeed,usSeedLen); 1.1384 + if (crv != CKR_OK) { 1.1385 + sftk_fatalError = PR_TRUE; 1.1386 + } 1.1387 + return crv; 1.1388 +} 1.1389 + 1.1390 + 1.1391 +/* FC_GenerateRandom generates random data. */ 1.1392 + CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession, 1.1393 + CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) { 1.1394 + CK_RV crv; 1.1395 + 1.1396 + CHECK_FORK(); 1.1397 + 1.1398 + SFTK_FIPSFATALCHECK(); 1.1399 + crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen); 1.1400 + if (crv != CKR_OK) { 1.1401 + sftk_fatalError = PR_TRUE; 1.1402 + if (sftk_audit_enabled) { 1.1403 + char msg[128]; 1.1404 + PR_snprintf(msg,sizeof msg, 1.1405 + "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " 1.1406 + "ulRandomLen=%lu)=0x%08lX " 1.1407 + "self-test: continuous RNG test failed", 1.1408 + (PRUint32)hSession,pRandomData, 1.1409 + (PRUint32)ulRandomLen,(PRUint32)crv); 1.1410 + sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); 1.1411 + } 1.1412 + } 1.1413 + return crv; 1.1414 +} 1.1415 + 1.1416 + 1.1417 +/* FC_GetFunctionStatus obtains an updated status of a function running 1.1418 + * in parallel with an application. */ 1.1419 + CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) { 1.1420 + SFTK_FIPSCHECK(); 1.1421 + CHECK_FORK(); 1.1422 + 1.1423 + return NSC_GetFunctionStatus(hSession); 1.1424 +} 1.1425 + 1.1426 + 1.1427 +/* FC_CancelFunction cancels a function running in parallel */ 1.1428 + CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) { 1.1429 + SFTK_FIPSCHECK(); 1.1430 + CHECK_FORK(); 1.1431 + 1.1432 + return NSC_CancelFunction(hSession); 1.1433 +} 1.1434 + 1.1435 +/* 1.1436 + **************************** Version 1.1 Functions: ************************ 1.1437 + */ 1.1438 + 1.1439 +/* FC_GetOperationState saves the state of the cryptographic 1.1440 + *operation in a session. */ 1.1441 +CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession, 1.1442 + CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) { 1.1443 + SFTK_FIPSFATALCHECK(); 1.1444 + CHECK_FORK(); 1.1445 + 1.1446 + return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen); 1.1447 +} 1.1448 + 1.1449 + 1.1450 +/* FC_SetOperationState restores the state of the cryptographic operation 1.1451 + * in a session. */ 1.1452 +CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession, 1.1453 + CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, 1.1454 + CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) { 1.1455 + SFTK_FIPSFATALCHECK(); 1.1456 + CHECK_FORK(); 1.1457 + 1.1458 + return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen, 1.1459 + hEncryptionKey,hAuthenticationKey); 1.1460 +} 1.1461 + 1.1462 +/* FC_FindObjectsFinal finishes a search for token and session objects. */ 1.1463 +CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) { 1.1464 + /* let publically readable object be found */ 1.1465 + SFTK_FIPSFATALCHECK(); 1.1466 + CHECK_FORK(); 1.1467 + 1.1468 + return NSC_FindObjectsFinal(hSession); 1.1469 +} 1.1470 + 1.1471 + 1.1472 +/* Dual-function cryptographic operations */ 1.1473 + 1.1474 +/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption 1.1475 + * operation. */ 1.1476 +CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1.1477 + CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 1.1478 + CK_ULONG_PTR pulEncryptedPartLen) { 1.1479 + SFTK_FIPSCHECK(); 1.1480 + CHECK_FORK(); 1.1481 + 1.1482 + return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart, 1.1483 + pulEncryptedPartLen); 1.1484 +} 1.1485 + 1.1486 + 1.1487 +/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting 1.1488 + * operation. */ 1.1489 +CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, 1.1490 + CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, 1.1491 + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { 1.1492 + SFTK_FIPSCHECK(); 1.1493 + CHECK_FORK(); 1.1494 + 1.1495 + return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen, 1.1496 + pPart,pulPartLen); 1.1497 +} 1.1498 + 1.1499 +/* FC_SignEncryptUpdate continues a multiple-part signing and encryption 1.1500 + * operation. */ 1.1501 +CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 1.1502 + CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 1.1503 + CK_ULONG_PTR pulEncryptedPartLen) { 1.1504 + SFTK_FIPSCHECK(); 1.1505 + CHECK_FORK(); 1.1506 + 1.1507 + return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart, 1.1508 + pulEncryptedPartLen); 1.1509 +} 1.1510 + 1.1511 +/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify 1.1512 + * operation. */ 1.1513 +CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, 1.1514 + CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, 1.1515 + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { 1.1516 + SFTK_FIPSCHECK(); 1.1517 + CHECK_FORK(); 1.1518 + 1.1519 + return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen, 1.1520 + pData,pulDataLen); 1.1521 +} 1.1522 + 1.1523 + 1.1524 +/* FC_DigestKey continues a multi-part message-digesting operation, 1.1525 + * by digesting the value of a secret key as part of the data already digested. 1.1526 + */ 1.1527 +CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { 1.1528 + SFTK_FIPSCHECK(); 1.1529 + CHECK_FORK(); 1.1530 + 1.1531 + rv = NSC_DigestKey(hSession,hKey); 1.1532 + if (sftk_audit_enabled) { 1.1533 + sftk_AuditDigestKey(hSession,hKey,rv); 1.1534 + } 1.1535 + return rv; 1.1536 +} 1.1537 + 1.1538 + 1.1539 +CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, 1.1540 + CK_VOID_PTR pReserved) 1.1541 +{ 1.1542 + CHECK_FORK(); 1.1543 + 1.1544 + return NSC_WaitForSlotEvent(flags, pSlot, pReserved); 1.1545 +}