Open Bug 1608630 Opened 5 years ago Updated 2 years ago

Better solution to avoid SDR slowness caused by master password iteration count

Categories

(NSS :: Libraries, enhancement, P2)

3.48
enhancement

Tracking

(Not tracked)

People

(Reporter: KaiE, Unassigned)

References

Details

After we've increased the master password iteration count, it was noticed that each SDR encrypt/decrypt iteration triggers the expensive iteration operation.

It was previously assumed that SDR uses a symmetric key stored inside the NSS database, and that the master password is required for unlocking the symmetric key, only. Was that assumption wrong?

Why does NSS perform calculation using the master password at all, if we simply want to use the stored symmetric key, and the database is already unlocked?

As a hotfix, bug 1606992 added a cache for the most recent PBKDF2 password calculation.

However, this bug suggests that we clean that up and implement a better strategy.

First, as asked above, we should get clarification, why the MP is required for SDR operations.

Apparently, when changing the master password, items that have been SDR encrypted earlier (and weren't modified) can still be decrypted. So clearly the MP itself isn't required for decryption. Rather, the MP appears to be used to unlock the relevant decryption key, only.

IIUC ideally, NSS should be able to cache the symmetric key required for decryption/encryption.

It's unclear how this caching could be done in general, because the actual encryption/decryption operations are more general implementations, and can be used by both SDR operations or other operations. So maybe we'd have to extend internal APIs to pass down the appropriate cached keys, if available.

If the above isn't doable, we could consider alternative approaches:

  • invent a mechanism that allows the application to obtain a handle to cached PBE data, and extend the PK11SDR APIs to accept a cache handle
  • in addition to PK11SDR_Encrypt/Decrypt, which takes a single item, add new APIs that take a list of items. While NSS would still have to do the calculation that involves the master password iteration count, the application could optimize by doing it just once each time a larger list of items need to be processed (e.g. when loading several hundred saved logins).
Flags: needinfo?(rrelyea)

The reason is there are "two" passwords here. There a lightly obscured version of the UTF8 password created by a single hash. That password is cached after login. Then there's a password for each entry in the database. That password is a strong password based on a unique salt and iteration count in each entry.

There are good reasons for having each entry have it's own key. There may be arguments for making the cached password a strong pbe and using a weaker iteration count on each entry. That would really require a database update to a new version number since it would be impossible to do that in a way that older versions of NSS could still work.

That said, adding an API to separate getting the SDR key and then using it would be quite easy. In the SDR case, there is just one key (it's one database entry). Applications could then just hang onto the SDR key if they want and use it when they decrypt.

Even if we did that, the low level cache is actually a good idea because it not only speed up access to the SDR keys, but it also speeds up access to all encrypted or signed data in the database, so I wouldn't back out the previous change.

bob

Flags: needinfo?(rrelyea)
Priority: -- → P2
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.