Improve algorithm steps for Modern Algorithms' supports() method - #558
Improve algorithm steps for Modern Algorithms' supports() method#558panva wants to merge 7 commits into
Conversation
Move parameter-only checks ahead of plaintext and ciphertext checks so
support queries can observe them.
For example, this now returns false:
SubtleCrypto.supports("encrypt", {
name: "AES-GCM",
iv: new Uint8Array(12),
tagLength: 31,
})
A 31-bit AES-GCM tag is never valid, regardless of key or plaintext.
Check HKDF's 255-block output limit before the operation reaches
unavailable key material.
For example, this now returns false:
SubtleCrypto.supports("deriveBits", {
name: "HKDF",
hash: "SHA-256",
salt: new Uint8Array(),
info: new Uint8Array(),
}, 65288)
With SHA-256 the maximum is 65280 bits, so 65288 bits can never be
derived.
| <li> | ||
| <p> | ||
| If the hash function identified by the {{EcdsaParams/hash}} | ||
| member of |normalizedAlgorithm| does not have a fixed output | ||
| length, then [= exception/throw =] a {{NotSupportedError}}. | ||
| </p> | ||
| </li> |
There was a problem hiding this comment.
I'm also a bit unsure about this (and the other instances).
I guess there's not much point to supporting it, but do we really need to forbid it everywhere?
If an implementation doesn't want to support it they can simply return false due to the text in https://github.com/WICG/webcrypto-modern-algos/blob/597a4f8cc6bc9ce6eed8ef6c7105d0de86adf92b/index.html#L1118-L1120, no?
There was a problem hiding this comment.
Yes this is prohibiting an interaction that no implementer has picked up on and implemented. That's a strong enough signal to out right close this explicitly.
There was a problem hiding this comment.
| Node 26.7.0 | Deno 2.9.5 | Ladybird | Servo | |
|---|---|---|---|---|
| RSA | Key generation and import reject with NotSupportedError; no XOF-bearing RSA key can be created. |
Generation rejects with NotSupportedError. Import succeeds, but sign, verify, encrypt, and decrypt then throw OperationError. |
Generation and import succeed, but the later RSA operation throws OperationError. |
Generation and import succeed, but the later RSA operation throws OperationError. |
| ECDSA | Sign and verify reject with NotSupportedError. |
Sign and verify reject with NotSupportedError. |
Sign and verify reject with NotSupportedError. |
Sign and verify execute using the XOF output as the ECDSA prehash. |
| HMAC | Generation, import, and explicit-length deriveKey reject with NotSupportedError; no XOF-bearing HMAC key can be created. |
Generation rejects with NotSupportedError. Raw import and explicit-length deriveKey succeed, but sign and verify then throw OperationError. |
Generation and deriveKey succeed when an explicit positive length is supplied, and raw import succeeds. Sign and verify then throw NotSupportedError. |
Generation and deriveKey succeed when an explicit positive length is supplied, and raw import succeeds. Sign and verify then throw NotSupportedError. |
| HKDF | Derivation rejects with NotSupportedError. |
Derivation rejects with NotSupportedError. |
An ordinary positive-length derivation rejects with NotSupportedError; a zero-length derivation bypasses the hash and succeeds with an empty result. |
Derivation throws OperationError. |
| PBKDF2 | Derivation rejects with NotSupportedError. |
Derivation rejects with NotSupportedError. |
Derivation rejects with NotSupportedError after valid length and iteration checks. |
Derivation rejects with NotSupportedError. |
Small correction from my previous broad statement. ECDSA in Servo is the only implementation that uses the XOF output as the ECDSA prehash.
There was a problem hiding this comment.
Thanks for the overview!
But, I'd still prefer to hold off on adding this text, also because it only really makes sense in the context of XOFs which only exist in the Modern Algorithms draft, not here in this spec (yet).
If there's a concrete danger to supporting this, we could state in the Modern Algorithms draft that implementations shouldn't, but I don't think there is.
Barring that, we could add this text in the main spec once we merge one or more of the XOFs, if there's still no support and we prefer to forbid it at that time.
There was a problem hiding this comment.
You'll call it a breaking change then while it isn't one now as implementations of modern algorithms are underway. Unfortunately the only place this can live in is here.
There was a problem hiding this comment.
We could add a note in the modern algorithms draft that it's not expected to be supported. I'll make a PR for that.
|
@twiss to confirm then
The rest is fine from your POV? |
|
Yeah, I'll do one more pass afterwards but I think the rest looks good 👍 Thanks! |
Expose the unconditional zero-length failure before import reaches unavailable key data.
For example, this now returns false:
SubtleCrypto.supports("importKey", {
name: "HMAC",
hash: "SHA-256",
length: 0,
})
No HMAC key data can satisfy an explicitly requested length of zero.
Expose universally invalid modulus lengths and public exponents before
the operation reaches key generation.
For example, this now returns false:
SubtleCrypto.supports("generateKey", {
name: "RSA-PSS",
modulusLength: 2048,
publicExponent: new Uint8Array([2]),
hash: "SHA-256",
})
No RSA key can use an even public exponent.
Expose impossible public-key inputs and overlong derivations before the
operation reaches unavailable base key material.
For example, this now returns false:
SubtleCrypto.supports("deriveBits", {
name: "X25519",
public: publicKey,
}, 257)
X25519 produces at most 256 bits, so 257 bits can never be derived.
Expose impossible public-key inputs and overlong derivations before the
operation reaches unavailable base key material.
For example, with a P-256 public key, this now returns false:
SubtleCrypto.supports("deriveBits", {
name: "ECDH",
public: publicKey,
}, 257)
A P-256 field element encodes to 256 bits. The output limit is derived
from the public key's EC domain parameters, so extended named curves are
handled without enumeration.
Expose unsupported ECDSA and ECDH named curves before import reaches unavailable key data.
For example, this now returns false:
SubtleCrypto.supports("importKey", {
name: "ECDSA",
namedCurve: "not-a-curve",
})
NamedCurve remains a DOMString so applicable specifications can define additional curves.
1583eb8 to
c635495
Compare
|
@twiss done, i'll leave the one review thread unresolved until the PR for modern algorithms is there. |
The Modern Algorithms specification defines
SubtleCrypto.supports()by normalizing an algorithm and executing its operation steps until it encounters unavailable key or data, key generation, a return, or an exception.This makes the ordering and explicitness of validation in the core Web Cryptography specification observable. Some core operations currently reach one of those stopping points before checking parameters that
supports()does have. This can makesupports()returntruefor an interaction that:This PR makes those outcomes observable before
supports()reaches its stopping point.Changes
NamedCurveas an enum so names not defined by the core or an applicable specification fail during normalization.The XOF checks establish an intentionally unsupported boundary rather than claiming every such composition is cryptographically impossible/undefined. Selecting an output length for an XOF does not turn it into the fixed-output hash expected by these traditional algorithms. In particular, implementations already reject RSA and ECDSA combinations with XOF digests using
NotSupportedError. This just sets it as baseline.Successful operations are unchanged.
Examples
Each of the following now returns
false.AES-GCM parameters
A 31-bit AES-GCM tag is never valid, regardless of key or plaintext.
HKDF output length
With SHA-256 the maximum is 65280 bits, so 65288 bits can never be derived.
XOFs in traditional algorithms
Modern Algorithms implementations deliberately exclude XOF digests from these traditional algorithms. Selecting an output length does not turn cSHAKE into a fixed-output hash.
Undefined named curves
No import using an undefined curve could ever succeed.
Zero-length HMAC imports
No HMAC key data can satisfy an explicitly requested length of zero.
RSA key generation parameters
No RSA key can use an even public exponent.
X25519 derivation length
X25519 produces at most 256 bits, so 257 bits can never be derived. Refs: WICG/webcrypto-modern-algos#74
ECDH derivation length
With a P-256 public key, the field element encodes to 256 bits. The output limit is derived from the public key’s EC domain parameters, so extended named curves are handled without enumeration. Refs: WICG/webcrypto-modern-algos#74
Preview | Diff