/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * This file implements PKCS 11 on top of our existing security modules * * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. * This implementation has two slots: * slot 1 is our generic crypto support. It does not require login * (unless you've enabled FIPS). It supports Public Key ops, and all they * bulk ciphers and hashes. It can also support Private Key ops for imported * Private keys. It does not have any token storage. * slot 2 is our private key support. It requires a login before use. It * can store Private Keys and Certs as token objects. Currently only private * keys and their associated Certificates are saved on the token. * * In this implementation, session objects are only visible to the session * that created or generated them.
*/ #include"seccomon.h" #include"softoken.h" #include"lowkeyi.h" #include"pkcs11.h" #include"pkcs11i.h" #include"prenv.h" #include"prprf.h"
/* * This function returns * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not * consist of characters from three or more character classes. * - CKR_OK otherwise * * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters. * We define five character classes: digits (0-9), ASCII lowercase letters, * ASCII uppercase letters, ASCII non-alphanumeric characters (such as * space and punctuation marks), and non-ASCII characters. If an ASCII * uppercase letter is the first character of the password/PIN, the * uppercase letter is not counted toward its character class. Similarly, * if a digit is the last character of the password/PIN, the digit is not * counted toward its character class. * * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum * password/PIN length checks, they check the length in bytes as opposed * to characters. To meet the minimum password/PIN guessing probability * requirements in FIPS 140-2, we need to check the length in characters.
*/ static CK_RV
sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
{ unsignedint i; int nchar = 0; /* number of characters */ int ntrail = 0; /* number of trailing bytes to follow */ int ndigit = 0; /* number of decimal digits */ int nlower = 0; /* number of ASCII lowercase letters */ int nupper = 0; /* number of ASCII uppercase letters */ int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */ int nnonascii = 0; /* number of non-ASCII characters */ int nclass; /* number of character classes */
for (i = 0; i < ulPinLen; i++) { unsignedint byte = pPin[i];
if (ntrail) { if ((byte & 0xc0) != 0x80) { /* illegal */
nchar = -1; break;
} if (--ntrail == 0) {
nchar++;
nnonascii++;
} continue;
} if ((byte & 0x80) == 0x00) { /* single-byte (ASCII) character */
nchar++; if (isdigit(byte)) { if (i < ulPinLen - 1) {
ndigit++;
}
} elseif (islower(byte)) {
nlower++;
} elseif (isupper(byte)) { if (i > 0) {
nupper++;
}
} else {
nnonalnum++;
}
} elseif ((byte & 0xe0) == 0xc0) { /* leading byte of two-byte character */
ntrail = 1;
} elseif ((byte & 0xf0) == 0xe0) { /* leading byte of three-byte character */
ntrail = 2;
} elseif ((byte & 0xf8) == 0xf0) { /* leading byte of four-byte character */
ntrail = 3;
} else { /* illegal */
nchar = -1; break;
}
} if (nchar == -1) { /* illegal UTF8 string */ return CKR_PIN_INVALID;
} if (nchar < FIPS_MIN_PIN) { return CKR_PIN_LEN_RANGE;
}
nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
(nnonalnum != 0) + (nnonascii != 0); if (nclass < 3) { return CKR_PIN_LEN_RANGE;
} return CKR_OK;
}
/* FIPS required checks before any useful cryptographic services */ static CK_RV
sftk_fipsCheck(void)
{ if (sftk_fatalError) return CKR_DEVICE_ERROR; if (isLevel2 && !isLoggedIn) return CKR_USER_NOT_LOGGED_IN; return CKR_OK;
}
int
sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType)
{ switch (auditType) { case NSS_AUDIT_ACCESS_KEY: case NSS_AUDIT_CHANGE_KEY: case NSS_AUDIT_COPY_KEY: case NSS_AUDIT_DERIVE_KEY: case NSS_AUDIT_DESTROY_KEY: case NSS_AUDIT_DIGEST_KEY: case NSS_AUDIT_GENERATE_KEY: case NSS_AUDIT_LOAD_KEY: case NSS_AUDIT_UNWRAP_KEY: case NSS_AUDIT_WRAP_KEY: return AUDIT_CRYPTO_KEY_USER; case NSS_AUDIT_CRYPT: return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER : AUDIT_CRYPTO_KEY_USER; case NSS_AUDIT_FIPS_STATE: case NSS_AUDIT_INIT_PIN: case NSS_AUDIT_INIT_TOKEN: case NSS_AUDIT_SET_PIN: return AUDIT_CRYPTO_PARAM_CHANGE_USER; case NSS_AUDIT_SELF_TEST: return AUDIT_CRYPTO_TEST_USER; case NSS_AUDIT_LOGIN: return AUDIT_CRYPTO_LOGIN; case NSS_AUDIT_LOGOUT: return AUDIT_CRYPTO_LOGOUT; /* we skip the fault case here so we can get compiler * warnings if new 'NSSAuditType's are added without
* added them to this list, defaults fall through */
} /* default */ return AUDIT_CRYPTO_PARAM_CHANGE_USER;
} #endif
/********************************************************************** * * FIPS 140 auditable event logging *
**********************************************************************/
PRBool sftk_audit_enabled = PR_FALSE;
/* * Each audit record must have the following information: * - Date and time of the event * - Type of event * - user (subject) identity * - outcome (success or failure) of the event * - process ID * - name (ID) of the object * - for changes to data (except for authentication data and CSPs), the new * and old values of the data * - for authentication attempts, the origin of the attempt (e.g., terminal * identifier) * - for assuming a role, the type of role, and the location of the request
*/ void
sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType, constchar *msg)
{ #ifdef NSS_AUDIT_WITH_SYSLOG int level;
switch (severity) { case NSS_AUDIT_ERROR:
level = LOG_ERR; break; case NSS_AUDIT_WARNING:
level = LOG_WARNING; break; default:
level = LOG_INFO; break;
} /* timestamp is provided by syslog in the message header */
syslog(level | LOG_USER /* facility */, "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s",
(int)getpid(), (int)getuid(), msg); #ifdef LINUX if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { return;
} if (libaudit_handle) { int audit_fd; int linuxAuditType; int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); if (!message) { return;
}
audit_fd = audit_open_func(); if (audit_fd < 0) {
PR_smprintf_free(message); return;
}
linuxAuditType = sftk_mapLinuxAuditType(severity, auditType); if (audit_log_user_message_func) {
audit_log_user_message_func(audit_fd, linuxAuditType, message,
NULL, NULL, NULL, result);
} else {
audit_send_user_message_func(audit_fd, linuxAuditType, message);
}
audit_close_func(audit_fd);
PR_smprintf_free(message);
} #endif/* LINUX */ #else /* do nothing */ #endif
}
/********************************************************************** * * Start of PKCS 11 functions *
**********************************************************************/ /* return the function list */
CK_RV
FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
{
/* if we have the forcePOST flag on, rerun the integrity checks */ /* we need to know this before we fully parse the arguments in
* nsc_CommonInitialize, so read it now */
rerun = sftk_RawArgHasFlag("flags", "forcePost", pReserved);
/* At this point we should have already done post and integrity checks. * if we haven't, it probably means the FIPS product has not been installed * or the tests failed. Don't let an application try to enter FIPS mode. This
* also forces the tests to be rerun if forcePOST is set. */
crv = sftk_FIPSEntryOK(rerun); if (crv != CKR_OK) {
sftk_fatalError = PR_TRUE;
fc_log_init_error(crv); return crv;
}
sftk_ForkReset(pReserved, &crv);
if (nsf_init) { return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
crv = nsc_CommonInitialize(pReserved, PR_TRUE);
/* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ if (crv != CKR_OK) {
sftk_fatalError = PR_TRUE; return crv;
}
sftk_fatalError = PR_FALSE; /* any error has been reset */
nsf_init = PR_TRUE;
isLevel2 = PR_TRUE; /* assume level 2 unless we learn otherwise */
return CKR_OK;
}
/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
CK_RV
FC_Finalize(CK_VOID_PTR pReserved)
{
CK_RV crv;
if (sftk_ForkReset(pReserved, &crv)) { return crv;
}
/* FC_GetInfo returns general information about PKCS #11. */
CK_RV
FC_GetInfo(CK_INFO_PTR pInfo)
{
CHECK_FORK();
return NSC_GetInfo(pInfo);
}
/* FC_GetInfo returns general information about PKCS #11. */
CK_RV
FC_GetInfoV2(CK_INFO_PTR pInfo)
{
CHECK_FORK();
return NSC_GetInfoV2(pInfo);
}
/* FC_GetSlotList obtains a list of slots in the system. */
CK_RV
FC_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
{
CHECK_FORK();
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV
FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{
CHECK_FORK();
return NSC_GetSlotInfo(slotID, pInfo);
}
/*FC_GetTokenInfo obtains information about a particular token in the system.*/
CK_RV
FC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
{
CK_RV crv;
CHECK_FORK();
crv = NSC_GetTokenInfo(slotID, pInfo); if (crv == CKR_OK) { /* use the global database to figure out if we are running in
* FIPS 140 Level 1 or Level 2 */ if (slotID == FIPS_SLOT_ID &&
(pInfo->flags & CKF_LOGIN_REQUIRED) == 0) {
isLevel2 = PR_FALSE;
}
} return crv;
}
/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
CK_RV
FC_GetMechanismList(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount)
{
CHECK_FORK();
SFTK_FIPSFATALCHECK(); if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
} /* FIPS Slots support all functions */ return NSC_GetMechanismList(slotID, pMechanismList, pusCount);
}
/* FC_GetMechanismInfo obtains information about a particular mechanism
* possibly supported by a token. */
CK_RV
FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR pInfo)
{
CHECK_FORK();
SFTK_FIPSFATALCHECK(); if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
} /* FIPS Slots support all functions */ return NSC_GetMechanismInfo(slotID, type, pInfo);
}
/* FC_GetMechanismInfoV2 same as FC_GetMechanismInfo except the Message
* flags have been stripped out */
CK_RV
FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR pInfo)
{
CHECK_FORK();
SFTK_FIPSFATALCHECK(); if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
} /* FIPS Slots support all functions */ return NSC_GetMechanismInfoV2(slotID, type, pInfo);
}
crv = NSC_InitToken(slotID, pPin, usPinLen, pLabel); if (sftk_audit_enabled) { char msg[128];
NSSAuditSeverity severity = (crv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; /* pLabel points to a 32-byte label, which is not null-terminated */
PR_snprintf(msg, sizeof msg, "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX",
(PRUint32)slotID, pLabel, (PRUint32)crv);
sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg);
} return crv;
}
/* FC_InitPIN initializes the normal user's PIN. */
CK_RV
FC_InitPIN(CK_SESSION_HANDLE hSession,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
{
CK_RV rv;
CHECK_FORK();
if (sftk_fatalError) return CKR_DEVICE_ERROR; /* NSC_InitPIN will only work once per database. We can either initialize * it to level1 (pin len == 0) or level2. If we initialize to level 2, then
* we need to make sure the pin meets FIPS requirements */ if ((ulPinLen == 0) || ((rv = sftk_newPinCheck(pPin, ulPinLen)) == CKR_OK)) {
rv = NSC_InitPIN(hSession, pPin, ulPinLen); if ((rv == CKR_OK) &&
(sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) {
isLevel2 = (ulPinLen > 0) ? PR_TRUE : PR_FALSE;
}
} if (sftk_audit_enabled) { char msg[128];
NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
PR_snprintf(msg, sizeof msg, "C_InitPIN(hSession=0x%08lX)=0x%08lX",
(PRUint32)hSession, (PRUint32)rv);
sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg);
} return rv;
}
/* FC_SetPIN modifies the PIN of user that is currently logged in. */ /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
CK_RV
FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen)
{
CK_RV rv;
if (isLevel2 || usNewLen > 0) {
rv = sftk_newPinCheck(pNewPin, usNewLen); if (rv != CKR_OK) { goto loser;
}
rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); if (rv != CKR_OK) { goto loser;
} if (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID) { /* if we set the password in level1 we now go * to level2. NOTE: we don't allow the user to
* go from level2 to level1 */
isLevel2 = PR_TRUE;
}
} else { /* here both old and new passwords are empty, but we need to
* call NSC_SetPIN to force rekey the database entries */
PORT_Assert(usNewLen == 0);
rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); if (rv != CKR_OK) { goto loser;
}
}
/* FC_OpenSession opens a session between an application and a token. */
CK_RV
FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
{
SFTK_FIPSFATALCHECK();
/* FC_GetAttributeValue obtains the value of one or more object attributes. */
CK_RV
FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
{
CK_RV rv;
CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
/* FC_SetAttributeValue modifies the value of one or more object attributes */
CK_RV
FC_SetAttributeValue(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
{
CK_RV rv;
CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
/* FC_FindObjectsInit initializes a search for token and session objects
* that match a template. */
CK_RV
FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount)
{ /* let publically readable object be found */ unsignedint i;
CK_RV rv;
PRBool needLogin = PR_FALSE;
CHECK_FORK();
SFTK_FIPSFATALCHECK();
for (i = 0; i < usCount; i++) {
CK_OBJECT_CLASS class; if (pTemplate[i].type != CKA_CLASS) { continue;
} if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) { continue;
} if (pTemplate[i].pValue == NULL) { continue;
} class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) {
needLogin = PR_TRUE; break;
}
} if (needLogin) { if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
} return NSC_FindObjectsInit(hSession, pTemplate, usCount);
}
/* FC_FindObjects continues a search for token and session objects
* that match a template, obtaining additional object handles. */
CK_RV
FC_FindObjects(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount,
CK_ULONG_PTR pusObjectCount)
{
CHECK_FORK();
/* let publically readable object be found */
SFTK_FIPSFATALCHECK(); return NSC_FindObjects(hSession, phObject, usMaxObjectCount,
pusObjectCount);
}
/* FC_SignInit initializes a signature (private key encryption) operation, * where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature */
CK_RV
FC_SignInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_Sign signs (encrypts with private key) data in a single part, * where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature */
CK_RV
FC_Sign(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature,
CK_ULONG_PTR pusSignatureLen)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_SignUpdate continues a multiple-part signature operation, * where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature */
CK_RV
FC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
CK_ULONG usPartLen)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* ************** Crypto Functions: Sign Recover ************************
*/ /* FC_SignRecoverInit initializes a signature operation, * where the (digest) data can be recovered from the signature.
* E.g. encryption with the user's private key */
CK_RV
FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_SignRecover signs data in a single operation * where the (digest) data can be recovered from the signature.
* E.g. encryption with the user's private key */
CK_RV
FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_VerifyInit initializes a verification operation, * where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature (e.g. DSA) */
CK_RV
FC_VerifyInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_Verify verifies a signature in a single-part operation, * where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature */
CK_RV
FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen)
{ /* make sure we're legal */
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_VerifyUpdate continues a multiple-part verification operation, * where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature */
CK_RV
FC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
CK_ULONG usPartLen)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_VerifyRecoverInit initializes a signature verification operation, * where the data is recovered from the signature.
* E.g. Decryption with the user's public key */
CK_RV
FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_VerifyRecover verifies a signature in a single-part operation, * where the data is recovered from the signature.
* E.g. Decryption with the user's public key */
CK_RV
FC_VerifyRecover(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen,
CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen)
{
SFTK_FIPSCHECK();
CHECK_FORK();
/* FC_GenerateKey generates a secret key, creating a new key object. */
CK_RV
FC_GenerateKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phKey)
{
CK_BBOOL *boolptr;
SFTK_FIPSCHECK();
CHECK_FORK();
/* all secret keys must be sensitive, if the upper level code tries to say
* otherwise, reject it. */
boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID;
}
}
/* all secret keys must be sensitive, if the upper level code tries to say
* otherwise, reject it. */
boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate,
ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID;
}
}
rv = NSC_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey,
ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey); if (sftk_audit_enabled) {
sftk_AuditUnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey,
ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey, rv);
} return rv;
}
/* FC_DeriveKey derives a key from a base key, creating a new key object. */
CK_RV
FC_DeriveKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey)
{
CK_BBOOL *boolptr;
SFTK_FIPSCHECK();
CHECK_FORK();
/* all secret keys must be sensitive, if the upper level code tries to say
* otherwise, reject it. */
boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate,
ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID;
}
}
rv = NSC_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate,
ulAttributeCount, phKey); if (sftk_audit_enabled) {
sftk_AuditDeriveKey(hSession, pMechanism, hBaseKey, pTemplate,
ulAttributeCount, phKey, rv);
} return rv;
}
/* **************************** Radom Functions: ************************
*/
/* FC_SeedRandom mixes additional seed material into the token's random number
* generator. */
CK_RV
FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
CK_ULONG usSeedLen)
{
CK_RV crv;
/* FC_GetFunctionStatus obtains an updated status of a function running
* in parallel with an application. */
CK_RV
FC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
{
SFTK_FIPSCHECK();
CHECK_FORK();
return NSC_GetFunctionStatus(hSession);
}
/* FC_CancelFunction cancels a function running in parallel */
CK_RV
FC_CancelFunction(CK_SESSION_HANDLE hSession)
{
SFTK_FIPSCHECK();
CHECK_FORK();
return NSC_CancelFunction(hSession);
}
/* **************************** Version 1.1 Functions: ************************
*/
/* FC_GetOperationState saves the state of the cryptographic
*operation in a session. */
CK_RV
FC_GetOperationState(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
{
SFTK_FIPSFATALCHECK();
CHECK_FORK();
/* FC_SetOperationState restores the state of the cryptographic operation
* in a session. */
CK_RV
FC_SetOperationState(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
{
SFTK_FIPSFATALCHECK();
CHECK_FORK();
/* FC_FindObjectsFinal finishes a search for token and session objects. */
CK_RV
FC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
{ /* let publically readable object be found */
SFTK_FIPSFATALCHECK();
CHECK_FORK();
/* FC_DigestKey continues a multi-part message-digesting operation, * by digesting the value of a secret key as part of the data already digested.
*/
CK_RV
FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
{
SFTK_FIPSCHECK();
CHECK_FORK();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.