Skip to content

Commit

Permalink
Bug 1606992 - Cache the most recent PBKDF2 password hash, to speed up…
Browse files Browse the repository at this point in the history
… repeated SDR operations. r=jcj
  • Loading branch information
kaie committed Jan 11, 2020
1 parent 71f897d commit c04dc87
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
74 changes: 74 additions & 0 deletions lib/softoken/lowpbe.c
Expand Up @@ -557,6 +557,52 @@ nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
return A;
}

/* Bug 1606992 - Cache the hash result for the common case that we're
* asked to repeatedly compute the key for the same password item,
* hash, iterations and salt. */
static PZLock *PBE_cache_lock = NULL;
static SECItem *cached_PBKDF2_item = NULL;
static HASH_HashType cached_hashType;
static int cached_iterations;
static int cached_keyLen;
static SECItem *cached_salt = NULL;
static SECItem *cached_pwitem = NULL;

void
sftk_PBELockInit(void)
{
if (!PBE_cache_lock) {
PBE_cache_lock = PZ_NewLock(nssIPBECacheLock);
}
}

static void
sftk_clearPBECacheItems(void)
{
if (cached_PBKDF2_item) {
SECITEM_FreeItem(cached_PBKDF2_item, PR_TRUE);
cached_PBKDF2_item = NULL;
}
if (cached_salt) {
SECITEM_FreeItem(cached_salt, PR_TRUE);
cached_salt = NULL;
}
if (cached_pwitem) {
SECITEM_FreeItem(cached_pwitem, PR_TRUE);
cached_pwitem = NULL;
}
}

void
sftk_PBELockShutdown(void)
{
if (PBE_cache_lock) {
PZ_DestroyLock(PBE_cache_lock);
PBE_cache_lock = 0;
}
sftk_clearPBECacheItems();
}

/*
* generate key as per PKCS 5
*/
Expand Down Expand Up @@ -600,7 +646,35 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,

break;
case NSSPKCS5_PBKDF2:
PZ_Lock(PBE_cache_lock);
if (cached_PBKDF2_item) {
if (pbe_param->hashType == cached_hashType &&
pbe_param->iter == cached_iterations &&
pbe_param->keyLen == cached_keyLen &&
cached_salt &&
SECITEM_ItemsAreEqual(&pbe_param->salt, cached_salt) &&
cached_pwitem &&
SECITEM_ItemsAreEqual(pwitem, cached_pwitem)) {
hash = SECITEM_DupItem(cached_PBKDF2_item);
} else {
sftk_clearPBECacheItems();
}
}
PZ_Unlock(PBE_cache_lock);
if (!hash) {
hash = nsspkcs5_PBKDF2(hashObj, pbe_param, pwitem);
PZ_Lock(PBE_cache_lock);
/* ensure no other thread was quicker than us setting the cache */
if (!cached_PBKDF2_item) {
cached_PBKDF2_item = SECITEM_DupItem(hash);
cached_hashType = pbe_param->hashType;
cached_iterations = pbe_param->iter;
cached_keyLen = pbe_param->keyLen;
cached_salt = SECITEM_DupItem(&pbe_param->salt);
cached_pwitem = SECITEM_DupItem(pwitem);
}
PZ_Unlock(PBE_cache_lock);
}
if (getIV) {
PORT_Memcpy(iv->data, pbe_param->ivData, iv->len);
}
Expand Down
7 changes: 7 additions & 0 deletions lib/softoken/pkcs11.c
Expand Up @@ -3104,6 +3104,9 @@ sftk_closePeer(PRBool isFIPS)
return;
}

extern void sftk_PBELockInit(void);
extern void sftk_PBELockShutdown(void);

/* NSC_Initialize initializes the Cryptoki library. */
CK_RV
nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
Expand All @@ -3120,6 +3123,8 @@ nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)

ENABLE_FORK_CHECK();

sftk_PBELockInit();

rv = SECOID_Init();
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
Expand Down Expand Up @@ -3300,6 +3305,8 @@ nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS)
/* clean up the default OID table */
SECOID_Shutdown();

sftk_PBELockShutdown();

/* reset fork status in util */
UTIL_SetForkState(PR_FALSE);

Expand Down

0 comments on commit c04dc87

Please sign in to comment.