security/nss/lib/softoken/fipstokn.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 /*
michael@0 5 * This file implements PKCS 11 on top of our existing security modules
michael@0 6 *
michael@0 7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
michael@0 8 * This implementation has two slots:
michael@0 9 * slot 1 is our generic crypto support. It does not require login
michael@0 10 * (unless you've enabled FIPS). It supports Public Key ops, and all they
michael@0 11 * bulk ciphers and hashes. It can also support Private Key ops for imported
michael@0 12 * Private keys. It does not have any token storage.
michael@0 13 * slot 2 is our private key support. It requires a login before use. It
michael@0 14 * can store Private Keys and Certs as token objects. Currently only private
michael@0 15 * keys and their associated Certificates are saved on the token.
michael@0 16 *
michael@0 17 * In this implementation, session objects are only visible to the session
michael@0 18 * that created or generated them.
michael@0 19 */
michael@0 20 #include "seccomon.h"
michael@0 21 #include "softoken.h"
michael@0 22 #include "lowkeyi.h"
michael@0 23 #include "pkcs11.h"
michael@0 24 #include "pkcs11i.h"
michael@0 25 #include "prenv.h"
michael@0 26 #include "prprf.h"
michael@0 27
michael@0 28 #include <ctype.h>
michael@0 29
michael@0 30 #ifdef XP_UNIX
michael@0 31 #define NSS_AUDIT_WITH_SYSLOG 1
michael@0 32 #include <syslog.h>
michael@0 33 #include <unistd.h>
michael@0 34 #endif
michael@0 35
michael@0 36 #ifdef LINUX
michael@0 37 #include <pthread.h>
michael@0 38 #include <dlfcn.h>
michael@0 39 #define LIBAUDIT_NAME "libaudit.so.0"
michael@0 40 #ifndef AUDIT_CRYPTO_TEST_USER
michael@0 41 #define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */
michael@0 42 #define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */
michael@0 43 #define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */
michael@0 44 #define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */
michael@0 45 #define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */
michael@0 46 #define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomize */
michael@0 47 #endif
michael@0 48 static void *libaudit_handle;
michael@0 49 static int (*audit_open_func)(void);
michael@0 50 static void (*audit_close_func)(int fd);
michael@0 51 static int (*audit_log_user_message_func)(int audit_fd, int type,
michael@0 52 const char *message, const char *hostname, const char *addr,
michael@0 53 const char *tty, int result);
michael@0 54 static int (*audit_send_user_message_func)(int fd, int type,
michael@0 55 const char *message);
michael@0 56
michael@0 57 static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT;
michael@0 58
michael@0 59 static void
michael@0 60 libaudit_init(void)
michael@0 61 {
michael@0 62 libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY);
michael@0 63 if (!libaudit_handle) {
michael@0 64 return;
michael@0 65 }
michael@0 66 audit_open_func = dlsym(libaudit_handle, "audit_open");
michael@0 67 audit_close_func = dlsym(libaudit_handle, "audit_close");
michael@0 68 /*
michael@0 69 * audit_send_user_message is the older function.
michael@0 70 * audit_log_user_message, if available, is preferred.
michael@0 71 */
michael@0 72 audit_log_user_message_func = dlsym(libaudit_handle,
michael@0 73 "audit_log_user_message");
michael@0 74 if (!audit_log_user_message_func) {
michael@0 75 audit_send_user_message_func = dlsym(libaudit_handle,
michael@0 76 "audit_send_user_message");
michael@0 77 }
michael@0 78 if (!audit_open_func || !audit_close_func ||
michael@0 79 (!audit_log_user_message_func && !audit_send_user_message_func)) {
michael@0 80 dlclose(libaudit_handle);
michael@0 81 libaudit_handle = NULL;
michael@0 82 audit_open_func = NULL;
michael@0 83 audit_close_func = NULL;
michael@0 84 audit_log_user_message_func = NULL;
michael@0 85 audit_send_user_message_func = NULL;
michael@0 86 }
michael@0 87 }
michael@0 88 #endif /* LINUX */
michael@0 89
michael@0 90
michael@0 91 /*
michael@0 92 * ******************** Password Utilities *******************************
michael@0 93 */
michael@0 94 static PRBool isLoggedIn = PR_FALSE;
michael@0 95 PRBool sftk_fatalError = PR_FALSE;
michael@0 96
michael@0 97 /*
michael@0 98 * This function returns
michael@0 99 * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string
michael@0 100 * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not
michael@0 101 * consist of characters from three or more character classes.
michael@0 102 * - CKR_OK otherwise
michael@0 103 *
michael@0 104 * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters.
michael@0 105 * We define five character classes: digits (0-9), ASCII lowercase letters,
michael@0 106 * ASCII uppercase letters, ASCII non-alphanumeric characters (such as
michael@0 107 * space and punctuation marks), and non-ASCII characters. If an ASCII
michael@0 108 * uppercase letter is the first character of the password/PIN, the
michael@0 109 * uppercase letter is not counted toward its character class. Similarly,
michael@0 110 * if a digit is the last character of the password/PIN, the digit is not
michael@0 111 * counted toward its character class.
michael@0 112 *
michael@0 113 * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum
michael@0 114 * password/PIN length checks, they check the length in bytes as opposed
michael@0 115 * to characters. To meet the minimum password/PIN guessing probability
michael@0 116 * requirements in FIPS 140-2, we need to check the length in characters.
michael@0 117 */
michael@0 118 static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
michael@0 119 unsigned int i;
michael@0 120 int nchar = 0; /* number of characters */
michael@0 121 int ntrail = 0; /* number of trailing bytes to follow */
michael@0 122 int ndigit = 0; /* number of decimal digits */
michael@0 123 int nlower = 0; /* number of ASCII lowercase letters */
michael@0 124 int nupper = 0; /* number of ASCII uppercase letters */
michael@0 125 int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */
michael@0 126 int nnonascii = 0; /* number of non-ASCII characters */
michael@0 127 int nclass; /* number of character classes */
michael@0 128
michael@0 129 for (i = 0; i < ulPinLen; i++) {
michael@0 130 unsigned int byte = pPin[i];
michael@0 131
michael@0 132 if (ntrail) {
michael@0 133 if ((byte & 0xc0) != 0x80) {
michael@0 134 /* illegal */
michael@0 135 nchar = -1;
michael@0 136 break;
michael@0 137 }
michael@0 138 if (--ntrail == 0) {
michael@0 139 nchar++;
michael@0 140 nnonascii++;
michael@0 141 }
michael@0 142 continue;
michael@0 143 }
michael@0 144 if ((byte & 0x80) == 0x00) {
michael@0 145 /* single-byte (ASCII) character */
michael@0 146 nchar++;
michael@0 147 if (isdigit(byte)) {
michael@0 148 if (i < ulPinLen - 1) {
michael@0 149 ndigit++;
michael@0 150 }
michael@0 151 } else if (islower(byte)) {
michael@0 152 nlower++;
michael@0 153 } else if (isupper(byte)) {
michael@0 154 if (i > 0) {
michael@0 155 nupper++;
michael@0 156 }
michael@0 157 } else {
michael@0 158 nnonalnum++;
michael@0 159 }
michael@0 160 } else if ((byte & 0xe0) == 0xc0) {
michael@0 161 /* leading byte of two-byte character */
michael@0 162 ntrail = 1;
michael@0 163 } else if ((byte & 0xf0) == 0xe0) {
michael@0 164 /* leading byte of three-byte character */
michael@0 165 ntrail = 2;
michael@0 166 } else if ((byte & 0xf8) == 0xf0) {
michael@0 167 /* leading byte of four-byte character */
michael@0 168 ntrail = 3;
michael@0 169 } else {
michael@0 170 /* illegal */
michael@0 171 nchar = -1;
michael@0 172 break;
michael@0 173 }
michael@0 174 }
michael@0 175 if (nchar == -1) {
michael@0 176 /* illegal UTF8 string */
michael@0 177 return CKR_PIN_INVALID;
michael@0 178 }
michael@0 179 if (nchar < FIPS_MIN_PIN) {
michael@0 180 return CKR_PIN_LEN_RANGE;
michael@0 181 }
michael@0 182 nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
michael@0 183 (nnonalnum != 0) + (nnonascii != 0);
michael@0 184 if (nclass < 3) {
michael@0 185 return CKR_PIN_LEN_RANGE;
michael@0 186 }
michael@0 187 return CKR_OK;
michael@0 188 }
michael@0 189
michael@0 190
michael@0 191 /* FIPS required checks before any useful cryptographic services */
michael@0 192 static CK_RV sftk_fipsCheck(void) {
michael@0 193 if (sftk_fatalError)
michael@0 194 return CKR_DEVICE_ERROR;
michael@0 195 if (!isLoggedIn)
michael@0 196 return CKR_USER_NOT_LOGGED_IN;
michael@0 197 return CKR_OK;
michael@0 198 }
michael@0 199
michael@0 200
michael@0 201 #define SFTK_FIPSCHECK() \
michael@0 202 CK_RV rv; \
michael@0 203 if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
michael@0 204
michael@0 205 #define SFTK_FIPSFATALCHECK() \
michael@0 206 if (sftk_fatalError) return CKR_DEVICE_ERROR;
michael@0 207
michael@0 208
michael@0 209 /* grab an attribute out of a raw template */
michael@0 210 void *
michael@0 211 fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
michael@0 212 CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
michael@0 213 {
michael@0 214 int i;
michael@0 215
michael@0 216 for (i=0; i < (int) ulCount; i++) {
michael@0 217 if (pTemplate[i].type == type) {
michael@0 218 return pTemplate[i].pValue;
michael@0 219 }
michael@0 220 }
michael@0 221 return NULL;
michael@0 222 }
michael@0 223
michael@0 224
michael@0 225 #define __PASTE(x,y) x##y
michael@0 226
michael@0 227 /* ------------- forward declare all the NSC_ functions ------------- */
michael@0 228 #undef CK_NEED_ARG_LIST
michael@0 229 #undef CK_PKCS11_FUNCTION_INFO
michael@0 230
michael@0 231 #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name)
michael@0 232 #define CK_NEED_ARG_LIST 1
michael@0 233
michael@0 234 #include "pkcs11f.h"
michael@0 235
michael@0 236 /* ------------- forward declare all the FIPS functions ------------- */
michael@0 237 #undef CK_NEED_ARG_LIST
michael@0 238 #undef CK_PKCS11_FUNCTION_INFO
michael@0 239
michael@0 240 #define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
michael@0 241 #define CK_NEED_ARG_LIST 1
michael@0 242
michael@0 243 #include "pkcs11f.h"
michael@0 244
michael@0 245 /* ------------- build the CK_CRYPTO_TABLE ------------------------- */
michael@0 246 static CK_FUNCTION_LIST sftk_fipsTable = {
michael@0 247 { 1, 10 },
michael@0 248
michael@0 249 #undef CK_NEED_ARG_LIST
michael@0 250 #undef CK_PKCS11_FUNCTION_INFO
michael@0 251
michael@0 252 #define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
michael@0 253
michael@0 254
michael@0 255 #include "pkcs11f.h"
michael@0 256
michael@0 257 };
michael@0 258
michael@0 259 #undef CK_NEED_ARG_LIST
michael@0 260 #undef CK_PKCS11_FUNCTION_INFO
michael@0 261
michael@0 262
michael@0 263 #undef __PASTE
michael@0 264
michael@0 265 /* CKO_NOT_A_KEY can be any object class that's not a key object. */
michael@0 266 #define CKO_NOT_A_KEY CKO_DATA
michael@0 267
michael@0 268 #define SFTK_IS_KEY_OBJECT(objClass) \
michael@0 269 (((objClass) == CKO_PUBLIC_KEY) || \
michael@0 270 ((objClass) == CKO_PRIVATE_KEY) || \
michael@0 271 ((objClass) == CKO_SECRET_KEY))
michael@0 272
michael@0 273 #define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \
michael@0 274 (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY))
michael@0 275
michael@0 276 static CK_RV
michael@0 277 sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession,
michael@0 278 CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass)
michael@0 279 {
michael@0 280 CK_RV rv;
michael@0 281 CK_ATTRIBUTE class;
michael@0 282 class.type = CKA_CLASS;
michael@0 283 class.pValue = pObjClass;
michael@0 284 class.ulValueLen = sizeof(*pObjClass);
michael@0 285 rv = NSC_GetAttributeValue(hSession, hObject, &class, 1);
michael@0 286 if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) {
michael@0 287 rv = sftk_fipsCheck();
michael@0 288 }
michael@0 289 return rv;
michael@0 290 }
michael@0 291
michael@0 292 #ifdef LINUX
michael@0 293
michael@0 294 int
michael@0 295 sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType)
michael@0 296 {
michael@0 297 switch (auditType) {
michael@0 298 case NSS_AUDIT_ACCESS_KEY:
michael@0 299 case NSS_AUDIT_CHANGE_KEY:
michael@0 300 case NSS_AUDIT_COPY_KEY:
michael@0 301 case NSS_AUDIT_DERIVE_KEY:
michael@0 302 case NSS_AUDIT_DESTROY_KEY:
michael@0 303 case NSS_AUDIT_DIGEST_KEY:
michael@0 304 case NSS_AUDIT_GENERATE_KEY:
michael@0 305 case NSS_AUDIT_LOAD_KEY:
michael@0 306 case NSS_AUDIT_UNWRAP_KEY:
michael@0 307 case NSS_AUDIT_WRAP_KEY:
michael@0 308 return AUDIT_CRYPTO_KEY_USER;
michael@0 309 case NSS_AUDIT_CRYPT:
michael@0 310 return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER :
michael@0 311 AUDIT_CRYPTO_KEY_USER;
michael@0 312 case NSS_AUDIT_FIPS_STATE:
michael@0 313 case NSS_AUDIT_INIT_PIN:
michael@0 314 case NSS_AUDIT_INIT_TOKEN:
michael@0 315 case NSS_AUDIT_SET_PIN:
michael@0 316 return AUDIT_CRYPTO_PARAM_CHANGE_USER;
michael@0 317 case NSS_AUDIT_SELF_TEST:
michael@0 318 return AUDIT_CRYPTO_TEST_USER;
michael@0 319 case NSS_AUDIT_LOGIN:
michael@0 320 return AUDIT_CRYPTO_LOGIN;
michael@0 321 case NSS_AUDIT_LOGOUT:
michael@0 322 return AUDIT_CRYPTO_LOGOUT;
michael@0 323 /* we skip the fault case here so we can get compiler
michael@0 324 * warnings if new 'NSSAuditType's are added without
michael@0 325 * added them to this list, defaults fall through */
michael@0 326 }
michael@0 327 /* default */
michael@0 328 return AUDIT_CRYPTO_PARAM_CHANGE_USER;
michael@0 329 }
michael@0 330 #endif
michael@0 331
michael@0 332
michael@0 333 /**********************************************************************
michael@0 334 *
michael@0 335 * FIPS 140 auditable event logging
michael@0 336 *
michael@0 337 **********************************************************************/
michael@0 338
michael@0 339 PRBool sftk_audit_enabled = PR_FALSE;
michael@0 340
michael@0 341 /*
michael@0 342 * Each audit record must have the following information:
michael@0 343 * - Date and time of the event
michael@0 344 * - Type of event
michael@0 345 * - user (subject) identity
michael@0 346 * - outcome (success or failure) of the event
michael@0 347 * - process ID
michael@0 348 * - name (ID) of the object
michael@0 349 * - for changes to data (except for authentication data and CSPs), the new
michael@0 350 * and old values of the data
michael@0 351 * - for authentication attempts, the origin of the attempt (e.g., terminal
michael@0 352 * identifier)
michael@0 353 * - for assuming a role, the type of role, and the location of the request
michael@0 354 */
michael@0 355 void
michael@0 356 sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType,
michael@0 357 const char *msg)
michael@0 358 {
michael@0 359 #ifdef NSS_AUDIT_WITH_SYSLOG
michael@0 360 int level;
michael@0 361
michael@0 362 switch (severity) {
michael@0 363 case NSS_AUDIT_ERROR:
michael@0 364 level = LOG_ERR;
michael@0 365 break;
michael@0 366 case NSS_AUDIT_WARNING:
michael@0 367 level = LOG_WARNING;
michael@0 368 break;
michael@0 369 default:
michael@0 370 level = LOG_INFO;
michael@0 371 break;
michael@0 372 }
michael@0 373 /* timestamp is provided by syslog in the message header */
michael@0 374 syslog(level | LOG_USER /* facility */,
michael@0 375 "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s",
michael@0 376 (int)getpid(), (int)getuid(), msg);
michael@0 377 #ifdef LINUX
michael@0 378 if (pthread_once(&libaudit_once_control, libaudit_init) != 0) {
michael@0 379 return;
michael@0 380 }
michael@0 381 if (libaudit_handle) {
michael@0 382 int audit_fd;
michael@0 383 int linuxAuditType;
michael@0 384 int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */
michael@0 385 char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
michael@0 386 if (!message) {
michael@0 387 return;
michael@0 388 }
michael@0 389 audit_fd = audit_open_func();
michael@0 390 if (audit_fd < 0) {
michael@0 391 PR_smprintf_free(message);
michael@0 392 return;
michael@0 393 }
michael@0 394 linuxAuditType = sftk_mapLinuxAuditType(severity, auditType);
michael@0 395 if (audit_log_user_message_func) {
michael@0 396 audit_log_user_message_func(audit_fd, linuxAuditType, message,
michael@0 397 NULL, NULL, NULL, result);
michael@0 398 } else {
michael@0 399 audit_send_user_message_func(audit_fd, linuxAuditType, message);
michael@0 400 }
michael@0 401 audit_close_func(audit_fd);
michael@0 402 PR_smprintf_free(message);
michael@0 403 }
michael@0 404 #endif /* LINUX */
michael@0 405 #else
michael@0 406 /* do nothing */
michael@0 407 #endif
michael@0 408 }
michael@0 409
michael@0 410
michael@0 411 /**********************************************************************
michael@0 412 *
michael@0 413 * Start of PKCS 11 functions
michael@0 414 *
michael@0 415 **********************************************************************/
michael@0 416 /* return the function list */
michael@0 417 CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
michael@0 418
michael@0 419 CHECK_FORK();
michael@0 420
michael@0 421 *pFunctionList = &sftk_fipsTable;
michael@0 422 return CKR_OK;
michael@0 423 }
michael@0 424
michael@0 425 /* sigh global so pkcs11 can read it */
michael@0 426 PRBool nsf_init = PR_FALSE;
michael@0 427
michael@0 428 /* FC_Initialize initializes the PKCS #11 library. */
michael@0 429 CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
michael@0 430 const char *envp;
michael@0 431 CK_RV crv;
michael@0 432
michael@0 433 sftk_ForkReset(pReserved, &crv);
michael@0 434
michael@0 435 if (nsf_init) {
michael@0 436 return CKR_CRYPTOKI_ALREADY_INITIALIZED;
michael@0 437 }
michael@0 438
michael@0 439 if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
michael@0 440 sftk_audit_enabled = (atoi(envp) == 1);
michael@0 441 }
michael@0 442
michael@0 443 crv = nsc_CommonInitialize(pReserved, PR_TRUE);
michael@0 444
michael@0 445 /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
michael@0 446 if (crv != CKR_OK) {
michael@0 447 sftk_fatalError = PR_TRUE;
michael@0 448 return crv;
michael@0 449 }
michael@0 450
michael@0 451 sftk_fatalError = PR_FALSE; /* any error has been reset */
michael@0 452
michael@0 453 crv = sftk_fipsPowerUpSelfTest();
michael@0 454 if (crv != CKR_OK) {
michael@0 455 nsc_CommonFinalize(NULL, PR_TRUE);
michael@0 456 sftk_fatalError = PR_TRUE;
michael@0 457 if (sftk_audit_enabled) {
michael@0 458 char msg[128];
michael@0 459 PR_snprintf(msg,sizeof msg,
michael@0 460 "C_Initialize()=0x%08lX "
michael@0 461 "power-up self-tests failed",
michael@0 462 (PRUint32)crv);
michael@0 463 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
michael@0 464 }
michael@0 465 return crv;
michael@0 466 }
michael@0 467 nsf_init = PR_TRUE;
michael@0 468
michael@0 469 return CKR_OK;
michael@0 470 }
michael@0 471
michael@0 472 /*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
michael@0 473 CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
michael@0 474 CK_RV crv;
michael@0 475
michael@0 476 if (sftk_ForkReset(pReserved, &crv)) {
michael@0 477 return crv;
michael@0 478 }
michael@0 479
michael@0 480 if (!nsf_init) {
michael@0 481 return CKR_OK;
michael@0 482 }
michael@0 483
michael@0 484 crv = nsc_CommonFinalize (pReserved, PR_TRUE);
michael@0 485
michael@0 486 nsf_init = (PRBool) !(crv == CKR_OK);
michael@0 487 return crv;
michael@0 488 }
michael@0 489
michael@0 490
michael@0 491 /* FC_GetInfo returns general information about PKCS #11. */
michael@0 492 CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
michael@0 493 CHECK_FORK();
michael@0 494
michael@0 495 return NSC_GetInfo(pInfo);
michael@0 496 }
michael@0 497
michael@0 498 /* FC_GetSlotList obtains a list of slots in the system. */
michael@0 499 CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
michael@0 500 CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
michael@0 501 CHECK_FORK();
michael@0 502
michael@0 503 return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount,
michael@0 504 NSC_FIPS_MODULE);
michael@0 505 }
michael@0 506
michael@0 507 /* FC_GetSlotInfo obtains information about a particular slot in the system. */
michael@0 508 CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
michael@0 509 CHECK_FORK();
michael@0 510
michael@0 511 return NSC_GetSlotInfo(slotID,pInfo);
michael@0 512 }
michael@0 513
michael@0 514
michael@0 515 /*FC_GetTokenInfo obtains information about a particular token in the system.*/
michael@0 516 CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
michael@0 517 CK_RV crv;
michael@0 518
michael@0 519 CHECK_FORK();
michael@0 520
michael@0 521 crv = NSC_GetTokenInfo(slotID,pInfo);
michael@0 522 if (crv == CKR_OK)
michael@0 523 pInfo->flags |= CKF_LOGIN_REQUIRED;
michael@0 524 return crv;
michael@0 525
michael@0 526 }
michael@0 527
michael@0 528
michael@0 529
michael@0 530 /*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
michael@0 531 CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
michael@0 532 CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
michael@0 533 CHECK_FORK();
michael@0 534
michael@0 535 SFTK_FIPSFATALCHECK();
michael@0 536 if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
michael@0 537 /* FIPS Slot supports all functions */
michael@0 538 return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
michael@0 539 }
michael@0 540
michael@0 541
michael@0 542 /* FC_GetMechanismInfo obtains information about a particular mechanism
michael@0 543 * possibly supported by a token. */
michael@0 544 CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
michael@0 545 CK_MECHANISM_INFO_PTR pInfo) {
michael@0 546 CHECK_FORK();
michael@0 547
michael@0 548 SFTK_FIPSFATALCHECK();
michael@0 549 if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
michael@0 550 /* FIPS Slot supports all functions */
michael@0 551 return NSC_GetMechanismInfo(slotID,type,pInfo);
michael@0 552 }
michael@0 553
michael@0 554
michael@0 555 /* FC_InitToken initializes a token. */
michael@0 556 CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
michael@0 557 CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
michael@0 558 CK_RV crv;
michael@0 559
michael@0 560 CHECK_FORK();
michael@0 561
michael@0 562 crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel);
michael@0 563 if (sftk_audit_enabled) {
michael@0 564 char msg[128];
michael@0 565 NSSAuditSeverity severity = (crv == CKR_OK) ?
michael@0 566 NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
michael@0 567 /* pLabel points to a 32-byte label, which is not null-terminated */
michael@0 568 PR_snprintf(msg,sizeof msg,
michael@0 569 "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX",
michael@0 570 (PRUint32)slotID,pLabel,(PRUint32)crv);
michael@0 571 sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg);
michael@0 572 }
michael@0 573 return crv;
michael@0 574 }
michael@0 575
michael@0 576
michael@0 577 /* FC_InitPIN initializes the normal user's PIN. */
michael@0 578 CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
michael@0 579 CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
michael@0 580 CK_RV rv;
michael@0 581
michael@0 582 CHECK_FORK();
michael@0 583
michael@0 584 if (sftk_fatalError) return CKR_DEVICE_ERROR;
michael@0 585 if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
michael@0 586 rv = NSC_InitPIN(hSession,pPin,ulPinLen);
michael@0 587 }
michael@0 588 if (sftk_audit_enabled) {
michael@0 589 char msg[128];
michael@0 590 NSSAuditSeverity severity = (rv == CKR_OK) ?
michael@0 591 NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
michael@0 592 PR_snprintf(msg,sizeof msg,
michael@0 593 "C_InitPIN(hSession=0x%08lX)=0x%08lX",
michael@0 594 (PRUint32)hSession,(PRUint32)rv);
michael@0 595 sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg);
michael@0 596 }
michael@0 597 return rv;
michael@0 598 }
michael@0 599
michael@0 600
michael@0 601 /* FC_SetPIN modifies the PIN of user that is currently logged in. */
michael@0 602 /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
michael@0 603 CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
michael@0 604 CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
michael@0 605 CK_RV rv;
michael@0 606
michael@0 607 CHECK_FORK();
michael@0 608
michael@0 609 if ((rv = sftk_fipsCheck()) == CKR_OK &&
michael@0 610 (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
michael@0 611 rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
michael@0 612 }
michael@0 613 if (sftk_audit_enabled) {
michael@0 614 char msg[128];
michael@0 615 NSSAuditSeverity severity = (rv == CKR_OK) ?
michael@0 616 NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
michael@0 617 PR_snprintf(msg,sizeof msg,
michael@0 618 "C_SetPIN(hSession=0x%08lX)=0x%08lX",
michael@0 619 (PRUint32)hSession,(PRUint32)rv);
michael@0 620 sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg);
michael@0 621 }
michael@0 622 return rv;
michael@0 623 }
michael@0 624
michael@0 625 /* FC_OpenSession opens a session between an application and a token. */
michael@0 626 CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
michael@0 627 CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) {
michael@0 628 SFTK_FIPSFATALCHECK();
michael@0 629
michael@0 630 CHECK_FORK();
michael@0 631
michael@0 632 return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession);
michael@0 633 }
michael@0 634
michael@0 635
michael@0 636 /* FC_CloseSession closes a session between an application and a token. */
michael@0 637 CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) {
michael@0 638 CHECK_FORK();
michael@0 639
michael@0 640 return NSC_CloseSession(hSession);
michael@0 641 }
michael@0 642
michael@0 643
michael@0 644 /* FC_CloseAllSessions closes all sessions with a token. */
michael@0 645 CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) {
michael@0 646
michael@0 647 CHECK_FORK();
michael@0 648
michael@0 649 return NSC_CloseAllSessions (slotID);
michael@0 650 }
michael@0 651
michael@0 652
michael@0 653 /* FC_GetSessionInfo obtains information about the session. */
michael@0 654 CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
michael@0 655 CK_SESSION_INFO_PTR pInfo) {
michael@0 656 CK_RV rv;
michael@0 657 SFTK_FIPSFATALCHECK();
michael@0 658
michael@0 659 CHECK_FORK();
michael@0 660
michael@0 661 rv = NSC_GetSessionInfo(hSession,pInfo);
michael@0 662 if (rv == CKR_OK) {
michael@0 663 if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) {
michael@0 664 pInfo->state = CKS_RO_USER_FUNCTIONS;
michael@0 665 }
michael@0 666 if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) {
michael@0 667 pInfo->state = CKS_RW_USER_FUNCTIONS;
michael@0 668 }
michael@0 669 }
michael@0 670 return rv;
michael@0 671 }
michael@0 672
michael@0 673 /* FC_Login logs a user into a token. */
michael@0 674 CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
michael@0 675 CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
michael@0 676 CK_RV rv;
michael@0 677 PRBool successful;
michael@0 678 if (sftk_fatalError) return CKR_DEVICE_ERROR;
michael@0 679 rv = NSC_Login(hSession,userType,pPin,usPinLen);
michael@0 680 successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN);
michael@0 681 if (successful)
michael@0 682 isLoggedIn = PR_TRUE;
michael@0 683 if (sftk_audit_enabled) {
michael@0 684 char msg[128];
michael@0 685 NSSAuditSeverity severity;
michael@0 686 severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
michael@0 687 PR_snprintf(msg,sizeof msg,
michael@0 688 "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX",
michael@0 689 (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
michael@0 690 sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg);
michael@0 691 }
michael@0 692 return rv;
michael@0 693 }
michael@0 694
michael@0 695 /* FC_Logout logs a user out from a token. */
michael@0 696 CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
michael@0 697 CK_RV rv;
michael@0 698
michael@0 699 CHECK_FORK();
michael@0 700
michael@0 701 if ((rv = sftk_fipsCheck()) == CKR_OK) {
michael@0 702 rv = NSC_Logout(hSession);
michael@0 703 isLoggedIn = PR_FALSE;
michael@0 704 }
michael@0 705 if (sftk_audit_enabled) {
michael@0 706 char msg[128];
michael@0 707 NSSAuditSeverity severity = (rv == CKR_OK) ?
michael@0 708 NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
michael@0 709 PR_snprintf(msg,sizeof msg,
michael@0 710 "C_Logout(hSession=0x%08lX)=0x%08lX",
michael@0 711 (PRUint32)hSession,(PRUint32)rv);
michael@0 712 sftk_LogAuditMessage(severity, NSS_AUDIT_LOGOUT, msg);
michael@0 713 }
michael@0 714 return rv;
michael@0 715 }
michael@0 716
michael@0 717
michael@0 718 /* FC_CreateObject creates a new object. */
michael@0 719 CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession,
michael@0 720 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
michael@0 721 CK_OBJECT_HANDLE_PTR phObject) {
michael@0 722 CK_OBJECT_CLASS * classptr;
michael@0 723
michael@0 724 SFTK_FIPSCHECK();
michael@0 725 CHECK_FORK();
michael@0 726
michael@0 727 classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
michael@0 728 if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
michael@0 729
michael@0 730 /* FIPS can't create keys from raw key material */
michael@0 731 if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) {
michael@0 732 rv = CKR_ATTRIBUTE_VALUE_INVALID;
michael@0 733 } else {
michael@0 734 rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
michael@0 735 }
michael@0 736 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) {
michael@0 737 sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv);
michael@0 738 }
michael@0 739 return rv;
michael@0 740 }
michael@0 741
michael@0 742
michael@0 743
michael@0 744
michael@0 745
michael@0 746 /* FC_CopyObject copies an object, creating a new object for the copy. */
michael@0 747 CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
michael@0 748 CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
michael@0 749 CK_OBJECT_HANDLE_PTR phNewObject) {
michael@0 750 CK_RV rv;
michael@0 751 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
michael@0 752
michael@0 753 CHECK_FORK();
michael@0 754
michael@0 755 SFTK_FIPSFATALCHECK();
michael@0 756 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
michael@0 757 if (rv == CKR_OK) {
michael@0 758 rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject);
michael@0 759 }
michael@0 760 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
michael@0 761 sftk_AuditCopyObject(hSession,
michael@0 762 hObject,pTemplate,ulCount,phNewObject,rv);
michael@0 763 }
michael@0 764 return rv;
michael@0 765 }
michael@0 766
michael@0 767
michael@0 768 /* FC_DestroyObject destroys an object. */
michael@0 769 CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
michael@0 770 CK_OBJECT_HANDLE hObject) {
michael@0 771 CK_RV rv;
michael@0 772 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
michael@0 773
michael@0 774 CHECK_FORK();
michael@0 775
michael@0 776 SFTK_FIPSFATALCHECK();
michael@0 777 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
michael@0 778 if (rv == CKR_OK) {
michael@0 779 rv = NSC_DestroyObject(hSession,hObject);
michael@0 780 }
michael@0 781 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
michael@0 782 sftk_AuditDestroyObject(hSession,hObject,rv);
michael@0 783 }
michael@0 784 return rv;
michael@0 785 }
michael@0 786
michael@0 787
michael@0 788 /* FC_GetObjectSize gets the size of an object in bytes. */
michael@0 789 CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
michael@0 790 CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) {
michael@0 791 CK_RV rv;
michael@0 792 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
michael@0 793
michael@0 794 CHECK_FORK();
michael@0 795
michael@0 796 SFTK_FIPSFATALCHECK();
michael@0 797 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
michael@0 798 if (rv == CKR_OK) {
michael@0 799 rv = NSC_GetObjectSize(hSession, hObject, pulSize);
michael@0 800 }
michael@0 801 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
michael@0 802 sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv);
michael@0 803 }
michael@0 804 return rv;
michael@0 805 }
michael@0 806
michael@0 807
michael@0 808 /* FC_GetAttributeValue obtains the value of one or more object attributes. */
michael@0 809 CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
michael@0 810 CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
michael@0 811 CK_RV rv;
michael@0 812 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
michael@0 813
michael@0 814 CHECK_FORK();
michael@0 815
michael@0 816 SFTK_FIPSFATALCHECK();
michael@0 817 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
michael@0 818 if (rv == CKR_OK) {
michael@0 819 rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount);
michael@0 820 }
michael@0 821 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
michael@0 822 sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
michael@0 823 }
michael@0 824 return rv;
michael@0 825 }
michael@0 826
michael@0 827
michael@0 828 /* FC_SetAttributeValue modifies the value of one or more object attributes */
michael@0 829 CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession,
michael@0 830 CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
michael@0 831 CK_RV rv;
michael@0 832 CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
michael@0 833
michael@0 834 CHECK_FORK();
michael@0 835
michael@0 836 SFTK_FIPSFATALCHECK();
michael@0 837 rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
michael@0 838 if (rv == CKR_OK) {
michael@0 839 rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount);
michael@0 840 }
michael@0 841 if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
michael@0 842 sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
michael@0 843 }
michael@0 844 return rv;
michael@0 845 }
michael@0 846
michael@0 847
michael@0 848
michael@0 849 /* FC_FindObjectsInit initializes a search for token and session objects
michael@0 850 * that match a template. */
michael@0 851 CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
michael@0 852 CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
michael@0 853 /* let publically readable object be found */
michael@0 854 unsigned int i;
michael@0 855 CK_RV rv;
michael@0 856 PRBool needLogin = PR_FALSE;
michael@0 857
michael@0 858
michael@0 859 CHECK_FORK();
michael@0 860
michael@0 861 SFTK_FIPSFATALCHECK();
michael@0 862
michael@0 863 for (i=0; i < usCount; i++) {
michael@0 864 CK_OBJECT_CLASS class;
michael@0 865 if (pTemplate[i].type != CKA_CLASS) {
michael@0 866 continue;
michael@0 867 }
michael@0 868 if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
michael@0 869 continue;
michael@0 870 }
michael@0 871 if (pTemplate[i].pValue == NULL) {
michael@0 872 continue;
michael@0 873 }
michael@0 874 class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
michael@0 875 if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) {
michael@0 876 needLogin = PR_TRUE;
michael@0 877 break;
michael@0 878 }
michael@0 879 }
michael@0 880 if (needLogin) {
michael@0 881 if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
michael@0 882 }
michael@0 883 return NSC_FindObjectsInit(hSession,pTemplate,usCount);
michael@0 884 }
michael@0 885
michael@0 886
michael@0 887 /* FC_FindObjects continues a search for token and session objects
michael@0 888 * that match a template, obtaining additional object handles. */
michael@0 889 CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession,
michael@0 890 CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount,
michael@0 891 CK_ULONG_PTR pusObjectCount) {
michael@0 892 CHECK_FORK();
michael@0 893
michael@0 894 /* let publically readable object be found */
michael@0 895 SFTK_FIPSFATALCHECK();
michael@0 896 return NSC_FindObjects(hSession,phObject,usMaxObjectCount,
michael@0 897 pusObjectCount);
michael@0 898 }
michael@0 899
michael@0 900
michael@0 901 /*
michael@0 902 ************** Crypto Functions: Encrypt ************************
michael@0 903 */
michael@0 904
michael@0 905 /* FC_EncryptInit initializes an encryption operation. */
michael@0 906 CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
michael@0 907 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
michael@0 908 SFTK_FIPSCHECK();
michael@0 909 CHECK_FORK();
michael@0 910
michael@0 911 rv = NSC_EncryptInit(hSession,pMechanism,hKey);
michael@0 912 if (sftk_audit_enabled) {
michael@0 913 sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv);
michael@0 914 }
michael@0 915 return rv;
michael@0 916 }
michael@0 917
michael@0 918 /* FC_Encrypt encrypts single-part data. */
michael@0 919 CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
michael@0 920 CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
michael@0 921 CK_ULONG_PTR pusEncryptedDataLen) {
michael@0 922 SFTK_FIPSCHECK();
michael@0 923 CHECK_FORK();
michael@0 924
michael@0 925 return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData,
michael@0 926 pusEncryptedDataLen);
michael@0 927 }
michael@0 928
michael@0 929
michael@0 930 /* FC_EncryptUpdate continues a multiple-part encryption operation. */
michael@0 931 CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession,
michael@0 932 CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,
michael@0 933 CK_ULONG_PTR pusEncryptedPartLen) {
michael@0 934 SFTK_FIPSCHECK();
michael@0 935 CHECK_FORK();
michael@0 936
michael@0 937 return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart,
michael@0 938 pusEncryptedPartLen);
michael@0 939 }
michael@0 940
michael@0 941
michael@0 942 /* FC_EncryptFinal finishes a multiple-part encryption operation. */
michael@0 943 CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession,
michael@0 944 CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) {
michael@0 945 SFTK_FIPSCHECK();
michael@0 946 CHECK_FORK();
michael@0 947
michael@0 948 return NSC_EncryptFinal(hSession,pLastEncryptedPart,
michael@0 949 pusLastEncryptedPartLen);
michael@0 950 }
michael@0 951
michael@0 952 /*
michael@0 953 ************** Crypto Functions: Decrypt ************************
michael@0 954 */
michael@0 955
michael@0 956
michael@0 957 /* FC_DecryptInit initializes a decryption operation. */
michael@0 958 CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
michael@0 959 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
michael@0 960 SFTK_FIPSCHECK();
michael@0 961 CHECK_FORK();
michael@0 962
michael@0 963 rv = NSC_DecryptInit(hSession,pMechanism,hKey);
michael@0 964 if (sftk_audit_enabled) {
michael@0 965 sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv);
michael@0 966 }
michael@0 967 return rv;
michael@0 968 }
michael@0 969
michael@0 970 /* FC_Decrypt decrypts encrypted data in a single part. */
michael@0 971 CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession,
michael@0 972 CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData,
michael@0 973 CK_ULONG_PTR pusDataLen) {
michael@0 974 SFTK_FIPSCHECK();
michael@0 975 CHECK_FORK();
michael@0 976
michael@0 977 return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData,
michael@0 978 pusDataLen);
michael@0 979 }
michael@0 980
michael@0 981
michael@0 982 /* FC_DecryptUpdate continues a multiple-part decryption operation. */
michael@0 983 CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession,
michael@0 984 CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen,
michael@0 985 CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) {
michael@0 986 SFTK_FIPSCHECK();
michael@0 987 CHECK_FORK();
michael@0 988
michael@0 989 return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen,
michael@0 990 pPart,pusPartLen);
michael@0 991 }
michael@0 992
michael@0 993
michael@0 994 /* FC_DecryptFinal finishes a multiple-part decryption operation. */
michael@0 995 CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession,
michael@0 996 CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) {
michael@0 997 SFTK_FIPSCHECK();
michael@0 998 CHECK_FORK();
michael@0 999
michael@0 1000 return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen);
michael@0 1001 }
michael@0 1002
michael@0 1003
michael@0 1004 /*
michael@0 1005 ************** Crypto Functions: Digest (HASH) ************************
michael@0 1006 */
michael@0 1007
michael@0 1008 /* FC_DigestInit initializes a message-digesting operation. */
michael@0 1009 CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession,
michael@0 1010 CK_MECHANISM_PTR pMechanism) {
michael@0 1011 SFTK_FIPSFATALCHECK();
michael@0 1012 CHECK_FORK();
michael@0 1013
michael@0 1014 return NSC_DigestInit(hSession, pMechanism);
michael@0 1015 }
michael@0 1016
michael@0 1017
michael@0 1018 /* FC_Digest digests data in a single part. */
michael@0 1019 CK_RV FC_Digest(CK_SESSION_HANDLE hSession,
michael@0 1020 CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
michael@0 1021 CK_ULONG_PTR pusDigestLen) {
michael@0 1022 SFTK_FIPSFATALCHECK();
michael@0 1023 CHECK_FORK();
michael@0 1024
michael@0 1025 return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen);
michael@0 1026 }
michael@0 1027
michael@0 1028
michael@0 1029 /* FC_DigestUpdate continues a multiple-part message-digesting operation. */
michael@0 1030 CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
michael@0 1031 CK_ULONG usPartLen) {
michael@0 1032 SFTK_FIPSFATALCHECK();
michael@0 1033 CHECK_FORK();
michael@0 1034
michael@0 1035 return NSC_DigestUpdate(hSession,pPart,usPartLen);
michael@0 1036 }
michael@0 1037
michael@0 1038
michael@0 1039 /* FC_DigestFinal finishes a multiple-part message-digesting operation. */
michael@0 1040 CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
michael@0 1041 CK_ULONG_PTR pusDigestLen) {
michael@0 1042 SFTK_FIPSFATALCHECK();
michael@0 1043 CHECK_FORK();
michael@0 1044
michael@0 1045 return NSC_DigestFinal(hSession,pDigest,pusDigestLen);
michael@0 1046 }
michael@0 1047
michael@0 1048
michael@0 1049 /*
michael@0 1050 ************** Crypto Functions: Sign ************************
michael@0 1051 */
michael@0 1052
michael@0 1053 /* FC_SignInit initializes a signature (private key encryption) operation,
michael@0 1054 * where the signature is (will be) an appendix to the data,
michael@0 1055 * and plaintext cannot be recovered from the signature */
michael@0 1056 CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
michael@0 1057 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
michael@0 1058 SFTK_FIPSCHECK();
michael@0 1059 CHECK_FORK();
michael@0 1060
michael@0 1061 rv = NSC_SignInit(hSession,pMechanism,hKey);
michael@0 1062 if (sftk_audit_enabled) {
michael@0 1063 sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv);
michael@0 1064 }
michael@0 1065 return rv;
michael@0 1066 }
michael@0 1067
michael@0 1068
michael@0 1069 /* FC_Sign signs (encrypts with private key) data in a single part,
michael@0 1070 * where the signature is (will be) an appendix to the data,
michael@0 1071 * and plaintext cannot be recovered from the signature */
michael@0 1072 CK_RV FC_Sign(CK_SESSION_HANDLE hSession,
michael@0 1073 CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature,
michael@0 1074 CK_ULONG_PTR pusSignatureLen) {
michael@0 1075 SFTK_FIPSCHECK();
michael@0 1076 CHECK_FORK();
michael@0 1077
michael@0 1078 return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen);
michael@0 1079 }
michael@0 1080
michael@0 1081
michael@0 1082 /* FC_SignUpdate continues a multiple-part signature operation,
michael@0 1083 * where the signature is (will be) an appendix to the data,
michael@0 1084 * and plaintext cannot be recovered from the signature */
michael@0 1085 CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
michael@0 1086 CK_ULONG usPartLen) {
michael@0 1087 SFTK_FIPSCHECK();
michael@0 1088 CHECK_FORK();
michael@0 1089
michael@0 1090 return NSC_SignUpdate(hSession,pPart,usPartLen);
michael@0 1091 }
michael@0 1092
michael@0 1093
michael@0 1094 /* FC_SignFinal finishes a multiple-part signature operation,
michael@0 1095 * returning the signature. */
michael@0 1096 CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
michael@0 1097 CK_ULONG_PTR pusSignatureLen) {
michael@0 1098 SFTK_FIPSCHECK();
michael@0 1099 CHECK_FORK();
michael@0 1100
michael@0 1101 return NSC_SignFinal(hSession,pSignature,pusSignatureLen);
michael@0 1102 }
michael@0 1103
michael@0 1104 /*
michael@0 1105 ************** Crypto Functions: Sign Recover ************************
michael@0 1106 */
michael@0 1107 /* FC_SignRecoverInit initializes a signature operation,
michael@0 1108 * where the (digest) data can be recovered from the signature.
michael@0 1109 * E.g. encryption with the user's private key */
michael@0 1110 CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
michael@0 1111 CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
michael@0 1112 SFTK_FIPSCHECK();
michael@0 1113 CHECK_FORK();
michael@0 1114
michael@0 1115 rv = NSC_SignRecoverInit(hSession,pMechanism,hKey);
michael@0 1116 if (sftk_audit_enabled) {
michael@0 1117 sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv);
michael@0 1118 }
michael@0 1119 return rv;
michael@0 1120 }
michael@0 1121
michael@0 1122
michael@0 1123 /* FC_SignRecover signs data in a single operation
michael@0 1124 * where the (digest) data can be recovered from the signature.
michael@0 1125 * E.g. encryption with the user's private key */
michael@0 1126 CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
michael@0 1127 CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) {
michael@0 1128 SFTK_FIPSCHECK();
michael@0 1129 CHECK_FORK();
michael@0 1130
michael@0 1131 return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen);
michael@0 1132 }
michael@0 1133
michael@0 1134 /*
michael@0 1135 ************** Crypto Functions: verify ************************
michael@0 1136 */
michael@0 1137
michael@0 1138 /* FC_VerifyInit initializes a verification operation,
michael@0 1139 * where the signature is an appendix to the data,
michael@0 1140 * and plaintext cannot be recovered from the signature (e.g. DSA) */
michael@0 1141 CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
michael@0 1142 CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
michael@0 1143 SFTK_FIPSCHECK();
michael@0 1144 CHECK_FORK();
michael@0 1145
michael@0 1146 rv = NSC_VerifyInit(hSession,pMechanism,hKey);
michael@0 1147 if (sftk_audit_enabled) {
michael@0 1148 sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv);
michael@0 1149 }
michael@0 1150 return rv;
michael@0 1151 }
michael@0 1152
michael@0 1153
michael@0 1154 /* FC_Verify verifies a signature in a single-part operation,
michael@0 1155 * where the signature is an appendix to the data,
michael@0 1156 * and plaintext cannot be recovered from the signature */
michael@0 1157 CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
michael@0 1158 CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) {
michael@0 1159 /* make sure we're legal */
michael@0 1160 SFTK_FIPSCHECK();
michael@0 1161 CHECK_FORK();
michael@0 1162
michael@0 1163 return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen);
michael@0 1164 }
michael@0 1165
michael@0 1166
michael@0 1167 /* FC_VerifyUpdate continues a multiple-part verification operation,
michael@0 1168 * where the signature is an appendix to the data,
michael@0 1169 * and plaintext cannot be recovered from the signature */
michael@0 1170 CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
michael@0 1171 CK_ULONG usPartLen) {
michael@0 1172 SFTK_FIPSCHECK();
michael@0 1173 CHECK_FORK();
michael@0 1174
michael@0 1175 return NSC_VerifyUpdate(hSession,pPart,usPartLen);
michael@0 1176 }
michael@0 1177
michael@0 1178
michael@0 1179 /* FC_VerifyFinal finishes a multiple-part verification operation,
michael@0 1180 * checking the signature. */
michael@0 1181 CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession,
michael@0 1182 CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) {
michael@0 1183 SFTK_FIPSCHECK();
michael@0 1184 CHECK_FORK();
michael@0 1185
michael@0 1186 return NSC_VerifyFinal(hSession,pSignature,usSignatureLen);
michael@0 1187 }
michael@0 1188
michael@0 1189 /*
michael@0 1190 ************** Crypto Functions: Verify Recover ************************
michael@0 1191 */
michael@0 1192
michael@0 1193 /* FC_VerifyRecoverInit initializes a signature verification operation,
michael@0 1194 * where the data is recovered from the signature.
michael@0 1195 * E.g. Decryption with the user's public key */
michael@0 1196 CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
michael@0 1197 CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
michael@0 1198 SFTK_FIPSCHECK();
michael@0 1199 CHECK_FORK();
michael@0 1200
michael@0 1201 rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
michael@0 1202 if (sftk_audit_enabled) {
michael@0 1203 sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv);
michael@0 1204 }
michael@0 1205 return rv;
michael@0 1206 }
michael@0 1207
michael@0 1208
michael@0 1209 /* FC_VerifyRecover verifies a signature in a single-part operation,
michael@0 1210 * where the data is recovered from the signature.
michael@0 1211 * E.g. Decryption with the user's public key */
michael@0 1212 CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession,
michael@0 1213 CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen,
michael@0 1214 CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) {
michael@0 1215 SFTK_FIPSCHECK();
michael@0 1216 CHECK_FORK();
michael@0 1217
michael@0 1218 return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData,
michael@0 1219 pusDataLen);
michael@0 1220 }
michael@0 1221
michael@0 1222 /*
michael@0 1223 **************************** Key Functions: ************************
michael@0 1224 */
michael@0 1225
michael@0 1226 /* FC_GenerateKey generates a secret key, creating a new key object. */
michael@0 1227 CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession,
michael@0 1228 CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
michael@0 1229 CK_OBJECT_HANDLE_PTR phKey) {
michael@0 1230 CK_BBOOL *boolptr;
michael@0 1231
michael@0 1232 SFTK_FIPSCHECK();
michael@0 1233 CHECK_FORK();
michael@0 1234
michael@0 1235 /* all secret keys must be sensitive, if the upper level code tries to say
michael@0 1236 * otherwise, reject it. */
michael@0 1237 boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
michael@0 1238 if (boolptr != NULL) {
michael@0 1239 if (!(*boolptr)) {
michael@0 1240 return CKR_ATTRIBUTE_VALUE_INVALID;
michael@0 1241 }
michael@0 1242 }
michael@0 1243
michael@0 1244 rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
michael@0 1245 if (sftk_audit_enabled) {
michael@0 1246 sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv);
michael@0 1247 }
michael@0 1248 return rv;
michael@0 1249 }
michael@0 1250
michael@0 1251
michael@0 1252 /* FC_GenerateKeyPair generates a public-key/private-key pair,
michael@0 1253 * creating new key objects. */
michael@0 1254 CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
michael@0 1255 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
michael@0 1256 CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
michael@0 1257 CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
michael@0 1258 CK_OBJECT_HANDLE_PTR phPrivateKey) {
michael@0 1259 CK_BBOOL *boolptr;
michael@0 1260 CK_RV crv;
michael@0 1261
michael@0 1262 SFTK_FIPSCHECK();
michael@0 1263 CHECK_FORK();
michael@0 1264
michael@0 1265
michael@0 1266 /* all private keys must be sensitive, if the upper level code tries to say
michael@0 1267 * otherwise, reject it. */
michael@0 1268 boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate,
michael@0 1269 usPrivateKeyAttributeCount, CKA_SENSITIVE);
michael@0 1270 if (boolptr != NULL) {
michael@0 1271 if (!(*boolptr)) {
michael@0 1272 return CKR_ATTRIBUTE_VALUE_INVALID;
michael@0 1273 }
michael@0 1274 }
michael@0 1275 crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
michael@0 1276 usPublicKeyAttributeCount,pPrivateKeyTemplate,
michael@0 1277 usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
michael@0 1278 if (crv == CKR_GENERAL_ERROR) {
michael@0 1279 /* pairwise consistency check failed. */
michael@0 1280 sftk_fatalError = PR_TRUE;
michael@0 1281 }
michael@0 1282 if (sftk_audit_enabled) {
michael@0 1283 sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate,
michael@0 1284 usPublicKeyAttributeCount,pPrivateKeyTemplate,
michael@0 1285 usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv);
michael@0 1286 }
michael@0 1287 return crv;
michael@0 1288 }
michael@0 1289
michael@0 1290
michael@0 1291 /* FC_WrapKey wraps (i.e., encrypts) a key. */
michael@0 1292 CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
michael@0 1293 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
michael@0 1294 CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
michael@0 1295 CK_ULONG_PTR pulWrappedKeyLen) {
michael@0 1296 SFTK_FIPSCHECK();
michael@0 1297 CHECK_FORK();
michael@0 1298
michael@0 1299 rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
michael@0 1300 pulWrappedKeyLen);
michael@0 1301 if (sftk_audit_enabled) {
michael@0 1302 sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
michael@0 1303 pulWrappedKeyLen,rv);
michael@0 1304 }
michael@0 1305 return rv;
michael@0 1306 }
michael@0 1307
michael@0 1308
michael@0 1309 /* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
michael@0 1310 CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
michael@0 1311 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
michael@0 1312 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
michael@0 1313 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
michael@0 1314 CK_OBJECT_HANDLE_PTR phKey) {
michael@0 1315 CK_BBOOL *boolptr;
michael@0 1316
michael@0 1317 SFTK_FIPSCHECK();
michael@0 1318 CHECK_FORK();
michael@0 1319
michael@0 1320 /* all secret keys must be sensitive, if the upper level code tries to say
michael@0 1321 * otherwise, reject it. */
michael@0 1322 boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
michael@0 1323 ulAttributeCount, CKA_SENSITIVE);
michael@0 1324 if (boolptr != NULL) {
michael@0 1325 if (!(*boolptr)) {
michael@0 1326 return CKR_ATTRIBUTE_VALUE_INVALID;
michael@0 1327 }
michael@0 1328 }
michael@0 1329 rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
michael@0 1330 ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey);
michael@0 1331 if (sftk_audit_enabled) {
michael@0 1332 sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
michael@0 1333 ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv);
michael@0 1334 }
michael@0 1335 return rv;
michael@0 1336 }
michael@0 1337
michael@0 1338
michael@0 1339 /* FC_DeriveKey derives a key from a base key, creating a new key object. */
michael@0 1340 CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession,
michael@0 1341 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
michael@0 1342 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
michael@0 1343 CK_OBJECT_HANDLE_PTR phKey) {
michael@0 1344 CK_BBOOL *boolptr;
michael@0 1345
michael@0 1346 SFTK_FIPSCHECK();
michael@0 1347 CHECK_FORK();
michael@0 1348
michael@0 1349 /* all secret keys must be sensitive, if the upper level code tries to say
michael@0 1350 * otherwise, reject it. */
michael@0 1351 boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
michael@0 1352 ulAttributeCount, CKA_SENSITIVE);
michael@0 1353 if (boolptr != NULL) {
michael@0 1354 if (!(*boolptr)) {
michael@0 1355 return CKR_ATTRIBUTE_VALUE_INVALID;
michael@0 1356 }
michael@0 1357 }
michael@0 1358 rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
michael@0 1359 ulAttributeCount, phKey);
michael@0 1360 if (sftk_audit_enabled) {
michael@0 1361 sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
michael@0 1362 ulAttributeCount,phKey,rv);
michael@0 1363 }
michael@0 1364 return rv;
michael@0 1365 }
michael@0 1366
michael@0 1367 /*
michael@0 1368 **************************** Radom Functions: ************************
michael@0 1369 */
michael@0 1370
michael@0 1371 /* FC_SeedRandom mixes additional seed material into the token's random number
michael@0 1372 * generator. */
michael@0 1373 CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
michael@0 1374 CK_ULONG usSeedLen) {
michael@0 1375 CK_RV crv;
michael@0 1376
michael@0 1377 SFTK_FIPSFATALCHECK();
michael@0 1378 CHECK_FORK();
michael@0 1379
michael@0 1380 crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
michael@0 1381 if (crv != CKR_OK) {
michael@0 1382 sftk_fatalError = PR_TRUE;
michael@0 1383 }
michael@0 1384 return crv;
michael@0 1385 }
michael@0 1386
michael@0 1387
michael@0 1388 /* FC_GenerateRandom generates random data. */
michael@0 1389 CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
michael@0 1390 CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) {
michael@0 1391 CK_RV crv;
michael@0 1392
michael@0 1393 CHECK_FORK();
michael@0 1394
michael@0 1395 SFTK_FIPSFATALCHECK();
michael@0 1396 crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
michael@0 1397 if (crv != CKR_OK) {
michael@0 1398 sftk_fatalError = PR_TRUE;
michael@0 1399 if (sftk_audit_enabled) {
michael@0 1400 char msg[128];
michael@0 1401 PR_snprintf(msg,sizeof msg,
michael@0 1402 "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, "
michael@0 1403 "ulRandomLen=%lu)=0x%08lX "
michael@0 1404 "self-test: continuous RNG test failed",
michael@0 1405 (PRUint32)hSession,pRandomData,
michael@0 1406 (PRUint32)ulRandomLen,(PRUint32)crv);
michael@0 1407 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
michael@0 1408 }
michael@0 1409 }
michael@0 1410 return crv;
michael@0 1411 }
michael@0 1412
michael@0 1413
michael@0 1414 /* FC_GetFunctionStatus obtains an updated status of a function running
michael@0 1415 * in parallel with an application. */
michael@0 1416 CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
michael@0 1417 SFTK_FIPSCHECK();
michael@0 1418 CHECK_FORK();
michael@0 1419
michael@0 1420 return NSC_GetFunctionStatus(hSession);
michael@0 1421 }
michael@0 1422
michael@0 1423
michael@0 1424 /* FC_CancelFunction cancels a function running in parallel */
michael@0 1425 CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) {
michael@0 1426 SFTK_FIPSCHECK();
michael@0 1427 CHECK_FORK();
michael@0 1428
michael@0 1429 return NSC_CancelFunction(hSession);
michael@0 1430 }
michael@0 1431
michael@0 1432 /*
michael@0 1433 **************************** Version 1.1 Functions: ************************
michael@0 1434 */
michael@0 1435
michael@0 1436 /* FC_GetOperationState saves the state of the cryptographic
michael@0 1437 *operation in a session. */
michael@0 1438 CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession,
michael@0 1439 CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) {
michael@0 1440 SFTK_FIPSFATALCHECK();
michael@0 1441 CHECK_FORK();
michael@0 1442
michael@0 1443 return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen);
michael@0 1444 }
michael@0 1445
michael@0 1446
michael@0 1447 /* FC_SetOperationState restores the state of the cryptographic operation
michael@0 1448 * in a session. */
michael@0 1449 CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession,
michael@0 1450 CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
michael@0 1451 CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) {
michael@0 1452 SFTK_FIPSFATALCHECK();
michael@0 1453 CHECK_FORK();
michael@0 1454
michael@0 1455 return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen,
michael@0 1456 hEncryptionKey,hAuthenticationKey);
michael@0 1457 }
michael@0 1458
michael@0 1459 /* FC_FindObjectsFinal finishes a search for token and session objects. */
michael@0 1460 CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
michael@0 1461 /* let publically readable object be found */
michael@0 1462 SFTK_FIPSFATALCHECK();
michael@0 1463 CHECK_FORK();
michael@0 1464
michael@0 1465 return NSC_FindObjectsFinal(hSession);
michael@0 1466 }
michael@0 1467
michael@0 1468
michael@0 1469 /* Dual-function cryptographic operations */
michael@0 1470
michael@0 1471 /* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption
michael@0 1472 * operation. */
michael@0 1473 CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
michael@0 1474 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
michael@0 1475 CK_ULONG_PTR pulEncryptedPartLen) {
michael@0 1476 SFTK_FIPSCHECK();
michael@0 1477 CHECK_FORK();
michael@0 1478
michael@0 1479 return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
michael@0 1480 pulEncryptedPartLen);
michael@0 1481 }
michael@0 1482
michael@0 1483
michael@0 1484 /* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting
michael@0 1485 * operation. */
michael@0 1486 CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
michael@0 1487 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
michael@0 1488 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) {
michael@0 1489 SFTK_FIPSCHECK();
michael@0 1490 CHECK_FORK();
michael@0 1491
michael@0 1492 return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen,
michael@0 1493 pPart,pulPartLen);
michael@0 1494 }
michael@0 1495
michael@0 1496 /* FC_SignEncryptUpdate continues a multiple-part signing and encryption
michael@0 1497 * operation. */
michael@0 1498 CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
michael@0 1499 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
michael@0 1500 CK_ULONG_PTR pulEncryptedPartLen) {
michael@0 1501 SFTK_FIPSCHECK();
michael@0 1502 CHECK_FORK();
michael@0 1503
michael@0 1504 return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
michael@0 1505 pulEncryptedPartLen);
michael@0 1506 }
michael@0 1507
michael@0 1508 /* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify
michael@0 1509 * operation. */
michael@0 1510 CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
michael@0 1511 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
michael@0 1512 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) {
michael@0 1513 SFTK_FIPSCHECK();
michael@0 1514 CHECK_FORK();
michael@0 1515
michael@0 1516 return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
michael@0 1517 pData,pulDataLen);
michael@0 1518 }
michael@0 1519
michael@0 1520
michael@0 1521 /* FC_DigestKey continues a multi-part message-digesting operation,
michael@0 1522 * by digesting the value of a secret key as part of the data already digested.
michael@0 1523 */
michael@0 1524 CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
michael@0 1525 SFTK_FIPSCHECK();
michael@0 1526 CHECK_FORK();
michael@0 1527
michael@0 1528 rv = NSC_DigestKey(hSession,hKey);
michael@0 1529 if (sftk_audit_enabled) {
michael@0 1530 sftk_AuditDigestKey(hSession,hKey,rv);
michael@0 1531 }
michael@0 1532 return rv;
michael@0 1533 }
michael@0 1534
michael@0 1535
michael@0 1536 CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
michael@0 1537 CK_VOID_PTR pReserved)
michael@0 1538 {
michael@0 1539 CHECK_FORK();
michael@0 1540
michael@0 1541 return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
michael@0 1542 }

mercurial