summaryrefslogtreecommitdiff
path: root/security/nss/lib/softoken
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/softoken')
-rw-r--r--security/nss/lib/softoken/config.mk1
-rw-r--r--security/nss/lib/softoken/dbinit.c1
-rw-r--r--security/nss/lib/softoken/dbmshim.c8
-rw-r--r--security/nss/lib/softoken/ecdecode.c16
-rw-r--r--security/nss/lib/softoken/fipsaudt.c351
-rw-r--r--security/nss/lib/softoken/fipstest.c876
-rw-r--r--security/nss/lib/softoken/fipstokn.c514
-rw-r--r--security/nss/lib/softoken/keydb.c101
-rw-r--r--security/nss/lib/softoken/lowcert.c6
-rw-r--r--security/nss/lib/softoken/lowkey.c1
-rw-r--r--security/nss/lib/softoken/lowpbe.c20
-rw-r--r--security/nss/lib/softoken/manifest.mn7
-rw-r--r--security/nss/lib/softoken/pcert.h12
-rw-r--r--security/nss/lib/softoken/pcertdb.c234
-rw-r--r--security/nss/lib/softoken/pcertt.h14
-rw-r--r--security/nss/lib/softoken/pk11db.c7
-rw-r--r--security/nss/lib/softoken/pkcs11.c257
-rw-r--r--security/nss/lib/softoken/pkcs11c.c429
-rw-r--r--security/nss/lib/softoken/pkcs11i.h21
-rw-r--r--security/nss/lib/softoken/pkcs11u.c43
-rw-r--r--security/nss/lib/softoken/rsawrapr.c57
-rw-r--r--security/nss/lib/softoken/softkver.c6
-rw-r--r--security/nss/lib/softoken/softkver.h66
-rw-r--r--security/nss/lib/softoken/softoken.h97
-rw-r--r--security/nss/lib/softoken/softokn.rc19
-rw-r--r--security/nss/lib/softoken/softoknt.h9
26 files changed, 2437 insertions, 736 deletions
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
index 2e097c8a5..bc48130aa 100644
--- a/security/nss/lib/softoken/config.mk
+++ b/security/nss/lib/softoken/config.mk
@@ -91,6 +91,7 @@ ifeq ($(OS_TARGET),SunOS)
# The -R '$ORIGIN' linker option instructs this library to search for its
# dependencies in the same directory where it resides.
MKSHLIB += -R '$$ORIGIN'
+OS_LIBS += -lbsm
endif
ifeq ($(OS_TARGET),WINCE)
diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c
index 2b7f81a73..d1f7fd303 100644
--- a/security/nss/lib/softoken/dbinit.c
+++ b/security/nss/lib/softoken/dbinit.c
@@ -291,6 +291,7 @@ sftk_freeCertDB(NSSLOWCERTCertDBHandle *certHandle)
PRInt32 ref = PR_AtomicDecrement(&certHandle->ref);
if (ref == 0) {
nsslowcert_ClosePermCertDB(certHandle);
+ PORT_Free(certHandle);
}
}
diff --git a/security/nss/lib/softoken/dbmshim.c b/security/nss/lib/softoken/dbmshim.c
index 04c291d7f..f75f4d70d 100644
--- a/security/nss/lib/softoken/dbmshim.c
+++ b/security/nss/lib/softoken/dbmshim.c
@@ -406,14 +406,6 @@ dbs_readBlob(DBS *dbsp, DBT *data)
loser:
/* preserve the error code */
error = PR_GetError();
- if (addr) {
- if (mapfile) {
- PORT_Assert(len != -1);
- PR_MemUnmap(addr,len);
- } else {
- PORT_Free(addr);
- }
- }
if (mapfile) {
PR_CloseFileMap(mapfile);
}
diff --git a/security/nss/lib/softoken/ecdecode.c b/security/nss/lib/softoken/ecdecode.c
index e649ff899..dbf1cb3f8 100644
--- a/security/nss/lib/softoken/ecdecode.c
+++ b/security/nss/lib/softoken/ecdecode.c
@@ -49,7 +49,12 @@
#define CHECK_OK(func) if (func == NULL) goto cleanup
#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
-/* Initializes a SECItem from a hexadecimal string */
+/*
+ * Initializes a SECItem from a hexadecimal string
+ *
+ * Warning: This function ignores leading 00's, so any leading 00's
+ * in the hexadecimal string must be optional.
+ */
static SECItem *
hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str)
{
@@ -59,6 +64,12 @@ hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str)
if ((tmp % 2) != 0) return NULL;
+ /* skip leading 00's unless the hex string is "00" */
+ while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
+ str += 2;
+ tmp -= 2;
+ }
+
item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2);
if (item->data == NULL) return NULL;
item->len = tmp/2;
@@ -136,7 +147,8 @@ EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
SECOidTag tag;
SECItem oid = { siBuffer, NULL, 0};
const ECCurveParams *curveParams;
- char genenc[2 + 2 * 2 * MAX_ECKEY_LEN];
+ /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
+ char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
#if EC_DEBUG
int i;
diff --git a/security/nss/lib/softoken/fipsaudt.c b/security/nss/lib/softoken/fipsaudt.c
new file mode 100644
index 000000000..d17496deb
--- /dev/null
+++ b/security/nss/lib/softoken/fipsaudt.c
@@ -0,0 +1,351 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Network Security Services (NSS).
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file implements audit logging required by FIPS 140-2 Security
+ * Level 2.
+ */
+
+#include "prprf.h"
+#include "softoken.h"
+
+/*
+ * Print the value of the returned object handle in the output buffer
+ * on a successful return of the PKCS #11 function. If the PKCS #11
+ * function failed or the pointer to object handle is NULL (which is
+ * the case for C_DeriveKey with CKM_TLS_KEY_AND_MAC_DERIVE), an empty
+ * string is stored in the output buffer.
+ *
+ * out: the output buffer
+ * outlen: the length of the output buffer
+ * argName: the name of the "pointer to object handle" argument
+ * phObject: the pointer to object handle
+ * rv: the return value of the PKCS #11 function
+ */
+static void sftk_PrintReturnedObjectHandle(char *out, PRUint32 outlen,
+ const char *argName, CK_OBJECT_HANDLE_PTR phObject, CK_RV rv)
+{
+ if ((rv == CKR_OK) && phObject) {
+ PR_snprintf(out, outlen,
+ " *%s=0x%08lX", argName, (PRUint32)*phObject);
+ } else {
+ PORT_Assert(outlen != 0);
+ out[0] = '\0';
+ }
+}
+
+/*
+ * MECHANISM_BUFSIZE needs to be large enough for sftk_PrintMechanism,
+ * which uses <= 49 bytes.
+ */
+#define MECHANISM_BUFSIZE 64
+
+static void sftk_PrintMechanism(char *out, PRUint32 outlen,
+ CK_MECHANISM_PTR pMechanism)
+{
+ if (pMechanism) {
+ /*
+ * If we change the format string, we need to make sure
+ * MECHANISM_BUFSIZE is still large enough. We allow
+ * 20 bytes for %p on a 64-bit platform.
+ */
+ PR_snprintf(out, outlen, "%p {mechanism=0x%08lX, ...}",
+ pMechanism, (PRUint32)pMechanism->mechanism);
+ } else {
+ PR_snprintf(out, outlen, "%p", pMechanism);
+ }
+}
+
+void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject, CK_RV rv)
+{
+ char msg[256];
+ char shObject[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintReturnedObjectHandle(shObject, sizeof shObject,
+ "phObject", phObject, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_CreateObject(hSession=0x%08lX, pTemplate=%p, ulCount=%lu, "
+ "phObject=%p)=0x%08lX%s",
+ (PRUint32)hSession, pTemplate, (PRUint32)ulCount,
+ phObject, (PRUint32)rv, shObject);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv)
+{
+ char msg[256];
+ char shNewObject[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintReturnedObjectHandle(shNewObject, sizeof shNewObject,
+ "phNewObject", phNewObject, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_CopyObject(hSession=0x%08lX, hObject=0x%08lX, "
+ "pTemplate=%p, ulCount=%lu, phNewObject=%p)=0x%08lX%s",
+ (PRUint32)hSession, (PRUint32)hObject,
+ pTemplate, (PRUint32)ulCount, phNewObject, (PRUint32)rv, shNewObject);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+/* WARNING: hObject has been destroyed and can only be printed. */
+void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_RV rv)
+{
+ char msg[256];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ PR_snprintf(msg, sizeof msg,
+ "C_DestroyObject(hSession=0x%08lX, hObject=0x%08lX)=0x%08lX",
+ (PRUint32)hSession, (PRUint32)hObject, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, CK_RV rv)
+{
+ char msg[256];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ PR_snprintf(msg, sizeof msg,
+ "C_GetObjectSize(hSession=0x%08lX, hObject=0x%08lX, "
+ "pulSize=%p)=0x%08lX",
+ (PRUint32)hSession, (PRUint32)hObject,
+ pulSize, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount, CK_RV rv)
+{
+ char msg[256];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ PR_snprintf(msg, sizeof msg,
+ "C_GetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, "
+ "pTemplate=%p, ulCount=%lu)=0x%08lX",
+ (PRUint32)hSession, (PRUint32)hObject,
+ pTemplate, (PRUint32)ulCount, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount, CK_RV rv)
+{
+ char msg[256];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ PR_snprintf(msg, sizeof msg,
+ "C_SetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, "
+ "pTemplate=%p, ulCount=%lu)=0x%08lX",
+ (PRUint32)hSession, (PRUint32)hObject,
+ pTemplate, (PRUint32)ulCount, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditCryptInit(const char *opName, CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_RV rv)
+{
+ char msg[256];
+ char mech[MECHANISM_BUFSIZE];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ PR_snprintf(msg, sizeof msg,
+ "C_%sInit(hSession=0x%08lX, pMechanism=%s, "
+ "hKey=0x%08lX)=0x%08lX",
+ opName, (PRUint32)hSession, mech,
+ (PRUint32)hKey, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey, CK_RV rv)
+{
+ char msg[256];
+ char mech[MECHANISM_BUFSIZE];
+ char shKey[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_GenerateKey(hSession=0x%08lX, pMechanism=%s, "
+ "pTemplate=%p, ulCount=%lu, phKey=%p)=0x%08lX%s",
+ (PRUint32)hSession, mech,
+ pTemplate, (PRUint32)ulCount, phKey, (PRUint32)rv, shKey);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
+ CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv)
+{
+ char msg[512];
+ char mech[MECHANISM_BUFSIZE];
+ char shPublicKey[32];
+ char shPrivateKey[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ sftk_PrintReturnedObjectHandle(shPublicKey, sizeof shPublicKey,
+ "phPublicKey", phPublicKey, rv);
+ sftk_PrintReturnedObjectHandle(shPrivateKey, sizeof shPrivateKey,
+ "phPrivateKey", phPrivateKey, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_GenerateKeyPair(hSession=0x%08lX, pMechanism=%s, "
+ "pPublicKeyTemplate=%p, ulPublicKeyAttributeCount=%lu, "
+ "pPrivateKeyTemplate=%p, ulPrivateKeyAttributeCount=%lu, "
+ "phPublicKey=%p, phPrivateKey=%p)=0x%08lX%s%s",
+ (PRUint32)hSession, mech,
+ pPublicKeyTemplate, (PRUint32)ulPublicKeyAttributeCount,
+ pPrivateKeyTemplate, (PRUint32)ulPrivateKeyAttributeCount,
+ phPublicKey, phPrivateKey, (PRUint32)rv, shPublicKey, shPrivateKey);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
+ CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
+ CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv)
+{
+ char msg[256];
+ char mech[MECHANISM_BUFSIZE];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ PR_snprintf(msg, sizeof msg,
+ "C_WrapKey(hSession=0x%08lX, pMechanism=%s, hWrappingKey=0x%08lX, "
+ "hKey=0x%08lX, pWrappedKey=%p, pulWrappedKeyLen=%p)=0x%08lX",
+ (PRUint32)hSession, mech, (PRUint32)hWrappingKey,
+ (PRUint32)hKey, pWrappedKey, pulWrappedKeyLen, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
+ CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey, CK_RV rv)
+{
+ char msg[256];
+ char mech[MECHANISM_BUFSIZE];
+ char shKey[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_UnwrapKey(hSession=0x%08lX, pMechanism=%s, "
+ "hUnwrappingKey=0x%08lX, pWrappedKey=%p, ulWrappedKeyLen=%lu, "
+ "pTemplate=%p, ulAttributeCount=%lu, phKey=%p)=0x%08lX%s",
+ (PRUint32)hSession, mech,
+ (PRUint32)hUnwrappingKey, pWrappedKey, (PRUint32)ulWrappedKeyLen,
+ pTemplate, (PRUint32)ulAttributeCount, phKey, (PRUint32)rv, shKey);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditDeriveKey(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_RV rv)
+{
+ char msg[512];
+ char mech[MECHANISM_BUFSIZE];
+ char shKey[32];
+ char sTlsKeys[128];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
+ if ((rv == CKR_OK) &&
+ (pMechanism->mechanism == CKM_TLS_KEY_AND_MAC_DERIVE)) {
+ CK_SSL3_KEY_MAT_PARAMS *param =
+ (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter;
+ CK_SSL3_KEY_MAT_OUT *keymat = param->pReturnedKeyMaterial;
+ PR_snprintf(sTlsKeys, sizeof sTlsKeys,
+ " hClientMacSecret=0x%08lX hServerMacSecret=0x%08lX"
+ " hClientKey=0x%08lX hServerKey=0x%08lX",
+ (PRUint32)keymat->hClientMacSecret,
+ (PRUint32)keymat->hServerMacSecret,
+ (PRUint32)keymat->hClientKey,
+ (PRUint32)keymat->hServerKey);
+ } else {
+ sTlsKeys[0] = '\0';
+ }
+ PR_snprintf(msg, sizeof msg,
+ "C_DeriveKey(hSession=0x%08lX, pMechanism=%s, "
+ "hBaseKey=0x%08lX, pTemplate=%p, ulAttributeCount=%lu, "
+ "phKey=%p)=0x%08lX%s%s",
+ (PRUint32)hSession, mech,
+ (PRUint32)hBaseKey, pTemplate,(PRUint32)ulAttributeCount,
+ phKey, (PRUint32)rv, shKey, sTlsKeys);
+ sftk_LogAuditMessage(severity, msg);
+}
+
+void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hKey, CK_RV rv)
+{
+ char msg[256];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ PR_snprintf(msg, sizeof msg,
+ "C_DigestKey(hSession=0x%08lX, hKey=0x%08lX)=0x%08lX",
+ (PRUint32)hSession, (PRUint32)hKey, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+}
diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c
index acee77676..942bd4034 100644
--- a/security/nss/lib/softoken/fipstest.c
+++ b/security/nss/lib/softoken/fipstest.c
@@ -42,10 +42,21 @@
/* DES-CBC, DES3-ECB, DES3-CBC, RSA */
/* and DSA. */
#include "seccomon.h" /* Required for RSA and DSA. */
-#include "lowkeyi.h" /* Required for RSA and DSA. */
+#include "lowkeyi.h" /* Required for RSA and DSA. */
#include "pkcs11.h" /* Required for PKCS #11. */
#include "secerr.h"
+#ifdef NSS_ENABLE_ECC
+#include "secdert.h" /* Required for ECDSA */
+#include "ec.h" /* Required for ECDSA */
+extern SECStatus
+EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
+extern SECStatus
+EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
+ const ECParams *srcParams);
+#endif
+
+
/* FIPS preprocessor directives for RC2-ECB and RC2-CBC. */
#define FIPS_RC2_KEY_LENGTH 5 /* 40-bits */
#define FIPS_RC2_ENCRYPT_LENGTH 8 /* 64-bits */
@@ -81,31 +92,33 @@
#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-/* FIPS preprocessor directives for RSA. */
+/* FIPS preprocessor directives for RSA. */
#define FIPS_RSA_TYPE siBuffer
-#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 1 /* 8-bits */
-#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */
-#define FIPS_RSA_MESSAGE_LENGTH 16 /* 128-bits */
-#define FIPS_RSA_COEFFICIENT_LENGTH 32 /* 256-bits */
-#define FIPS_RSA_PRIME0_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_PRIME1_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_EXPONENT0_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_EXPONENT1_LENGTH 33 /* 264-bits */
-#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_ENCRYPT_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_DECRYPT_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_CRYPTO_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_SIGNATURE_LENGTH 64 /* 512-bits */
-#define FIPS_RSA_MODULUS_LENGTH 65 /* 520-bits */
+#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 3 /* 24-bits */
+#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */
+#define FIPS_RSA_MESSAGE_LENGTH 128 /* 1024-bits */
+#define FIPS_RSA_COEFFICIENT_LENGTH 64 /* 512-bits */
+#define FIPS_RSA_PRIME0_LENGTH 64 /* 512-bits */
+#define FIPS_RSA_PRIME1_LENGTH 64 /* 512-bits */
+#define FIPS_RSA_EXPONENT0_LENGTH 64 /* 512-bits */
+#define FIPS_RSA_EXPONENT1_LENGTH 64 /* 512-bits */
+#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 128 /* 1024-bits */
+#define FIPS_RSA_ENCRYPT_LENGTH 128 /* 1024-bits */
+#define FIPS_RSA_DECRYPT_LENGTH 128 /* 1024-bits */
+#define FIPS_RSA_SIGNATURE_LENGTH 128 /* 1024-bits */
+#define FIPS_RSA_MODULUS_LENGTH 128 /* 1024-bits */
/* FIPS preprocessor directives for DSA. */
#define FIPS_DSA_TYPE siBuffer
-#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */
-#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */
-#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */
-#define FIPS_DSA_PRIME_LENGTH 64 /* 512-bits */
-#define FIPS_DSA_BASE_LENGTH 64 /* 512-bits */
+#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */
+#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */
+#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */
+#define FIPS_DSA_PRIME_LENGTH 128 /* 1024-bits */
+#define FIPS_DSA_BASE_LENGTH 128 /* 1024-bits */
+
+/* FIPS preprocessor directives for RNG. */
+#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */
static CK_RV
sftk_fips_RC2_PowerUpSelfTest( void )
@@ -1046,121 +1059,324 @@ sftk_fips_SHA_PowerUpSelfTest( void )
return( CKR_OK );
}
+/*
+* Single round RSA Signature Known Answer Test
+*/
+static SECStatus
+sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg,
+ NSSLOWKEYPublicKey *rsa_public_key,
+ NSSLOWKEYPrivateKey *rsa_private_key,
+ const unsigned char *rsa_known_msg,
+ const unsigned int rsa_kmsg_length,
+ const unsigned char *rsa_known_signature)
+{
+ SECOidTag shaOid; /* SHA OID */
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* length of SHA */
+ unsigned int rsa_bytes_signed;
+ unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
+ SECStatus rv;
+
+ if (shaAlg == HASH_AlgSHA1) {
+ if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
+ != SECSuccess) {
+ goto loser;
+ }
+ shaLength = SHA1_LENGTH;
+ shaOid = SEC_OID_SHA1;
+ } else if (shaAlg == HASH_AlgSHA256) {
+ if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
+ != SECSuccess) {
+ goto loser;
+ }
+ shaLength = SHA256_LENGTH;
+ shaOid = SEC_OID_SHA256;
+ } else if (shaAlg == HASH_AlgSHA384) {
+ if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
+ != SECSuccess) {
+ goto loser;
+ }
+ shaLength = SHA384_LENGTH;
+ shaOid = SEC_OID_SHA384;
+ } else if (shaAlg == HASH_AlgSHA512) {
+ if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
+ != SECSuccess) {
+ goto loser;
+ }
+ shaLength = SHA512_LENGTH;
+ shaOid = SEC_OID_SHA512;
+ } else {
+ goto loser;
+ }
+
+ /*************************************************/
+ /* RSA Single-Round Known Answer Signature Test. */
+ /*************************************************/
+
+ /* Perform RSA signature with the RSA private key. */
+ rv = RSA_HashSign( shaOid,
+ rsa_private_key,
+ rsa_computed_signature,
+ &rsa_bytes_signed,
+ FIPS_RSA_SIGNATURE_LENGTH,
+ sha,
+ shaLength);
+
+ if( ( rv != SECSuccess ) ||
+ ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) ||
+ ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature,
+ FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) {
+ goto loser;
+ }
+
+ /****************************************************/
+ /* RSA Single-Round Known Answer Verification Test. */
+ /****************************************************/
+
+ /* Perform RSA verification with the RSA public key. */
+ rv = RSA_HashCheckSign( shaOid,
+ rsa_public_key,
+ rsa_computed_signature,
+ rsa_bytes_signed,
+ sha,
+ shaLength);
+
+ if( rv != SECSuccess ) {
+ goto loser;
+ }
+ return( SECSuccess );
+
+loser:
+
+ return( SECFailure );
+
+}
static CK_RV
sftk_fips_RSA_PowerUpSelfTest( void )
{
- /* RSA Known Modulus used in both Public/Private Key Values (520-bits). */
+ /* RSA Known Modulus used in both Public/Private Key Values (1024-bits). */
static const PRUint8 rsa_modulus[FIPS_RSA_MODULUS_LENGTH] = {
- 0x00,0xa1,0xe9,0x5e,0x66,0x88,0xe2,0xf2,
- 0x2b,0xe7,0x70,0x36,0x33,0xbc,0xeb,0x55,
- 0x55,0xf1,0x60,0x18,0x3c,0xfb,0xd2,0x79,
- 0xf6,0xc4,0xb8,0x09,0xe3,0x12,0xf6,0x63,
- 0x6d,0xc7,0x8e,0x19,0xc0,0x0e,0x10,0x78,
- 0xc1,0xfe,0x2a,0x41,0x74,0x2d,0xf7,0xc4,
- 0x69,0xa7,0x3c,0xbc,0x8a,0xc8,0x31,0x2b,
- 0x4f,0x60,0xf0,0xf1,0xec,0x5a,0x29,0xec,
- 0x6b};
-
- /* RSA Known Public Key Values (8-bits). */
- static const PRUint8 rsa_public_exponent[] = { 0x03 };
-
- /* RSA Known Private Key Values (version is 8-bits), */
- /* (private exponent is 512-bits), */
- /* (private prime0 is 264-bits), */
- /* (private prime1 is 264-bits), */
- /* (private prime exponent0 is 264-bits), */
- /* (private prime exponent1 is 264-bits), */
- /* and (private coefficient is 256-bits). */
+ 0xd5, 0x84, 0x95, 0x07, 0xf4, 0xd0, 0x1f, 0x82,
+ 0xf3, 0x79, 0xf4, 0x99, 0x48, 0x10, 0xe1, 0x71,
+ 0xa5, 0x62, 0x22, 0xa3, 0x4b, 0x00, 0xe3, 0x5b,
+ 0x3a, 0xcc, 0x10, 0x83, 0xe0, 0xaf, 0x61, 0x13,
+ 0x54, 0x6a, 0xa2, 0x6a, 0x2c, 0x5e, 0xb3, 0xcc,
+ 0xa3, 0x71, 0x9a, 0xb2, 0x3e, 0x78, 0xec, 0xb5,
+ 0x0e, 0x6e, 0x31, 0x3b, 0x77, 0x1f, 0x6e, 0x94,
+ 0x41, 0x60, 0xd5, 0x6e, 0xd9, 0xc6, 0xf9, 0x29,
+ 0xc3, 0x40, 0x36, 0x25, 0xdb, 0xea, 0x0b, 0x07,
+ 0xae, 0x76, 0xfd, 0x99, 0x29, 0xf4, 0x22, 0xc1,
+ 0x1a, 0x8f, 0x05, 0xfe, 0x98, 0x09, 0x07, 0x05,
+ 0xc2, 0x0f, 0x0b, 0x11, 0x83, 0x39, 0xca, 0xc7,
+ 0x43, 0x63, 0xff, 0x33, 0x80, 0xe7, 0xc3, 0x78,
+ 0xae, 0xf1, 0x73, 0x52, 0x98, 0x1d, 0xde, 0x5c,
+ 0x53, 0x6e, 0x01, 0x73, 0x0d, 0x12, 0x7e, 0x77,
+ 0x03, 0xf1, 0xef, 0x1b, 0xc8, 0xa8, 0x0f, 0x97};
+
+ /* RSA Known Public Key Values (24-bits). */
+ static const PRUint8 rsa_public_exponent[FIPS_RSA_PUBLIC_EXPONENT_LENGTH]
+ = { 0x01, 0x00, 0x01 };
+ /* RSA Known Private Key Values (version is 8-bits), */
+ /* (private exponent is 1024-bits), */
+ /* (private prime0 is 512-bits), */
+ /* (private prime1 is 512-bits), */
+ /* (private prime exponent0 is 512-bits), */
+ /* (private prime exponent1 is 512-bits), */
+ /* and (private coefficient is 512-bits). */
static const PRUint8 rsa_version[] = { 0x00 };
- static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] = {
- 0x6b,0xf0,0xe9,0x99,0xb0,0x97,0x4c,0x1d,
- 0x44,0xf5,0x79,0x77,0xd3,0x47,0x8e,0x39,
- 0x4b,0x95,0x65,0x7d,0xfd,0x36,0xfb,0xf9,
- 0xd8,0x7a,0xb1,0x42,0x0c,0xa4,0x42,0x48,
- 0x20,0x1c,0x6b,0x7d,0x5d,0xa3,0x58,0xd6,
- 0x95,0xd6,0x41,0xe3,0xd6,0x73,0xad,0xdb,
- 0x3b,0x89,0x00,0x8a,0xcd,0x1d,0xb9,0x06,
- 0xac,0xac,0x0e,0x02,0x72,0x1c,0xf8,0xab };
+
+ static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH]
+ = { 0x85, 0x27, 0x47, 0x61, 0x4c, 0xd4, 0xb5, 0xb2,
+ 0x0e, 0x70, 0x91, 0x8f, 0x3d, 0x97, 0xf9, 0x5f,
+ 0xcc, 0x09, 0x65, 0x1c, 0x7c, 0x5b, 0xb3, 0x6d,
+ 0x63, 0x3f, 0x7b, 0x55, 0x22, 0xbb, 0x7c, 0x48,
+ 0x77, 0xae, 0x80, 0x56, 0xc2, 0x10, 0xd5, 0x03,
+ 0xdb, 0x31, 0xaf, 0x8d, 0x54, 0xd4, 0x48, 0x99,
+ 0xa8, 0xc4, 0x23, 0x43, 0xb8, 0x48, 0x0b, 0xc7,
+ 0xbc, 0xf5, 0xcc, 0x64, 0x72, 0xbf, 0x59, 0x06,
+ 0x04, 0x1c, 0x32, 0xf5, 0x14, 0x2e, 0x6e, 0xe2,
+ 0x0f, 0x5c, 0xde, 0x36, 0x3c, 0x6e, 0x7c, 0x4d,
+ 0xcc, 0xd3, 0x00, 0x6e, 0xe5, 0x45, 0x46, 0xef,
+ 0x4d, 0x25, 0x46, 0x6d, 0x7f, 0xed, 0xbb, 0x4f,
+ 0x4d, 0x9f, 0xda, 0x87, 0x47, 0x8f, 0x74, 0x44,
+ 0xb7, 0xbe, 0x9d, 0xf5, 0xdd, 0xd2, 0x4c, 0xa5,
+ 0xab, 0x74, 0xe5, 0x29, 0xa1, 0xd2, 0x45, 0x3b,
+ 0x33, 0xde, 0xd5, 0xae, 0xf7, 0x03, 0x10, 0x21};
+
static const PRUint8 rsa_prime0[FIPS_RSA_PRIME0_LENGTH] = {
- 0x00,0xd2,0x2c,0x9d,0xef,0x7c,0x8f,0x58,
- 0x93,0x19,0xa1,0x77,0x0e,0x38,0x3e,0x85,
- 0xb4,0xaf,0xcc,0x99,0xa5,0x43,0xbf,0x97,
- 0xdc,0x46,0xb8,0x3f,0x6e,0x85,0x18,0x00,
- 0x81};
+ 0xf9, 0x74, 0x8f, 0x16, 0x02, 0x6b, 0xa0, 0xee,
+ 0x7f, 0x28, 0x97, 0x91, 0xdc, 0xec, 0xc0, 0x7c,
+ 0x49, 0xc2, 0x85, 0x76, 0xee, 0x66, 0x74, 0x2d,
+ 0x1a, 0xb8, 0xf7, 0x2f, 0x11, 0x5b, 0x36, 0xd8,
+ 0x46, 0x33, 0x3b, 0xd8, 0xf3, 0x2d, 0xa1, 0x03,
+ 0x83, 0x2b, 0xec, 0x35, 0x43, 0x32, 0xff, 0xdd,
+ 0x81, 0x7c, 0xfd, 0x65, 0x13, 0x04, 0x7c, 0xfc,
+ 0x03, 0x97, 0xf0, 0xd5, 0x62, 0xdc, 0x0d, 0xbf};
static const PRUint8 rsa_prime1[FIPS_RSA_PRIME1_LENGTH] = {
- 0x00,0xc5,0x36,0xda,0x94,0x85,0x0c,0x1a,
- 0xed,0x03,0xc7,0x67,0x90,0x34,0x0b,0xb9,
- 0xec,0x1e,0x22,0xa2,0x15,0x50,0xc4,0xfd,
- 0xe9,0x17,0x36,0x9d,0x7a,0x29,0xe6,0x76,
- 0xeb};
+ 0xdb, 0x1e, 0xa7, 0x3d, 0xe7, 0xfa, 0x8b, 0x04,
+ 0x83, 0x48, 0xf3, 0xa5, 0x31, 0x9d, 0x35, 0x5e,
+ 0x4d, 0x54, 0x77, 0xcc, 0x84, 0x09, 0xf3, 0x11,
+ 0x0d, 0x54, 0xed, 0x85, 0x39, 0xa9, 0xca, 0xa8,
+ 0xea, 0xae, 0x19, 0x9c, 0x75, 0xdb, 0x88, 0xb8,
+ 0x04, 0x8d, 0x54, 0xc6, 0xa4, 0x80, 0xf8, 0x93,
+ 0xf0, 0xdb, 0x19, 0xef, 0xd7, 0x87, 0x8a, 0x8f,
+ 0x5a, 0x09, 0x2e, 0x54, 0xf3, 0x45, 0x24, 0x29};
static const PRUint8 rsa_exponent0[FIPS_RSA_EXPONENT0_LENGTH] = {
- 0x00,0x8c,0x1d,0xbe,0x9f,0xa8,
- 0x5f,0x90,0x62,0x11,0x16,0x4f,
- 0x5e,0xd0,0x29,0xae,0x78,0x75,
- 0x33,0x11,0x18,0xd7,0xd5,0x0f,
- 0xe8,0x2f,0x25,0x7f,0x9f,0x03,
- 0x65,0x55,0xab};
+ 0x6a, 0xd1, 0x25, 0x80, 0x18, 0x33, 0x3c, 0x2b,
+ 0x44, 0x19, 0xfe, 0xa5, 0x40, 0x03, 0xc4, 0xfc,
+ 0xb3, 0x9c, 0xef, 0x07, 0x99, 0x58, 0x17, 0xc1,
+ 0x44, 0xa3, 0x15, 0x7d, 0x7b, 0x22, 0x22, 0xdf,
+ 0x03, 0x58, 0x66, 0xf5, 0x24, 0x54, 0x52, 0x91,
+ 0x2d, 0x76, 0xfe, 0x63, 0x64, 0x4e, 0x0f, 0x50,
+ 0x2b, 0x65, 0x79, 0x1f, 0xf1, 0xbf, 0xc7, 0x41,
+ 0x26, 0xcc, 0xc6, 0x1c, 0xa9, 0x83, 0x6f, 0x03};
static const PRUint8 rsa_exponent1[FIPS_RSA_EXPONENT1_LENGTH] = {
- 0x00,0x83,0x79,0xe7,0x0d,0xae,
- 0x08,0x11,0xf3,0x57,0xda,0x45,
- 0x0a,0xcd,0x5d,0x26,0x9d,0x69,
- 0x6c,0x6c,0x0e,0x35,0xd8,0xa9,
- 0x46,0x0f,0x79,0xbe,0x51,0x71,
- 0x44,0x4f,0x47};
+ 0x12, 0x84, 0x1a, 0x99, 0xce, 0x9a, 0x8b, 0x58,
+ 0xcc, 0x47, 0x43, 0xdf, 0x77, 0xbb, 0xd3, 0x20,
+ 0xae, 0xe4, 0x2e, 0x63, 0x67, 0xdc, 0xf7, 0x5f,
+ 0x3f, 0x83, 0x27, 0xb7, 0x14, 0x52, 0x56, 0xbf,
+ 0xc3, 0x65, 0x06, 0xe1, 0x03, 0xcc, 0x93, 0x57,
+ 0x09, 0x7b, 0x6f, 0xe8, 0x81, 0x4a, 0x2c, 0xb7,
+ 0x43, 0xa9, 0x20, 0x1d, 0xf6, 0x56, 0x8b, 0xcc,
+ 0xe5, 0x4c, 0xd5, 0x4f, 0x74, 0x67, 0x29, 0x51};
static const PRUint8 rsa_coefficient[FIPS_RSA_COEFFICIENT_LENGTH] = {
- 0x54,0x8d,0xb8,0xdc,0x8b,0xde,0xbb,
- 0x08,0xc9,0x67,0xb7,0xa9,0x5f,0xa5,
- 0xc4,0x5e,0x67,0xaa,0xfe,0x1a,0x08,
- 0xeb,0x48,0x43,0xcb,0xb0,0xb9,0x38,
- 0x3a,0x31,0x39,0xde};
-
-
- /* RSA Known Plaintext (512-bits). */
- static const PRUint8 rsa_known_plaintext[] = {
- "Known plaintext utilized for RSA"
- " Encryption and Decryption test." };
-
- /* RSA Known Ciphertext (512-bits). */
+ 0x23, 0xab, 0xf4, 0x03, 0x2f, 0x29, 0x95, 0x74,
+ 0xac, 0x1a, 0x33, 0x96, 0x62, 0xed, 0xf7, 0xf6,
+ 0xae, 0x07, 0x2a, 0x2e, 0xe8, 0xab, 0xfb, 0x1e,
+ 0xb9, 0xb2, 0x88, 0x1e, 0x85, 0x05, 0x42, 0x64,
+ 0x03, 0xb2, 0x8b, 0xc1, 0x81, 0x75, 0xd7, 0xba,
+ 0xaa, 0xd4, 0x31, 0x3c, 0x8a, 0x96, 0x23, 0x9d,
+ 0x3f, 0x06, 0x3e, 0x44, 0xa9, 0x62, 0x2f, 0x61,
+ 0x5a, 0x51, 0x82, 0x2c, 0x04, 0x85, 0x73, 0xd1};
+
+ /* RSA Known Plaintext Message (1024-bits). */
+ static const PRUint8 rsa_known_plaintext_msg[FIPS_RSA_MESSAGE_LENGTH] = {
+ "Known plaintext message utilized"
+ "for RSA Encryption & Decryption"
+ "block, SHA1, SHA256, SHA384 and"
+ "SHA512 RSA Signature KAT tests."};
+
+ /* RSA Known Ciphertext (1024-bits). */
static const PRUint8 rsa_known_ciphertext[] = {
- 0x12,0x80,0x3a,0x53,0xee,0x93,0x81,0xa5,
- 0xf7,0x40,0xc5,0xb1,0xef,0xd9,0x27,0xaf,
- 0xef,0x4b,0x87,0x44,0x00,0xd0,0xda,0xcf,
- 0x10,0x57,0x4c,0xd5,0xc3,0xed,0x84,0xdc,
- 0x74,0x03,0x19,0x69,0x2c,0xd6,0x54,0x3e,
- 0xd2,0xe3,0x90,0xb6,0x67,0x91,0x2f,0x1f,
- 0x54,0x13,0x99,0x00,0x0b,0xfd,0x52,0x7f,
- 0xd8,0xc6,0xdb,0x8a,0xfe,0x06,0xf3,0xb1};
-
- /* RSA Known Message (128-bits). */
- static const PRUint8 rsa_known_message[] = { "Netscape Forever" };
-
- /* RSA Known Signed Hash (512-bits). */
- static const PRUint8 rsa_known_signature[] = {
- 0x27,0x23,0xa6,0x71,0x57,0xc8,0x70,0x5f,
- 0x70,0x0e,0x06,0x7b,0x96,0x6a,0xaa,0x41,
- 0x6e,0xab,0x67,0x4b,0x5f,0x76,0xc4,0x53,
- 0x23,0xd7,0x57,0x7a,0x3a,0xbc,0x4c,0x27,
- 0x65,0xca,0xde,0x9f,0xd3,0x1d,0xa4,0x5a,
- 0xf9,0x8f,0xb2,0x05,0xa3,0x86,0xf9,0x66,
- 0x55,0x4c,0x68,0x50,0x66,0xa4,0xe9,0x17,
- 0x45,0x11,0xb8,0x1a,0xfc,0xbc,0x79,0x3b};
-
-
- static const RSAPublicKey bl_public_key = { NULL,
- { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, FIPS_RSA_MODULUS_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH }
+ 0x1e, 0x7e, 0x12, 0xbb, 0x15, 0x62, 0xd0, 0x23,
+ 0x53, 0x4c, 0x51, 0x97, 0x77, 0x06, 0xa0, 0xbb,
+ 0x26, 0x99, 0x9a, 0x8f, 0x39, 0xad, 0x88, 0x5c,
+ 0xc4, 0xce, 0x33, 0x40, 0x94, 0x92, 0xb4, 0x0e,
+ 0xab, 0x71, 0xa9, 0x5d, 0x9a, 0x37, 0xe3, 0x9a,
+ 0x24, 0x95, 0x13, 0xea, 0x0f, 0xbb, 0xf7, 0xff,
+ 0xdf, 0x31, 0x33, 0x23, 0x1d, 0xce, 0x26, 0x9e,
+ 0xd1, 0xde, 0x98, 0x40, 0xde, 0x57, 0x86, 0x12,
+ 0xf1, 0xe6, 0x5a, 0x3f, 0x08, 0x02, 0x81, 0x85,
+ 0xe0, 0xd9, 0xad, 0x3c, 0x8c, 0x71, 0xf8, 0xcf,
+ 0x0a, 0x98, 0xc5, 0x08, 0xdc, 0xc4, 0xca, 0x8c,
+ 0x23, 0x1b, 0x4d, 0x9b, 0xb5, 0x13, 0x44, 0xe1,
+ 0x5f, 0xf9, 0x30, 0x80, 0x25, 0xe0, 0x1e, 0x94,
+ 0xa3, 0x0c, 0xdc, 0x82, 0x2e, 0xfb, 0x30, 0xbe,
+ 0x89, 0xba, 0x76, 0xb6, 0x23, 0xf7, 0xda, 0x7c,
+ 0xca, 0xe6, 0x02, 0xbd, 0x92, 0xce, 0x64, 0xfc};
+
+ /* RSA Known Signed Hash (1024-bits). */
+ static const PRUint8 rsa_known_sha1_signature[] = {
+ 0xd2, 0xa4, 0xe0, 0x2b, 0xc7, 0x03, 0x7f, 0xc6,
+ 0x06, 0x9e, 0xa2, 0x82, 0x19, 0xe9, 0x2b, 0xaf,
+ 0xe3, 0x48, 0x88, 0xc1, 0xf3, 0xb5, 0x0d, 0xe4,
+ 0x52, 0x9e, 0xad, 0xd5, 0x58, 0xb5, 0x9f, 0xe8,
+ 0x40, 0xe9, 0xb7, 0x2e, 0xc6, 0x71, 0x58, 0x56,
+ 0x04, 0xac, 0xb0, 0xf3, 0x3a, 0x42, 0x38, 0x08,
+ 0xc4, 0x43, 0x39, 0xba, 0x19, 0xce, 0xb1, 0x99,
+ 0xf1, 0x8d, 0x89, 0xd8, 0x50, 0x07, 0x14, 0x3d,
+ 0xcf, 0xd0, 0xb6, 0x79, 0xde, 0x9c, 0x89, 0x32,
+ 0xb0, 0x73, 0x3f, 0xed, 0x03, 0x0b, 0xdf, 0x6d,
+ 0x7e, 0xc9, 0x1c, 0x39, 0xe8, 0x2b, 0x16, 0x09,
+ 0xbb, 0x5f, 0x99, 0x2f, 0xeb, 0xf3, 0x37, 0x73,
+ 0x0d, 0x0e, 0xcc, 0x95, 0xad, 0x90, 0x80, 0x03,
+ 0x1d, 0x80, 0x55, 0x37, 0xa1, 0x2a, 0x71, 0x76,
+ 0x23, 0x87, 0x8c, 0x9b, 0x41, 0x07, 0xc6, 0x3d,
+ 0xc6, 0xa3, 0x7d, 0x1b, 0xff, 0x4e, 0x11, 0x19};
+
+ /* RSA Known Signed Hash (1024-bits). */
+ static const PRUint8 rsa_known_sha256_signature[] = {
+ 0x27, 0x35, 0xdd, 0xc4, 0xf8, 0xe2, 0x0b, 0xa3,
+ 0xef, 0x63, 0x57, 0x3b, 0xe1, 0x58, 0x9a, 0xbc,
+ 0x20, 0x9c, 0x25, 0x12, 0x01, 0xbf, 0xbb, 0x29,
+ 0x80, 0x1a, 0xb1, 0x37, 0x9c, 0xcd, 0x67, 0xc7,
+ 0x0d, 0xf8, 0x64, 0x10, 0x9f, 0xe2, 0xa1, 0x9b,
+ 0x21, 0x90, 0xcc, 0xda, 0x8b, 0x76, 0x5e, 0x79,
+ 0x00, 0x9d, 0x58, 0x8b, 0x8a, 0xb3, 0xc3, 0xb5,
+ 0xf1, 0x54, 0xc5, 0x8c, 0x72, 0xba, 0xde, 0x51,
+ 0x3c, 0x6b, 0x94, 0xd6, 0xf3, 0x1b, 0xa2, 0x53,
+ 0xe6, 0x1a, 0x46, 0x1d, 0x7f, 0x14, 0x86, 0xcc,
+ 0xa6, 0x30, 0x92, 0x96, 0xc0, 0x96, 0x24, 0xf0,
+ 0x42, 0x53, 0x4c, 0xdd, 0x27, 0xdf, 0x1d, 0x2e,
+ 0x8b, 0x83, 0xbe, 0xed, 0x85, 0x1d, 0x50, 0x46,
+ 0xa3, 0x7d, 0x20, 0xea, 0x3e, 0x91, 0xfb, 0xf6,
+ 0x86, 0x51, 0xfd, 0x8c, 0xe5, 0x31, 0xe6, 0x7e,
+ 0x60, 0x08, 0x0e, 0xec, 0xa6, 0xea, 0x24, 0x8d};
+
+ /* RSA Known Signed Hash (1024-bits). */
+ static const PRUint8 rsa_known_sha384_signature[] = {
+ 0x0b, 0x03, 0x94, 0x4f, 0x94, 0x78, 0x9b, 0x96,
+ 0x76, 0xeb, 0x72, 0x58, 0xe1, 0xc5, 0xc7, 0x5f,
+ 0x85, 0x01, 0xa8, 0xc4, 0xf6, 0x1a, 0xb5, 0x2c,
+ 0xd1, 0xd8, 0x87, 0xde, 0x3a, 0x9c, 0x9f, 0x57,
+ 0x81, 0x2a, 0x1e, 0x23, 0x07, 0x70, 0xb0, 0xf9,
+ 0x28, 0x3d, 0xfa, 0xe5, 0x2e, 0x1b, 0x9a, 0x72,
+ 0xc3, 0x74, 0xb3, 0x42, 0x1c, 0x9a, 0x13, 0xdc,
+ 0xc9, 0xd6, 0xd5, 0x88, 0xc9, 0x9c, 0x46, 0xf1,
+ 0x0c, 0xa6, 0xf7, 0xd8, 0x06, 0xa3, 0x1b, 0xdf,
+ 0x55, 0xb3, 0x1b, 0x7b, 0x58, 0x1d, 0xff, 0x19,
+ 0xc7, 0xe0, 0xdd, 0x59, 0xac, 0x2f, 0x78, 0x71,
+ 0xe7, 0xe0, 0x17, 0xa3, 0x1c, 0x5c, 0x92, 0xef,
+ 0xb6, 0x75, 0xed, 0xbe, 0x18, 0x39, 0x6b, 0xd7,
+ 0xc9, 0x08, 0x62, 0x55, 0x62, 0xac, 0x5d, 0xa1,
+ 0x9b, 0xd5, 0xb8, 0x98, 0x15, 0xc0, 0xf5, 0x41,
+ 0x85, 0x44, 0x96, 0xca, 0x10, 0xdc, 0x57, 0x21};
+
+ /* RSA Known Signed Hash (1024-bits). */
+ static const PRUint8 rsa_known_sha512_signature[] = {
+ 0xa5, 0xd0, 0x80, 0x04, 0x22, 0xfc, 0x80, 0x73,
+ 0x7d, 0x46, 0xc8, 0x7b, 0xac, 0x44, 0x7b, 0xe6,
+ 0x07, 0xe5, 0x61, 0x4c, 0x33, 0x7f, 0x6f, 0x46,
+ 0x7c, 0x30, 0xe3, 0x75, 0x59, 0x4b, 0x42, 0xf3,
+ 0x9f, 0x35, 0x3c, 0x10, 0x56, 0xdb, 0xd2, 0x69,
+ 0x43, 0xcb, 0x77, 0xe9, 0x7d, 0xcd, 0x07, 0x43,
+ 0xc5, 0xd4, 0x0c, 0x9d, 0xf5, 0x92, 0xbd, 0x0e,
+ 0x3b, 0xb7, 0x68, 0x88, 0x84, 0xca, 0xae, 0x0d,
+ 0xab, 0x71, 0x10, 0xad, 0xab, 0x27, 0xe4, 0xa3,
+ 0x24, 0x41, 0xeb, 0x1c, 0xa6, 0x5f, 0xf1, 0x85,
+ 0xd0, 0xf6, 0x22, 0x74, 0x3d, 0x81, 0xbe, 0xdd,
+ 0x1b, 0x2a, 0x4c, 0xd1, 0x6c, 0xb5, 0x6d, 0x7a,
+ 0xbb, 0x99, 0x69, 0x01, 0xa6, 0xc0, 0x98, 0xfa,
+ 0x97, 0xa3, 0xd1, 0xb0, 0xdf, 0x09, 0xe3, 0x3d,
+ 0x88, 0xee, 0x90, 0xf3, 0x10, 0x41, 0x0f, 0x06,
+ 0x31, 0xe9, 0x60, 0x2d, 0xbf, 0x63, 0x7b, 0xf8};
+
+ static const RSAPublicKey bl_public_key = { NULL,
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus,
+ FIPS_RSA_MODULUS_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent,
+ FIPS_RSA_PUBLIC_EXPONENT_LENGTH }
};
static const RSAPrivateKey bl_private_key = { NULL,
- { FIPS_RSA_TYPE, (unsigned char *)rsa_version, FIPS_RSA_PRIVATE_VERSION_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, FIPS_RSA_MODULUS_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent, FIPS_RSA_PRIVATE_EXPONENT_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0, FIPS_RSA_PRIME0_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1, FIPS_RSA_PRIME1_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0, FIPS_RSA_EXPONENT0_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1, FIPS_RSA_EXPONENT1_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient, FIPS_RSA_COEFFICIENT_LENGTH }
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_version,
+ FIPS_RSA_PRIVATE_VERSION_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus,
+ FIPS_RSA_MODULUS_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent,
+ FIPS_RSA_PUBLIC_EXPONENT_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent,
+ FIPS_RSA_PRIVATE_EXPONENT_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0,
+ FIPS_RSA_PRIME0_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1,
+ FIPS_RSA_PRIME1_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0,
+ FIPS_RSA_EXPONENT0_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1,
+ FIPS_RSA_EXPONENT1_LENGTH },
+ { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient,
+ FIPS_RSA_COEFFICIENT_LENGTH }
};
/* RSA variables. */
@@ -1170,14 +1386,12 @@ sftk_fips_RSA_PowerUpSelfTest( void )
#endif
NSSLOWKEYPublicKey * rsa_public_key;
NSSLOWKEYPrivateKey * rsa_private_key;
- unsigned int rsa_bytes_signed;
SECStatus rsa_status;
NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey, };
NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey, };
PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH];
PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH];
- PRUint8 rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
/****************************************/
/* Compose RSA Public/Private Key Pair. */
@@ -1216,8 +1430,9 @@ sftk_fips_RSA_PowerUpSelfTest( void )
/**************************************************/
/* Perform RSA Public Key Encryption. */
- rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa,
- rsa_computed_ciphertext, rsa_known_plaintext);
+ rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa,
+ rsa_computed_ciphertext,
+ rsa_known_plaintext_msg);
if( ( rsa_status != SECSuccess ) ||
( PORT_Memcmp( rsa_computed_ciphertext, rsa_known_ciphertext,
@@ -1229,44 +1444,40 @@ sftk_fips_RSA_PowerUpSelfTest( void )
/**************************************************/
/* Perform RSA Private Key Decryption. */
- rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa,
- rsa_computed_plaintext, rsa_known_ciphertext);
+ rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa,
+ rsa_computed_plaintext,
+ rsa_known_ciphertext);
if( ( rsa_status != SECSuccess ) ||
- ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext,
+ ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext_msg,
FIPS_RSA_DECRYPT_LENGTH ) != 0 ) )
goto rsa_loser;
-
- /*************************************************/
- /* RSA Single-Round Known Answer Signature Test. */
- /*************************************************/
-
- /* Perform RSA signature with the RSA private key. */
- rsa_status = RSA_Sign( rsa_private_key, rsa_computed_signature,
- &rsa_bytes_signed,
- FIPS_RSA_SIGNATURE_LENGTH,
- (unsigned char *)rsa_known_message,
- FIPS_RSA_MESSAGE_LENGTH );
-
- if( ( rsa_status != SECSuccess ) ||
- ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) ||
- ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature,
- FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) )
+ rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA1,
+ rsa_public_key, rsa_private_key,
+ rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
+ rsa_known_sha1_signature);
+ if( rsa_status != SECSuccess )
goto rsa_loser;
+ rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA256,
+ rsa_public_key, rsa_private_key,
+ rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
+ rsa_known_sha256_signature);
+ if( rsa_status != SECSuccess )
+ goto rsa_loser;
- /****************************************************/
- /* RSA Single-Round Known Answer Verification Test. */
- /****************************************************/
-
- /* Perform RSA verification with the RSA public key. */
- rsa_status = RSA_CheckSign( rsa_public_key,
- rsa_computed_signature,
- FIPS_RSA_SIGNATURE_LENGTH,
- (unsigned char *)rsa_known_message,
- FIPS_RSA_MESSAGE_LENGTH );
+ rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA384,
+ rsa_public_key, rsa_private_key,
+ rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
+ rsa_known_sha384_signature);
+ if( rsa_status != SECSuccess )
+ goto rsa_loser;
+ rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA512,
+ rsa_public_key, rsa_private_key,
+ rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
+ rsa_known_sha512_signature);
if( rsa_status != SECSuccess )
goto rsa_loser;
@@ -1276,7 +1487,6 @@ sftk_fips_RSA_PowerUpSelfTest( void )
return( CKR_OK );
-
rsa_loser:
nsslowkey_DestroyPublicKey( rsa_public_key );
@@ -1285,33 +1495,235 @@ rsa_loser:
return( CKR_DEVICE_ERROR );
}
+#ifdef NSS_ENABLE_ECC
+
+static CK_RV
+sftk_fips_ECDSA_Test(const PRUint8 *encodedParams,
+ unsigned int encodedParamsLen,
+ const PRUint8 *knownSignature,
+ unsigned int knownSignatureLen) {
+
+ /* ECDSA Known Seed info for curves nistp256 and nistk283 */
+ static const PRUint8 ecdsa_Known_Seed[] = {
+ 0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11,
+ 0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1,
+ 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc,
+ 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f};
+
+ static const PRUint8 msg[] = {
+ "Firefox and ThunderBird are awesome!"};
+
+ unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[2*MAX_ECKEY_LEN];
+ SECItem signature, digest;
+ SECItem encodedparams;
+ ECParams *ecparams = NULL;
+ ECPrivateKey *ecdsa_private_key = NULL;
+ ECPublicKey ecdsa_public_key;
+ SECStatus ecdsaStatus = SECSuccess;
+
+ /* construct the ECDSA private/public key pair */
+ encodedparams.type = siBuffer;
+ encodedparams.data = (unsigned char *) encodedParams;
+ encodedparams.len = encodedParamsLen;
+
+ if (EC_DecodeParams(&encodedparams, &ecparams) != SECSuccess) {
+ return( CKR_DEVICE_ERROR );
+ }
+
+ /* Generates a new EC key pair. The private key is a supplied
+ * random value (in seed) and the public key is the result of
+ * performing a scalar point multiplication of that value with
+ * the curve's base point.
+ */
+ ecdsaStatus = EC_NewKeyFromSeed(ecparams, &ecdsa_private_key,
+ ecdsa_Known_Seed,
+ sizeof(ecdsa_Known_Seed));
+ /* free the ecparams they are no longer needed */
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ if (ecdsaStatus != SECSuccess) {
+ return ( CKR_DEVICE_ERROR );
+ }
+
+ /* construct public key from private key. */
+ ecdsaStatus = EC_CopyParams(ecdsa_private_key->ecParams.arena,
+ &ecdsa_public_key.ecParams,
+ &ecdsa_private_key->ecParams);
+ if (ecdsaStatus != SECSuccess) {
+ goto loser;
+ }
+ ecdsa_public_key.publicValue = ecdsa_private_key->publicValue;
+
+ /* validate public key value */
+ ecdsaStatus = EC_ValidatePublicKey(&ecdsa_public_key.ecParams,
+ &ecdsa_public_key.publicValue);
+ if (ecdsaStatus != SECSuccess) {
+ goto loser;
+ }
+
+ /* validate public key value */
+ ecdsaStatus = EC_ValidatePublicKey(&ecdsa_private_key->ecParams,
+ &ecdsa_private_key->publicValue);
+ if (ecdsaStatus != SECSuccess) {
+ goto loser;
+ }
+
+ /***************************************************/
+ /* ECDSA Single-Round Known Answer Signature Test. */
+ /***************************************************/
+
+ ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg);
+ if (ecdsaStatus != SECSuccess) {
+ goto loser;
+ }
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = SHA1_LENGTH;
+
+ memset(sig, 0, sizeof sig);
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+
+ ecdsaStatus = ECDSA_SignDigestWithSeed(ecdsa_private_key, &signature,
+ &digest, ecdsa_Known_Seed, sizeof ecdsa_Known_Seed);
+ if (ecdsaStatus != SECSuccess) {
+ goto loser;
+ }
+
+ if( ( signature.len != knownSignatureLen ) ||
+ ( PORT_Memcmp( signature.data, knownSignature,
+ knownSignatureLen ) != 0 ) ) {
+ ecdsaStatus = SECFailure;
+ goto loser;
+ }
+
+ /******************************************************/
+ /* ECDSA Single-Round Known Answer Verification Test. */
+ /******************************************************/
+
+ /* Perform ECDSA verification process. */
+ ecdsaStatus = ECDSA_VerifyDigest(&ecdsa_public_key, &signature, &digest);
+
+loser:
+ /* free the memory for the private key arena*/
+ if (ecdsa_private_key != NULL) {
+ PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE);
+ }
+
+ if (ecdsaStatus != SECSuccess) {
+ return CKR_DEVICE_ERROR ;
+ }
+ return( CKR_OK );
+}
+
+static CK_RV
+sftk_fips_ECDSA_PowerUpSelfTest() {
+
+ /* ECDSA Known curve nistp256 == SEC_OID_SECG_EC_SECP256R1 params */
+ static const PRUint8 ecdsa_known_P256_EncodedParams[] = {
+ 0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,
+ 0x01,0x07};
+
+ static const PRUint8 ecdsa_known_P256_signature[] = {
+ 0x07,0xb1,0xcb,0x57,0x20,0xa7,0x10,0xd6,
+ 0x9d,0x37,0x4b,0x1c,0xdc,0x35,0x90,0xff,
+ 0x1a,0x2d,0x98,0x95,0x1b,0x2f,0xeb,0x7f,
+ 0xbb,0x81,0xca,0xc0,0x69,0x75,0xea,0xc5,
+ 0x59,0x6a,0x62,0x49,0x3d,0x50,0xc9,0xe1,
+ 0x27,0x3b,0xff,0x9b,0x13,0x66,0x67,0xdd,
+ 0x7d,0xd1,0x0d,0x2d,0x7c,0x44,0x04,0x1b,
+ 0x16,0x21,0x12,0xc5,0xcb,0xbd,0x9e,0x75};
+
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+ /* ECDSA Known curve nistk283 == SEC_OID_SECG_EC_SECT283K1 params */
+ static const PRUint8 ecdsa_known_K283_EncodedParams[] = {
+ 0x06,0x05,0x2b,0x81,0x04,0x00,0x10};
+
+ static const PRUint8 ecdsa_known_K283_signature[] = {
+ 0x00,0x45,0x88,0xc0,0x79,0x09,0x07,0xd1,
+ 0x4e,0x88,0xe6,0xd5,0x2f,0x22,0x04,0x74,
+ 0x35,0x24,0x65,0xe8,0x15,0xde,0x90,0x66,
+ 0x94,0x70,0xdd,0x3a,0x14,0x70,0x02,0xd1,
+ 0xef,0x86,0xbd,0x15,0x00,0xd9,0xdc,0xfc,
+ 0x87,0x2e,0x7c,0x99,0xe2,0xe3,0x79,0xb8,
+ 0xd9,0x10,0x49,0x78,0x4b,0x59,0x8b,0x05,
+ 0x77,0xec,0x6c,0xe8,0x35,0xe6,0x2e,0xa9,
+ 0xf9,0x77,0x1f,0x71,0x86,0xa5,0x4a,0xd0};
+#endif
+
+ CK_RV crv;
+
+ /* ECDSA GF(p) prime field curve test */
+ crv = sftk_fips_ECDSA_Test(ecdsa_known_P256_EncodedParams,
+ sizeof ecdsa_known_P256_EncodedParams,
+ ecdsa_known_P256_signature,
+ sizeof ecdsa_known_P256_signature );
+ if (crv != CKR_OK) {
+ return( CKR_DEVICE_ERROR );
+ }
+
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+ /* ECDSA GF(2m) binary field curve test */
+ crv = sftk_fips_ECDSA_Test(ecdsa_known_K283_EncodedParams,
+ sizeof ecdsa_known_K283_EncodedParams,
+ ecdsa_known_K283_signature,
+ sizeof ecdsa_known_K283_signature );
+ if (crv != CKR_OK) {
+ return( CKR_DEVICE_ERROR );
+ }
+#endif
+
+ return( CKR_OK );
+}
+
+#endif /* NSS_ENABLE_ECC */
static CK_RV
sftk_fips_DSA_PowerUpSelfTest( void )
{
- /* DSA Known P (512-bits), Q (160-bits), and G (512-bits) Values. */
+ /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
static const PRUint8 dsa_P[] = {
- 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
- 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
- 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
- 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
- 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
- 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
- 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
- 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91};
+ 0x80,0xb0,0xd1,0x9d,0x6e,0xa4,0xf3,0x28,
+ 0x9f,0x24,0xa9,0x8a,0x49,0xd0,0x0c,0x63,
+ 0xe8,0x59,0x04,0xf9,0x89,0x4a,0x5e,0xc0,
+ 0x6d,0xd2,0x67,0x6b,0x37,0x81,0x83,0x0c,
+ 0xfe,0x3a,0x8a,0xfd,0xa0,0x3b,0x08,0x91,
+ 0x1c,0xcb,0xb5,0x63,0xb0,0x1c,0x70,0xd0,
+ 0xae,0xe1,0x60,0x2e,0x12,0xeb,0x54,0xc7,
+ 0xcf,0xc6,0xcc,0xae,0x97,0x52,0x32,0x63,
+ 0xd3,0xeb,0x55,0xea,0x2f,0x4c,0xd5,0xd7,
+ 0x3f,0xda,0xec,0x49,0x27,0x0b,0x14,0x56,
+ 0xc5,0x09,0xbe,0x4d,0x09,0x15,0x75,0x2b,
+ 0xa3,0x42,0x0d,0x03,0x71,0xdf,0x0f,0xf4,
+ 0x0e,0xe9,0x0c,0x46,0x93,0x3d,0x3f,0xa6,
+ 0x6c,0xdb,0xca,0xe5,0xac,0x96,0xc8,0x64,
+ 0x5c,0xec,0x4b,0x35,0x65,0xfc,0xfb,0x5a,
+ 0x1b,0x04,0x1b,0xa1,0x0e,0xfd,0x88,0x15};
+
static const PRUint8 dsa_Q[] = {
- 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
- 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
- 0xda,0xce,0x91,0x5f};
+ 0xad,0x22,0x59,0xdf,0xe5,0xec,0x4c,0x6e,
+ 0xf9,0x43,0xf0,0x4b,0x2d,0x50,0x51,0xc6,
+ 0x91,0x99,0x8b,0xcf};
+
static const PRUint8 dsa_G[] = {
- 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
- 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
- 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
- 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
- 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
- 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
- 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
- 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02};
+ 0x78,0x6e,0xa9,0xd8,0xcd,0x4a,0x85,0xa4,
+ 0x45,0xb6,0x6e,0x5d,0x21,0x50,0x61,0xf6,
+ 0x5f,0xdf,0x5c,0x7a,0xde,0x0d,0x19,0xd3,
+ 0xc1,0x3b,0x14,0xcc,0x8e,0xed,0xdb,0x17,
+ 0xb6,0xca,0xba,0x86,0xa9,0xea,0x51,0x2d,
+ 0xc1,0xa9,0x16,0xda,0xf8,0x7b,0x59,0x8a,
+ 0xdf,0xcb,0xa4,0x67,0x00,0x44,0xea,0x24,
+ 0x73,0xe5,0xcb,0x4b,0xaf,0x2a,0x31,0x25,
+ 0x22,0x28,0x3f,0x16,0x10,0x82,0xf7,0xeb,
+ 0x94,0x0d,0xdd,0x09,0x22,0x14,0x08,0x79,
+ 0xba,0x11,0x0b,0xf1,0xff,0x2d,0x67,0xac,
+ 0xeb,0xb6,0x55,0x51,0x69,0x97,0xa7,0x25,
+ 0x6b,0x9c,0xa0,0x9b,0xd5,0x08,0x9b,0x27,
+ 0x42,0x1c,0x7a,0x69,0x57,0xe6,0x2e,0xed,
+ 0xa9,0x5b,0x25,0xe8,0x1f,0xd2,0xed,0x1f,
+ 0xdf,0xe7,0x80,0x17,0xba,0x0d,0x4d,0x38};
/* DSA Known Random Values (known random key block is 160-bits) */
/* and (known random signature block is 160-bits). */
@@ -1325,11 +1737,11 @@ sftk_fips_DSA_PowerUpSelfTest( void )
/* DSA Known Signature (320-bits). */
static const PRUint8 dsa_known_signature[] = {
- 0x39,0x0d,0x84,0xb1,0xf7,0x52,0x89,0xba,
- 0xec,0x1e,0xa8,0xe2,0x00,0x8e,0x37,0x8f,
- 0xc2,0xf5,0xf8,0x70,0x11,0xa8,0xc7,0x02,
- 0x0e,0x75,0xcf,0x6b,0x54,0x4a,0x52,0xe8,
- 0xd8,0x6d,0x4a,0xe8,0xee,0x56,0x8e,0x59};
+ 0x25,0x7c,0x3a,0x79,0x32,0x45,0xb7,0x32,
+ 0x70,0xca,0x62,0x63,0x2b,0xf6,0x29,0x2c,
+ 0x22,0x2a,0x03,0xce,0x48,0x15,0x11,0x72,
+ 0x7b,0x7e,0xf5,0x7a,0xf3,0x10,0x3b,0xde,
+ 0x34,0xc1,0x9e,0xd7,0x27,0x9e,0x77,0x38};
/* DSA variables. */
DSAPrivateKey * dsa_private_key;
@@ -1348,12 +1760,11 @@ sftk_fips_DSA_PowerUpSelfTest( void )
/*******************************************/
/* Generate a DSA public/private key pair. */
-
dsa_status = DSA_NewKeyFromSeed(&dsa_pqg, dsa_known_random_key_block,
&dsa_private_key);
if( dsa_status != SECSuccess )
- return( CKR_HOST_MEMORY );
+ return( CKR_HOST_MEMORY );
/* construct public key from private key. */
dsa_public_key.params = dsa_private_key->params;
@@ -1372,8 +1783,8 @@ sftk_fips_DSA_PowerUpSelfTest( void )
/* Perform DSA signature process. */
dsa_status = DSA_SignDigestWithSeed( dsa_private_key,
&dsa_signature_item,
- &dsa_digest_item,
- dsa_known_random_signature_block );
+ &dsa_digest_item,
+ dsa_known_random_signature_block );
if( ( dsa_status != SECSuccess ) ||
( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) ||
@@ -1389,7 +1800,7 @@ sftk_fips_DSA_PowerUpSelfTest( void )
/* Perform DSA verification process. */
dsa_status = DSA_VerifyDigest( &dsa_public_key,
&dsa_signature_item,
- &dsa_digest_item);
+ &dsa_digest_item);
}
PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE);
@@ -1404,6 +1815,79 @@ sftk_fips_DSA_PowerUpSelfTest( void )
}
+static CK_RV
+sftk_fips_RNG_PowerUpSelfTest( void )
+{
+ static const PRUint8 XKeyValue[] = {
+ 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
+ 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
+ 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+ 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5};
+ static const PRUint8 XSeed[] = {
+ 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+ 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
+ 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
+ 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac};
+ static const PRUint8 Q[] = {
+ 0x85,0x89,0x9c,0x77,0xa3,0x79,0xff,0x1a,
+ 0x86,0x6f,0x2f,0x3e,0x2e,0xf9,0x8c,0x9c,
+ 0x9d,0xef,0xeb,0xed};
+ static const PRUint8 rng_known_GENX[] = {
+ 0x65,0x48,0xe3,0xca,0xac,0x64,0x2d,0xf7,
+ 0x7b,0xd3,0x4e,0x79,0xc9,0x7d,0xa6,0xa8,
+ 0xa2,0xc2,0x1f,0x8f,0xe9,0xb9,0xd3,0xa1,
+ 0x3f,0xf7,0x0c,0xcd,0xa6,0xca,0xbf,0xce,
+ 0x84,0x0e,0xb6,0xf1,0x0d,0xbe,0xa9,0xa3};
+ static const PRUint8 rng_known_DSAX[] = {
+ 0x7a,0x86,0xf1,0x7f,0xbd,0x4e,0x6e,0xd9,
+ 0x0a,0x26,0x21,0xd0,0x19,0xcb,0x86,0x73,
+ 0x10,0x1f,0x60,0xd7};
+
+ SECStatus rng_status = SECSuccess;
+ PRUint8 GENX[2*SHA1_LENGTH];
+ PRUint8 DSAX[FIPS_DSA_SUBPRIME_LENGTH];
+ PRUint8 XKey[FIPS_RNG_XKEY_LENGTH];
+
+ PORT_Memcpy (XKey, XKeyValue, FIPS_RNG_XKEY_LENGTH);
+
+ /*******************************************/
+ /* Generate X with a known seed. */
+ /*******************************************/
+ rng_status = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+
+ /* Verify GENX to perform the RNG integrity check */
+ if( ( rng_status != SECSuccess ) ||
+ ( PORT_Memcmp( GENX, rng_known_GENX,
+ (2*SHA1_LENGTH) ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /*******************************************/
+ /* Generate DSAX fow given Q. */
+ /*******************************************/
+
+ rng_status = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+
+ /* Verify DSAX to perform the RNG integrity check */
+ if( ( rng_status != SECSuccess ) ||
+ ( PORT_Memcmp( DSAX, rng_known_DSAX,
+ (FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ return( CKR_OK );
+}
+
+static CK_RV
+sftk_fipsSoftwareIntegrityTest(void)
+{
+ CK_RV crv = CKR_OK;
+
+ /* make sure that our check file signatures are OK */
+ if( !BLAPI_VerifySelf( NULL ) ||
+ !BLAPI_SHVerify( SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_fips_HMAC ) ) {
+ crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
+ }
+ return crv;
+}
CK_RV
sftk_fipsPowerUpSelfTest( void )
@@ -1488,6 +1972,26 @@ sftk_fipsPowerUpSelfTest( void )
if( rv != CKR_OK )
return rv;
+ /* RNG Power-Up SelfTest(s). */
+ rv = sftk_fips_RNG_PowerUpSelfTest();
+
+ if( rv != CKR_OK )
+ return rv;
+
+#ifdef NSS_ENABLE_ECC
+ /* ECDSA Power-Up SelfTest(s). */
+ rv = sftk_fips_ECDSA_PowerUpSelfTest();
+
+ if( rv != CKR_OK )
+ return rv;
+#endif
+
+ /* Software/Firmware Integrity Test. */
+ rv = sftk_fipsSoftwareIntegrityTest();
+
+ if( rv != CKR_OK )
+ return rv;
+
/* Passed Power-Up SelfTest(s). */
return( CKR_OK );
}
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
index 9ef144cb8..6cfcfcb05 100644
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -55,15 +55,77 @@
#include "pcert.h"
#include "pkcs11.h"
#include "pkcs11i.h"
+#include "prenv.h"
+#include "prprf.h"
#include <ctype.h>
+#ifdef XP_UNIX
+#define NSS_AUDIT_WITH_SYSLOG 1
+#include <syslog.h>
+#include <unistd.h>
+#endif
+
+#ifdef SOLARIS
+#include <bsm/libbsm.h>
+#define AUE_FIPS_AUDIT 34444
+#endif
+
+#ifdef LINUX
+#include <pthread.h>
+#include <dlfcn.h>
+#define LIBAUDIT_NAME "libaudit.so.0"
+#ifndef AUDIT_USER
+#define AUDIT_USER 1005 /* message type: message from userspace */
+#endif
+static void *libaudit_handle;
+static int (*audit_open_func)(void);
+static void (*audit_close_func)(int fd);
+static int (*audit_log_user_message_func)(int audit_fd, int type,
+ const char *message, const char *hostname, const char *addr,
+ const char *tty, int result);
+static int (*audit_send_user_message_func)(int fd, int type,
+ const char *message);
+
+static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT;
+
+static void
+libaudit_init(void)
+{
+ libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY);
+ if (!libaudit_handle) {
+ return;
+ }
+ audit_open_func = dlsym(libaudit_handle, "audit_open");
+ audit_close_func = dlsym(libaudit_handle, "audit_close");
+ /*
+ * audit_send_user_message is the older function.
+ * audit_log_user_message, if available, is preferred.
+ */
+ audit_log_user_message_func = dlsym(libaudit_handle,
+ "audit_log_user_message");
+ if (!audit_log_user_message_func) {
+ audit_send_user_message_func = dlsym(libaudit_handle,
+ "audit_send_user_message");
+ }
+ if (!audit_open_func || !audit_close_func ||
+ (!audit_log_user_message_func && !audit_send_user_message_func)) {
+ dlclose(libaudit_handle);
+ libaudit_handle = NULL;
+ audit_open_func = NULL;
+ audit_close_func = NULL;
+ audit_log_user_message_func = NULL;
+ audit_send_user_message_func = NULL;
+ }
+}
+#endif /* LINUX */
+
/*
* ******************** Password Utilities *******************************
*/
static PRBool isLoggedIn = PR_FALSE;
-static PRBool fatalError = PR_FALSE;
+PRBool sftk_fatalError = PR_FALSE;
/*
* This function returns
@@ -161,10 +223,10 @@ static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
/* FIPS required checks before any useful cryptographic services */
static CK_RV sftk_fipsCheck(void) {
- if (isLoggedIn != PR_TRUE)
- return CKR_USER_NOT_LOGGED_IN;
- if (fatalError)
+ if (sftk_fatalError)
return CKR_DEVICE_ERROR;
+ if (!isLoggedIn)
+ return CKR_USER_NOT_LOGGED_IN;
return CKR_OK;
}
@@ -174,7 +236,7 @@ static CK_RV sftk_fipsCheck(void) {
if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
#define SFTK_FIPSFATALCHECK() \
- if (fatalError) return CKR_DEVICE_ERROR;
+ if (sftk_fatalError) return CKR_DEVICE_ERROR;
/* grab an attribute out of a raw template */
@@ -233,24 +295,135 @@ static CK_FUNCTION_LIST sftk_fipsTable = {
#undef __PASTE
+/* CKO_NOT_A_KEY can be any object class that's not a key object. */
+#define CKO_NOT_A_KEY CKO_DATA
+
+#define SFTK_IS_KEY_OBJECT(objClass) \
+ (((objClass) == CKO_PUBLIC_KEY) || \
+ ((objClass) == CKO_PRIVATE_KEY) || \
+ ((objClass) == CKO_SECRET_KEY))
+
+#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \
+ (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY))
+
static CK_RV
-fips_login_if_key_object(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
+sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass)
{
CK_RV rv;
- CK_OBJECT_CLASS objClass;
CK_ATTRIBUTE class;
class.type = CKA_CLASS;
- class.pValue = &objClass;
- class.ulValueLen = sizeof(objClass);
+ class.pValue = pObjClass;
+ class.ulValueLen = sizeof(*pObjClass);
rv = NSC_GetAttributeValue(hSession, hObject, &class, 1);
- if (rv == CKR_OK) {
- if ((objClass == CKO_PRIVATE_KEY) || (objClass == CKO_SECRET_KEY)) {
- rv = sftk_fipsCheck();
- }
+ if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) {
+ rv = sftk_fipsCheck();
}
return rv;
}
+/**********************************************************************
+ *
+ * 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, const char *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 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;
+ }
+ if (audit_log_user_message_func) {
+ audit_log_user_message_func(audit_fd, AUDIT_USER, message,
+ NULL, NULL, NULL, result);
+ } else {
+ audit_send_user_message_func(audit_fd, AUDIT_USER, message);
+ }
+ audit_close_func(audit_fd);
+ PR_smprintf_free(message);
+ }
+#endif /* LINUX */
+#ifdef SOLARIS
+ {
+ int rd;
+ char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
+
+ if (!message) {
+ return;
+ }
+
+ /* open the record descriptor */
+ if ((rd = au_open()) == -1) {
+ PR_smprintf_free(message);
+ return;
+ }
+
+ /* write the audit tokens to the audit record */
+ if (au_write(rd, au_to_text(message))) {
+ (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT);
+ PR_smprintf_free(message);
+ return;
+ }
+
+ /* close the record and send it to the audit trail */
+ (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT);
+
+ PR_smprintf_free(message);
+ }
+#endif /* SOLARIS */
+#else
+ /* do nothing */
+#endif
+}
+
/**********************************************************************
*
@@ -268,26 +441,39 @@ PRBool nsf_init = PR_FALSE;
/* FC_Initialize initializes the PKCS #11 library. */
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
+ const char *envp;
CK_RV crv;
if (nsf_init) {
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
+ if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
+ sftk_audit_enabled = (atoi(envp) == 1);
+ }
+
crv = nsc_CommonInitialize(pReserved, PR_TRUE);
/* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
if (crv != CKR_OK) {
- fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
return crv;
}
- fatalError = PR_FALSE; /* any error has been reset */
+ sftk_fatalError = PR_FALSE; /* any error has been reset */
crv = sftk_fipsPowerUpSelfTest();
if (crv != CKR_OK) {
nsc_CommonFinalize(NULL, PR_TRUE);
- fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_Initialize()=0x%08lX "
+ "power-up self-tests failed",
+ (PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
return crv;
}
nsf_init = PR_TRUE;
@@ -321,15 +507,7 @@ CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
-
- CK_RV crv;
-
- crv = NSC_GetSlotInfo(slotID,pInfo);
- if (crv != CKR_OK) {
- return crv;
- }
-
- return CKR_OK;
+ return NSC_GetSlotInfo(slotID,pInfo);
}
@@ -338,7 +516,8 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV crv;
crv = NSC_GetTokenInfo(slotID,pInfo);
- pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED;
+ if (crv == CKR_OK)
+ pInfo->flags |= CKF_LOGIN_REQUIRED;
return crv;
}
@@ -369,7 +548,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FC_InitToken initializes a token. */
CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
- return NSC_InitToken(slotID,pPin,usPinLen,pLabel);
+ CK_RV crv;
+
+ 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, msg);
+ }
+ return crv;
}
@@ -377,9 +569,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
CK_RV rv;
- SFTK_FIPSFATALCHECK();
- if ((rv = sftk_newPinCheck(pPin,ulPinLen)) != CKR_OK) return rv;
- return NSC_InitPIN(hSession,pPin,ulPinLen);
+ if (sftk_fatalError) return CKR_DEVICE_ERROR;
+ if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
+ rv = NSC_InitPIN(hSession,pPin,ulPinLen);
+ }
+ 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, msg);
+ }
+ return rv;
}
@@ -388,9 +591,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
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 ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
- if ((rv = sftk_newPinCheck(pNewPin,usNewLen)) != CKR_OK) return rv;
- return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
+ if ((rv = sftk_fipsCheck()) == CKR_OK &&
+ (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
+ rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
+ }
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity = (rv == CKR_OK) ?
+ NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_SetPIN(hSession=0x%08lX)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+ }
+ return rv;
}
/* FC_OpenSession opens a session between an application and a token. */
@@ -435,30 +649,40 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
CK_RV rv;
- SFTK_FIPSFATALCHECK();
+ PRBool successful;
+ if (sftk_fatalError) return CKR_DEVICE_ERROR;
rv = NSC_Login(hSession,userType,pPin,usPinLen);
- if (rv == CKR_OK)
+ successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN);
+ if (successful)
isLoggedIn = PR_TRUE;
- else if (rv == CKR_USER_ALREADY_LOGGED_IN)
- {
- isLoggedIn = PR_TRUE;
-
- /* Provide FIPS PUB 140-1 power-up self-tests on demand. */
- rv = sftk_fipsPowerUpSelfTest();
- if (rv == CKR_OK)
- return CKR_USER_ALREADY_LOGGED_IN;
- else
- fatalError = PR_TRUE;
+ if (sftk_audit_enabled) {
+ char msg[128];
+ NSSAuditSeverity severity;
+ severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg,sizeof msg,
+ "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
}
return rv;
}
/* FC_Logout logs a user out from a token. */
CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
- SFTK_FIPSCHECK();
-
- rv = NSC_Logout(hSession);
- isLoggedIn = PR_FALSE;
+ CK_RV rv;
+ if ((rv = sftk_fipsCheck()) == CKR_OK) {
+ rv = NSC_Logout(hSession);
+ isLoggedIn = 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_Logout(hSession=0x%08lX)=0x%08lX",
+ (PRUint32)hSession,(PRUint32)rv);
+ sftk_LogAuditMessage(severity, msg);
+ }
return rv;
}
@@ -473,10 +697,15 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
/* FIPS can't create keys from raw key material */
- if ((*classptr == CKO_SECRET_KEY) || (*classptr == CKO_PRIVATE_KEY)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) {
+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
+ } else {
+ rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
}
- return NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
+ if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) {
+ sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv);
+ }
+ return rv;
}
@@ -485,15 +714,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FC_CopyObject copies an object, creating a new object for the copy. */
CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount,
+ CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phNewObject) {
CK_RV rv;
+ CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
SFTK_FIPSFATALCHECK();
- rv = fips_login_if_key_object(hSession, hObject);
- if (rv != CKR_OK) {
- return rv;
+ rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
+ if (rv == CKR_OK) {
+ rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject);
}
- return NSC_CopyObject(hSession,hObject,pTemplate,usCount,phNewObject);
+ if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
+ sftk_AuditCopyObject(hSession,
+ hObject,pTemplate,ulCount,phNewObject,rv);
+ }
+ return rv;
}
@@ -501,51 +735,67 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject) {
CK_RV rv;
+ CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
SFTK_FIPSFATALCHECK();
- rv = fips_login_if_key_object(hSession, hObject);
- if (rv != CKR_OK) {
- return rv;
+ rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
+ if (rv == CKR_OK) {
+ rv = NSC_DestroyObject(hSession,hObject);
+ }
+ if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
+ sftk_AuditDestroyObject(hSession,hObject,rv);
}
- return NSC_DestroyObject(hSession,hObject);
+ return rv;
}
/* FC_GetObjectSize gets the size of an object in bytes. */
CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize) {
+ CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) {
CK_RV rv;
+ CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
SFTK_FIPSFATALCHECK();
- rv = fips_login_if_key_object(hSession, hObject);
- if (rv != CKR_OK) {
- return rv;
+ rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
+ if (rv == CKR_OK) {
+ rv = NSC_GetObjectSize(hSession, hObject, pulSize);
+ }
+ if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
+ sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv);
}
- return NSC_GetObjectSize(hSession, hObject, pusSize);
+ return rv;
}
/* 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 usCount) {
+ CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
CK_RV rv;
+ CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
SFTK_FIPSFATALCHECK();
- rv = fips_login_if_key_object(hSession, hObject);
- if (rv != CKR_OK) {
- return rv;
+ rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
+ if (rv == CKR_OK) {
+ rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount);
+ }
+ if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
+ sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
}
- return NSC_GetAttributeValue(hSession,hObject,pTemplate,usCount);
+ return rv;
}
/* 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 usCount) {
+ CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
CK_RV rv;
+ CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
SFTK_FIPSFATALCHECK();
- rv = fips_login_if_key_object(hSession, hObject);
- if (rv != CKR_OK) {
- return rv;
+ rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
+ if (rv == CKR_OK) {
+ rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount);
+ }
+ if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
+ sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
}
- return NSC_SetAttributeValue(hSession,hObject,pTemplate,usCount);
+ return rv;
}
@@ -605,7 +855,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_EncryptInit(hSession,pMechanism,hKey);
+ rv = NSC_EncryptInit(hSession,pMechanism,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv);
+ }
+ return rv;
}
/* FC_Encrypt encrypts single-part data. */
@@ -646,7 +900,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_DecryptInit(hSession,pMechanism,hKey);
+ rv = NSC_DecryptInit(hSession,pMechanism,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv);
+ }
+ return rv;
}
/* FC_Decrypt decrypts encrypted data in a single part. */
@@ -724,7 +982,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_SignInit(hSession,pMechanism,hKey);
+ rv = NSC_SignInit(hSession,pMechanism,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv);
+ }
+ return rv;
}
@@ -766,7 +1028,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_SignRecoverInit(hSession,pMechanism,hKey);
+ rv = NSC_SignRecoverInit(hSession,pMechanism,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv);
+ }
+ return rv;
}
@@ -789,7 +1055,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_VerifyInit(hSession,pMechanism,hKey);
+ rv = NSC_VerifyInit(hSession,pMechanism,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv);
+ }
+ return rv;
}
@@ -832,7 +1102,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
+ rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv);
+ }
+ return rv;
}
@@ -868,7 +1142,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
}
}
- return NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
+ rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv);
+ }
+ return rv;
}
@@ -898,7 +1176,12 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
if (crv == CKR_GENERAL_ERROR) {
/* pairwise consistency check failed. */
- fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
+ }
+ if (sftk_audit_enabled) {
+ sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate,
+ usPublicKeyAttributeCount,pPrivateKeyTemplate,
+ usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv);
}
return crv;
}
@@ -908,18 +1191,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pusWrappedKeyLen) {
+ CK_ULONG_PTR pulWrappedKeyLen) {
SFTK_FIPSCHECK();
- return NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
- pusWrappedKeyLen);
+ rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
+ pulWrappedKeyLen);
+ if (sftk_audit_enabled) {
+ sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
+ pulWrappedKeyLen,rv);
+ }
+ return rv;
}
/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount,
+ CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey) {
CK_BBOOL *boolptr;
@@ -928,21 +1216,26 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* all secret keys must be sensitive, if the upper level code tries to say
* otherwise, reject it. */
boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
- usAttributeCount, CKA_SENSITIVE);
+ ulAttributeCount, CKA_SENSITIVE);
if (boolptr != NULL) {
if (!(*boolptr)) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
}
- return NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
- usWrappedKeyLen,pTemplate,usAttributeCount,phKey);
+ 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 usAttributeCount,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey) {
CK_BBOOL *boolptr;
@@ -951,14 +1244,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* all secret keys must be sensitive, if the upper level code tries to say
* otherwise, reject it. */
boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
- usAttributeCount, CKA_SENSITIVE);
+ ulAttributeCount, CKA_SENSITIVE);
if (boolptr != NULL) {
if (!(*boolptr)) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
}
- return NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
- usAttributeCount, phKey);
+ rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
+ ulAttributeCount, phKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
+ ulAttributeCount,phKey,rv);
+ }
+ return rv;
}
/*
@@ -974,7 +1272,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
SFTK_FIPSFATALCHECK();
crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
if (crv != CKR_OK) {
- fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
}
return crv;
}
@@ -982,13 +1280,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FC_GenerateRandom generates random data. */
CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen) {
+ CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) {
CK_RV crv;
SFTK_FIPSFATALCHECK();
- crv = NSC_GenerateRandom(hSession,pRandomData,usRandomLen);
+ crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
if (crv != CKR_OK) {
- fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, "
+ "ulRandomLen=%lu)=0x%08lX "
+ "self-test: continuous RNG test failed",
+ (PRUint32)hSession,pRandomData,
+ (PRUint32)ulRandomLen,(PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
}
return crv;
}
@@ -1091,7 +1399,11 @@ CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
*/
CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
SFTK_FIPSCHECK();
- return NSC_DigestKey(hSession,hKey);
+ rv = NSC_DigestKey(hSession,hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditDigestKey(hSession,hKey,rv);
+ }
+ return rv;
}
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index 2f685a5a6..81e2802ea 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -49,15 +49,10 @@
#include "lowpbe.h"
#include "secerr.h"
#include "cdbhdl.h"
-#include "nsslocks.h"
#include "keydbi.h"
+#include "softoken.h"
-#ifdef NSS_ENABLE_ECC
-extern SECStatus EC_FillParams(PRArenaPool *arena,
- const SECItem *encodedParams,
- ECParams *params);
-#endif
/*
* Record keys for keydb
@@ -175,7 +170,7 @@ static void
keydb_InitLocks(NSSLOWKEYDBHandle *handle)
{
if (handle->lock == NULL) {
- nss_InitLock(&handle->lock, nssILockKeyDB);
+ handle->lock = PZ_NewLock(nssILockKeyDB);
}
return;
@@ -584,13 +579,18 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle)
DBT saltData;
unsigned char saltbuf[16];
int status;
+ SECStatus rv;
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
saltData.data = (void *)saltbuf;
saltData.size = sizeof(saltbuf);
- RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
+ rv = RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
+ if ( rv != SECSuccess ) {
+ sftk_fatalError = PR_TRUE;
+ return(rv);
+ }
/* put global salt into the database now */
status = keydb_Put(handle, &saltKey, &saltData, 0);
@@ -717,7 +717,6 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
DBT key;
DBT data;
unsigned char version;
- SECItem *rc4key = NULL;
NSSLOWKEYDBKey *dbkey = NULL;
NSSLOWKEYDBHandle *update = NULL;
SECItem *oldSalt = NULL;
@@ -886,10 +885,6 @@ done:
nsslowkey_CloseKeyDB(update);
- if ( rc4key ) {
- SECITEM_FreeItem(rc4key, PR_TRUE);
- }
-
if ( oldSalt ) {
SECITEM_FreeItem(oldSalt, PR_TRUE);
}
@@ -942,7 +937,7 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
* local database we can update from.
*/
if (appName) {
- NSSLOWKEYDBHandle *updateHandle = nsslowkey_NewHandle(updatedb);
+ NSSLOWKEYDBHandle *updateHandle;
updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
if (!updatedb) {
goto noupdate;
@@ -1429,50 +1424,6 @@ nsslowkey_DeriveKeyDBPassword(NSSLOWKEYDBHandle *keydb, char *pw)
return nsslowkey_HashPassword(pw, keydb->global_salt);
}
-#if 0
-/* Appears obsolete - TNH */
-/* get the algorithm with which a private key
- * is encrypted.
- */
-SECOidTag
-seckey_get_private_key_algorithm(NSSLOWKEYDBHandle *keydb, DBT *index)
-{
- NSSLOWKEYDBKey *dbkey = NULL;
- SECOidTag algorithm = SEC_OID_UNKNOWN;
- NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL;
- PLArenaPool *poolp = NULL;
- SECStatus rv;
-
- poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(poolp == NULL)
- return (SECOidTag)SECFailure; /* TNH - this is bad */
-
- dbkey = get_dbkey(keydb, index);
- if(dbkey == NULL)
- return (SECOidTag)SECFailure;
-
- epki = (NSSLOWKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp,
- sizeof(NSSLOWKEYEncryptedPrivateKeyInfo));
- if(epki == NULL)
- goto loser;
- rv = SEC_ASN1DecodeItem(poolp, epki,
- nsslowkey_EncryptedPrivateKeyInfoTemplate, &dbkey->derPK);
- if(rv == SECFailure)
- goto loser;
-
- algorithm = SECOID_GetAlgorithmTag(&epki->algorithm);
-
- /* let success fall through */
-loser:
- if(poolp != NULL)
- PORT_FreeArena(poolp, PR_TRUE);\
- if(dbkey != NULL)
- sec_destroy_dbkey(dbkey);
-
- return algorithm;
-}
-#endif
-
/*
* Derive an RC4 key from a password key and a salt. This
* was the method to used to encrypt keys in the version 2?
@@ -1531,11 +1482,12 @@ seckey_create_rc4_salt(void)
if(salt->data != NULL)
{
salt->len = SALT_LENGTH;
- RNG_GenerateGlobalRandomBytes(salt->data, salt->len);
- rv = SECSuccess;
+ rv = RNG_GenerateGlobalRandomBytes(salt->data, salt->len);
+ if(rv != SECSuccess)
+ sftk_fatalError = PR_TRUE;
}
- if(rv == SECFailure)
+ if(rv != SECSuccess)
{
SECITEM_FreeItem(salt, PR_TRUE);
salt = NULL;
@@ -1816,7 +1768,7 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
{
NSSLOWKEYDBKey *dbkey = NULL;
NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL;
- PLArenaPool *temparena = NULL, *permarena = NULL;
+ PLArenaPool *arena = NULL;
SECItem *dummy = NULL;
SECItem *salt = NULL;
SECStatus rv = SECFailure;
@@ -1825,14 +1777,14 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
(pk == NULL))
return SECFailure;
- permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(permarena == NULL)
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if(arena == NULL)
return SECFailure;
- dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(permarena, sizeof(NSSLOWKEYDBKey));
+ dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
if(dbkey == NULL)
goto loser;
- dbkey->arena = permarena;
+ dbkey->arena = arena;
dbkey->nickname = nickname;
/* TNH - for RC4, the salt should be created here */
@@ -1840,15 +1792,14 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm, &salt);
if(epki == NULL)
goto loser;
- temparena = epki->arena;
if(salt != NULL)
{
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt);
+ rv = SECITEM_CopyItem(arena, &(dbkey->salt), salt);
SECITEM_ZfreeItem(salt, PR_TRUE);
}
- dummy = SEC_ASN1EncodeItem(permarena, &(dbkey->derPK), epki,
+ dummy = SEC_ASN1EncodeItem(arena, &(dbkey->derPK), epki,
nsslowkey_EncryptedPrivateKeyInfoTemplate);
if(dummy == NULL)
rv = SECFailure;
@@ -1857,11 +1808,10 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
/* let success fall through */
loser:
- if(rv != SECSuccess)
- if(permarena != NULL)
- PORT_FreeArena(permarena, PR_TRUE);
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
+ if(arena != NULL)
+ PORT_FreeArena(arena, PR_TRUE);
+ if(epki != NULL)
+ PORT_FreeArena(epki->arena, PR_TRUE);
return rv;
}
@@ -2046,6 +1996,9 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki,
rv = EC_FillParams(permarena, &pk->u.ec.ecParams.DEREncoding,
&pk->u.ec.ecParams);
+ if (rv != SECSuccess)
+ goto loser;
+
/*
* NOTE: Encoding of the publicValue is optional
* so we need to be able to regenerate the publicValue
diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c
index cb048307d..008687e52 100644
--- a/security/nss/lib/softoken/lowcert.c
+++ b/security/nss/lib/softoken/lowcert.c
@@ -51,12 +51,8 @@
#include "secasn1.h"
#include "secoid.h"
#include "secerr.h"
+#include "softoken.h"
-#ifdef NSS_ENABLE_ECC
-extern SECStatus EC_FillParams(PRArenaPool *arena,
- const SECItem *encodedParams,
- ECParams *params);
-#endif
static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) },
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
index fb6e30fdc..9c984b4d3 100644
--- a/security/nss/lib/softoken/lowkey.c
+++ b/security/nss/lib/softoken/lowkey.c
@@ -295,7 +295,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
if (rv == SECSuccess)
return pubk;
}
- nsslowkey_DestroyPublicKey (pubk);
} else {
PORT_SetError (SEC_ERROR_NO_MEMORY);
}
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
index 81a0cb06b..6b4605b4e 100644
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -546,13 +546,15 @@ loser:
PORT_FreeArena(arena, PR_TRUE);
}
- /* if i != c, then we didn't complete the loop above and must of failed
- * somwhere along the way */
- if (i != c) {
- SECITEM_ZfreeItem(A,PR_TRUE);
- A = NULL;
- } else {
- A->len = bytesNeeded;
+ if (A) {
+ /* if i != c, then we didn't complete the loop above and must of failed
+ * somwhere along the way */
+ if (i != c) {
+ SECITEM_ZfreeItem(A,PR_TRUE);
+ A = NULL;
+ } else {
+ A->len = bytesNeeded;
+ }
}
return A;
@@ -634,7 +636,7 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
PORT_Memcpy(key->data, hash->data, key->len);
}
- SECITEM_FreeItem(hash, PR_TRUE);
+ SECITEM_ZfreeItem(hash, PR_TRUE);
return key;
loser:
@@ -822,7 +824,7 @@ void
nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
{
if (pbe_param != NULL) {
- PORT_FreeArena(pbe_param->poolp, PR_TRUE);
+ PORT_FreeArena(pbe_param->poolp, PR_FALSE);
}
}
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
index 52d1f75cd..5df3a4517 100644
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -59,12 +59,19 @@ EXPORTS = \
PRIVATE_EXPORTS = \
pk11pars.h \
pkcs11ni.h \
+ lowkeyi.h \
+ lowkeyti.h \
+ pcertt.h \
+ softoken.h \
+ softoknt.h \
+ softkver.h \
$(NULL)
CSRCS = \
dbinit.c \
dbmshim.c \
ecdecode.c \
+ fipsaudt.c \
fipstest.c \
fipstokn.c \
keydb.c \
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
index a808373d8..d4314f634 100644
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -41,9 +41,16 @@
#include "prlong.h"
#include "pcertt.h"
+#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */
+
SEC_BEGIN_PROTOS
/*
+ * initialize any global certificate locks
+ */
+SECStatus nsslowcert_InitLocks(void);
+
+/*
** Add a DER encoded certificate to the permanent database.
** "derCert" is the DER encoded certificate.
** "nickname" is the nickname to use for the cert
@@ -244,6 +251,11 @@ pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space,
int spaceLen);
NSSLOWCERTCertificate *
nsslowcert_CreateCert(void);
+
+certDBEntry *
+nsslowcert_DecodeAnyDBEntry(SECItem *dbData, SECItem *dbKey,
+ certDBEntryType entryType, void *pdata);
+
SEC_END_PROTOS
#endif /* _PCERTDB_H_ */
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
index 4a7706378..6630b6134 100644
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -54,7 +54,6 @@
#include "secerr.h"
#include "nssilock.h"
#include "prmon.h"
-#include "nsslocks.h"
#include "base64.h"
#include "sechash.h"
#include "plhash.h"
@@ -91,16 +90,42 @@ static int entryListCount = 0;
* a global lock to make the database thread safe.
*/
static PZLock *dbLock = NULL;
+static PZLock *certRefCountLock = NULL;
+static PZLock *certTrustLock = NULL;
+static PZLock *freeListLock = NULL;
void
certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle)
{
if (dbLock == NULL) {
- nss_InitLock(&dbLock, nssILockCertDB);
+ dbLock = PZ_NewLock(nssILockCertDB);
PORT_Assert(dbLock != NULL);
}
+}
- return;
+SECStatus
+nsslowcert_InitLocks(void)
+{
+ if (freeListLock == NULL) {
+ freeListLock = PZ_NewLock(nssILockRefLock);
+ if (freeListLock == NULL) {
+ return SECFailure;
+ }
+ }
+ if (certRefCountLock == NULL) {
+ certRefCountLock = PZ_NewLock(nssILockRefLock);
+ if (certRefCountLock == NULL) {
+ return SECFailure;
+ }
+ }
+ if (certTrustLock == NULL ) {
+ certTrustLock = PZ_NewLock(nssILockCertDB);
+ if (certTrustLock == NULL) {
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
}
/*
@@ -133,7 +158,6 @@ nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle)
return;
}
-static PZLock *certRefCountLock = NULL;
/*
* Acquire the cert reference count lock
@@ -144,10 +168,7 @@ static PZLock *certRefCountLock = NULL;
static void
nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert)
{
- if ( certRefCountLock == NULL ) {
- nss_InitLock(&certRefCountLock, nssILockRefLock);
- PORT_Assert(certRefCountLock != NULL);
- }
+ PORT_Assert(certRefCountLock != NULL);
PZ_Lock(certRefCountLock);
return;
@@ -170,8 +191,6 @@ nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert)
return;
}
-static PZLock *certTrustLock = NULL;
-
/*
* Acquire the cert trust lock
* There is currently one global lock for all certs, but I'm putting a cert
@@ -181,11 +200,8 @@ static PZLock *certTrustLock = NULL;
void
nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert)
{
- if ( certTrustLock == NULL ) {
- nss_InitLock(&certTrustLock, nssILockCertDB);
- PORT_Assert(certTrustLock != NULL);
- }
-
+ PORT_Assert(certTrustLock != NULL);
+
PZ_Lock(certTrustLock);
return;
}
@@ -207,7 +223,6 @@ nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
return;
}
-static PZLock *freeListLock = NULL;
/*
* Acquire the cert reference count lock
@@ -218,10 +233,7 @@ static PZLock *freeListLock = NULL;
static void
nsslowcert_LockFreeList(void)
{
- if ( freeListLock == NULL ) {
- nss_InitLock(&freeListLock, nssILockRefLock);
- PORT_Assert(freeListLock != NULL);
- }
+ PORT_Assert(freeListLock != NULL);
PZ_Lock(freeListLock);
return;
@@ -825,8 +837,7 @@ NewDBCertEntry(SECItem *derCert, char *nickname,
goto loser;
}
- entry = (certDBEntryCert *)PORT_ArenaZAlloc(arena, sizeof(certDBEntryCert));
-
+ entry = PORT_ArenaZNew(arena, certDBEntryCert);
if ( entry == NULL ) {
goto loser;
}
@@ -917,21 +928,6 @@ DecodeV4DBCertEntry(unsigned char *buf, int len)
goto loser;
}
- entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
- if ( !entry->derCert.data ) {
- goto loser;
- }
- entry->derCert.len = certlen;
-
- if ( nnlen ) {
- entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->nickname ) {
- goto loser;
- }
- } else {
- entry->nickname = 0;
- }
-
entry->common.arena = arena;
entry->common.version = CERT_DB_FILE_VERSION;
entry->common.type = certDBEntryTypeCert;
@@ -940,11 +936,25 @@ DecodeV4DBCertEntry(unsigned char *buf, int len)
entry->trust.emailFlags = buf[1];
entry->trust.objectSigningFlags = buf[2];
+ entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
+ if ( !entry->derCert.data ) {
+ goto loser;
+ }
+ entry->derCert.len = certlen;
PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen);
- PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);
- if (PORT_Strcmp(entry->nickname,"Server-Cert") == 0) {
- entry->trust.sslFlags |= CERTDB_USER;
+ if ( nnlen ) {
+ entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen);
+ if ( !entry->nickname ) {
+ goto loser;
+ }
+ PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);
+
+ if (PORT_Strcmp(entry->nickname, "Server-Cert") == 0) {
+ entry->trust.sslFlags |= CERTDB_USER;
+ }
+ } else {
+ entry->nickname = 0;
}
return(entry);
@@ -1056,7 +1066,7 @@ CreateCertEntry(void)
return entry;
}
- return PORT_ZAlloc(sizeof(certDBEntryCert));
+ return PORT_ZNew(certDBEntryCert);
}
static void
@@ -1121,9 +1131,8 @@ loser:
pkcs11_freeStaticData(dbkey.data,buf);
dbkey.data = NULL;
if ( entry ) {
-
+ DestroyDBEntry((certDBEntry *)entry);
}
- DestroyDBEntry((certDBEntry *)entry);
return(NULL);
}
@@ -1245,9 +1254,7 @@ NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags)
goto loser;
}
- entry = (certDBEntryRevocation*)
- PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation));
-
+ entry = PORT_ArenaZNew(arena, certDBEntryRevocation);
if ( entry == NULL ) {
goto loser;
}
@@ -1457,7 +1464,6 @@ EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena,
dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
}
@@ -2706,36 +2712,37 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
entry = ReadDBSubjectEntry(dbhandle,derSubject);
if (entry == NULL) {
- goto loser;
+ rv = SECFailure;
+ goto done;
}
- if ( entry->emailAddrs ) {
- for (i=0; i < (int)(entry->nemailAddrs); i++) {
- if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) {
- index = i;
- }
+ for (i=0; i < (int)(entry->nemailAddrs); i++) {
+ if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) {
+ index = i;
}
}
-
if (updateType == nsslowcert_remove) {
if (index == -1) {
- return SECSuccess;
+ rv = SECSuccess;
+ goto done;
}
-
entry->nemailAddrs--;
for (i=index; i < (int)(entry->nemailAddrs); i++) {
entry->emailAddrs[i] = entry->emailAddrs[i+1];
}
} else {
char **newAddrs = NULL;
+
if (index != -1) {
- return SECSuccess;
+ rv = SECSuccess;
+ goto done;
}
newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena,
(entry->nemailAddrs+1)* sizeof(char *));
if (!newAddrs) {
- goto loser;
+ rv = SECFailure;
+ goto done;
}
for (i=0; i < (int)(entry->nemailAddrs); i++) {
newAddrs[i] = entry->emailAddrs[i];
@@ -2743,7 +2750,8 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
newAddrs[entry->nemailAddrs] =
PORT_ArenaStrdup(entry->common.arena,emailAddr);
if (!newAddrs[entry->nemailAddrs]) {
- goto loser;
+ rv = SECFailure;
+ goto done;
}
entry->emailAddrs = newAddrs;
entry->nemailAddrs++;
@@ -2754,18 +2762,11 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
/* write the new one */
rv = WriteDBSubjectEntry(dbhandle, entry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- DestroyDBEntry((certDBEntry *)entry);
- if (emailAddr) PORT_Free(emailAddr);
- return(SECSuccess);
-loser:
+ done:
if (entry) DestroyDBEntry((certDBEntry *)entry);
if (emailAddr) PORT_Free(emailAddr);
- return(SECFailure);
+ return rv;
}
/*
@@ -2794,8 +2795,7 @@ AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle,
goto loser;
}
- entry->nickname = (nickname) ?
- PORT_ArenaStrdup(entry->common.arena, nickname) : NULL;
+ entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
if ( entry->nickname == NULL ) {
goto loser;
@@ -2876,8 +2876,7 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
goto loser;
}
- entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryVersion));
+ entry = PORT_ArenaZNew(arena, certDBEntryVersion);
if ( entry == NULL ) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
@@ -3070,6 +3069,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
}
if ( nsslowcert_IsNewer(cert, cmpcert) ) {
+ nsslowcert_DestroyCertificate(cmpcert);
/* insert before cmpcert */
rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i],
&cert->certKey);
@@ -3097,6 +3097,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
added = PR_TRUE;
break;
}
+ nsslowcert_DestroyCertificate(cmpcert);
/* copy this cert entry */
newCertKeys[new_i] = entry->certKeys[i];
newKeyIDs[new_i] = entry->keyIDs[i];
@@ -3849,6 +3850,8 @@ UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
updatehandle.permCertDB = updatedb;
updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB);
+ updatehandle.dbVerify = 0;
+ updatehandle.ref = 1; /* prevent premature close */
rv = nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback,
(void *)handle);
@@ -4298,7 +4301,8 @@ nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
keybuf = (unsigned char *)key.data;
keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN];
keyitem.type = siBuffer;
-
+ /* type should equal keybuf[0]. */
+
rv = (* callback)(&dataitem, &keyitem, type, udata);
if ( rv != SECSuccess ) {
return(rv);
@@ -4352,7 +4356,7 @@ CreateTrust(void)
return trust;
}
- return PORT_ZAlloc(sizeof(NSSLOWCERTTrust));
+ return PORT_ZNew(NSSLOWCERTTrust);
}
static void
@@ -5079,7 +5083,7 @@ nsslowcert_CreateCert(void)
if (cert) {
return cert;
}
- return (NSSLOWCERTCertificate *) PORT_ZAlloc(sizeof(NSSLOWCERTCertificate));
+ return PORT_ZNew(NSSLOWCERTCertificate);
}
static void
@@ -5106,6 +5110,9 @@ nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
if ( entry ) {
DestroyDBEntry((certDBEntry *)entry);
}
+ if (trust->dbhandle) {
+ sftk_freeCertDB(trust->dbhandle);
+ }
pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace);
PORT_Memset(trust, 0, sizeof(*trust));
@@ -5338,9 +5345,6 @@ nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
return(rv);
}
-/* If the freeListLock doesn't exist when this function is called,
-** this function will create it, use it 3 times, and delete it.
-*/
void
nsslowcert_DestroyFreeLists(void)
{
@@ -5368,3 +5372,77 @@ nsslowcert_DestroyGlobalLocks(void)
}
}
+certDBEntry *
+nsslowcert_DecodeAnyDBEntry(SECItem *dbData, SECItem *dbKey,
+ certDBEntryType entryType, void *pdata)
+{
+ PLArenaPool *arena = NULL;
+ certDBEntry *entry;
+ SECStatus rv;
+ SECItem dbEntry;
+
+
+ if ((dbData->len < SEC_DB_ENTRY_HEADER_LEN) || (dbKey->len == 0)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ dbEntry.data = &dbData->data[SEC_DB_ENTRY_HEADER_LEN];
+ dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ goto loser;
+ }
+ entry = PORT_ArenaZNew(arena, certDBEntry);
+ if (!entry)
+ goto loser;
+
+ entry->common.version = (unsigned int)dbData->data[0];
+ entry->common.flags = (unsigned int)dbData->data[2];
+ entry->common.type = entryType;
+ entry->common.arena = arena;
+
+ switch (entryType) {
+ case certDBEntryTypeContentVersion: /* This type appears to be unused */
+ case certDBEntryTypeVersion: /* This type has only the common hdr */
+ rv = SECSuccess;
+ break;
+
+ case certDBEntryTypeSubject:
+ rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey);
+ break;
+
+ case certDBEntryTypeNickname:
+ rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry,
+ (char *)dbKey->data);
+ break;
+
+ /* smime profiles need entries created after the certs have
+ * been imported, loop over them in a second run */
+ case certDBEntryTypeSMimeProfile:
+ rv = DecodeDBSMimeEntry(&entry->smime, &dbEntry, (char *)dbKey->data);
+ break;
+
+ case certDBEntryTypeCert:
+ rv = DecodeDBCertEntry(&entry->cert, &dbEntry);
+ break;
+
+ case certDBEntryTypeKeyRevocation:
+ case certDBEntryTypeRevocation:
+ rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry);
+ break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ }
+
+ if (rv == SECSuccess)
+ return entry;
+
+loser:
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
+}
+
diff --git a/security/nss/lib/softoken/pcertt.h b/security/nss/lib/softoken/pcertt.h
index e805950e1..848fe69e9 100644
--- a/security/nss/lib/softoken/pcertt.h
+++ b/security/nss/lib/softoken/pcertt.h
@@ -410,12 +410,14 @@ typedef struct {
#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY)
typedef union {
- certDBEntryCommon common;
- certDBEntryVersion version;
- certDBEntryCert cert;
- certDBEntryNickname nickname;
- certDBEntrySubject subject;
- certDBEntryRevocation revocation;
+ certDBEntryCommon common;
+ certDBEntryCert cert;
+ certDBEntryContentVersion content;
+ certDBEntryNickname nickname;
+ certDBEntryRevocation revocation;
+ certDBEntrySMime smime;
+ certDBEntrySubject subject;
+ certDBEntryVersion version;
} certDBEntry;
/* length of the fixed part of a database entry */
diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c
index c60e87780..30584c91e 100644
--- a/security/nss/lib/softoken/pk11db.c
+++ b/security/nss/lib/softoken/pk11db.c
@@ -868,7 +868,7 @@ secmod_ReadPermDB(const char *appName, const char *filename,
DBT key,data;
int ret;
DB *pkcs11db = NULL;
- char **moduleList = NULL;
+ char **moduleList = NULL, **newModuleList = NULL;
int moduleCount = 1;
int useCount = SECMOD_STEP;
@@ -888,9 +888,10 @@ secmod_ReadPermDB(const char *appName, const char *filename,
PRBool internal = PR_FALSE;
if ((moduleCount+1) >= useCount) {
useCount += SECMOD_STEP;
- moduleList =
+ newModuleList =
(char **)PORT_Realloc(moduleList,useCount*sizeof(char *));
- if (moduleList == NULL) goto done;
+ if (newModuleList == NULL) goto done;
+ moduleList = newModuleList;
PORT_Memset(&moduleList[moduleCount+1],0,
sizeof(char *)*SECMOD_STEP);
}
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 10a7bcfb7..7061059ce 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -55,7 +55,6 @@
#include "secitem.h"
#include "pkcs11.h"
#include "pkcs11i.h"
-#include "pkcs11p.h"
#include "softoken.h"
#include "lowkeyi.h"
#include "blapi.h"
@@ -63,13 +62,12 @@
#include "secport.h"
#include "pcert.h"
#include "secrng.h"
-#include "nss.h"
+#include "softkver.h"
#include "keydbi.h"
-#ifdef NSS_ENABLE_ECC
-extern SECStatus EC_FillParams(PRArenaPool *arena,
- const SECItem *encodedParams, ECParams *params);
+#ifdef DEBUG
+#include "cdbhdl.h"
#endif
/*
@@ -77,7 +75,7 @@ extern SECStatus EC_FillParams(PRArenaPool *arena,
*/
/* The next three strings must be exactly 32 characters long */
-static char *manufacturerID = "mozilla.org ";
+static char *manufacturerID = "Mozilla Foundation ";
static char manufacturerID_space[33];
static char *libraryDescription = "NSS Internal Crypto Services ";
static char libraryDescription_space[33];
@@ -87,6 +85,7 @@ static char libraryDescription_space[33];
* failure so that there are at most 60 login attempts per minute.
*/
static PRIntervalTime loginWaitTime;
+static PRUint32 minSessionObjectHandle = 1U;
#define __PASTE(x,y) x##y
@@ -1228,6 +1227,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
+ CK_BBOOL sign = CK_FALSE;
CK_BBOOL recover = CK_TRUE;
CK_BBOOL wrap = CK_TRUE;
CK_BBOOL derive = CK_FALSE;
@@ -1268,15 +1268,18 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
sftk_item_expand(&mod));
if (mod.data) PORT_Free(mod.data);
if (crv != CKR_OK) return crv;
-
+
+ sign = CK_TRUE;
break;
case CKK_DSA:
if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) {
return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
+ if (sftk_isTrue(object,CKA_TOKEN) &&
+ !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ sign = CK_TRUE;
/* fall through */
case CKK_DH:
if ( !sftk_hasAttribute(object, CKA_PRIME)) {
@@ -1300,10 +1303,12 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
if ( !sftk_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
+ if (sftk_isTrue(object,CKA_TOKEN) &&
+ !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
return CKR_TEMPLATE_INCOMPLETE;
}
encrypt = CK_FALSE;
+ sign = CK_TRUE;
recover = CK_FALSE;
wrap = CK_FALSE;
derive = CK_TRUE;
@@ -1320,7 +1325,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
if (crv != CKR_OK) return crv;
crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
+ crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover,
sizeof(CK_BBOOL));
@@ -1397,7 +1402,7 @@ fail:
return CKR_OK;
}
-/* forward delcare the DES formating function for handleSecretKey */
+/* forward declare the DES formating function for handleSecretKey */
void sftk_FormatDESKey(unsigned char *key, int length);
static NSSLOWKEYPrivateKey *sftk_mkSecretKeyRep(SFTKObject *object);
@@ -1532,6 +1537,9 @@ sftk_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
(++retries <= SFTK_KEY_MAX_RETRIES));
if ((rv != SECSuccess) || (retries > SFTK_KEY_MAX_RETRIES)) {
+ if (rv != SECSuccess) {
+ sftk_fatalError = PR_TRUE;
+ }
crv = CKR_DEVICE_ERROR; /* random number generator is bad */
PORT_Free(id->data);
id->data = NULL;
@@ -1644,6 +1652,9 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
/* get the key type */
attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
+ if (!attribute) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
@@ -1750,6 +1761,9 @@ sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
/* get the key type */
attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
+ if (!attribute) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
@@ -1773,9 +1787,11 @@ CK_RV
sftk_handleObject(SFTKObject *object, SFTKSession *session)
{
SFTKSlot *slot = session->slot;
+ SFTKAttribute *attribute;
+ SFTKObject *duplicateObject = NULL;
+ CK_OBJECT_HANDLE handle;
CK_BBOOL ckfalse = CK_FALSE;
CK_BBOOL cktrue = CK_TRUE;
- SFTKAttribute *attribute;
CK_RV crv;
/* make sure all the base object types are defined. If not set the
@@ -1801,11 +1817,37 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session)
return CKR_SESSION_READ_ONLY;
}
- /* PKCS #11 object ID's are unique for all objects on a
- * token */
- PZ_Lock(slot->objectLock);
- object->handle = slot->tokenIDCount++;
- PZ_Unlock(slot->objectLock);
+ /* Assign a unique SESSION object handle to every new object,
+ * whether it is a session object or a token object.
+ * At this point, all new objects are structured as session objects.
+ * Objects with the CKA_TOKEN attribute true will be turned into
+ * token objects and will have a token object handle assigned to
+ * them by a call to sftk_mkHandle in the handler for each object
+ * class, invoked below.
+ *
+ * It may be helpful to note/remember that
+ * sftk_narrowToXxxObject uses sftk_isToken,
+ * sftk_isToken examines the sign bit of the object's handle, but
+ * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute.
+ */
+ do {
+ PRUint32 wrappedAround;
+
+ duplicateObject = NULL;
+ PZ_Lock(slot->objectLock);
+ wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK;
+ handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK;
+ if (!handle) /* don't allow zero handle */
+ handle = minSessionObjectHandle;
+ slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround;
+ /* Is there already a session object with this handle? */
+ if (wrappedAround) {
+ sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, \
+ slot->sessObjHashSize);
+ }
+ PZ_Unlock(slot->objectLock);
+ } while (duplicateObject != NULL);
+ object->handle = handle;
/* get the object class */
attribute = sftk_FindAttribute(object,CKA_CLASS);
@@ -1815,8 +1857,10 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session)
object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
- /* now handle the specific. Get a session handle for these functions
- * to use */
+ /* Now handle the specific object class.
+ * At this point, all objects are session objects, and the session
+ * number must be passed to the object class handlers.
+ */
switch (object->objclass) {
case CKO_DATA:
crv = sftk_handleDataObject(session,object);
@@ -1852,7 +1896,11 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session)
return crv;
}
- /* now link the object into the slot and session structures */
+ /* Now link the object into the slot and session structures.
+ * If the object has a true CKA_TOKEN attribute, the above object
+ * class handlers will have set the sign bit in the object handle,
+ * causing the following test to be true.
+ */
if (sftk_isToken(object->handle)) {
sftk_convertSessionToToken(object);
} else {
@@ -1952,7 +2000,10 @@ NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,CK_KEY_TYPE key_type,
* based on the encoded params
*/
if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding,
- &pubKey->u.ec.ecParams) != SECSuccess) break;
+ &pubKey->u.ec.ecParams) != SECSuccess) {
+ crv = CKR_DOMAIN_PARAMS_INVALID;
+ break;
+ }
crv = sftk_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue,
object,CKA_EC_POINT);
@@ -2045,9 +2096,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.publicValue,
- object,CKA_NETSCAPE_DB);
- /* can't set the public value.... */
+ if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) {
+ crv = sftk_Attribute2SSecItem(arena, &privKey->u.dsa.publicValue,
+ object,CKA_NETSCAPE_DB);
+ /* privKey was zero'd so public value is already set to NULL, 0
+ * if we don't set it explicitly */
+ }
break;
case CKK_DH:
@@ -2061,8 +2115,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.publicValue,
- object,CKA_NETSCAPE_DB);
+ if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) {
+ crv = sftk_Attribute2SSecItem(arena, &privKey->u.dh.publicValue,
+ object,CKA_NETSCAPE_DB);
+ /* privKey was zero'd so public value is already set to NULL, 0
+ * if we don't set it explicitly */
+ }
break;
#ifdef NSS_ENABLE_ECC
@@ -2077,13 +2135,20 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
* based on the encoded params
*/
if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
- &privKey->u.ec.ecParams) != SECSuccess) break;
+ &privKey->u.ec.ecParams) != SECSuccess) {
+ crv = CKR_DOMAIN_PARAMS_INVALID;
+ break;
+ }
crv = sftk_Attribute2SSecItem(arena,&privKey->u.ec.privateValue,
object,CKA_VALUE);
if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
+ if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) {
+ crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) break;
+ if (crv != CKR_OK) break;
+ /* privKey was zero'd so public value is already set to NULL, 0
+ * if we don't set it explicitly */
+ }
rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
@@ -2333,7 +2398,7 @@ sftk_getDefTokName(CK_SLOT_ID slotID)
case PRIVATE_KEY_SLOT_ID:
return "NSS Certificate DB ";
case FIPS_SLOT_ID:
- return "NSS FIPS-140-1 Certificate DB ";
+ return "NSS FIPS 140-2 Certificate DB ";
default:
break;
}
@@ -2355,7 +2420,7 @@ sftk_getDefSlotName(CK_SLOT_ID slotID)
"NSS User Private Key and Certificate Services ";
case FIPS_SLOT_ID:
return
- "Netscape FIPS-140-1 User Private Key Services ";
+ "NSS FIPS 140-2 User Private Key Services ";
default:
break;
}
@@ -2388,6 +2453,8 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
{
SFTKSlot *slot;
int index = sftk_GetModuleIndex(slotID);
+
+ if (nscSlotHashTable[index] == NULL) return NULL;
slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
(void *)slotID);
/* cleared slots shouldn't 'show up' */
@@ -2622,11 +2689,11 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
slot->optimizeSpace = params->optimizeSpace;
if (slot->optimizeSpace) {
- slot->tokObjHashSize = SPACE_TOKEN_OBJECT_HASH_SIZE;
+ slot->sessObjHashSize = SPACE_SESSION_OBJECT_HASH_SIZE;
slot->sessHashSize = SPACE_SESSION_HASH_SIZE;
slot->numSessionLocks = 1;
} else {
- slot->tokObjHashSize = TIME_TOKEN_OBJECT_HASH_SIZE;
+ slot->sessObjHashSize = TIME_SESSION_OBJECT_HASH_SIZE;
slot->sessHashSize = TIME_SESSION_HASH_SIZE;
slot->numSessionLocks = slot->sessHashSize/BUCKETS_PER_SESSION_LOCK;
}
@@ -2652,16 +2719,16 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize);
if (slot->head == NULL)
goto mem_loser;
- slot->tokObjects = PORT_ZNewArray(SFTKObject *, slot->tokObjHashSize);
- if (slot->tokObjects == NULL)
+ slot->sessObjHashTable = PORT_ZNewArray(SFTKObject *, slot->sessObjHashSize);
+ if (slot->sessObjHashTable == NULL)
goto mem_loser;
- slot->tokenHashTable = PL_NewHashTable(64,sftk_HashNumber,PL_CompareValues,
+ slot->tokObjHashTable = PL_NewHashTable(64,sftk_HashNumber,PL_CompareValues,
SECITEM_HashCompare, NULL, 0);
- if (slot->tokenHashTable == NULL)
+ if (slot->tokObjHashTable == NULL)
goto mem_loser;
slot->sessionIDCount = 0;
- slot->tokenIDCount = 1;
+ slot->sessionObjectHandleCount = minSessionObjectHandle;
slot->slotID = slotID;
sftk_setStringName(params->slotdes ? params->slotdes :
sftk_getDefSlotName(slotID), slot->slotDescription,
@@ -2756,9 +2823,11 @@ sftk_DBShutdown(SFTKSlot *slot)
slot->keyDB = NULL;
PZ_Unlock(slot->slotLock);
if (certHandle) {
+ PORT_Assert(certHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID);
sftk_freeCertDB(certHandle);
}
if (keyHandle) {
+ PORT_Assert(keyHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID);
sftk_freeKeyDB(keyHandle);
}
}
@@ -2778,9 +2847,9 @@ SFTK_ShutdownSlot(SFTKSlot *slot)
/* clear all objects.. session objects are cleared as a result of
* closing all the sessions. We just need to clear the token object
- * cache. slot->tokenHashTable guarentees we have the token
+ * cache. slot->tokObjHashTable guarentees we have the token
* infrastructure set up. */
- if (slot->tokenHashTable) {
+ if (slot->tokObjHashTable) {
SFTK_ClearTokenKeyHashTable(slot);
}
@@ -2802,16 +2871,16 @@ SFTK_DestroySlotData(SFTKSlot *slot)
SFTK_ShutdownSlot(slot);
- if (slot->tokenHashTable) {
- PL_HashTableDestroy(slot->tokenHashTable);
- slot->tokenHashTable = NULL;
+ if (slot->tokObjHashTable) {
+ PL_HashTableDestroy(slot->tokObjHashTable);
+ slot->tokObjHashTable = NULL;
}
- if (slot->tokObjects) {
- PORT_Free(slot->tokObjects);
- slot->tokObjects = NULL;
+ if (slot->sessObjHashTable) {
+ PORT_Free(slot->sessObjHashTable);
+ slot->sessObjHashTable = NULL;
}
- slot->tokObjHashSize = 0;
+ slot->sessObjHashSize = 0;
if (slot->head) {
PORT_Free(slot->head);
@@ -2953,13 +3022,6 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
if (isFIPS) {
- /* make sure that our check file signatures are OK */
- if (!BLAPI_VerifySelf(NULL) ||
- !BLAPI_SHVerify(SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_closePeer)) {
- crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
- return crv;
- }
-
loginWaitTime = PR_SecondsToInterval(1);
}
@@ -2976,6 +3038,12 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
}
RNG_SystemInfoForRNG();
+ rv = nsslowcert_InitLocks();
+ if (rv != SECSuccess) {
+ crv = CKR_DEVICE_ERROR;
+ return crv;
+ }
+
/* NOTE:
* we should be getting out mutexes from this list, not statically binding
@@ -3022,6 +3090,13 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
* don't clobber each other. */
if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
sftk_closePeer(isFIPS);
+ if (sftk_audit_enabled) {
+ if (isFIPS && nsc_init) {
+ sftk_LogAuditMessage(NSS_AUDIT_INFO, "enabled FIPS mode");
+ } else {
+ sftk_LogAuditMessage(NSS_AUDIT_INFO, "disabled FIPS mode");
+ }
+ }
}
for (i=0; i < paramStrings.token_count; i++) {
@@ -3076,21 +3151,13 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
nsslowcert_DestroyFreeLists();
nsslowcert_DestroyGlobalLocks();
-#ifdef LEAK_TEST
- /*
- * do we really want to throw away all our hard earned entropy here!!?
- * No we don't! Not calling RNG_RNGShutdown only 'leaks' data on the
- * initial call to RNG_Init(). So the only reason to call this is to clean
- * up leak detection warnings on shutdown. In many cases we *don't* want
- * to free up the global RNG context because the application has Finalized
- * simply to swap profiles. We don't want to loose the entropy we've
- * already collected.
- */
+ /* This function does not discard all our previously aquired entropy. */
RNG_RNGShutdown();
-#endif
/* tell freeBL to clean up after itself */
BL_Cleanup();
+ /* unload freeBL shared library from memory */
+ BL_Unload();
/* clean up the default OID table */
SECOID_Shutdown();
nsc_init = PR_FALSE;
@@ -3127,8 +3194,8 @@ CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
pInfo->cryptokiVersion.major = 2;
pInfo->cryptokiVersion.minor = 20;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- pInfo->libraryVersion.major = NSS_VMAJOR;
- pInfo->libraryVersion.minor = NSS_VMINOR;
+ pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
+ pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
pInfo->flags = 0;
return CKR_OK;
@@ -3173,12 +3240,11 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
}
/* ok we really should read it out of the keydb file. */
/* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
- pInfo->hardwareVersion.major = NSS_VMAJOR;
- pInfo->hardwareVersion.minor = NSS_VMINOR;
+ pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR;
+ pInfo->hardwareVersion.minor = SOFTOKEN_VMINOR;
return CKR_OK;
}
-#define CKF_THREAD_SAFE 0x8000 /* for now */
/*
* check the current state of the 'needLogin' flag in case the database has
* been changed underneath us.
@@ -3206,14 +3272,17 @@ sftk_checkNeedLogin(SFTKSlot *slot, NSSLOWKEYDBHandle *keyHandle)
* the system. */
CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
{
- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
+ SFTKSlot *slot;
NSSLOWKEYDBHandle *handle;
+ if (!nsc_init && !nsf_init) return CKR_CRYPTOKI_NOT_INITIALIZED;
+ slot = sftk_SlotFromID(slotID, PR_FALSE);
if (slot == NULL) return CKR_SLOT_ID_INVALID;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
PORT_Memcpy(pInfo->model,"NSS 3 ",16);
PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16);
+ PORT_Memcpy(pInfo->utcTime,"0000000000000000",16);
pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
pInfo->ulSessionCount = slot->sessionCount;
pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */
@@ -3222,8 +3291,9 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->firmwareVersion.minor = 0;
PORT_Memcpy(pInfo->label,slot->tokDescription,32);
handle = sftk_getKeyDB(slot);
+ pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS;
if (handle == NULL) {
- pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE;
+ pInfo->flags |= CKF_WRITE_PROTECTED;
pInfo->ulMaxPinLen = 0;
pInfo->ulMinPinLen = 0;
pInfo->ulTotalPublicMemory = 0;
@@ -3243,12 +3313,11 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
* we will need to prompt for it.
*/
if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) {
- pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED;
+ pInfo->flags |= CKF_LOGIN_REQUIRED;
} else if (!sftk_checkNeedLogin(slot,handle)) {
- pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED;
+ pInfo->flags |= CKF_USER_PIN_INITIALIZED;
} else {
- pInfo->flags = CKF_THREAD_SAFE |
- CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
+ pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
}
pInfo->ulMaxPinLen = SFTK_MAX_PIN;
pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
@@ -3260,6 +3329,18 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->hardwareVersion.minor = handle->version;
sftk_freeKeyDB(handle);
}
+ /*
+ * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED
+ * should be set
+ * 0 0 1
+ * 1 0 0
+ * 0 1 1
+ * 1 1 1
+ */
+ if (!(pInfo->flags & CKF_LOGIN_REQUIRED) ||
+ (pInfo->flags & CKF_USER_PIN_INITIALIZED)) {
+ pInfo->flags |= CKF_TOKEN_INITIALIZED;
+ }
return CKR_OK;
}
@@ -3392,15 +3473,15 @@ CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
/* first, delete all our loaded key and cert objects from our
* internal list. */
PZ_Lock(slot->objectLock);
- for (i=0; i < slot->tokObjHashSize; i++) {
+ for (i=0; i < slot->sessObjHashSize; i++) {
do {
- object = slot->tokObjects[i];
+ object = slot->sessObjHashTable[i];
/* hand deque */
/* this duplicates function of NSC_close session functions, but
* because we know that we are freeing all the sessions, we can
* do more efficient processing */
if (object) {
- slot->tokObjects[i] = object->next;
+ slot->sessObjHashTable[i] = object->next;
if (object->next) object->next->prev = NULL;
object->next = object->prev = NULL;
@@ -3551,7 +3632,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
sftk_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */
}
if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
@@ -3927,7 +4008,7 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
if (attribute == NULL) {
return CKR_TEMPLATE_INCOMPLETE;
}
- paramString = (unsigned char *)attribute->attrib.pValue;
+ paramString = (char *)attribute->attrib.pValue;
crv = secmod_parseParameters(paramString, &paramStrings, isFIPS);
if (crv != CKR_OK) {
goto loser;
@@ -3990,7 +4071,9 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
SFTKSession *session;
SFTKObject *object;
- CK_OBJECT_CLASS class;
+ /* make sure class isn't randomly CKO_NETSCAPE_NEWSLOT or
+ * CKO_NETSCPE_DELSLOT. */
+ CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED;
CK_RV crv;
int i;
@@ -4393,7 +4476,7 @@ sftk_key_collect(DBT *key, DBT *data, void *arg)
tmpDBKey.type = siBuffer;
PORT_Assert(keyData->keyHandle);
- if (!keyData->strict && keyData->id) {
+ if (!keyData->strict && keyData->id && keyData->id->data) {
SECItem result;
PRBool haveMatch= PR_FALSE;
unsigned char hashKey[SHA1_LENGTH];
@@ -5006,7 +5089,7 @@ sftk_searchTokenList(SFTKSlot *slot, SFTKSearchResults *search,
/* keys */
if (classFlags & (NSC_PRIVATE|NSC_PUBLIC|NSC_KEY)) {
- PRBool mustStrict = ((classFlags & NSC_KEY) != 0) && (name.len != 0);
+ PRBool mustStrict = (name.len != 0);
sftk_searchKeys(slot, &key_id, isLoggedIn, classFlags, search,
mustStrict, pTemplate, ulCount);
}
@@ -5066,9 +5149,9 @@ CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
/* build list of found objects in the session */
if (!tokenOnly) {
- crv = sftk_searchObjectList(search, slot->tokObjects,
- slot->tokObjHashSize, slot->objectLock,
- pTemplate, ulCount, isLoggedIn);
+ crv = sftk_searchObjectList(search, slot->sessObjHashTable,
+ slot->sessObjHashSize, slot->objectLock,
+ pTemplate, ulCount, isLoggedIn);
}
if (crv != CKR_OK) {
goto loser;
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 56eb1814c..b722d3d4c 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -73,6 +73,7 @@
#include "pcert.h"
#include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */
+#include "prprf.h"
#define __PASTE(x,y) x##y
@@ -441,17 +442,23 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
break;
}
context->multi = PR_FALSE;
- context->cipherInfo = isEncrypt ?
- (void *)sftk_GetPubKey(key,CKK_RSA,&crv) :
- (void *)sftk_GetPrivKey(key,CKK_RSA,&crv);
- if (context->cipherInfo == NULL) {
- break;
- }
if (isEncrypt) {
+ NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
+ if (pubKey == NULL) {
+ break;
+ }
+ context->maxLen = nsslowkey_PublicModulusLen(pubKey);
+ context->cipherInfo = (void *)pubKey;
context->update = (SFTKCipher)
(pMechanism->mechanism == CKM_RSA_X_509
? RSA_EncryptRaw : RSA_EncryptBlock);
} else {
+ NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
+ if (privKey == NULL) {
+ break;
+ }
+ context->maxLen = nsslowkey_PrivateModulusLen(privKey);
+ context->cipherInfo = (void *)privKey;
context->update = (SFTKCipher)
(pMechanism->mechanism == CKM_RSA_X_509
? RSA_DecryptRaw : RSA_DecryptBlock);
@@ -717,6 +724,18 @@ CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL);
if (crv != CKR_OK) return crv;
+ if (!pEncryptedPart) {
+ if (context->doPad) {
+ CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength;
+ CK_ULONG blocksToSend = totalDataAvailable/context->blockSize;
+
+ *pulEncryptedPartLen = blocksToSend * context->blockSize;
+ return CKR_OK;
+ }
+ *pulEncryptedPartLen = ulPartLen;
+ return CKR_OK;
+ }
+
/* do padding */
if (context->doPad) {
/* deal with previous buffered data */
@@ -837,7 +856,8 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
if (crv != CKR_OK) return crv;
if (!pEncryptedData) {
- *pulEncryptedDataLen = ulDataLen + 2 * context->blockSize;
+ *pulEncryptedDataLen = context->multi ?
+ ulDataLen + 2 * context->blockSize : context->maxLen;
goto finish;
}
@@ -923,6 +943,35 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL);
if (crv != CKR_OK) return crv;
+ /* this can only happen on an NSS programming error */
+ PORT_Assert((context->padDataLength == 0)
+ || context->padDataLength == context->blockSize);
+
+
+ if (!pPart) {
+ if (context->doPad) {
+ /* we can check the data length here because if we are padding,
+ * then we must be using a block cipher. In the non-padding case
+ * the error will be returned by the underlying decryption
+ * function when do do the actual decrypt. We need to do the
+ * check here to avoid returning a negative length to the caller.
+ */
+ if ((ulEncryptedPartLen == 0) ||
+ (ulEncryptedPartLen % context->blockSize) != 0) {
+ return CKR_ENCRYPTED_DATA_LEN_RANGE;
+ }
+ *pulPartLen =
+ ulEncryptedPartLen + context->padDataLength - context->blockSize;
+ return CKR_OK;
+ }
+ /* for stream ciphers there is are no constraints on ulEncryptedPartLen.
+ * for block ciphers, it must be a multiple of blockSize. The error is
+ * detected when this function is called again do decrypt the output.
+ */
+ *pulPartLen = ulEncryptedPartLen;
+ return CKR_OK;
+ }
+
if (context->doPad) {
/* first decrypt our saved buffer */
if (context->padDataLength != 0) {
@@ -957,7 +1006,6 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
unsigned int maxout = *pulLastPartLen;
CK_RV crv;
SECStatus rv = SECSuccess;
- PRBool contextFinished = PR_TRUE;
/* make sure we're legal */
crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session);
@@ -967,9 +1015,9 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
if (!pLastPart) {
/* caller is checking the amount of remaining data */
if (context->padDataLength > 0) {
- *pulLastPartLen = 2 * context->blockSize;
- contextFinished = PR_FALSE; /* still have padding to go */
+ *pulLastPartLen = context->padDataLength;
}
+ rv = SECSuccess;
goto finish;
}
@@ -992,11 +1040,9 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
}
}
+ sftk_SetContextByType(session, SFTK_DECRYPT, NULL);
+ sftk_FreeContext(context);
finish:
- if (contextFinished) {
- sftk_SetContextByType(session, SFTK_DECRYPT, NULL);
- sftk_FreeContext(context);
- }
sftk_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}
@@ -1247,7 +1293,7 @@ static SECStatus
sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
unsigned char *hash, unsigned int hashLen)
{
- return PORT_Memcmp(sig,hash,*copyLen) ? SECSuccess : SECFailure ;
+ return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ;
}
/*
@@ -1548,6 +1594,15 @@ static SECStatus
sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
{
+ return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen,
+ hash,hashLen);
+}
+
+SECStatus
+RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+ unsigned char *hash, unsigned int hashLen)
+{
SECStatus rv = SECFailure;
SECItem digder;
@@ -1560,7 +1615,7 @@ sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
if ( !arena ) { goto loser; }
/* Construct digest info */
- di = SGN_CreateDigestInfo(info->hashOid, hash, hashLen);
+ di = SGN_CreateDigestInfo(hashOid, hash, hashLen);
if (!di) { goto loser; }
/* Der encode the digest as a DigestInfo */
@@ -1573,7 +1628,7 @@ sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
** Encrypt signature after constructing appropriate PKCS#1 signature
** block
*/
- rv = RSA_Sign(info->key,sig,sigLen,maxLen,digder.data,digder.len);
+ rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len);
loser:
SGN_DestroyDigestInfo(di);
@@ -1611,6 +1666,9 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
digest.data = (unsigned char *)dataBuf;
digest.len = dataLen;
rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
*sigLen = signature.len;
return rv;
}
@@ -1644,6 +1702,9 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
digest.data = (unsigned char *)dataBuf;
digest.len = dataLen;
rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
*sigLen = signature.len;
return rv;
}
@@ -1857,7 +1918,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
SECStatus rv;
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,type,PR_FALSE,NULL);
+ crv = sftk_GetContext(hSession,&context,type,PR_TRUE,NULL);
if (crv != CKR_OK) return crv;
if (context->hashInfo) {
@@ -2055,11 +2116,20 @@ CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
************** Crypto Functions: verify ************************
*/
-/* Handle RSA Signature formating */
+/* Handle RSA Signature formatting */
static SECStatus
sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig,
unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
{
+ return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen,
+ digest, digestLen);
+}
+
+SECStatus
+RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
+ unsigned char *sig, unsigned int sigLen,
+ unsigned char *digest, unsigned int digestLen)
+{
SECItem it;
SGNDigestInfo *di = NULL;
@@ -2067,16 +2137,16 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig,
it.data = NULL;
- if (info->key == NULL) goto loser;
+ if (key == NULL) goto loser;
- it.len = nsslowkey_PublicModulusLen(info->key);
+ it.len = nsslowkey_PublicModulusLen(key);
if (!it.len) goto loser;
it.data = (unsigned char *) PORT_Alloc(it.len);
if (it.data == NULL) goto loser;
/* decrypt the block */
- rv = RSA_CheckSignRecover(info->key, it.data, &it.len, it.len, sig, sigLen);
+ rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen);
if (rv != SECSuccess) goto loser;
di = SGN_DecodeDigestInfo(&it);
@@ -2084,7 +2154,11 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig,
if (di->digest.len != digestLen) goto loser;
/* make sure the tag is OK */
- if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != info->hashOid) {
+ if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) {
+ goto loser;
+ }
+ /* make sure the "parameters" are not too bogus. */
+ if (di->digestAlgorithm.parameters.len > 2) {
goto loser;
}
/* Now check the signature */
@@ -2093,6 +2167,7 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig,
}
loser:
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
rv = SECFailure;
done:
@@ -2202,7 +2277,6 @@ finish_rsa:
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}
- context->multi = PR_FALSE;
pubKey = sftk_GetPubKey(key,CKK_EC,&crv);
if (pubKey == NULL) {
crv = CKR_HOST_MEMORY;
@@ -2246,6 +2320,7 @@ finish_rsa:
}
if (crv != CKR_OK) {
+ if (info) PORT_Free(info);
PORT_Free(context);
sftk_FreeSession(session);
return crv;
@@ -2263,13 +2338,22 @@ CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
{
SFTKSession *session;
SFTKSessionContext *context;
- CK_RV crv;
+ CK_RV crv, crv2;
SECStatus rv;
/* make sure we're legal */
crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session);
if (crv != CKR_OK) return crv;
+ /* multi part Verifying are completely implemented by VerifyUpdate and
+ * VerifyFinal */
+ if (context->multi) {
+ sftk_FreeSession(session);
+ crv = NSC_VerifyUpdate(hSession, pData, ulDataLen);
+ crv2 = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
+ return crv == CKR_OK ? crv2 :crv;
+ }
+
rv = (*context->verify)(context->cipherInfo,pSignature, ulSignatureLen,
pData, ulDataLen);
sftk_FreeContext(context);
@@ -2414,14 +2498,23 @@ CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER,
PR_FALSE,&session);
if (crv != CKR_OK) return crv;
+ if (pData == NULL) {
+ /* to return the actual size, we need to do the decrypt, just return
+ * the max size, which is the size of the input signature. */
+ *pulDataLen = ulSignatureLen;
+ rv = SECSuccess;
+ goto finish;
+ }
rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
pSignature, ulSignatureLen);
*pulDataLen = (CK_ULONG) outlen;
+
sftk_FreeContext(context);
sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, NULL);
+finish:
sftk_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
+ return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID;
}
/*
@@ -2482,9 +2575,13 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
SECITEM_ZfreeItem(pbe_key, PR_TRUE);
pbe_key = NULL;
- if (iv.data && pbe_params->pInitVector != NULL) {
- PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
+ if (iv.data) {
+ if (pbe_params->pInitVector != NULL) {
+ PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
+ }
+ PORT_Free(iv.data);
}
+
return CKR_OK;
}
static CK_RV
@@ -2527,6 +2624,9 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
}
if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
return CKR_DEVICE_ERROR;
}
crv = sftk_AddAttributeType(key,CKA_PRIME,
@@ -3355,6 +3455,9 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
PORT_Free(pubExp.data);
if (rsaPriv == NULL) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
crv = CKR_DEVICE_ERROR;
break;
}
@@ -3471,7 +3574,13 @@ kpg_done:
PORT_Free(pqgParam.subPrime.data);
PORT_Free(pqgParam.base.data);
- if (rv != SECSuccess) { crv = CKR_DEVICE_ERROR; break; }
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+ crv = CKR_DEVICE_ERROR;
+ break;
+ }
/* store the generated key into the attributes */
crv = sftk_AddAttributeType(publicKey,CKA_VALUE,
@@ -3539,6 +3648,9 @@ dsagn_done:
PORT_Free(dhParam.prime.data);
PORT_Free(dhParam.base.data);
if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
crv = CKR_DEVICE_ERROR;
break;
}
@@ -3588,8 +3700,11 @@ dhgn_done:
rv = EC_NewKey(ecParams, &ecPriv);
PORT_FreeArena(ecParams->arena, PR_TRUE);
if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- break;
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+ crv = CKR_DEVICE_ERROR;
+ break;
}
crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
@@ -3695,6 +3810,16 @@ ecgn_done:
sftk_FreeObject(publicKey);
NSC_DestroyObject(hSession,privateKey->handle);
sftk_FreeObject(privateKey);
+ if (sftk_audit_enabled) {
+ char msg[128];
+ PR_snprintf(msg,sizeof msg,
+ "C_GenerateKeyPair(hSession=0x%08lX, "
+ "pMechanism->mechanism=0x%08lX)=0x%08lX "
+ "self-test: pair-wise consistency test failed",
+ (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
+ (PRUint32)crv);
+ sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg);
+ }
return crv;
}
@@ -3937,6 +4062,17 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data,
pText.len, pWrappedKey, pulWrappedKeyLen);
+ /* always force a finalize, both on errors and when
+ * we are just getting the size */
+ if (crv != CKR_OK || pWrappedKey == NULL) {
+ CK_RV lcrv ;
+ lcrv = sftk_GetContext(hSession,&context,
+ SFTK_ENCRYPT,PR_FALSE,NULL);
+ sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
+ if (lcrv == CKR_OK && context) {
+ sftk_FreeContext(context);
+ }
+ }
if (pText.data != (unsigned char *)attribute->attrib.pValue)
PORT_ZFree(pText.data, pText.len);
@@ -3947,6 +4083,7 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
case CKO_PRIVATE_KEY:
{
SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
+ SFTKSessionContext *context = NULL;
if(!bpki) {
break;
@@ -3962,6 +4099,16 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
pWrappedKey, pulWrappedKeyLen);
+ /* always force a finalize */
+ if (crv != CKR_OK || pWrappedKey == NULL) {
+ CK_RV lcrv ;
+ lcrv = sftk_GetContext(hSession,&context,
+ SFTK_ENCRYPT,PR_FALSE,NULL);
+ sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
+ if (lcrv == CKR_OK && context) {
+ sftk_FreeContext(context);
+ }
+ }
SECITEM_ZfreeItem(bpki, PR_TRUE);
break;
}
@@ -3989,7 +4136,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
PLArenaPool *arena;
NSSLOWKEYPrivateKey *lpk = NULL;
NSSLOWKEYPrivateKeyInfo *pki = NULL;
- SECItem *ck_id = NULL;
CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
arena = PORT_NewArena(2048);
@@ -4000,13 +4146,13 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
sizeof(NSSLOWKEYPrivateKeyInfo));
if(!pki) {
- PORT_FreeArena(arena, PR_TRUE);
+ PORT_FreeArena(arena, PR_FALSE);
return SECFailure;
}
if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki)
!= SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
@@ -4197,10 +4343,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
}
loser:
- if(ck_id) {
- SECITEM_ZfreeItem(ck_id, PR_TRUE);
- }
-
if(lpk) {
nsslowkey_DestroyPrivateKey(lpk);
}
@@ -4605,14 +4747,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
return CKR_KEY_HANDLE_INVALID;
}
- /* don't use key derive to expose sensitive keys */
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) {
- sftk_FreeObject(key);
- sftk_FreeObject(sourceKey);
- return crv;
- }
-
/* get the value of the base key */
att = sftk_FindAttribute(sourceKey,CKA_VALUE);
if (att == NULL) {
@@ -4633,7 +4767,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
case CKM_SSL3_MASTER_KEY_DERIVE_DH:
{
CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
- SSL3RSAPreMasterSecret *rsa_pms;
+ SSL3RSAPreMasterSecret * rsa_pms;
+ unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
+
if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
(pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH))
isDH = PR_TRUE;
@@ -4660,10 +4796,15 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
break;
}
-
/* finally do the key gen */
ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
pMechanism->pParameter;
+
+ PORT_Memcpy(crsrdata,
+ ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
+ ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
+
if (ssl3_master->pVersion) {
SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
@@ -4686,23 +4827,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
}
if (isTLS) {
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
- SECItem crsr = { siBuffer, NULL, 0 };
- SECItem master = { siBuffer, NULL, 0 };
- SECItem pms = { siBuffer, NULL, 0 };
SECStatus status;
+ SECItem crsr = { siBuffer, NULL, 0 };
+ SECItem master = { siBuffer, NULL, 0 };
+ SECItem pms = { siBuffer, NULL, 0 };
- pms.data = (unsigned char*)att->attrib.pValue;
- pms.len = att->attrib.ulValueLen;
- master.data = key_block;
- master.len = SSL3_MASTER_SECRET_LENGTH;
- crsr.data = crsrdata;
- crsr.len = sizeof(crsrdata);
-
- PORT_Memcpy(crsrdata, ssl3_master->RandomInfo.pClientRandom,
- SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
- ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
+ crsr.data = crsrdata;
+ crsr.len = sizeof crsrdata;
+ master.data = key_block;
+ master.len = SSL3_MASTER_SECRET_LENGTH;
+ pms.data = (unsigned char*)att->attrib.pValue;
+ pms.len = att->attrib.ulValueLen;
status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
if (status != SECSuccess) {
@@ -4727,12 +4862,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
att->attrib.ulValueLen);
- SHA1_Update(sha, ssl3_master->RandomInfo.pClientRandom,
- ssl3_master->RandomInfo.ulClientRandomLen);
- SHA1_Update(sha, ssl3_master->RandomInfo.pServerRandom,
- ssl3_master->RandomInfo.ulServerRandomLen);
+ SHA1_Update(sha, crsrdata, sizeof crsrdata);
SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
PORT_Assert(outLen == SHA1_LENGTH);
+
MD5_Begin(md5);
MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
att->attrib.ulValueLen);
@@ -4773,6 +4906,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
CK_SSL3_KEY_MAT_OUT * ssl3_keys_out;
CK_ULONG effKeySize;
+ unsigned int block_needed;
+ unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
+ unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
crv = sftk_DeriveSensitiveCheck(sourceKey,key);
if (crv != CKR_OK) break;
@@ -4801,6 +4937,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
break;
}
ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter;
+
+ PORT_Memcpy(srcrdata,
+ ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH,
+ ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
+
+ PORT_Memcpy(crsrdata,
+ ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
+ ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
+
/*
* clear out our returned keys so we can recover on failure
*/
@@ -4811,29 +4958,36 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
ssl3_keys_out->hServerKey = CK_INVALID_HANDLE;
/*
+ * How much key material do we need?
+ */
+ macSize = ssl3_keys->ulMacSizeInBits/8;
+ effKeySize = ssl3_keys->ulKeySizeInBits/8;
+ IVSize = ssl3_keys->ulIVSizeInBits/8;
+ if (keySize == 0) {
+ effKeySize = keySize;
+ }
+ block_needed = 2 * (macSize + effKeySize +
+ ((!ssl3_keys->bIsExport) * IVSize));
+ PORT_Assert(block_needed <= sizeof key_block);
+ if (block_needed > sizeof key_block)
+ block_needed = sizeof key_block;
+
+ /*
* generate the key material: This looks amazingly similar to the
* PMS code, and is clearly crying out for a function to provide it.
*/
if (isTLS) {
SECStatus status;
- SECItem master = { siBuffer, NULL, 0 };
SECItem srcr = { siBuffer, NULL, 0 };
SECItem keyblk = { siBuffer, NULL, 0 };
- unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
+ SECItem master = { siBuffer, NULL, 0 };
- master.data = (unsigned char*)att->attrib.pValue;
- master.len = att->attrib.ulValueLen;
srcr.data = srcrdata;
srcr.len = sizeof srcrdata;
keyblk.data = key_block;
- keyblk.len = sizeof key_block;
-
- PORT_Memcpy(srcrdata,
- ssl3_keys->RandomInfo.pServerRandom,
- SSL3_RANDOM_LENGTH);
- PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH,
- ssl3_keys->RandomInfo.pClientRandom,
- SSL3_RANDOM_LENGTH);
+ keyblk.len = block_needed;
+ master.data = (unsigned char*)att->attrib.pValue;
+ master.len = att->attrib.ulValueLen;
status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
isFIPS);
@@ -4841,6 +4995,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
goto key_and_mac_derive_fail;
}
} else {
+ unsigned int block_bytes = 0;
/* key_block =
* MD5(master_secret + SHA('A' + master_secret +
* ServerHello.random + ClientHello.random)) +
@@ -4850,15 +5005,12 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
* ServerHello.random + ClientHello.random)) +
* [...];
*/
- for (i = 0; i < NUM_MIXERS; i++) {
+ for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) {
SHA1_Begin(sha);
SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
att->attrib.ulValueLen);
- SHA1_Update(sha, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- SHA1_Update(sha, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
+ SHA1_Update(sha, srcrdata, sizeof srcrdata);
SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
PORT_Assert(outLen == SHA1_LENGTH);
MD5_Begin(md5);
@@ -4867,6 +5019,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
MD5_Update(md5, sha_out, outLen);
MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
PORT_Assert(outLen == MD5_LENGTH);
+ block_bytes += outLen;
}
}
@@ -4874,12 +5027,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
* Put the key material where it goes.
*/
i = 0; /* now shows how much consumed */
- macSize = ssl3_keys->ulMacSizeInBits/8;
- effKeySize = ssl3_keys->ulKeySizeInBits/8;
- IVSize = ssl3_keys->ulIVSizeInBits/8;
- if (keySize == 0) {
- effKeySize = keySize;
- }
/*
* The key_block is partitioned as follows:
@@ -4954,10 +5101,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
*/
MD5_Begin(md5);
MD5_Update(md5, &key_block[i], effKeySize);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
+ MD5_Update(md5, crsrdata, sizeof crsrdata);
MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
i += effKeySize;
crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
@@ -4973,10 +5117,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
*/
MD5_Begin(md5);
MD5_Update(md5, &key_block[i], effKeySize);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
+ MD5_Update(md5, srcrdata, sizeof srcrdata);
MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
i += effKeySize;
crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
@@ -4990,10 +5131,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
** MD5(ClientHello.random + ServerHello.random);
*/
MD5_Begin(md5);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
+ MD5_Update(md5, crsrdata, sizeof crsrdata);
MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize);
@@ -5002,10 +5140,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
** MD5(ServerHello.random + ClientHello.random);
*/
MD5_Begin(md5);
- MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom,
- ssl3_keys->RandomInfo.ulServerRandomLen);
- MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom,
- ssl3_keys->RandomInfo.ulClientRandomLen);
+ MD5_Update(md5, srcrdata, sizeof srcrdata);
MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize);
@@ -5018,18 +5153,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
SECItem secret = { siBuffer, NULL, 0 };
SECItem crsr = { siBuffer, NULL, 0 };
SECItem keyblk = { siBuffer, NULL, 0 };
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
-
- crsr.data = crsrdata;
- crsr.len = sizeof crsrdata;
-
- PORT_Memcpy(crsrdata,
- ssl3_keys->RandomInfo.pClientRandom,
- SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
- ssl3_keys->RandomInfo.pServerRandom,
- SSL3_RANDOM_LENGTH);
-
/*
** client_write_key[CipherSpec.key_material]
@@ -5040,6 +5163,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
secret.data = &key_block[i];
secret.len = effKeySize;
i += effKeySize;
+ crsr.data = crsrdata;
+ crsr.len = sizeof crsrdata;
keyblk.data = key_block2;
keyblk.len = sizeof key_block2;
status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
@@ -5177,6 +5302,9 @@ key_and_mac_derive_fail:
}
case CKM_CONCATENATE_BASE_AND_DATA:
+ crv = sftk_DeriveSensitiveCheck(sourceKey,key);
+ if (crv != CKR_OK) break;
+
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter;
tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
if (keySize == 0) keySize = tmpKeySize;
@@ -5198,6 +5326,9 @@ key_and_mac_derive_fail:
PORT_ZFree(buf,tmpKeySize);
break;
case CKM_CONCATENATE_DATA_AND_BASE:
+ crv = sftk_DeriveSensitiveCheck(sourceKey,key);
+ if (crv != CKR_OK) break;
+
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
if (keySize == 0) keySize = tmpKeySize;
@@ -5219,6 +5350,9 @@ key_and_mac_derive_fail:
PORT_ZFree(buf,tmpKeySize);
break;
case CKM_XOR_BASE_AND_DATA:
+ crv = sftk_DeriveSensitiveCheck(sourceKey,key);
+ if (crv != CKR_OK) break;
+
stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen);
if (keySize == 0) keySize = tmpKeySize;
@@ -5249,6 +5383,9 @@ key_and_mac_derive_fail:
CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */
+ crv = sftk_DeriveSensitiveCheck(sourceKey,key);
+ if (crv != CKR_OK) break;
+
if (keySize == 0) {
crv = CKR_TEMPLATE_INCOMPLETE;
break;
@@ -5382,6 +5519,7 @@ key_and_mac_derive_fail:
PRBool withCofactor = PR_FALSE;
unsigned char secret_hash[20];
unsigned char *secret;
+ unsigned char *keyData = NULL;
int secretlen;
CK_ECDH1_DERIVE_PARAMS *mechParams;
NSSLOWKEYPrivateKey *privKey;
@@ -5435,26 +5573,59 @@ key_and_mac_derive_fail:
break;
}
+ /*
+ * tmp is the raw data created by ECDH_Derive,
+ * secret and secretlen are the values we will eventually pass as our
+ * generated key.
+ */
secret = tmp.data;
secretlen = tmp.len;
+
+ /*
+ * apply the kdf function.
+ */
if (mechParams->kdf == CKD_SHA1_KDF) {
/* Compute SHA1 hash */
- memset(secret_hash, 0, 20);
+ PORT_Memset(secret_hash, 0, 20);
rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len);
if (rv != SECSuccess) {
PORT_ZFree(tmp.data, tmp.len);
+ crv = CKR_HOST_MEMORY;
+ break;
+ }
+ secret = secret_hash;
+ secretlen = 20;
+ }
+
+ /*
+ * if keySize is supplied, then we are generating a key of a specific
+ * length. This is done by taking the least significant 'keySize'
+ * bytes from the unsigned value calculated by ECDH. Note: this may
+ * mean padding temp with extra leading zeros from what ECDH_Derive
+ * already returned (which itself may contain leading zeros).
+ */
+ if (keySize) {
+ if (secretlen < keySize) {
+ keyData = PORT_ZAlloc(keySize);
+ if (!keyData) {
+ PORT_ZFree(tmp.data, tmp.len);
+ crv = CKR_HOST_MEMORY;
+ break;
+ }
+ PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen);
+ secret = keyData;
} else {
- secret = secret_hash;
- secretlen = 20;
+ secret += (secretlen - keySize);
}
+ secretlen = keySize;
}
- if (rv == SECSuccess) {
- sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
- PORT_ZFree(tmp.data, tmp.len);
- memset(secret_hash, 0, 20);
- } else
- crv = CKR_HOST_MEMORY;
+ sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
+ PORT_ZFree(tmp.data, tmp.len);
+ if (keyData) {
+ PORT_ZFree(keyData, keySize);
+ }
+ PORT_Memset(secret_hash, 0, 20);
break;
}
@@ -5700,7 +5871,9 @@ CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
/* get the key value */
att = sftk_FindAttribute(key,CKA_VALUE);
sftk_FreeObject(key);
-
+ if (!att) {
+ return CKR_KEY_HANDLE_INVALID;
+ }
crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue,
att->attrib.ulValueLen);
sftk_FreeAttribute(att);
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index 0eaf5bf37..cadcb6ffe 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -88,10 +88,10 @@
* NSS is a shared library.
*/
#define SPACE_ATTRIBUTE_HASH_SIZE 32
-#define SPACE_TOKEN_OBJECT_HASH_SIZE 32
+#define SPACE_SESSION_OBJECT_HASH_SIZE 32
#define SPACE_SESSION_HASH_SIZE 32
#define TIME_ATTRIBUTE_HASH_SIZE 32
-#define TIME_TOKEN_OBJECT_HASH_SIZE 1024
+#define TIME_SESSION_OBJECT_HASH_SIZE 1024
#define TIME_SESSION_HASH_SIZE 1024
#define MAX_OBJECT_LIST_SIZE 800
/* how many objects to keep on the free list
@@ -319,8 +319,9 @@ struct SFTKSessionStr {
*
* The array of sessionLock's protect the session hash table (head[])
* as well as the reference count of session objects in that bucket
- * (head[]->refCount), objectLock protects all elements of the token
- * object hash table (tokObjects[], tokenIDCount, and tokenHashTable),
+ * (head[]->refCount), objectLock protects all elements of the slot's
+ * object hash tables (sessObjHashTable[] and tokObjHashTable), and
+ * sessionObjectHandleCount.
* slotLock protects the remaining protected elements:
* password, isLoggedIn, ssoLoggedIn, and sessionCount,
* and pwCheckLock serializes the key database password checks in
@@ -366,11 +367,11 @@ struct SFTKSlotStr {
int sessionCount; /* variable - reset */
PRInt32 rwSessionCount; /* set by atomic operations */
/* (reset) */
- int tokenIDCount; /* variable - perserved */
+ PRUint32 sessionObjectHandleCount; /* variable - preserved */
int index; /* invariant */
- PLHashTable *tokenHashTable; /* invariant */
- SFTKObject **tokObjects; /* variable - reset */
- unsigned int tokObjHashSize; /* invariant */
+ PLHashTable *tokObjHashTable; /* invariant */
+ SFTKObject **sessObjHashTable; /* variable - reset */
+ unsigned int sessObjHashSize; /* invariant */
SFTKSession **head; /* variable -reset */
unsigned int sessHashSize; /* invariant */
char tokDescription[33]; /* per load */
@@ -555,8 +556,8 @@ typedef struct sftk_parametersStr {
SEC_BEGIN_PROTOS
-/* shared functions between PKCS11.c and SFTKFIPS.c */
-extern int nsf_init;
+/* shared functions between pkcs11.c and fipstokn.c */
+extern PRBool nsf_init;
extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 8e68587ce..9fc2e08e3 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -67,6 +67,7 @@ sftk_NewAttribute(SFTKObject *object,
if (so == NULL) {
/* allocate new attribute in a buffer */
PORT_Assert(0);
+ return NULL;
}
/*
* We attempt to keep down contention on Malloc and Arena locks by
@@ -891,6 +892,11 @@ sftk_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
case CKA_BASE:
return sftk_NewTokenAttributeSigned(type,key->u.dsa.params.base.data,
key->u.dsa.params.base.len, PR_FALSE);
+ case CKA_NETSCAPE_DB:
+ return sftk_NewTokenAttributeSigned(type,
+ key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len,
+ PR_FALSE);
default:
break;
}
@@ -925,6 +931,11 @@ sftk_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
case CKA_BASE:
return sftk_NewTokenAttributeSigned(type,key->u.dh.base.data,
key->u.dh.base.len, PR_FALSE);
+ case CKA_NETSCAPE_DB:
+ return sftk_NewTokenAttributeSigned(type,
+ key->u.dh.publicValue.data,
+ key->u.dh.publicValue.len,
+ PR_FALSE);
default:
break;
}
@@ -960,6 +971,11 @@ sftk_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
key->u.ec.ecParams.DEREncoding.data,
key->u.ec.ecParams.DEREncoding.len,
PR_FALSE);
+ case CKA_NETSCAPE_DB:
+ return sftk_NewTokenAttributeSigned(type,
+ key->u.ec.publicValue.data,
+ key->u.ec.publicValue.len,
+ PR_FALSE);
default:
break;
}
@@ -1502,7 +1518,6 @@ sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
sessObject->head, sessObject->hashSize);
}
PZ_Unlock(sessObject->attributeLock);
- sftk_FreeAttribute(attribute);
}
/*
@@ -2078,8 +2093,8 @@ sftk_deleteTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
SECItem *item;
PRBool rem;
- item = (SECItem *)PL_HashTableLookup(slot->tokenHashTable, (void *)handle);
- rem = PL_HashTableRemove(slot->tokenHashTable,(void *)handle) ;
+ item = (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle);
+ rem = PL_HashTableRemove(slot->tokObjHashTable,(void *)handle) ;
if (rem && item) {
SECITEM_FreeItem(item,PR_TRUE);
}
@@ -2102,7 +2117,7 @@ sftk_addTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle, SECItem *key)
if (item == NULL) {
return SECFailure;
}
- entry = PL_HashTableAdd(slot->tokenHashTable,(void *)handle,item);
+ entry = PL_HashTableAdd(slot->tokObjHashTable,(void *)handle,item);
if (entry == NULL) {
SECITEM_FreeItem(item,PR_TRUE);
return SECFailure;
@@ -2114,7 +2129,7 @@ sftk_addTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle, SECItem *key)
static SECItem *
sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
{
- return (SECItem *)PL_HashTableLookup(slot->tokenHashTable, (void *)handle);
+ return (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle);
}
/*
@@ -2146,7 +2161,7 @@ SFTK_ClearTokenKeyHashTable(SFTKSlot *slot)
{
sftk_tokenKeyLock(slot);
PORT_Assert(!slot->present);
- PL_HashTableEnumerateEntries(slot->tokenHashTable, sftk_freeHashItem, NULL);
+ PL_HashTableEnumerateEntries(slot->tokObjHashTable, sftk_freeHashItem, NULL);
sftk_tokenKeyUnlock(slot);
return CKR_OK;
}
@@ -2181,7 +2196,7 @@ sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace,
+ hashSize *sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);
object = (SFTKObject*)PORT_ZAlloc(size);
- if (isSessionObject) {
+ if (isSessionObject && object) {
((SFTKSessionObject *)object)->hashSize = hashSize;
}
*hasLocks = PR_FALSE;
@@ -2393,14 +2408,14 @@ static SFTKObject *
sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot)
{
SFTKObject *object;
- PRUint32 index = sftk_hash(handle, slot->tokObjHashSize);
+ PRUint32 index = sftk_hash(handle, slot->sessObjHashSize);
if (sftk_isToken(handle)) {
return sftk_NewTokenObject(slot, NULL, handle);
}
PZ_Lock(slot->objectLock);
- sftkqueue_find2(object, handle, index, slot->tokObjects);
+ sftkqueue_find2(object, handle, index, slot->sessObjHashTable);
if (object) {
sftk_ReferenceObject(object);
}
@@ -2453,10 +2468,10 @@ sftk_FreeObject(SFTKObject *object)
void
sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object)
{
- PRUint32 index = sftk_hash(object->handle, slot->tokObjHashSize);
+ PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
sftkqueue_init_element(object);
PZ_Lock(slot->objectLock);
- sftkqueue_add2(object, object->handle, index, slot->tokObjects);
+ sftkqueue_add2(object, object->handle, index, slot->sessObjHashTable);
PZ_Unlock(slot->objectLock);
}
@@ -2490,7 +2505,7 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
NSSLOWCERTCertificate *cert;
NSSLOWCERTCertTrust tmptrust;
PRBool isKrl;
- PRUint32 index = sftk_hash(object->handle, slot->tokObjHashSize);
+ PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
/* Handle Token case */
if (so && so->session) {
@@ -2499,7 +2514,7 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
sftkqueue_delete(&so->sessionList,0,session->objects,0);
PZ_Unlock(session->objectLock);
PZ_Lock(slot->objectLock);
- sftkqueue_delete2(object, object->handle, index, slot->tokObjects);
+ sftkqueue_delete2(object, object->handle, index, slot->sessObjHashTable);
PZ_Unlock(slot->objectLock);
sftkqueue_clear_deleted_element(object);
sftk_FreeObject(object); /* reduce it's reference count */
@@ -2749,7 +2764,7 @@ stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to)
}
/* copy the common attributes for all private keys next */
crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
- commonKeyAttrsCount);
+ commonPrivKeyAttrsCount);
if (crv != CKR_OK) {
goto fail;
}
diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c
index b40a30d80..c60c71344 100644
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -193,6 +193,7 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
unsigned char *bp;
int padLen;
int i;
+ SECStatus rv;
block = (unsigned char *) PORT_Alloc(modulusLen);
if (block == NULL)
@@ -254,8 +255,13 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
for (i = 0; i < padLen; i++) {
/* Pad with non-zero random data. */
do {
- RNG_GenerateGlobalRandomBytes(bp + i, 1);
- } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
+ rv = RNG_GenerateGlobalRandomBytes(bp + i, 1);
+ } while (rv == SECSuccess && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
+ if (rv != SECSuccess) {
+ sftk_fatalError = PR_TRUE;
+ PORT_Free (block);
+ return NULL;
+ }
}
bp += padLen;
*bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
@@ -292,7 +298,12 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
/*
* Salt
*/
- RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
+ rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
+ if (rv != SECSuccess) {
+ sftk_fatalError = PR_TRUE;
+ PORT_Free (block);
+ return NULL;
+ }
bp += OAEP_SALT_LEN;
/*
@@ -310,8 +321,14 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
/*
* Pad2
*/
- if (bp < (block + modulusLen))
- RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
+ if (bp < (block + modulusLen)) {
+ rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
+ if (rv != SECSuccess) {
+ sftk_fatalError = PR_TRUE;
+ PORT_Free (block);
+ return NULL;
+ }
+ }
/*
* Now we have the following:
@@ -463,6 +480,9 @@ RSA_Sign(NSSLOWKEYPrivateKey *key,
goto done;
rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
*output_len = modulus_len;
goto done;
@@ -489,7 +509,13 @@ RSA_CheckSign(NSSLOWKEYPublicKey *key,
modulus_len = nsslowkey_PublicModulusLen(key);
if (sign_len != modulus_len)
goto failure;
- if (hash_len > modulus_len - 8)
+ /*
+ * 0x00 || BT || Pad || 0x00 || ActualData
+ *
+ * The "3" below is the first octet + the second octet + the 0x00
+ * octet that always comes just before the ActualData.
+ */
+ if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN))
goto failure;
PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
if (key->keyType != NSSLOWKEYRSAKey)
@@ -509,11 +535,11 @@ RSA_CheckSign(NSSLOWKEYPublicKey *key,
if (buffer[0] != 0 || buffer[1] != 1)
goto loser;
for (i = 2; i < modulus_len - hash_len - 1; i++) {
- if (buffer[i] == 0)
- break;
if (buffer[i] != 0xff)
goto loser;
}
+ if (buffer[i] != 0)
+ goto loser;
/*
* make sure we get the same results
@@ -659,8 +685,12 @@ RSA_DecryptBlock(NSSLOWKEYPrivateKey *key,
goto failure;
rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
- if (rv != SECSuccess)
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
goto loser;
+ }
if (buffer[0] != 0 || buffer[1] != 2)
goto loser;
@@ -719,6 +749,9 @@ RSA_SignRaw(NSSLOWKEYPrivateKey *key,
goto done;
rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
*output_len = modulus_len;
done:
@@ -868,8 +901,12 @@ RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
goto failure;
rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
- if (rv != SECSuccess)
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
goto failure;
+ }
*output_len = modulus_len;
return SECSuccess;
diff --git a/security/nss/lib/softoken/softkver.c b/security/nss/lib/softoken/softkver.c
index 343be94bb..931d620e1 100644
--- a/security/nss/lib/softoken/softkver.c
+++ b/security/nss/lib/softoken/softkver.c
@@ -36,7 +36,7 @@
/* Library identity and versioning */
-#include "nss.h"
+#include "softkver.h"
#if defined(DEBUG)
#define _DEBUG_STRING " (debug)"
@@ -50,7 +50,7 @@
* NOTE: the first component of the concatenated rcsid string
* must not end in a '$' to prevent rcs keyword substitution.
*/
-const char __nss_softokn_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
+const char __nss_softokn_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING
" " __DATE__ " " __TIME__ " $";
-const char __nss_softokn_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
+const char __nss_softokn_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING
" " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
new file mode 100644
index 000000000..be3ce70fe
--- /dev/null
+++ b/security/nss/lib/softoken/softkver.h
@@ -0,0 +1,66 @@
+/*
+ * Softoken version numbers
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _SOFTKVER_H_
+#define _SOFTKVER_H_
+
+#ifdef NSS_ENABLE_ECC
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+#define SOFTOKEN_ECC_STRING " Extended ECC"
+#else
+#define SOFTOKEN_ECC_STRING " Basic ECC"
+#endif
+#else
+#define SOFTOKEN_ECC_STRING ""
+#endif
+
+/*
+ * Softoken's major version, minor version, patch level, and whether
+ * this is a beta release.
+ *
+ * The format of the version string should be
+ * "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]"
+ */
+#define SOFTOKEN_VERSION "3.11.9.0" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VMAJOR 3
+#define SOFTOKEN_VMINOR 11
+#define SOFTOKEN_VPATCH 9
+#define SOFTOKEN_BETA PR_FALSE
+
+#endif /* _SOFTKVER_H_ */
diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h
index b89546e53..ed9108dcc 100644
--- a/security/nss/lib/softoken/softoken.h
+++ b/security/nss/lib/softoken/softoken.h
@@ -81,7 +81,7 @@ extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen,
/*
* convenience wrappers for doing single RSA operations. They create the
* RSA context internally and take care of the formatting
- * requirements. Blinding happens automagically within RSA_SignHash and
+ * requirements. Blinding happens automagically within RSA_Sign and
* RSA_DecryptBlock.
*/
extern
@@ -89,10 +89,20 @@ SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
unsigned char *input, unsigned int inputLen);
extern
+SECStatus RSA_HashSign(SECOidTag hashOid,
+ NSSLOWKEYPrivateKey *key, unsigned char *sig,
+ unsigned int *sigLen, unsigned int maxLen,
+ unsigned char *hash, unsigned int hashLen);
+extern
SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign,
unsigned int signLength, unsigned char *hash,
unsigned int hashLength);
extern
+SECStatus RSA_HashCheckSign(SECOidTag hashOid,
+ NSSLOWKEYPublicKey *key, unsigned char *sig,
+ unsigned int sigLen, unsigned char *digest,
+ unsigned int digestLen);
+extern
SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data,
unsigned int *data_len,unsigned int max_output_len,
unsigned char *sign, unsigned int sign_len);
@@ -131,6 +141,14 @@ SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
unsigned int *output_len,
unsigned int max_output_len,
unsigned char *input, unsigned int input_len);
+#ifdef NSS_ENABLE_ECC
+/*
+** pepare an ECParam structure from DEREncoded params
+ */
+extern SECStatus EC_FillParams(PRArenaPool *arena,
+ const SECItem *encodedParams, ECParams *params);
+#endif
+
/*
** Prepare a buffer for DES encryption, growing to the appropriate boundary,
@@ -159,6 +177,83 @@ extern CK_RV sftk_fipsPowerUpSelfTest( void );
*/
unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
+/*
+** FIPS 140-2 auditing
+*/
+extern PRBool sftk_audit_enabled;
+
+extern void sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg);
+
+extern void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject, CK_RV rv);
+
+extern void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv);
+
+extern void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_RV rv);
+
+extern void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize,
+ CK_RV rv);
+
+extern void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount, CK_RV rv);
+
+extern void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount, CK_RV rv);
+
+extern void sftk_AuditCryptInit(const char *opName,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey, CK_RV rv);
+
+extern void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phKey, CK_RV rv);
+
+extern void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE_PTR phPublicKey,
+ CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv);
+
+extern void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv);
+
+extern void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hUnwrappingKey,
+ CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey, CK_RV rv);
+
+extern void sftk_AuditDeriveKey(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_RV rv);
+
+extern void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hKey, CK_RV rv);
+
+/*
+** FIPS 140-2 Error state
+*/
+extern PRBool sftk_fatalError;
+
SEC_END_PROTOS
#endif /* _SOFTOKEN_H_ */
diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc
index 0fcaa1219..860155318 100644
--- a/security/nss/lib/softoken/softokn.rc
+++ b/security/nss/lib/softoken/softokn.rc
@@ -34,7 +34,7 @@
*
* ***** END LICENSE BLOCK ***** */
-#include "nss.h"
+#include "softkver.h"
#include <winver.h>
#define MY_LIBNAME "softokn"
@@ -42,7 +42,7 @@
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
-#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
+#define SOFTOKEN_VMAJOR_STR STRINGIZE2(SOFTOKEN_VMAJOR)
#ifdef _DEBUG
#define MY_DEBUG_STR " (debug)"
@@ -51,7 +51,7 @@
#define MY_DEBUG_STR ""
#define MY_FILEFLAGS_1 0x0L
#endif
-#if NSS_BETA
+#if SOFTOKEN_BETA
#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
#else
#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
@@ -63,7 +63,7 @@
#define MY_FILEOS VOS__WINDOWS32
#endif
-#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
+#define MY_INTERNAL_NAME MY_LIBNAME SOFTOKEN_VMAJOR_STR
/////////////////////////////////////////////////////////////////////////////
//
@@ -71,8 +71,8 @@
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
- PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
+ FILEVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,0
+ PRODUCTVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS MY_FILEFLAGS_2
FILEOS MY_FILEOS
@@ -84,14 +84,13 @@ BEGIN
BEGIN
BLOCK "040904B0" // Lang=US English, CharSet=Unicode
BEGIN
- VALUE "CompanyName", "Netscape Communications Corporation\0"
+ VALUE "CompanyName", "Mozilla Foundation\0"
VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_VERSION "\0"
+ VALUE "FileVersion", SOFTOKEN_VERSION "\0"
VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0"
VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_VERSION "\0"
+ VALUE "ProductVersion", SOFTOKEN_VERSION "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h
index b499eb6b0..3af94e286 100644
--- a/security/nss/lib/softoken/softoknt.h
+++ b/security/nss/lib/softoken/softoknt.h
@@ -61,4 +61,13 @@ typedef enum {
#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
+/*
+ * FIPS 140-2 auditing
+ */
+typedef enum {
+ NSS_AUDIT_ERROR = 3, /* errors */
+ NSS_AUDIT_WARNING = 2, /* warning messages */
+ NSS_AUDIT_INFO = 1 /* informational messages */
+} NSSAuditSeverity;
+
#endif /* _SOFTOKNT_H_ */