summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Relyea <rrelyea@redhat.com>2021-08-17 16:33:51 -0700
committerRobert Relyea <rrelyea@redhat.com>2021-08-17 16:33:51 -0700
commit7792cc6490f98d929fa269b5fb4bab04cb2890d4 (patch)
tree7121955ad379c2b3eac282e213ceae931ab901a7
parente980c4e09898ee86163d8d93624a90ad0d2b2e1a (diff)
downloadnss-hg-7792cc6490f98d929fa269b5fb4bab04cb2890d4.tar.gz
Bug 1726022 Cache additional PBE entries
Firefox password manager is slow to load (22s for 361 passwords on an i7), using 100% CPU and causing laptop fans to spin up Possible solution based on increasing the number of cache entries used by the PKCS5v2 values as the current code thrashes the cache as we use 2 pbe's per read operation. This patch is tested for correctness, but not fixing the issue. New test cases are needed. Differential Revision: https://phabricator.services.mozilla.com/D122917
-rw-r--r--lib/softoken/lowpbe.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/lib/softoken/lowpbe.c b/lib/softoken/lowpbe.c
index 2ce6c415e..dcb79a5d9 100644
--- a/lib/softoken/lowpbe.c
+++ b/lib/softoken/lowpbe.c
@@ -570,6 +570,7 @@ typedef struct KDFCacheItemStr KDFCacheItem;
/* 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. */
+#define KDF2_CACHE_COUNT 2
static struct {
PZLock *lock;
struct {
@@ -578,7 +579,8 @@ static struct {
PRBool faulty3DES;
} cacheKDF1;
struct {
- KDFCacheItem common;
+ KDFCacheItem common[KDF2_CACHE_COUNT];
+ int next;
} cacheKDF2;
} PBECache;
@@ -627,11 +629,15 @@ sftk_setPBECacheKDF2(const SECItem *hash,
const SECItem *pwItem)
{
PZ_Lock(PBECache.lock);
+ KDFCacheItem *next = &PBECache.cacheKDF2.common[PBECache.cacheKDF2.next];
- sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF2.common);
+ sftk_clearPBECommonCacheItemsLocked(next);
- sftk_setPBECommonCacheItemsKDFLocked(&PBECache.cacheKDF2.common,
- hash, pbe_param, pwItem);
+ sftk_setPBECommonCacheItemsKDFLocked(next, hash, pbe_param, pwItem);
+ PBECache.cacheKDF2.next++;
+ if (PBECache.cacheKDF2.next >= KDF2_CACHE_COUNT) {
+ PBECache.cacheKDF2.next = 0;
+ }
PZ_Unlock(PBECache.lock);
}
@@ -674,11 +680,16 @@ sftk_getPBECacheKDF2(const NSSPKCS5PBEParameter *pbe_param,
const SECItem *pwItem)
{
SECItem *result = NULL;
- const KDFCacheItem *cacheItem = &PBECache.cacheKDF2.common;
+ int i;
PZ_Lock(PBECache.lock);
- if (sftk_comparePBECommonCacheItemLocked(cacheItem, pbe_param, pwItem)) {
- result = SECITEM_DupItem(cacheItem->hash);
+ for (i = 0; i < KDF2_CACHE_COUNT; i++) {
+ const KDFCacheItem *cacheItem = &PBECache.cacheKDF2.common[i];
+ if (sftk_comparePBECommonCacheItemLocked(cacheItem,
+ pbe_param, pwItem)) {
+ result = SECITEM_DupItem(cacheItem->hash);
+ break;
+ }
}
PZ_Unlock(PBECache.lock);
@@ -707,12 +718,16 @@ sftk_getPBECacheKDF1(const NSSPKCS5PBEParameter *pbe_param,
void
sftk_PBELockShutdown(void)
{
+ int i;
if (PBECache.lock) {
PZ_DestroyLock(PBECache.lock);
PBECache.lock = 0;
}
sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF1.common);
- sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF2.common);
+ for (i = 0; i < KDF2_CACHE_COUNT; i++) {
+ sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF2.common[i]);
+ }
+ PBECache.cacheKDF2.next = 0;
}
/*