Open Bug 1469482 Opened 6 years ago Updated 2 months ago

subtle crypto deriveBits using pbkdf2 throws exception if dklen >2048 bits

Categories

(Core :: DOM: Web Crypto, defect, P5)

defect

Tracking

()

REOPENED

People

(Reporter: alex, Unassigned)

Details

User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36

Steps to reproduce:

Currently using Firefox Quantum 60.0.2 (64-bit).

```bash
$ firefox --version
Mozilla Firefox 60.0.2
$ uname -a
Linux Alexanders-Dell-XPS13 4.16.0-2-amd64 #1 SMP Debian 4.16.12-1 (2018-05-27) x86_64 GNU/Linux
```
Trying to generate a buffer from a user inputted password. Setting the bits length to 2056 throws an exception. 2048 bits seems okay.

```js
var pw = window.crypto.getRandomValues(new Uint8Array(16));
window.crypto.subtle.importKey("raw", pw, "PBKDF2", false, ["deriveBits"]).then(key => {
  console.log(key);
  var st = window.crypto.getRandomValues(new Uint8Array(16));
  // const keySizeBits = 2048; // this is okay
  const keySizeBits = 2056; // this throws exception
  return window.crypto.subtle.deriveBits({ name: "PBKDF2", salt: st, iterations: 10000, hash: "SHA-256" }, key, keySizeBits);
}).then(bits => {
  console.log(bits);
}).catch(err => {
  console.error(err);
});
```




Actual results:

Got the following exception: "OperationError: The operation failed for an operation-specific reason"

DOMException {
  code: 0,
  columnNumber: 0,
  data: null,
  filename: "",
  lineNumber: 0,
  message: "The operation failed for an operation-specific reason",
  name: "OperationError",
  result: 2152923168,
  stack: ""
}


Expected results:

Expected console log to log an array buffer of byte length 257.

Ideally I would like to specify derived bits length of any size. My original use case is deriving bits of length 256*3*8 (6144).
I tested this on Windows 10 with the latest nightly and it is reproducible.
The error shows when the script in comment 0 is run in the console. The error is "DOMException: "The operation failed for an operation-specific reason"

Test env't
----------
Version 	62.0a1
Build ID 	20180622100109
Update Channel 	nightly
User Agent 	Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0
Status: UNCONFIRMED → NEW
Component: Untriaged → DOM
Ever confirmed: true
Product: Firefox → Core
Priority: -- → P3
Component: DOM → DOM: Core & HTML

Looks like the limitation is here:

https://github.com/mozilla/gecko-dev/blob/8a061c286b958b90c3925056e2ef3586e1a987a2/security/nss/lib/softoken/pkcs11.c#L491

Is there any reason this needs to have a maximum?

Any updates on this?

Assignee: nobody → nobody
Component: DOM: Core & HTML → Libraries
Product: Core → NSS
Version: 60 Branch → other
Severity: normal → --
Priority: P3 → --

The maximum output length for PBKDF2 is implementation defined (https://datatracker.ietf.org/doc/html/rfc2898#appendix-A.2), and NSS happens to have a 2048 bit maximum. If you need a longer bit string you should use the output to seed a bit generator.

As an NSS bug this is a WONTFIX.

Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → WONTFIX

(New) Web Crypto spec editor here. I'm not sure your reading of the spec is correct - the Web Crypto spec refers to RFC8018 for PBKDF2, not RFC2898. Section 5.2 of RFC8018 says that:

The length of the derived key is
essentially unbounded.  (However, the maximum effective search space
for the derived key may be limited by the structure of the underlying
pseudorandom function.  See Appendix B.1 for further discussion.)

(...)

Steps:

   1.  If dkLen > (2^32 - 1) * hLen, output "derived key too long"
       and stop.

RFC2898 defines an OID for PBKDF2, and can of course impose or allow additional restrictions on the output length, and the Web Crypto API could do so as well, but today it doesn't. If Mozilla's position is that it should, could you open a spec issue here to discuss this, please?

This is a wontfix for NSS. But the desired functionality can be implemented at a higher level. Re-opening for further discussion.

Assignee: nobody → nobody
Severity: -- → S4
Status: RESOLVED → REOPENED
Component: Libraries → DOM: Web Crypto
Priority: -- → P5
Product: NSS → Core
Resolution: WONTFIX → ---
Version: other → unspecified

How the code from Alex can be implemented in firefox?

Two years after initially addressing this issue, it remains unresolved and reproducible. In the interim, I have explored alternatives such as nodeForge and CryptoJS; however, these libraries significantly underperform compared to the native deriveBits API in terms of speed. Is there a viable workaround to this problem, or is it still necessary to rely on non-native APIs within Firefox for this functionality?

You need to log in before you can comment on or make changes to this bug.