Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define the deriveBits length parameter as optional #30667

Merged
merged 1 commit into from
Jul 23, 2024

Conversation

javifernandez
Copy link
Contributor

@javifernandez javifernandez commented Jul 10, 2024

9586d3d

Define the deriveBits length parameter as optional
https://bugs.webkit.org/show_bug.cgi?id=276394

Reviewed by Youenn Fablet and Nitin Mahendru.

The PR#345 [1] to the WebCryptoAPI spec defines now the 'length'
parameter as optional, defaulting to 'null'. This change tries to
solve a long-standing interoperability issue in the deriveBits
operation.

This patch implements the required changes in the IDL so that the
'length' parameter is declared as optional, with 'null' as default
value when omitted. The affected algorithms (ECDH, HKDF, PBKDF2
and X25519) are adapted to the parameter's new type.

The PR#43400 [2] defined tests for the new behavior of the afected
algorithms, which they all pass now.

[1] w3c/webcrypto#345
[2] web-platform-tests/wpt#43400

* LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt:
* LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/interfaces/WebCryptoAPI.idl:
* Source/WebCore/crypto/CryptoAlgorithm.cpp:
(WebCore::CryptoAlgorithm::deriveBits):
* Source/WebCore/crypto/CryptoAlgorithm.h:
* Source/WebCore/crypto/SubtleCrypto.cpp:
(WebCore::SubtleCrypto::deriveKey):
(WebCore::SubtleCrypto::deriveBits):
* Source/WebCore/crypto/SubtleCrypto.h:
* Source/WebCore/crypto/SubtleCrypto.idl:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp:
(WebCore::CryptoAlgorithmECDH::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp:
(WebCore::CryptoAlgorithmHKDF::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp:
(WebCore::CryptoAlgorithmPBKDF2::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp:
(WebCore::CryptoAlgorithmX25519::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h:

Canonical link: https://commits.webkit.org/281240@main

5db8323

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 wincairo
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 wincairo-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress 🧪 api-gtk
✅ 🛠 🧪 merge ✅ 🧪 vision-wk2
✅ 🛠 tv
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

@javifernandez javifernandez requested a review from zdobersek as a code owner July 10, 2024 22:19
@javifernandez javifernandez self-assigned this Jul 10, 2024
@javifernandez javifernandez added the WebCore Misc. For miscellaneous bugs in the WebCore framework (and not JavaScriptCore or WebKit). label Jul 10, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jul 10, 2024
@javifernandez javifernandez marked this pull request as draft July 11, 2024 11:14
@javifernandez javifernandez removed the merging-blocked Applied to prevent a change from being merged label Jul 11, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jul 11, 2024
@javifernandez javifernandez requested a review from youennf July 11, 2024 15:57
@javifernandez javifernandez marked this pull request as ready for review July 11, 2024 15:58
@javifernandez javifernandez removed the merging-blocked Applied to prevent a change from being merged label Jul 11, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jul 11, 2024
@aproskuryakov aproskuryakov requested a review from nmahendru July 12, 2024 00:24
@@ -85,7 +85,7 @@
return Promise.resolve().then(function(result) {
// P-256
return Promise.all([
deriveBits(P256, 0, 256),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: While you are at it, how about add:
deriveBits(P256, 0) also and such to all the cases so that they also get tested here.
I am aware that such tests are in wpt, but this will read better in itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. As a matter of fact I've been thinking on porting those tests to WPT; anyway, this will be a follow up patch, so I'll add the new test cases here meanwhile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I think about it, it's unfortunate the deriveBits utility function defines the "expectedLength" as the last parameter. This makes more complex to add test cases for the "omitted" case.

Do you think it's worth to do a refactoring of the test because of this ?

{
if (!length || length % 8) {
if (!length || !(*length) || *length % 8) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:rant
This thing is super onfortunate :D
:end-rant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I'd rather have *length != 0 but it seems the style-checker complains about that.

Copy link
Contributor

@nmahendru nmahendru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

Copy link
Contributor

@youennf youennf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
Could you beef up the commit message and explain why it is ok to change length=0 behavior?
AIUI from the GitHub issue, usage is very low so this is likely ok but it would be good that you confirm this.
And maybe the length=0 change should be done in a separate PR in case of regression.

@@ -49,7 +49,7 @@ PASS SubtleCrypto interface: operation verify(AlgorithmIdentifier, CryptoKey, Bu
PASS SubtleCrypto interface: operation digest(AlgorithmIdentifier, BufferSource)
PASS SubtleCrypto interface: operation generateKey(AlgorithmIdentifier, boolean, sequence<KeyUsage>)
PASS SubtleCrypto interface: operation deriveKey(AlgorithmIdentifier, CryptoKey, AlgorithmIdentifier, boolean, sequence<KeyUsage>)
PASS SubtleCrypto interface: operation deriveBits(AlgorithmIdentifier, CryptoKey, unsigned long)
FAIL SubtleCrypto interface: operation deriveBits(AlgorithmIdentifier, CryptoKey, unsigned long) assert_equals: property has wrong .length expected 3 but got 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we resync that test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

PASS X25519 derivation with 256 as 'length' parameter
FAIL X25519 derivation with 0 as 'length' parameter assert_array_equals: Derived bits do not match the expected result. lengths differ, expected array object "" length 0, got object "63,245,136,2,149,247,97,118,8,143,137,228,61,254,190,126,161,149,0,8" length 32
PASS X25519 derivation with 0 as 'length' parameter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is probably ok to both make the parameter optional and change the behavior for length 0.
But maybe it would be a bit safer to split in two.
@javifernandez, how confident are you with this change of behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is consensus in the PR about pursuing the same behavior for the four algorithms when length=0 is used, so that it returns an empty string. However, I think there is a bit of a mess in terms of interoperability regarding this operation:

https://wpt.fyi/results/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.html?label=master&label=experimental

Chrome already returns an empty string for X25519, while WebKit doesn´t. However, Chrome doesn't do the same with HKDF (although it does for PBKDF2), while WebKit does.

Chrome also asked to do the length=0 change, for its affected algorithms, in a separate change, so I'll do the same for WebKit.

@javifernandez javifernandez removed the merging-blocked Applied to prevent a change from being merged label Jul 22, 2024
@javifernandez javifernandez added the merge-queue Applied to send a pull request to merge-queue label Jul 23, 2024
@javifernandez
Copy link
Contributor Author

The failures in the gtk-wk2 bot seems unrelated to this change. So I'll try the merge queue now.

https://bugs.webkit.org/show_bug.cgi?id=276394

Reviewed by Youenn Fablet and Nitin Mahendru.

The PR#345 [1] to the WebCryptoAPI spec defines now the 'length'
parameter as optional, defaulting to 'null'. This change tries to
solve a long-standing interoperability issue in the deriveBits
operation.

This patch implements the required changes in the IDL so that the
'length' parameter is declared as optional, with 'null' as default
value when omitted. The affected algorithms (ECDH, HKDF, PBKDF2
and X25519) are adapted to the parameter's new type.

The PR#43400 [2] defined tests for the new behavior of the afected
algorithms, which they all pass now.

[1] w3c/webcrypto#345
[2] web-platform-tests/wpt#43400

* LayoutTests/crypto/subtle/derive-bits-malformed-parameters-expected.txt:
* LayoutTests/crypto/subtle/derive-bits-malformed-parameters.html:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/derived_bits_length.https.any.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/idlharness.https.any.worker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/interfaces/WebCryptoAPI.idl:
* Source/WebCore/crypto/CryptoAlgorithm.cpp:
(WebCore::CryptoAlgorithm::deriveBits):
* Source/WebCore/crypto/CryptoAlgorithm.h:
* Source/WebCore/crypto/SubtleCrypto.cpp:
(WebCore::SubtleCrypto::deriveKey):
(WebCore::SubtleCrypto::deriveBits):
* Source/WebCore/crypto/SubtleCrypto.h:
* Source/WebCore/crypto/SubtleCrypto.idl:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.cpp:
(WebCore::CryptoAlgorithmECDH::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmECDH.h:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.cpp:
(WebCore::CryptoAlgorithmHKDF::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmHKDF.h:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.cpp:
(WebCore::CryptoAlgorithmPBKDF2::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmPBKDF2.h:
* Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.cpp:
(WebCore::CryptoAlgorithmX25519::deriveBits):
* Source/WebCore/crypto/algorithms/CryptoAlgorithmX25519.h:

Canonical link: https://commits.webkit.org/281240@main
@webkit-commit-queue
Copy link
Collaborator

Committed 281240@main (9586d3d): https://commits.webkit.org/281240@main

Reviewed commits have been landed. Closing PR #30667 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 9586d3d into WebKit:main Jul 23, 2024
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Jul 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WebCore Misc. For miscellaneous bugs in the WebCore framework (and not JavaScriptCore or WebKit).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants