Title: [260238] trunk
Revision
260238
Author
[email protected]
Date
2020-04-17 00:35:02 -0700 (Fri, 17 Apr 2020)

Log Message

Fix an integer overflow in WebCrypto AES-CTR Mac implementation, which may detect a false loop
https://bugs.webkit.org/show_bug.cgi?id=210540

Source/WebCore:

(1 << counterLength) causes an integer overflow, and the undefined behavior.
The longest valid counterLength on 64 bit machine is 63,
and the literal 1 is considered as 32-bit signed integer.
Left shifting 1 beyond or to sign-bit is undefined behavior in C++ spec.
- https://en.cppreference.com/w/cpp/language/integer_literal
- https://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators

This issue is originally found in https://bugs.webkit.org/show_bug.cgi?id=208186#c2

Patch by Tomoki Imai <[email protected]> on 2020-04-17
Reviewed by Jiewen Tan.

Test: crypto/subtle/aes-ctr-import-key-encrypt.html

* crypto/mac/CryptoAlgorithmAES_CTRMac.cpp:
(WebCore::transformAES_CTR):

LayoutTests:

Patch by Tomoki Imai <[email protected]> on 2020-04-17
Reviewed by Jiewen Tan.

Added more AES-CTR tests for AesCtrParams.length larger than 32.
* crypto/subtle/aes-ctr-import-key-encrypt-expected.txt:
* crypto/subtle/aes-ctr-import-key-encrypt.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (260237 => 260238)


--- trunk/LayoutTests/ChangeLog	2020-04-17 04:57:13 UTC (rev 260237)
+++ trunk/LayoutTests/ChangeLog	2020-04-17 07:35:02 UTC (rev 260238)
@@ -1,3 +1,14 @@
+2020-04-17  Tomoki Imai  <[email protected]>
+
+        Fix an integer overflow in WebCrypto AES-CTR Mac implementation, which may detect a false loop
+        https://bugs.webkit.org/show_bug.cgi?id=210540
+
+        Reviewed by Jiewen Tan.
+
+        Added more AES-CTR tests for AesCtrParams.length larger than 32.
+        * crypto/subtle/aes-ctr-import-key-encrypt-expected.txt:
+        * crypto/subtle/aes-ctr-import-key-encrypt.html:
+
 2020-04-16  Simon Fraser  <[email protected]>
 
         Scrolling-tree hit-testing is off by top content inset

Modified: trunk/LayoutTests/crypto/subtle/aes-ctr-import-key-encrypt-expected.txt (260237 => 260238)


--- trunk/LayoutTests/crypto/subtle/aes-ctr-import-key-encrypt-expected.txt	2020-04-17 04:57:13 UTC (rev 260237)
+++ trunk/LayoutTests/crypto/subtle/aes-ctr-import-key-encrypt-expected.txt	2020-04-17 07:35:02 UTC (rev 260238)
@@ -29,6 +29,10 @@
 PASS bytesToHexString(cipherText) is expectedCipherText12
 Length = 128, overflow
 PASS bytesToHexString(cipherText) is expectedCipherText13
+Length = 33
+PASS bytesToHexString(cipherText) is expectedCipherText
+Length = 63
+PASS bytesToHexString(cipherText) is expectedCipherText
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/crypto/subtle/aes-ctr-import-key-encrypt.html (260237 => 260238)


--- trunk/LayoutTests/crypto/subtle/aes-ctr-import-key-encrypt.html	2020-04-17 04:57:13 UTC (rev 260237)
+++ trunk/LayoutTests/crypto/subtle/aes-ctr-import-key-encrypt.html	2020-04-17 07:35:02 UTC (rev 260238)
@@ -80,6 +80,17 @@
     counter: hexStringToUint8Array("fffffffffffffffffffffffffffffffe"),
     length: 128,
 }
+var aesCtrParams14 = {
+    name: "aes-ctr",
+    counter: asciiToUint8Array("jnOw99oOZFLIEPMr"),
+    length: 33,
+}
+var aesCtrParams15 = {
+    name: "aes-ctr",
+    counter: asciiToUint8Array("jnOw99oOZFLIEPMr"),
+    length: 63,
+}
+
 var rawKey = asciiToUint8Array("jnOw99oOZFLIEPMr");
 var expectedCipherText = "a5f940e93406d4bd9b7318e653d4cb9d1af497f52fcbb659a038e711e8bd61fb4863931d25911e2e9ff30cf37ec27dd813a62830";
 var expectedCipherText4 = "6a461eb3f64ef4c466597ba877a9512b5ab41b4338edc2822d1f0dfac0cec07149766e189fa426d5ea30fe541018362088db2117";
@@ -187,6 +198,20 @@
 
     shouldBe("bytesToHexString(cipherText)", "expectedCipherText13");
 
+    debug("Length = 33");
+    return crypto.subtle.encrypt(aesCtrParams14, key, plainText);
+}).then(function(result) {
+    cipherText = result;
+
+    shouldBe("bytesToHexString(cipherText)", "expectedCipherText");
+
+    debug("Length = 63");
+    return crypto.subtle.encrypt(aesCtrParams15, key, plainText);
+}).then(function(result) {
+    cipherText = result;
+
+    shouldBe("bytesToHexString(cipherText)", "expectedCipherText");
+
     finishJSTest();
 });
 

Modified: trunk/Source/WebCore/ChangeLog (260237 => 260238)


--- trunk/Source/WebCore/ChangeLog	2020-04-17 04:57:13 UTC (rev 260237)
+++ trunk/Source/WebCore/ChangeLog	2020-04-17 07:35:02 UTC (rev 260238)
@@ -1,3 +1,24 @@
+2020-04-17  Tomoki Imai  <[email protected]>
+
+        Fix an integer overflow in WebCrypto AES-CTR Mac implementation, which may detect a false loop
+        https://bugs.webkit.org/show_bug.cgi?id=210540
+
+        (1 << counterLength) causes an integer overflow, and the undefined behavior.
+        The longest valid counterLength on 64 bit machine is 63,
+        and the literal 1 is considered as 32-bit signed integer.
+        Left shifting 1 beyond or to sign-bit is undefined behavior in C++ spec.
+        - https://en.cppreference.com/w/cpp/language/integer_literal
+        - https://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators
+
+        This issue is originally found in https://bugs.webkit.org/show_bug.cgi?id=208186#c2
+
+        Reviewed by Jiewen Tan.
+
+        Test: crypto/subtle/aes-ctr-import-key-encrypt.html
+
+        * crypto/mac/CryptoAlgorithmAES_CTRMac.cpp:
+        (WebCore::transformAES_CTR):
+
 2020-04-16  Simon Fraser  <[email protected]>
 
         Scrolling-tree hit-testing is off by top content inset

Modified: trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_CTRMac.cpp (260237 => 260238)


--- trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_CTRMac.cpp	2020-04-17 04:57:13 UTC (rev 260237)
+++ trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_CTRMac.cpp	2020-04-17 07:35:02 UTC (rev 260238)
@@ -45,7 +45,7 @@
     size_t numberOfBlocks = data.size() % kCCBlockSizeAES128 ? data.size() / kCCBlockSizeAES128 + 1 : data.size() / kCCBlockSizeAES128;
 
     // Detect loop
-    if (counterLength < sizeof(size_t) * 8 && numberOfBlocks > (1 << counterLength))
+    if (counterLength < sizeof(size_t) * 8 && numberOfBlocks > (static_cast<size_t>(1) << counterLength))
         return Exception { OperationError };
 
     // Calculate capacity before overflow
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to