summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkirk.erickson%sun.com <devnull@localhost>2003-04-08 06:12:09 +0000
committerkirk.erickson%sun.com <devnull@localhost>2003-04-08 06:12:09 +0000
commitaa38c4bc2ba67218c7455966cc004d414897af43 (patch)
tree2662112062e85c7f3ffab8b5fca5db7d7e3dd72b
parent52e4d590f9421a8ff9a4ddfcd741ac6df29818ab (diff)
downloadnss-hg-aa38c4bc2ba67218c7455966cc004d414897af43.tar.gz
Backported performance enhancements.SUN_SECURITY_3_3_5_BETA
Resolves 198159,
-rw-r--r--security/coreconf/SunOS5.mk4
-rw-r--r--security/nss/cmd/selfserv/selfserv.c65
-rw-r--r--security/nss/lib/freebl/md5.c3
-rw-r--r--security/nss/lib/freebl/prng_fips1861.c2
-rw-r--r--security/nss/lib/freebl/sha_fast.c3
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c147
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c4
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h3
-rw-r--r--security/nss/lib/softoken/alghmac.c6
-rw-r--r--security/nss/lib/softoken/alghmac.h3
-rw-r--r--security/nss/lib/softoken/pkcs11.c67
-rw-r--r--security/nss/lib/softoken/pkcs11c.c82
-rw-r--r--security/nss/lib/softoken/pkcs11i.h48
-rw-r--r--security/nss/lib/softoken/pkcs11u.c20
14 files changed, 333 insertions, 124 deletions
diff --git a/security/coreconf/SunOS5.mk b/security/coreconf/SunOS5.mk
index 37c98c787..a3d00b032 100644
--- a/security/coreconf/SunOS5.mk
+++ b/security/coreconf/SunOS5.mk
@@ -112,8 +112,8 @@ else
OS_CFLAGS += $(NOMD_OS_CFLAGS) $(ARCHFLAG)
ifndef BUILD_OPT
OS_CFLAGS += -xs
-# else
-# OPTIMIZER += -fast
+ else
+ OPTIMIZER = -xO3
endif
endif
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index 895ba5f56..b10e94a7d 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -88,6 +88,10 @@ static int handle_connection( PRFileDesc *, PRFileDesc *, int );
static const char envVarName[] = { SSL_ENV_VAR_NAME };
static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
+static PRBool logStats = PR_FALSE;
+static int logPeriod = 30;
+static PRUint32 loggerOps = 0;
+
const int ssl2CipherSuites[] = {
SSL_EN_RC4_128_WITH_MD5, /* A */
@@ -157,7 +161,7 @@ Usage(const char *progName)
"Usage: %s -n rsa_nickname -p port [-3DRTmrvx] [-w password] [-t threads]\n"
" [-i pid_file] [-c ciphers] [-d dbdir] [-f fortezza_nickname] \n"
-" [-M maxProcs] \n"
+" [-L [seconds]] [-M maxProcs] \n"
"-3 means disable SSL v3\n"
"-D means disable Nagle delays in TCP\n"
"-T means disable TLS\n"
@@ -170,6 +174,7 @@ Usage(const char *progName)
" 4 -r's mean request and require, cert on second handshake.\n"
"-v means verbose output\n"
"-x means use export policy.\n"
+"-L seconds means log statistics every 'seconds' seconds (default=30).\n"
"-M maxProcs tells how many processes to run in a multi-process server\n"
"-t threads -- specify the number of threads to use for connections.\n"
"-i pid_file file to write the process id of selfserve\n"
@@ -490,6 +495,36 @@ terminateWorkerThreads(void)
PR_Free(threads);
}
+static void
+logger(void *arg)
+{
+ PRFloat64 seconds;
+ PRFloat64 opsPerSec;
+ PRIntervalTime period;
+ PRIntervalTime previousTime;
+ PRIntervalTime latestTime;
+ PRUint32 previousOps;
+ PRUint32 ops;
+ PRIntervalTime logPeriodTicks = PR_SecondsToInterval(logPeriod);
+ PRFloat64 secondsPerTick = 1.0 / (PRFloat64)PR_TicksPerSecond();
+
+ previousOps = loggerOps;
+ previousTime = PR_IntervalNow();
+
+ for (;;) {
+ PR_Sleep(logPeriodTicks);
+ latestTime = PR_IntervalNow();
+ ops = loggerOps;
+ period = latestTime - previousTime;
+ seconds = (PRFloat64) period*secondsPerTick;
+ opsPerSec = (ops - previousOps) / seconds;
+ printf("%.2f ops/second, %d threads\n",
+ opsPerSec, threadCount);
+ fflush(stdout);
+ previousOps = ops;
+ previousTime = latestTime;
+ }
+}
/**************************************************************************
** End thread management routines.
@@ -979,6 +1014,10 @@ do_accepts(
VLOG(("selfserv: do_accept: Got connection\n"));
+ if (logStats) {
+ loggerOps++;
+ }
+
PZ_Lock(qLock);
while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) {
PZ_WaitCondVar(freeListNotEmptyCv, PR_INTERVAL_NO_TIMEOUT);
@@ -1288,6 +1327,7 @@ main(int argc, char **argv)
PRBool useExportPolicy = PR_FALSE;
PLOptState *optstate;
PLOptStatus status;
+ PRThread *loggerThread;
tmp = strrchr(argv[0], '/');
@@ -1297,7 +1337,7 @@ main(int argc, char **argv)
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
- optstate = PL_CreateOptState(argc, argv, "2:3DM:RTc:d:p:mn:hi:f:rt:vw:x");
+ optstate = PL_CreateOptState(argc, argv, "2:3DL:M:RTc:d:p:mn:hi:f:rt:vw:x");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
++optionsFound;
switch(optstate->option) {
@@ -1307,6 +1347,16 @@ main(int argc, char **argv)
case 'D': noDelay = PR_TRUE; break;
+ case 'L':
+ logStats = PR_TRUE;
+ if (optstate->value == NULL) {
+ logPeriod = 30;
+ } else {
+ logPeriod = PORT_Atoi(optstate->value);
+ if (logPeriod <= 0) logPeriod = 30;
+ }
+ break;
+
case 'M':
maxProcs = PORT_Atoi(optstate->value);
if (maxProcs < 1) maxProcs = 1;
@@ -1496,6 +1546,17 @@ main(int argc, char **argv)
/* allocate the array of thread slots, and launch the worker threads. */
rv = launch_threads(&jobLoop, 0, 0, requestCert);
+ if (rv == SECSuccess && logStats) {
+ loggerThread = PR_CreateThread(PR_USER_THREAD,
+ logger, NULL, PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, 0);
+ if (loggerThread == NULL) {
+ fprintf(stderr, "selfserv: Failed to launch logger thread!\n");
+ rv = SECFailure;
+ }
+ }
+
if ( rv == SECSuccess) {
server_main(listen_sock, requestCert, privKey, cert);
}
diff --git a/security/nss/lib/freebl/md5.c b/security/nss/lib/freebl/md5.c
index b0c0ed6a0..c3d02fbce 100644
--- a/security/nss/lib/freebl/md5.c
+++ b/security/nss/lib/freebl/md5.c
@@ -241,7 +241,8 @@ MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
MD5Context *
MD5_NewContext(void)
{
- MD5Context *cx = (MD5Context *)PORT_ZAlloc(sizeof(MD5Context));
+ /* no need to ZAlloc, _Begin will init the context */
+ MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context));
if (cx == NULL) {
PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
return NULL;
diff --git a/security/nss/lib/freebl/prng_fips1861.c b/security/nss/lib/freebl/prng_fips1861.c
index 2359913fd..0f7d90a78 100644
--- a/security/nss/lib/freebl/prng_fips1861.c
+++ b/security/nss/lib/freebl/prng_fips1861.c
@@ -166,8 +166,6 @@ alg_fips186_1_x3_1(RNGContext *rng,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- /* initialize the SHA1 context */
- memset(&sha1cx, 0, sizeof(sha1cx));
/*
* <Step 2> Initialize t, taken care of in SHA-1 (same initial values)
*/
diff --git a/security/nss/lib/freebl/sha_fast.c b/security/nss/lib/freebl/sha_fast.c
index 655f5c3e6..612e3d1ab 100644
--- a/security/nss/lib/freebl/sha_fast.c
+++ b/security/nss/lib/freebl/sha_fast.c
@@ -325,7 +325,8 @@ SHA1_NewContext(void)
{
SHA1Context *cx;
- cx = PORT_ZNew(SHA1Context);
+ /* no need to ZNew, _Begin will init the context */
+ cx = PORT_New(SHA1Context);
return cx;
}
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index d52df806d..a4bc0ab2f 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -180,11 +180,6 @@ pk11_getKeyFromList(PK11SlotInfo *slot) {
if (symKey == NULL) {
return NULL;
}
- symKey->refLock = PZ_NewLock(nssILockRefLock);
- if (symKey->refLock == NULL) {
- PORT_Free(symKey);
- return NULL;
- }
symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
symKey->next = NULL;
return symKey;
@@ -199,7 +194,6 @@ PK11_CleanKeyList(PK11SlotInfo *slot)
symKey = slot->freeSymKeysHead;
slot->freeSymKeysHead = symKey->next;
pk11_CloseSession(slot, symKey->session,symKey->sessionOwner);
- PK11_USE_THREADS(PZ_DestroyLock(symKey->refLock);)
PORT_Free(symKey);
};
return;
@@ -243,17 +237,15 @@ PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx)
void
PK11_FreeSymKey(PK11SymKey *symKey)
{
- PRBool destroy = PR_FALSE;
PK11SlotInfo *slot;
PRBool freeit = PR_TRUE;
- PK11_USE_THREADS(PZ_Lock(symKey->refLock);)
- if (symKey->refCount-- == 1) {
- destroy= PR_TRUE;
- }
- PK11_USE_THREADS(PZ_Unlock(symKey->refLock);)
- if (destroy) {
+ if (PR_AtomicDecrement(&symKey->refCount) == 0) {
+#if 0
if ((symKey->owner) && symKey->objectID != CK_INVALID_KEY) {
+#else
+ if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) {
+#endif
pk11_EnterKeyMonitor(symKey);
(void) PK11_GETTAB(symKey->slot)->
C_DestroyObject(symKey->session, symKey->objectID);
@@ -276,7 +268,6 @@ PK11_FreeSymKey(PK11SymKey *symKey)
if (freeit) {
pk11_CloseSession(symKey->slot, symKey->session,
symKey->sessionOwner);
- PK11_USE_THREADS(PZ_DestroyLock(symKey->refLock);)
PORT_Free(symKey);
}
PK11_FreeSlot(slot);
@@ -286,9 +277,7 @@ PK11_FreeSymKey(PK11SymKey *symKey)
PK11SymKey *
PK11_ReferenceSymKey(PK11SymKey *symKey)
{
- PK11_USE_THREADS(PZ_Lock(symKey->refLock);)
- symKey->refCount++;
- PK11_USE_THREADS(PZ_Unlock(symKey->refLock);)
+ PR_AtomicIncrement(&symKey->refCount);
return symKey;
}
@@ -314,17 +303,6 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
symKey->origin = origin;
symKey->owner = owner;
- /* adopt the parent's session */
- /* This is only used by SSL. What we really want here is a session
- * structure with a ref count so the session goes away only after all the
- * keys do. */
- if (owner && parent) {
- pk11_CloseSession(symKey->slot, symKey->session,symKey->sessionOwner);
- symKey->sessionOwner = parent->sessionOwner;
- symKey->session = parent->session;
- parent->sessionOwner = PR_FALSE;
- }
-
return symKey;
}
@@ -3167,7 +3145,20 @@ PK11_ExitContextMonitor(PK11Context *cx) {
void
PK11_DestroyContext(PK11Context *context, PRBool freeit)
{
+ SECStatus rv = SECFailure;
+ if (context->ownSession && context->key && /* context owns session & key */
+ context->key->session == context->session && /* sharing session */
+ !context->key->sessionOwner) /* sanity check */
+ {
+ /* session still valid, let the key free it as necessary */
+ rv = PK11_Finalize(context); /* end any ongoing activity */
+ if (rv == SECSuccess) {
+ context->key->sessionOwner = PR_TRUE;
+ } /* else couldn't finalize the session, close it */
+ }
+ if (rv == SECFailure) {
pk11_CloseSession(context->slot,context->session,context->ownSession);
+ }
/* initialize the critical fields of the context */
if (context->savedData != NULL ) PORT_Free(context->savedData);
if (context->key) PK11_FreeSymKey(context->key);
@@ -3180,46 +3171,46 @@ PK11_DestroyContext(PK11Context *context, PRBool freeit)
/*
* save the current context. Allocate Space if necessary.
*/
-static void *
-pk11_saveContextHelper(PK11Context *context, void *space,
- unsigned long *savedLength, PRBool staticBuffer, PRBool recurse)
+static unsigned char *
+pk11_saveContextHelper(PK11Context *context, unsigned char *buffer,
+ unsigned long *savedLength)
{
- CK_ULONG length;
CK_RV crv;
- if (staticBuffer) PORT_Assert(space != NULL);
-
- if (space == NULL) {
- crv =PK11_GETTAB(context->slot)->C_GetOperationState(context->session,
- NULL,&length);
+ /* If buffer is NULL, this will get the length */
+ crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session,
+ (CK_BYTE_PTR)buffer,
+ savedLength);
+ if (!buffer || (crv == CKR_BUFFER_TOO_SMALL)) {
+ /* the given buffer wasn't big enough (or was NULL), but we
+ * have the length, so try again with a new buffer and the
+ * correct length
+ */
+ unsigned long bufLen = *savedLength;
+ buffer = PORT_Alloc(bufLen);
+ if (buffer == NULL) {
+ return (unsigned char *)NULL;
+ }
+ crv = PK11_GETTAB(context->slot)->C_GetOperationState(
+ context->session,
+ (CK_BYTE_PTR)buffer,
+ savedLength);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
+ PORT_ZFree(buffer, bufLen);
}
- space = PORT_Alloc(length);
- if (space == NULL) return NULL;
- *savedLength = length;
- }
- crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session,
- (CK_BYTE_PTR)space,savedLength);
- if (!staticBuffer && !recurse && (crv == CKR_BUFFER_TOO_SMALL)) {
- if (!staticBuffer) PORT_Free(space);
- return pk11_saveContextHelper(context, NULL,
- savedLength, PR_FALSE, PR_TRUE);
}
if (crv != CKR_OK) {
- if (!staticBuffer) PORT_Free(space);
PORT_SetError( PK11_MapError(crv) );
- return NULL;
+ return (unsigned char *)NULL;
}
- return space;
+ return buffer;
}
void *
pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength)
{
- return pk11_saveContextHelper(context, space,
- savedLength, PR_FALSE, PR_FALSE);
+ return pk11_saveContextHelper(context,
+ (unsigned char *)space, savedLength);
}
/*
@@ -3351,7 +3342,14 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
context->operation = operation;
context->key = symKey ? PK11_ReferenceSymKey(symKey) : NULL;
context->slot = PK11_ReferenceSlot(slot);
- context->session = pk11_GetNewSession(slot,&context->ownSession);
+ if (symKey && symKey->sessionOwner) {
+ /* The symkey owns a session. Adopt that session. */
+ context->session = symKey->session;
+ context->ownSession = symKey->sessionOwner;
+ symKey->sessionOwner = PR_FALSE;
+ } else {
+ context->session = pk11_GetNewSession(slot, &context->ownSession);
+ }
context->cx = symKey ? symKey->cx : NULL;
/* get our session */
context->savedData = NULL;
@@ -3557,8 +3555,7 @@ PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength)
if (cx->ownSession) {
PK11_EnterContextMonitor(cx);
- data = (unsigned char*)pk11_saveContextHelper(cx,save,&length,
- PR_FALSE,PR_FALSE);
+ data = pk11_saveContextHelper(cx, save, &length);
PK11_ExitContextMonitor(cx);
if (data) *len = length;
} else if (saveLength >= cx->savedLength) {
@@ -3568,7 +3565,14 @@ PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength)
}
*len = cx->savedLength;
}
- return (data != NULL) ? SECSuccess : SECFailure;
+ if (data != NULL) {
+ if (cx->ownSession) {
+ PORT_ZFree(data, length);
+ }
+ return SECSuccess;
+ } else {
+ return SECFailure;
+ }
}
/*
@@ -3945,31 +3949,34 @@ pk11_Finalize(PK11Context *context)
{
CK_ULONG count = 0;
CK_RV crv;
+ unsigned char stackBuf[256];
+ unsigned char *buffer = NULL;
if (!context->ownSession) {
return SECSuccess;
}
+finalize:
switch (context->operation) {
case CKA_ENCRYPT:
crv=PK11_GETTAB(context->slot)->C_EncryptFinal(context->session,
- NULL,&count);
+ buffer, &count);
break;
case CKA_DECRYPT:
crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session,
- NULL,&count);
+ buffer, &count);
break;
case CKA_SIGN:
crv=PK11_GETTAB(context->slot)->C_SignFinal(context->session,
- NULL,&count);
+ buffer, &count);
break;
case CKA_VERIFY:
crv=PK11_GETTAB(context->slot)->C_VerifyFinal(context->session,
- NULL,count);
+ buffer, count);
break;
case CKA_DIGEST:
crv=PK11_GETTAB(context->slot)->C_DigestFinal(context->session,
- NULL,&count);
+ buffer, &count);
break;
default:
crv = CKR_OPERATION_NOT_INITIALIZED;
@@ -3977,9 +3984,23 @@ pk11_Finalize(PK11Context *context)
}
if (crv != CKR_OK) {
+ if (crv == CKR_OPERATION_NOT_INITIALIZED) {
+ /* if there's no operation, it is finalized */
+ return SECSuccess;
+ }
PORT_SetError( PK11_MapError(crv) );
return SECFailure;
}
+
+ /* try to finalize the session with a buffer */
+ if (buffer == NULL && count > 0) {
+ if (count < sizeof stackBuf) {
+ buffer = stackBuf;
+ goto finalize;
+ } else {
+ return SECFailure;
+ }
+ }
return SECSuccess;
}
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index 5abb593c9..85734b8f0 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -3650,10 +3650,10 @@ PK11_GenerateRandom(unsigned char *data,int len) {
slot = PK11_GetBestSlot(CKM_FAKE_RANDOM,NULL);
if (slot == NULL) return SECFailure;
- PK11_EnterSlotMonitor(slot);
+ if (!slot->isInternal) PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session,data,
(CK_ULONG)len);
- PK11_ExitSlotMonitor(slot);
+ if (!slot->isInternal) PK11_ExitSlotMonitor(slot);
PK11_FreeSlot(slot);
return (crv != CKR_OK) ? SECFailure : SECSuccess;
}
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index 43d95c750..3444bff12 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -144,8 +144,7 @@ struct PK11SymKeyStr {
SECItem data; /* raw key data if available */
CK_SESSION_HANDLE session;
PRBool sessionOwner;
- int refCount; /* number of references to this key */
- PZLock *refLock;
+ PRInt32 refCount; /* number of references to this key */
int size; /* key size in bytes */
PK11Origin origin; /* where this key came from
(see def in secmodt.h) */
diff --git a/security/nss/lib/softoken/alghmac.c b/security/nss/lib/softoken/alghmac.c
index aef81a76b..1d877644b 100644
--- a/security/nss/lib/softoken/alghmac.c
+++ b/security/nss/lib/softoken/alghmac.c
@@ -56,6 +56,12 @@ HMAC_Destroy(HMACContext *cx)
PORT_ZFree(cx, sizeof(HMACContext));
}
+int
+HMAC_GetLength(HMACContext *cx)
+{
+ return cx->hashobj->length;
+}
+
HMACContext *
HMAC_Create(SECOidTag hash_alg,
const unsigned char *secret,
diff --git a/security/nss/lib/softoken/alghmac.h b/security/nss/lib/softoken/alghmac.h
index 10d598267..3edd7df8f 100644
--- a/security/nss/lib/softoken/alghmac.h
+++ b/security/nss/lib/softoken/alghmac.h
@@ -85,6 +85,9 @@ HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
extern HMACContext *
HMAC_Clone(HMACContext *cx);
+extern int
+HMAC_GetLength(HMACContext *cx);
+
SEC_END_PROTOS
#endif
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 56c340984..55c6ad26c 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -2390,12 +2390,19 @@ PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin)
int i;
PK11Slot *slot = pk11_SlotFromID(slotID);
#ifdef PKCS11_USE_THREADS
- slot->sessionLock = PZ_NewLock(nssILockSession);
- if (slot->sessionLock == NULL) return CKR_HOST_MEMORY;
+ slot->slotLock = PZ_NewLock(nssILockSession);
+ if (slot->slotLock == NULL) return CKR_HOST_MEMORY;
+ for (i=0; i < NUMBER_OF_SESSION_LOCKS; i++) {
+ slot->sessionLock[i] = PZ_NewLock(nssILockSession);
+ if (slot->sessionLock[i] == NULL) return CKR_HOST_MEMORY;
+ }
slot->objectLock = PZ_NewLock(nssILockObject);
if (slot->objectLock == NULL) return CKR_HOST_MEMORY;
#else
- slot->sessionLock = NULL;
+ slot->slotLock = NULL;
+ for (i=0; i < NUMBER_OF_SESSION_LOCKS; i++) {
+ slot->sessionLock[i] = NULL;
+ }
slot->objectLock = NULL;
#endif
for(i=0; i < SESSION_HASH_SIZE; i++) {
@@ -2909,11 +2916,17 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
flags | CKF_SERIAL_SESSION);
if (session == NULL) return CKR_HOST_MEMORY;
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
if (slotID == NETSCAPE_SLOT_ID && (flags & CKF_RW_SESSION)) {
/* NETSCAPE_SLOT_ID is Read ONLY */
session->info.flags &= ~CKF_RW_SESSION;
}
+ slot->sessionCount++;
+ if (session->info.flags & CKF_RW_SESSION) {
+ slot->rwSessionCount++;
+ }
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
+
do {
do {
sessionID = (slot->sessionIDCount++ & MAX_SESSION_ID);
@@ -2923,6 +2936,7 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
} else if (slotID == FIPS_SLOT_ID) {
sessionID |= PK11_FIPS_FLAG;
}
+ PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,sessionID));)
pk11queue_find(sameID, sessionID, slot->head, SESSION_HASH_SIZE);
if (sameID == NULL) {
session->handle = sessionID;
@@ -2931,35 +2945,38 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
} else {
slot->sessionIDConflict++; /* for debugging */
}
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,sessionID));)
} while (sameID != NULL);
- slot->sessionCount++;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount++;
- }
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
-
*phSession = sessionID;
return CKR_OK;
}
-
/* NSC_CloseSession closes a session between an application and a token. */
CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
{
PK11Slot *slot;
PK11Session *session;
SECItem *pw = NULL;
+ PRBool sessionFound;
session = pk11_SessionFromHandle(hSession);
if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
slot = pk11_SlotFromSession(session);
+ sessionFound = PR_FALSE;
/* lock */
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,hSession));)
if (pk11queue_is_queued(session,hSession,slot->head,SESSION_HASH_SIZE)) {
+ sessionFound = PR_TRUE;
pk11queue_delete(session,hSession,slot->head,SESSION_HASH_SIZE);
session->refCount--; /* can't go to zero while we hold the reference */
+ PORT_Assert(session->refCount > 0);
+ }
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,hSession));)
+
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
+ if (sessionFound) {
slot->sessionCount--;
if (session->info.flags & CKF_RW_SESSION) {
slot->rwSessionCount--;
@@ -2970,7 +2987,7 @@ CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
slot->isLoggedIn = PR_FALSE;
slot->password = NULL;
}
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
pk11_FreeSession(session);
if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
@@ -2990,11 +3007,11 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
if (slot == NULL) return CKR_SLOT_ID_INVALID;
/* first log out the card */
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
pw = slot->password;
slot->isLoggedIn = PR_FALSE;
slot->password = NULL;
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
/* now close all the current sessions */
@@ -3004,7 +3021,7 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
* will guarrenteed be close, and no session will be partially closed */
for (i=0; i < SESSION_HASH_SIZE; i++) {
do {
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,i));)
session = slot->head[i];
/* hand deque */
/* this duplicates function of NSC_close session functions, but
@@ -3014,12 +3031,16 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
slot->head[i] = session->next;
if (session->next) session->next->prev = NULL;
session->next = session->prev = NULL;
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,i));)
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
slot->sessionCount--;
if (session->info.flags & CKF_RW_SESSION) {
slot->rwSessionCount--;
}
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
+ } else {
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,i));)
}
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
if (session) pk11_FreeSession(session);
} while (session != NULL);
}
@@ -3091,12 +3112,12 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
/* should this be a fixed password? */
if (ulPinLen == 0) {
SECItem *pw;
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
pw = slot->password;
slot->password = NULL;
slot->isLoggedIn = PR_TRUE;
slot->ssoLoggedIn = (PRBool)(userType == CKU_SO);
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
pk11_update_all_states(slot);
SECITEM_ZfreeItem(pw,PR_TRUE);
return CKR_OK;
@@ -3116,11 +3137,11 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
if (SECKEY_CheckKeyDBPassword(handle,pin) == SECSuccess) {
SECItem *tmp;
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
tmp = slot->password;
slot->isLoggedIn = PR_TRUE;
slot->password = pin;
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
if (tmp) SECITEM_ZfreeItem(tmp, PR_TRUE);
/* update all sessions */
@@ -3146,12 +3167,12 @@ CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
if (!slot->isLoggedIn) return CKR_USER_NOT_LOGGED_IN;
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(slot->slotLock);)
pw = slot->password;
slot->isLoggedIn = PR_FALSE;
slot->ssoLoggedIn = PR_FALSE;
slot->password = NULL;
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(slot->slotLock);)
if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
pk11_update_all_states(slot);
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 31e59f070..6b6a1daa3 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -499,6 +499,7 @@ pk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr,
context->hashInfo = NULL;
context->doPad = PR_FALSE;
context->padDataLength = 0;
+ context->blockSize = 0;
*contextPtr = context;
return CKR_OK;
@@ -845,12 +846,21 @@ CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
unsigned int maxout = *pulLastEncryptedPartLen;
CK_RV crv;
SECStatus rv = SECSuccess;
+ PRBool contextFinished = PR_TRUE;
/* make sure we're legal */
crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_TRUE,&session);
if (crv != CKR_OK) return crv;
*pulLastEncryptedPartLen = 0;
+ if (!pLastEncryptedPart) {
+ /* caller is checking the amount of remaining data */
+ if (context->blockSize > 0) {
+ *pulLastEncryptedPartLen = context->blockSize;
+ contextFinished = PR_FALSE; /* still have padding to go */
+ }
+ goto finish;
+ }
/* do padding */
if (context->doPad) {
@@ -865,9 +875,11 @@ CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen;
}
- /* do it */
+finish:
+ if (contextFinished) {
pk11_SetContextByType(session, PK11_ENCRYPT, NULL);
pk11_FreeContext(context);
+ }
pk11_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}
@@ -889,6 +901,11 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_FALSE,&session);
if (crv != CKR_OK) return crv;
+ if (!pEncryptedData) {
+ *pulEncryptedDataLen = ulDataLen + 2 * context->blockSize;
+ goto finish;
+ }
+
if (context->doPad) {
CK_ULONG finalLen;
/* padding is fairly complicated, have the update and final
@@ -910,8 +927,9 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
rv = (*context->update)(context->cipherInfo, pEncryptedData,
&outlen, maxoutlen, pData, ulDataLen);
*pulEncryptedDataLen = (CK_ULONG) outlen;
- pk11_FreeContext(context);
pk11_SetContextByType(session, PK11_ENCRYPT, NULL);
+ pk11_FreeContext(context);
+finish:
pk11_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
@@ -1227,12 +1245,22 @@ 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 = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_TRUE,&session);
if (crv != CKR_OK) return crv;
*pulLastPartLen = 0;
+ 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 */
+ }
+ goto finish;
+ }
+
if (context->doPad) {
/* decrypt our saved buffer */
if (context->padDataLength != 0) {
@@ -1249,9 +1277,11 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
}
}
- /* do it */
+finish:
+ if (contextFinished) {
pk11_SetContextByType(session, PK11_DECRYPT, NULL);
pk11_FreeContext(context);
+ }
pk11_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}
@@ -1273,6 +1303,11 @@ CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_FALSE,&session);
if (crv != CKR_OK) return crv;
+ if (!pData) {
+ *pulDataLen = ulEncryptedDataLen + context->blockSize;
+ goto finish;
+ }
+
if (context->doPad) {
CK_ULONG finalLen;
/* padding is fairly complicated, have the update and final
@@ -1292,8 +1327,9 @@ CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
pEncryptedData, ulEncryptedDataLen);
*pulDataLen = (CK_ULONG) outlen;
- pk11_FreeContext(context);
pk11_SetContextByType(session, PK11_DECRYPT, NULL);
+ pk11_FreeContext(context);
+finish:
pk11_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
}
@@ -1336,6 +1372,7 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
context->hashUpdate = (PK11Hash) MD2_Update;
context->end = (PK11End) MD2_End;
context->destroy = (PK11Destroy) MD2_DestroyContext;
+ context->maxLen = MD2_LENGTH;
MD2_Begin(md2_context);
break;
case CKM_MD5:
@@ -1350,6 +1387,7 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
context->hashUpdate = (PK11Hash) MD5_Update;
context->end = (PK11End) MD5_End;
context->destroy = (PK11Destroy) MD5_DestroyContext;
+ context->maxLen = MD5_LENGTH;
MD5_Begin(md5_context);
break;
case CKM_SHA_1:
@@ -1365,6 +1403,7 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
context->end = (PK11End) SHA1_End;
context->destroy = (PK11Destroy) SHA1_DestroyContext;
SHA1_Begin(sha1_context);
+ context->maxLen = SHA1_LENGTH;
break;
default:
crv = CKR_MECHANISM_INVALID;
@@ -1397,6 +1436,11 @@ CK_RV NSC_Digest(CK_SESSION_HANDLE hSession,
crv = pk11_GetContext(hSession,&context,PK11_HASH,PR_FALSE,&session);
if (crv != CKR_OK) return crv;
+ if (pDigest == NULL) {
+ *pulDigestLen = context->maxLen;
+ goto finish;
+ }
+
/* do it: */
(*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
/* NOTE: this assumes buf size is bigenough for the algorithm */
@@ -1405,6 +1449,7 @@ CK_RV NSC_Digest(CK_SESSION_HANDLE hSession,
pk11_SetContextByType(session, PK11_HASH, NULL);
pk11_FreeContext(context);
+finish:
pk11_FreeSession(session);
return CKR_OK;
}
@@ -1443,12 +1488,12 @@ CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
if (pDigest != NULL) {
(*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
*pulDigestLen = digestLen;
+ pk11_SetContextByType(session, PK11_HASH, NULL);
+ pk11_FreeContext(context);
} else {
- *pulDigestLen = 0;
+ *pulDigestLen = context->maxLen;
}
- pk11_SetContextByType(session, PK11_HASH, NULL);
- pk11_FreeContext(context);
pk11_FreeSession(session);
return CKR_OK;
}
@@ -1556,6 +1601,7 @@ pk11_doHMACInit(PK11SessionContext *context,SECOidTag oid,
context->destroy = (PK11Destroy) pk11_Space;
context->update = (PK11Cipher) pk11_HMACCopy;
context->verify = (PK11Verify) pk11_HMACCmp;
+ context->maxLen = HMAC_GetLength(HMACcontext);
HMAC_Begin(HMACcontext);
return CKR_OK;
}
@@ -1676,6 +1722,7 @@ pk11_doSSLMACInit(PK11SessionContext *context,SECOidTag oid,
context->destroy = (PK11Destroy) pk11_Space;
context->update = (PK11Cipher) pk11_SSLMACSign;
context->verify = (PK11Verify) pk11_SSLMACVerify;
+ context->maxLen = mac_size;
return CKR_OK;
}
@@ -2156,6 +2203,7 @@ finish_rsa:
context->destroy = (privKey == key->objectInfo) ?
(PK11Destroy)pk11_Null:(PK11Destroy)pk11_FreePrivKey;
}
+ context->maxLen = SECKEY_LowPrivateModulusLen(privKey);
break;
case CKM_DSA_SHA1:
@@ -2177,6 +2225,7 @@ finish_rsa:
context->update = (PK11Cipher) nsc_DSA_Sign_Stub;
context->destroy = (privKey == key->objectInfo) ?
(PK11Destroy) pk11_Null:(PK11Destroy)pk11_FreePrivKey;
+ context->maxLen = DSA_SIGNATURE_LEN;
break;
case CKM_MD2_HMAC_GENERAL:
@@ -2325,7 +2374,10 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
crv = pk11_GetContext(hSession,&context,PK11_SIGN,PR_TRUE,&session);
if (crv != CKR_OK) return crv;
- if (context->hashInfo) {
+ if (!pSignature) {
+ *pulSignatureLen = context->maxLen;
+ goto finish;
+ } else if (context->hashInfo) {
(*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
rv = (*context->update)(context->cipherInfo, pSignature,
&outlen, maxoutlen, tmpbuf, digestLen);
@@ -2349,6 +2401,8 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
pk11_FreeContext(context);
pk11_SetContextByType(session, PK11_SIGN, NULL);
+
+finish:
pk11_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
@@ -2372,6 +2426,11 @@ CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
crv = pk11_GetContext(hSession,&context,PK11_SIGN,PR_FALSE,&session);
if (crv != CKR_OK) return crv;
+ if (!pSignature) {
+ *pulSignatureLen = context->maxLen;
+ goto finish;
+ }
+
/* multi part Signing are completely implemented by SignUpdate and
* sign Final */
if (context->multi) {
@@ -2387,6 +2446,8 @@ CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
*pulSignatureLen = (CK_ULONG) outlen;
pk11_FreeContext(context);
pk11_SetContextByType(session, PK11_SIGN, NULL);
+
+finish:
pk11_FreeSession(session);
return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
@@ -5329,6 +5390,7 @@ CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession,
PK11SessionContext *context;
PK11Session *session;
CK_RV crv;
+ CK_ULONG pOSLen = *pulOperationStateLen;
/* make sure we're legal */
crv = pk11_GetContext(hSession, &context, PK11_HASH, PR_TRUE, &session);
@@ -5339,6 +5401,10 @@ CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession,
if (pOperationState == NULL) {
pk11_FreeSession(session);
return CKR_OK;
+ } else {
+ if (pOSLen < *pulOperationStateLen) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
}
PORT_Memcpy(pOperationState,&context->type,sizeof(PK11ContextType));
pOperationState += sizeof(PK11ContextType);
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index acce33c29..72b0a6674 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -85,9 +85,33 @@ typedef void (*PK11Free)(void *);
#define ATTRIBUTE_HASH_SIZE 32
#define SESSION_OBJECT_HASH_SIZE 32
#define TOKEN_OBJECT_HASH_SIZE 1024
-#define SESSION_HASH_SIZE 512
#define MAX_KEY_LEN 256
#define MAX_OBJECT_LIST_SIZE 800
+#define SESSION_HASH_SIZE 1024
+
+/*
+ * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number.
+ * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0.
+ * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0.
+ *
+ * HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS
+ * 1024 9 512 2
+ * 1024 5 32 32
+ * 1024 1 2 512
+ * 1024 0 1 1024
+ * 4096 11 2048 2
+ * 4096 9 512 8
+ * 4096 5 32 128
+ * 4096 1 2 2048
+ * 4096 0 1 4096
+ */
+#define LOG2_BUCKETS_PER_SESSION_LOCK 1
+#define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK))
+#define NUMBER_OF_SESSION_LOCKS (SESSION_HASH_SIZE/BUCKETS_PER_SESSION_LOCK)
+/* NOSPREAD sessionID to hash table index macro has been slower. */
+#if 0
+#define NOSPREAD
+#endif
/* Value to tell if an attribute is modifiable or not.
* NEVER: attribute is only set on creation.
@@ -237,7 +261,6 @@ struct PK11SessionStr {
PK11Session *prev;
CK_SESSION_HANDLE handle;
int refCount;
- PZLock *refLock;
PZLock *objectLock;
int objectIDCount;
CK_SESSION_INFO info;
@@ -256,7 +279,8 @@ struct PK11SessionStr {
*/
struct PK11SlotStr {
CK_SLOT_ID slotID;
- PZLock *sessionLock;
+ PZLock *slotLock;
+ PZLock *sessionLock[NUMBER_OF_SESSION_LOCKS];
PZLock *objectLock;
SECItem *password;
PRBool hasTokens;
@@ -329,8 +353,12 @@ struct PK11SSLMACInfoStr {
#define pk11_SlotFromSession(sp) ((sp)->slot)
#define pk11_isToken(id) (((id) & PK11_TOKEN_MASK) == PK11_TOKEN_MAGIC)
+/* the session hash multiplier */
+#define SHMULTIPLIER 1791398085
+
/* queueing helper macros */
-#define pk11_hash(value,size) ((value) & (size-1))/*size must be a power of 2*/
+#define pk11_hash(value,size) \
+ ((PRUint32)((value) * SHMULTIPLIER) & (size-1))
#define pk11queue_add(element,id,head,hash_size) \
{ int tmp = pk11_hash(id,hash_size); \
(element)->next = (head)[tmp]; \
@@ -351,6 +379,18 @@ struct PK11SSLMACInfoStr {
(element)->next = NULL; \
(element)->prev = NULL; \
+/* sessionID (handle) is used to determine session lock bucket */
+#ifdef NOSPREAD
+/* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */
+#define PK11_SESSION_LOCK(slot,handle) \
+ ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) \
+ & (NUMBER_OF_SESSION_LOCKS-1)])
+#else
+/* SPREAD: ID & (perbucket-1) */
+#define PK11_SESSION_LOCK(slot,handle) \
+ ((slot)->sessionLock[(handle) & (NUMBER_OF_SESSION_LOCKS-1)])
+#endif
+
/* expand an attribute & secitem structures out */
#define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
#define pk11_item_expand(ip) (ip)->data,(ip)->len
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index e9dd6f7b3..e34f5454e 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -1107,11 +1107,11 @@ pk11_update_all_states(PK11Slot *slot)
PK11Session *session;
for (i=0; i < SESSION_HASH_SIZE; i++) {
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,i));)
for (session = slot->head[i]; session; session = session->next) {
pk11_update_state(slot,session);
}
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,i));)
}
}
@@ -1184,19 +1184,12 @@ pk11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
session->search = NULL;
session->objectIDCount = 1;
#ifdef PKCS11_USE_THREADS
- session->refLock = PZ_NewLock(nssILockRefLock);
- if (session->refLock == NULL) {
- PORT_Free(session);
- return NULL;
- }
session->objectLock = PZ_NewLock(nssILockObject);
if (session->objectLock == NULL) {
- PK11_USE_THREADS(PZ_DestroyLock(session->refLock);)
PORT_Free(session);
return NULL;
}
#else
- session->refLock = NULL;
session->objectLock = NULL;
#endif
session->objects[0] = NULL;
@@ -1228,7 +1221,6 @@ pk11_DestroySession(PK11Session *session)
pk11_DeleteObject(session,op->parent);
}
PK11_USE_THREADS(PZ_DestroyLock(session->objectLock);)
- PK11_USE_THREADS(PZ_DestroyLock(session->refLock);)
if (session->enc_context) {
pk11_FreeContext(session->enc_context);
}
@@ -1255,10 +1247,10 @@ pk11_SessionFromHandle(CK_SESSION_HANDLE handle)
PK11Slot *slot = pk11_SlotFromSessionHandle(handle);
PK11Session *session;
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,handle));)
pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE);
if (session) session->refCount++;
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,handle));)
return (session);
}
@@ -1272,10 +1264,10 @@ pk11_FreeSession(PK11Session *session)
PRBool destroy = PR_FALSE;
PK11_USE_THREADS(PK11Slot *slot = pk11_SlotFromSession(session);)
- PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,session->handle));)
if (session->refCount == 1) destroy = PR_TRUE;
session->refCount--;
- PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);)
+ PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,session->handle));)
if (destroy) pk11_DestroySession(session);
}