Title: [275656] trunk
Revision
275656
Author
[email protected]
Date
2021-04-08 03:53:44 -0700 (Thu, 08 Apr 2021)

Log Message

Update SFrame implementation to latest version
https://bugs.webkit.org/show_bug.cgi?id=224276

Reviewed by Eric Carlson.

Source/WebCore:

Update implementation according to latest draft at https://github.com/eomara/sframe/blob/master/draft-omara-sframe.md.
In particular, we derive keys with new algorithm and the generation of the signature by including header and data length as well as nonce.

Test: webrtc/sframe-test-vectors.html

* Modules/mediastream/RTCRtpSFrameTransform.cpp:
(WebCore::RTCRtpSFrameTransform::setCounterForTesting):
* Modules/mediastream/RTCRtpSFrameTransform.h:
* Modules/mediastream/RTCRtpSFrameTransformer.cpp:
(WebCore::computeIV):
(WebCore::RTCRtpSFrameTransformer::updateEncryptionKey):
(WebCore::RTCRtpSFrameTransformer::decryptFrame):
(WebCore::RTCRtpSFrameTransformer::encryptFrame):
(WebCore::RTCRtpSFrameTransformer::computeEncryptedDataSignature):
* Modules/mediastream/RTCRtpSFrameTransformer.h:
* Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp:
(WebCore::RTCRtpSFrameTransformer::computeSaltKey):
(WebCore::createBaseSFrameKey):
(WebCore::RTCRtpSFrameTransformer::computeAuthenticationKey):
(WebCore::RTCRtpSFrameTransformer::computeEncryptionKey):
(WebCore::encodeBigEndian):
(WebCore::RTCRtpSFrameTransformer::computeEncryptedDataSignature):
* testing/Internals.cpp:
(WebCore::Internals::setSFrameCounter):
* testing/Internals.h:
* testing/Internals.idl:

Tools:

Update tests according new way of deriving keys and generating the signature.

* TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp:
(TestWebKitAPI::TEST):

LayoutTests:

* webrtc/sframe-test-vectors-expected.txt: Added.
* webrtc/sframe-test-vectors.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (275655 => 275656)


--- trunk/LayoutTests/ChangeLog	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/LayoutTests/ChangeLog	2021-04-08 10:53:44 UTC (rev 275656)
@@ -1,3 +1,13 @@
+2021-04-08  Youenn Fablet  <[email protected]>
+
+        Update SFrame implementation to latest version
+        https://bugs.webkit.org/show_bug.cgi?id=224276
+
+        Reviewed by Eric Carlson.
+
+        * webrtc/sframe-test-vectors-expected.txt: Added.
+        * webrtc/sframe-test-vectors.html: Added.
+
 2021-04-07  Julian Gonzalez  <[email protected]>
 
         Nullptr dereference in ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline

Added: trunk/LayoutTests/webrtc/sframe-test-vectors-expected.txt (0 => 275656)


--- trunk/LayoutTests/webrtc/sframe-test-vectors-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/webrtc/sframe-test-vectors-expected.txt	2021-04-08 10:53:44 UTC (rev 275656)
@@ -0,0 +1,34 @@
+
+PASS Decryption test 1 for ciphersuite 1
+PASS Encryption/Decryption test 1 for ciphersuite 1
+PASS Decryption test 2 for ciphersuite 1
+PASS Encryption/Decryption test 2 for ciphersuite 1
+PASS Decryption test 3 for ciphersuite 1
+PASS Encryption/Decryption test 3 for ciphersuite 1
+PASS Decryption test 4 for ciphersuite 1
+PASS Encryption/Decryption test 4 for ciphersuite 1
+PASS Decryption test 5 for ciphersuite 1
+PASS Encryption/Decryption test 5 for ciphersuite 1
+PASS Decryption test 6 for ciphersuite 1
+PASS Encryption/Decryption test 6 for ciphersuite 1
+PASS Decryption test 7 for ciphersuite 1
+PASS Encryption/Decryption test 7 for ciphersuite 1
+PASS Decryption test 8 for ciphersuite 1
+PASS Encryption/Decryption test 8 for ciphersuite 1
+PASS Decryption test 1 for ciphersuite 2
+PASS Encryption/Decryption test 1 for ciphersuite 2
+PASS Decryption test 2 for ciphersuite 2
+PASS Encryption/Decryption test 2 for ciphersuite 2
+PASS Decryption test 3 for ciphersuite 2
+PASS Encryption/Decryption test 3 for ciphersuite 2
+PASS Decryption test 4 for ciphersuite 2
+PASS Encryption/Decryption test 4 for ciphersuite 2
+PASS Decryption test 5 for ciphersuite 2
+PASS Encryption/Decryption test 5 for ciphersuite 2
+PASS Decryption test 6 for ciphersuite 2
+PASS Encryption/Decryption test 6 for ciphersuite 2
+PASS Decryption test 7 for ciphersuite 2
+PASS Encryption/Decryption test 7 for ciphersuite 2
+PASS Decryption test 8 for ciphersuite 2
+PASS Encryption/Decryption test 8 for ciphersuite 2
+

Added: trunk/LayoutTests/webrtc/sframe-test-vectors.html (0 => 275656)


--- trunk/LayoutTests/webrtc/sframe-test-vectors.html	                        (rev 0)
+++ trunk/LayoutTests/webrtc/sframe-test-vectors.html	2021-04-08 10:53:44 UTC (rev 275656)
@@ -0,0 +1,225 @@
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>SFrame test vector</title>
+        <script src=""
+        <script src=""
+    </head>
+    <body>
+<script>
+// Tests taken from https://github.com/eomara/sframe/blob/master/test-vectors.json and updated to cope with key/counter length difference.
+// Test suite 1 is AES_CM_128_HMAC_SHA256_4, test suite 2 is AES_CM_128_HMAC_SHA256_8.
+// Test suites 3 and 4 are GCM and not yet added here since not supported.
+const tests = [
+  {
+    "cipher_suite": 1,
+    "base_key": "101112131415161718191a1b1c1d1e1f",
+    "key": "343d3290f5c0b936415bea9a43c6f5a2",
+    "salt": "42d662fbad5cd81eb3aad79a",
+    "plaintext": "46726f6d2068656176656e6c79206861726d6f6e79202f2f205468697320756e6976657273616c206672616d6520626567616e",
+    "encryptions": [
+      {
+        "kid": "7",
+        "ctr": "0",
+        "header": "0700",
+        "nonce": "42d662fbad5cd81eb3aad79a",
+        "ciphertext": "070065c67c6fb784631a7db1b589ffb62d75b78e28b0899e632fbbee3b944747a6382d75b6bd3788dc7b71b9295c7fb90b5098f7ad92befabb"
+      },
+      {
+        "kid": "7",
+        "ctr": "1",
+        "header": "0701",
+        "nonce": "42d662fbad5cd81eb3aad79b",
+        "ciphertext": "0701ec742e98d667be810f153ff0d4dad7969f69b310aa7c6b9cb911e83af09b0f0a6d74772d8195c8c9dae3878fd1cb10edb4176dd4a56026"
+      },
+      {
+        "kid": "7",
+        "ctr": "2",
+        "header": "0702",
+        "nonce": "42d662fbad5cd81eb3aad798",
+        "ciphertext": "0702ac9b495d37a1e48c712ade5cba72df0bf90f24aa022a454cfb92d8b87cd54335fb6b9eeded6a5aa4e2643d7a09946646001d0afd6a2d5f"
+      },
+      {
+        "kid": "15",
+        "ctr": "170",
+        "header": "080faa",
+        "nonce": "42d662fbad5cd81eb3aad730",
+        "ciphertext": "080faaeaa5adc70cae0d6ebd36805fa87d2351dd02c55c751cd351a7fdb7f0927b474eae3e800033e08100a440002da17579678b36dcafb808b3"
+      },
+      {
+        "kid": "511",
+        "ctr": "170",
+        "header": "0901ffaa",
+        "nonce": "42d662fbad5cd81eb3aad730",
+        "ciphertext": "0901ffaaeaa5adc70cae0d6ebd36805fa87d2351dd02c55c751cd351a7fdb7f0927b474eae3e800033e08100a440002da17579678b36dcc0a409c5"
+      },
+      {
+        "kid": "511",
+        "ctr": "543690",
+        "header": "2901ff084bca",
+        "nonce": "42d662fbad5cd81eb3a29c50",
+        "ciphertext": "2901ff084bca99362198463c4739ebe78d4c1158fc7b7e118e8d035130a583744af343a370ab964a76d31aba68939336187bd251a7f63e9ec25a2bed97"
+      },
+      {
+        "kid": "72057594037927935",
+        "ctr": "72057594037927935",
+        "header": "6effffffffffffffffffffffffffff",
+        "nonce": "42d662fbada327e14c552865",
+        "ciphertext": "6effffffffffffffffffffffffffffdca3655d5117bc838d6f4382ca468a4f992ff77bfd1d2f4391be6b33e8fb638dc48aa82f57fd91430c714def0b2089c8bfb2ac6a36e584"
+      },
+      {
+        "kid": "92057594037927935",
+        "ctr": "8",
+        "header": "0f01470de4df81ffff08",
+        "nonce": "42d662fbad5cd81eb3aad792",
+        "ciphertext": "0f01470de4df81ffff084db66f48555956af80a014f06670d7771071afc72ad7452fbb835d353d07d16e771b2ca3593a6a87b643e39370b404a2eb898de8114fb9"
+      }
+    ]
+  },
+  {
+    "cipher_suite": 2,
+    "base_key": "202122232425262728292a2b2c2d2e2f",
+    "key": "3fce747d505e46ec9b92d9f58ee7a5d4",
+    "salt": "77fbf5f1d82c73f6d2b353c9",
+    "plaintext": "46726f6d2068656176656e6c79206861726d6f6e79202f2f205468697320756e6976657273616c206672616d6520626567616e",
+    "encryptions": [
+      {
+        "kid": "7",
+        "ctr": "0",
+        "header": "0700",
+        "nonce": "77fbf5f1d82c73f6d2b353c900000000",
+        "ciphertext": "0700647513fce71aab7fed1e904fd9240343d77092c831f0d58fde0985a0f3e5ba4020e87a7b9c870b5f8f7f628d27690cc1e571e4e8b90ec99c582cfa"
+      },
+      {
+        "kid": "7",
+        "ctr": "1",
+        "header": "0701",
+        "nonce": "77fbf5f1d82c73f6d2b353c8",
+        "ciphertext": "07019e1bdf713b0d4c02f3dbf50a72ea773286e7da38f3872cc734f3e1b1448aab5009b424e05495214f96d02e4e8f8da975cc808fe931237a6ab700e8"
+      },
+      {
+        "kid": "7",
+        "ctr": "2",
+        "header": "0702",
+        "nonce": "77fbf5f1d82c73f6d2b353cb",
+        "ciphertext": "070220ad36fd9191453ace2d36a175ad8a69c1f16b8613d14b4f7ef30c68bc5609e349df38155cc1544d7dbfa079e3faae3c7883b479fccb144b0c78a5"
+      },
+      {
+        "kid": "15",
+        "ctr": "170",
+        "header": "080faa",
+        "nonce": "77fbf5f1d82c73f6d2b35363",
+        "ciphertext": "080faadab9b284a4b9e3aea36b9cdcae4a58e141d3f0f52f240ef80a93dbb8d809ede01b05b2cace18a22fb39c032724481c5baa181d081e260067ccd683"
+      },
+      {
+        "kid": "511",
+        "ctr": "170",
+        "header": "0901ffaa",
+        "nonce": "77fbf5f1d82c73f6d2b35363",
+        "ciphertext": "0901ffaadab9b284a4b9e3aea36b9cdcae4a58e141d3f0f52f240ef80a93dbb8d809ede01b05b2cace18a22fb39c032724481c5baa181dc24facba5e9f7ea5"
+      },
+      {
+        "kid": "511",
+        "ctr": "43690",
+        "header": "1901ffaaaa",
+        "nonce": "77fbf5f1d82c73f6d2b3f963",
+        "ciphertext": "1901ffaaaae0f2384e4dc472cb92238b5b722159205c4481665484de66985f155071655ca4e9d1c998781f8c7d439f8d1eb6f6071cd80fd2af2cd093aa260618"
+      },
+      {
+        "kid": "72057594037927935",
+        "ctr": "72057594037927935",
+        "header": "6effffffffffffffffffffffffffff",
+        "nonce": "77fbf5f1d8d38c092d4cac36",
+        "ciphertext": "6effffffffffffffffffffffffffff4b8c7429d7ee83eec5e53808b80555b1f80b1df9d97877575fa1c7fa35b6119c68ed6543020075959dcc4ca6900a7f9cf1d9366dfcb086029e8966"
+      },
+      {
+        "kid": "92057594037927935",
+        "ctr": "8",
+        "header": "0f01470de4df81ffff08",
+        "nonce": "77fbf5f1d82c73f6d2b353c1",
+        "ciphertext": "0f01470de4df81ffff08aaf4ea538ad99858a76f87b673dd548459dfbf98906fe82ce159ec738363b2af84d39c34418e2c56609d185ef66a3d7ce8d30547c1c9725439ac12"
+      }
+    ]
+  }
+];
+
+function hexaDecodeToUint8Array(encoded)
+{
+    return new Uint8Array(encoded.match(/[\da-f]{2}/gi).map(function (h) {
+        return parseInt(h, 16)
+    }));
+}
+
+function hexaEncodeUint8Array(buffer)
+{
+    return Array.prototype.map.call(new Uint8Array(buffer), x => {
+        return ('00' + x.toString(16)).slice(-2)
+    }).join('');
+}
+
+function numberOrBigIntFromString(string)
+{
+    const value = parseInt(string);
+    if ((''+ value) === string)
+        return string;
+    return BigInt(string);
+}
+
+async function doAESCMTest(testSuite, authenticationSize)
+{
+    let testCounter = 0;
+    const key = await crypto.subtle.importKey("raw", hexaDecodeToUint8Array(testSuite.base_key), "HKDF", false, ["deriveBits", "deriveKey"]);
+
+    for (const encryption of testSuite.encryptions) {
+        testCounter++;
+
+        promise_test(async () => {
+            const transform = new SFrameTransform({ role : 'decrypt', authenticationSize : authenticationSize });
+            transform.setEncryptionKey(key, numberOrBigIntFromString(encryption.kid));
+            const reader = transform.readable.getReader();
+            const writer = transform.writable.getWriter();
+
+            const encryptedData = hexaDecodeToUint8Array(encryption.ciphertext);
+            writer.write(encryptedData.buffer);
+            const decrypted = await reader.read();
+
+            const text = hexaEncodeUint8Array(new Uint8Array(decrypted.value));
+            assert_equals(text, testSuite.plaintext);
+        }, "Decryption test " + testCounter + " for ciphersuite " + testSuite.cipher_suite);
+
+        const plaintextData = hexaDecodeToUint8Array(testSuite.plaintext);
+        promise_test(async () => {
+            const transform1 = new SFrameTransform({ role : 'encrypt', authenticationSize : authenticationSize });
+            const transform2 = new SFrameTransform({ role : 'decrypt', authenticationSize : authenticationSize });
+            transform1.setEncryptionKey(key, numberOrBigIntFromString(encryption.kid));
+            transform2.setEncryptionKey(key, numberOrBigIntFromString(encryption.kid));
+            const reader = transform2.readable.getReader();
+            const writer = transform1.writable.getWriter();
+            transform1.readable.pipeTo(transform2.writable);
+
+            if (window.internals)
+                internals.setSFrameCounter(transform1, encryption.ctr);
+            else {
+                const counter = numberOrBigIntFromString(encryption.ctr);
+                if (typeof counter === "bigint") 
+                    return;
+                for (let i = 0; i < counter; ++i) {
+                    await writer.write(new ArrayBuffer());
+                    await reader.read();
+               }
+            }
+
+            writer.write(plaintextData.buffer);
+            const decrypted = await reader.read();
+
+            const text = hexaEncodeUint8Array(new Uint8Array(decrypted.value));
+            assert_equals(text, testSuite.plaintext);
+        }, "Encryption/Decryption test " + testCounter + " for ciphersuite " + testSuite.cipher_suite);
+    }
+}
+doAESCMTest(tests[0], 4);
+doAESCMTest(tests[1], 8);
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (275655 => 275656)


--- trunk/Source/WebCore/ChangeLog	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/ChangeLog	2021-04-08 10:53:44 UTC (rev 275656)
@@ -1,3 +1,37 @@
+2021-04-08  Youenn Fablet  <[email protected]>
+
+        Update SFrame implementation to latest version
+        https://bugs.webkit.org/show_bug.cgi?id=224276
+
+        Reviewed by Eric Carlson.
+
+        Update implementation according to latest draft at https://github.com/eomara/sframe/blob/master/draft-omara-sframe.md.
+        In particular, we derive keys with new algorithm and the generation of the signature by including header and data length as well as nonce.
+
+        Test: webrtc/sframe-test-vectors.html
+
+        * Modules/mediastream/RTCRtpSFrameTransform.cpp:
+        (WebCore::RTCRtpSFrameTransform::setCounterForTesting):
+        * Modules/mediastream/RTCRtpSFrameTransform.h:
+        * Modules/mediastream/RTCRtpSFrameTransformer.cpp:
+        (WebCore::computeIV):
+        (WebCore::RTCRtpSFrameTransformer::updateEncryptionKey):
+        (WebCore::RTCRtpSFrameTransformer::decryptFrame):
+        (WebCore::RTCRtpSFrameTransformer::encryptFrame):
+        (WebCore::RTCRtpSFrameTransformer::computeEncryptedDataSignature):
+        * Modules/mediastream/RTCRtpSFrameTransformer.h:
+        * Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp:
+        (WebCore::RTCRtpSFrameTransformer::computeSaltKey):
+        (WebCore::createBaseSFrameKey):
+        (WebCore::RTCRtpSFrameTransformer::computeAuthenticationKey):
+        (WebCore::RTCRtpSFrameTransformer::computeEncryptionKey):
+        (WebCore::encodeBigEndian):
+        (WebCore::RTCRtpSFrameTransformer::computeEncryptedDataSignature):
+        * testing/Internals.cpp:
+        (WebCore::Internals::setSFrameCounter):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2021-04-08  Xabier Rodriguez Calvar  <[email protected]>
 
         Unreviewed. Fixed build warning.

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp (275655 => 275656)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp	2021-04-08 10:53:44 UTC (rev 275656)
@@ -75,6 +75,11 @@
     promise.settle(m_transformer->setEncryptionKey(rawKey.key(), keyId));
 }
 
+void RTCRtpSFrameTransform::setCounterForTesting(uint64_t counter)
+{
+    m_transformer->setCounter(counter);
+}
+
 uint64_t RTCRtpSFrameTransform::counterForTesting() const
 {
     return m_transformer->counter();

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h (275655 => 275656)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h	2021-04-08 10:53:44 UTC (rev 275656)
@@ -63,6 +63,7 @@
     void initializeBackendForSender(RTCRtpTransformBackend&);
     void willClearBackend(RTCRtpTransformBackend&);
 
+    WEBCORE_EXPORT void setCounterForTesting(uint64_t);
     WEBCORE_EXPORT uint64_t counterForTesting() const;
     WEBCORE_EXPORT uint64_t keyIdForTesting() const;
 

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp (275655 => 275656)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp	2021-04-08 10:53:44 UTC (rev 275656)
@@ -32,6 +32,8 @@
 
 namespace WebCore {
 
+static constexpr unsigned AES_CM_128_HMAC_SHA256_NONCE_SIZE = 12;
+
 static inline void writeUInt64(uint8_t* data, uint64_t value, uint8_t valueLength)
 {
     for (unsigned i = 0; i < valueLength; ++i)
@@ -71,13 +73,18 @@
 
 static inline Vector<uint8_t> computeIV(uint64_t counter, const Vector<uint8_t>& saltKey)
 {
+    // The saltKey is 12 bytes (AES_CM_128_HMAC_SHA256_NONCE_SIZE), we XOR with the counter as 12 bytes.
+    // We then extend it to 16 bytes since that is what is expected by the crypto routines.
     Vector<uint8_t> iv(16);
-    for (unsigned i = 0; i < 8; ++i) {
-        auto value = (counter >> ((7 - i) * 8)) & 0xff;
+    for (unsigned i = 0; i < 4; ++i)
+        iv[i] = saltKey[i];
+    for (unsigned i = 11; i >= 4; --i) {
+        auto value = counter & 0xff;
+        counter = counter >> 8;
         iv[i] = value ^ saltKey[i];
     }
-    for (unsigned i = 8; i < 16; ++i)
-        iv[i] = saltKey[i];
+    for (unsigned i = 12; i < 16; ++i)
+        iv[i] = 0;
     return iv;
 }
 
@@ -161,7 +168,7 @@
     if (saltKeyResult.hasException())
         return saltKeyResult.releaseException();
 
-    ASSERT(saltKeyResult.returnValue().size() >= 16);
+    ASSERT(saltKeyResult.returnValue().size() >= AES_CM_128_HMAC_SHA256_NONCE_SIZE);
 
     auto authenticationKeyResult = computeAuthenticationKey(rawKey);
     if (authenticationKeyResult.hasException())
@@ -240,9 +247,11 @@
     if (frameSize < (header->size + m_authenticationSize))
         return Exception { DataError, "Chunk is too small for authentication size" };
 
+    auto iv = computeIV(m_counter, m_saltKey);
+
     // Compute signature
     auto* transmittedSignature = frameData + frameSize - m_authenticationSize;
-    auto signature = computeEncryptedDataSignature(frameData, frameSize  - m_authenticationSize, m_authenticationKey);
+    auto signature = computeEncryptedDataSignature(iv, frameData, header->size, frameData + header->size, frameSize  - m_authenticationSize - header->size, m_authenticationKey);
     for (size_t cptr = 0; cptr < m_authenticationSize; ++cptr) {
         if (signature[cptr] != transmittedSignature[cptr]) {
             // FIXME: We should try ratcheting.
@@ -251,7 +260,6 @@
     }
 
     // Decrypt data
-    auto iv = computeIV(m_counter, m_saltKey);
     auto dataSize = frameSize - header->size - m_authenticationSize;
     auto result = decryptData(frameData + header->size, dataSize, iv, m_encryptionKey);
 
@@ -311,7 +319,7 @@
     std::memcpy(newDataPointer + headerSize, encryptedData.returnValue().data(), frameSize);
 
     // Fill signature
-    auto signature = computeEncryptedDataSignature(newDataPointer, frameSize + headerSize, m_authenticationKey);
+    auto signature = computeEncryptedDataSignature(iv, newDataPointer, headerSize, newDataPointer + headerSize, frameSize, m_authenticationKey);
     std::memcpy(newDataPointer + frameSize + headerSize, signature.data(), m_authenticationSize);
 
     if (m_compatibilityMode == CompatibilityMode::H264)
@@ -356,7 +364,7 @@
     return Exception { NotSupportedError };
 }
 
-Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const uint8_t*, size_t, const Vector<uint8_t>&)
+Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const Vector<uint8_t>&, const uint8_t*, size_t, const uint8_t*, size_t, const Vector<uint8_t>&)
 {
     return { };
 }

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h (275655 => 275656)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h	2021-04-08 10:53:44 UTC (rev 275656)
@@ -74,7 +74,7 @@
 
     ExceptionOr<Vector<uint8_t>> encryptData(const uint8_t*, size_t, const Vector<uint8_t>& iv, const Vector<uint8_t>& key);
     ExceptionOr<Vector<uint8_t>> decryptData(const uint8_t*, size_t, const Vector<uint8_t>& iv, const Vector<uint8_t>& key);
-    Vector<uint8_t> computeEncryptedDataSignature(const uint8_t*, size_t, const Vector<uint8_t>& key);
+    Vector<uint8_t> computeEncryptedDataSignature(const Vector<uint8_t>& nonce, const uint8_t* header, size_t headerSize, const uint8_t* data, size_t dataSize, const Vector<uint8_t>& key);
     void updateAuthenticationSize();
 
     Lock m_keyLock;

Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp (275655 => 275656)


--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp	2021-04-08 10:53:44 UTC (rev 275656)
@@ -35,20 +35,38 @@
 
 ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::computeSaltKey(const Vector<uint8_t>& rawKey)
 {
-    uint8_t usage[] = "SFrameSaltKey";
-    return deriveHDKFSHA256Bits(rawKey.data(), 16, rawKey.data() + 16, rawKey.size() - 16, usage, sizeof(usage) - 1, 128);
+    uint8_t usage[] = "SFrame10";
+    uint8_t info[] = "salt";
+    return deriveHDKFSHA256Bits(rawKey.data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 96);
 }
 
+static ExceptionOr<Vector<uint8_t>> createBaseSFrameKey(const Vector<uint8_t>& rawKey)
+{
+    uint8_t usage[] = "SFrame10";
+    uint8_t info[] = "key";
+    return deriveHDKFSHA256Bits(rawKey.data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 128);
+}
+
 ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::computeAuthenticationKey(const Vector<uint8_t>& rawKey)
 {
-    uint8_t usage[] = "SFrameAuthenticationKey";
-    return deriveHDKFSHA256Bits(rawKey.data(), 16, rawKey.data() + 16, rawKey.size() - 16, usage, sizeof(usage) - 1, 256);
+    auto key = createBaseSFrameKey(rawKey);
+    if (key.hasException())
+        return key;
+
+    uint8_t usage[] = "SFrame10 AES CM AEAD";
+    uint8_t info[] = "auth";
+    return deriveHDKFSHA256Bits(key.returnValue().data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 256);
 }
 
 ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::computeEncryptionKey(const Vector<uint8_t>& rawKey)
 {
-    uint8_t usage[] = "SFrameEncryptionKey";
-    return deriveHDKFSHA256Bits(rawKey.data(), 16, rawKey.data() + 16, rawKey.size() - 16, usage, sizeof(usage) - 1, 128);
+    auto key = createBaseSFrameKey(rawKey);
+    if (key.hasException())
+        return key;
+
+    uint8_t usage[] = "SFrame10 AES CM AEAD";
+    uint8_t info[] = "enc";
+    return deriveHDKFSHA256Bits(key.returnValue().data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 128);
 }
 
 ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::decryptData(const uint8_t* data, size_t size, const Vector<uint8_t>& iv, const Vector<uint8_t>& key)
@@ -61,11 +79,34 @@
     return transformAES_CTR(kCCEncrypt, iv, iv.size(), key, data, size);
 }
 
-Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const uint8_t* data, size_t size, const Vector<uint8_t>& key)
+static inline Vector<uint8_t, 8> encodeBigEndian(uint64_t value)
 {
-    return calculateSHA256Signature(key, data, size);
+    Vector<uint8_t, 8> result(8);
+    for (int i = 7; i >= 0; --i) {
+        result.data()[i] = value & 0xff;
+        value = value >> 8;
+    }
+    return result;
 }
 
+Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const Vector<uint8_t>& nonce, const uint8_t* header, size_t headerSize, const uint8_t* data, size_t dataSize, const Vector<uint8_t>& key)
+{
+    auto headerLength = encodeBigEndian(headerSize);
+    auto dataLength = encodeBigEndian(dataSize);
+
+    Vector<uint8_t> result(CC_SHA256_DIGEST_LENGTH);
+    CCHmacContext context;
+    CCHmacInit(&context, kCCHmacAlgSHA256, key.data(), key.size());
+    CCHmacUpdate(&context, headerLength.data(), headerLength.size());
+    CCHmacUpdate(&context, dataLength.data(), dataLength.size());
+    CCHmacUpdate(&context, nonce.data(), 12);
+    CCHmacUpdate(&context, header, headerSize);
+    CCHmacUpdate(&context, data, dataSize);
+    CCHmacFinal(&context, result.data());
+
+    return result;
+}
+
 void RTCRtpSFrameTransformer::updateAuthenticationSize()
 {
     if (m_authenticationSize > CC_SHA256_DIGEST_LENGTH)

Modified: trunk/Source/WebCore/testing/Internals.cpp (275655 => 275656)


--- trunk/Source/WebCore/testing/Internals.cpp	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/testing/Internals.cpp	2021-04-08 10:53:44 UTC (rev 275656)
@@ -1595,6 +1595,12 @@
 #endif
 }
 
+void Internals::setSFrameCounter(RTCRtpSFrameTransform& transform, const String& counter)
+{
+    if (auto value = StringView(counter).toUInt64Strict())
+        transform.setCounterForTesting(*value);
+}
+
 uint64_t Internals::sframeCounter(const RTCRtpSFrameTransform& transform)
 {
     return transform.counterForTesting();

Modified: trunk/Source/WebCore/testing/Internals.h (275655 => 275656)


--- trunk/Source/WebCore/testing/Internals.h	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/testing/Internals.h	2021-04-08 10:53:44 UTC (rev 275656)
@@ -617,6 +617,7 @@
     void setWebRTCH265Support(bool);
     void setWebRTCVP9Support(bool supportVP9Profile0, bool supportVP9Profile2);
     void setWebRTCVP9VTBSupport(bool);
+    void setSFrameCounter(RTCRtpSFrameTransform&, const String&);
     uint64_t sframeCounter(const RTCRtpSFrameTransform&);
     uint64_t sframeKeyId(const RTCRtpSFrameTransform&);
     void setEnableWebRTCEncryption(bool);

Modified: trunk/Source/WebCore/testing/Internals.idl (275655 => 275656)


--- trunk/Source/WebCore/testing/Internals.idl	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Source/WebCore/testing/Internals.idl	2021-04-08 10:53:44 UTC (rev 275656)
@@ -825,6 +825,7 @@
     [Conditional=WEB_RTC] undefined setWebRTCH265Support(boolean allowed);
     [Conditional=WEB_RTC] undefined setWebRTCVP9Support(boolean supportVP9Profile0, boolean supportVP9Profile2);
     [Conditional=WEB_RTC] undefined setWebRTCVP9VTBSupport(boolean allowed);
+    [Conditional=WEB_RTC] undefined setSFrameCounter(RTCRtpSFrameTransform transform, DOMString counter);
     [Conditional=WEB_RTC] unsigned long long sframeCounter(RTCRtpSFrameTransform transform);
     [Conditional=WEB_RTC] unsigned long long sframeKeyId(RTCRtpSFrameTransform transform);
 

Modified: trunk/Tools/ChangeLog (275655 => 275656)


--- trunk/Tools/ChangeLog	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Tools/ChangeLog	2021-04-08 10:53:44 UTC (rev 275656)
@@ -1,3 +1,15 @@
+2021-04-08  Youenn Fablet  <[email protected]>
+
+        Update SFrame implementation to latest version
+        https://bugs.webkit.org/show_bug.cgi?id=224276
+
+        Reviewed by Eric Carlson.
+
+        Update tests according new way of deriving keys and generating the signature.
+
+        * TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp:
+        (TestWebKitAPI::TEST):
+
 2021-04-07  Jonathan Bedard  <[email protected]>
 
         [webkitscmpy] Handle multiple double-branch commits

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp (275655 => 275656)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp	2021-04-08 08:58:24 UTC (rev 275655)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp	2021-04-08 10:53:44 UTC (rev 275656)
@@ -116,38 +116,38 @@
 {
     auto transformer = createVideoTransformer();
     checkVectorsAreEqual(transformer->authenticationKey(), Vector<uint8_t>::from(
-        92,
-        228,
-        139,
-        195,
+        4,
         98,
-        16,
-        4,
+        231,
+        89,
+        19,
+        177,
+        253,
+        241,
+        246,
+        85,
         193,
-        221,
-        248,
-        232,
-        178,
-        135,
-        22,
-        141,
-        150,
+        64,
+        19,
+        72,
+        211,
+        48,
+        57,
+        235,
+        63,
+        57,
         165,
-        242,
-        73,
-        72,
-        10,
-        197,
-        15,
-        87,
-        181,
-        34,
-        120,
-        71,
-        42,
-        174,
-        131,
-        72
+        252,
+        130,
+        58,
+        142,
+        14,
+        142,
+        223,
+        134,
+        92,
+        167,
+        253
     ));
 }
 
@@ -155,22 +155,22 @@
 {
     auto transformer = createVideoTransformer();
     checkVectorsAreEqual(transformer->encryptionKey(), Vector<uint8_t>::from(
-        207,
-        251,
-        52,
-        21,
+        180,
+        189,
+        66,
+        149,
+        6,
         101,
-        50,
-        232,
-        48,
-        211,
-        115,
+        148,
+        179,
+        158,
+        210,
+        132,
+        83,
+        75,
         11,
-        155,
-        101,
-        116,
-        153,
-        71
+        43,
+        50
     ));
 }
 
@@ -178,22 +178,18 @@
 {
     auto transformer = createVideoTransformer();
     checkVectorsAreEqual(transformer->saltKey(), Vector<uint8_t>::from(
-        229,
-        19,
-        42,
+        184,
+        43,
+        180,
+        28,
         93,
-        164,
-        103,
-        120,
-        53,
-        25,
-        26,
-        237,
-        204,
-        79,
-        138,
-        138,
-        231
+        139,
+        8,
+        109,
+        65,
+        142,
+        81,
+        22
     ));
 }
 
@@ -274,27 +270,27 @@
         91,
         51,
         0,
-        254,
-        171,
-        168,
-        127,
-        158,
-        97,
-        70,
-        4,
-        233,
-        156,
-        134,
-        220,
-        44,
-        50,
-        90,
-        3,
-        68,
-        200,
-        127,
-        223,
-        6
+        176,
+        194,
+        94,
+        42,
+        248,
+        190,
+        103,
+        74,
+        123,
+        208,
+        120,
+        249,
+        75,
+        63,
+        244,
+        81,
+        244,
+        71,
+        64,
+        46,
+        28
     ));
 }
 
@@ -309,6 +305,7 @@
         result = transformer->transform(frame1, sizeof(frame1));
         EXPECT_FALSE(result.hasException());
     }
+
     checkVectorsAreEqual(result.releaseReturnValue(), Vector<uint8_t>::from(
         31,
         198,
@@ -321,27 +318,27 @@
         51,
         1,
         0,
-        124,
-        218,
-        61,
-        23,
-        78,
-        15,
-        190,
-        35,
-        255,
-        253,
-        120,
-        64,
-        28,
-        183,
-        172,
-        154,
-        144,
-        16,
-        229,
-        87,
-        52
+        37,
+        39,
+        205,
+        106,
+        44,
+        155,
+        25,
+        174,
+        2,
+        206,
+        198,
+        89,
+        82,
+        57,
+        224,
+        232,
+        26,
+        29,
+        98,
+        176,
+        57
     ));
 }
 
@@ -367,27 +364,27 @@
         1,
         0,
         0,
-        98,
-        212,
-        137,
-        244,
-        209,
-        16,
-        89,
-        234,
-        21,
-        171,
-        15,
-        107,
-        50,
-        145,
-        73,
-        107,
-        165,
-        45,
-        190,
-        25,
-        82
+        117,
+        5,
+        112,
+        126,
+        205,
+        197,
+        116,
+        213,
+        249,
+        178,
+        47,
+        154,
+        151,
+        123,
+        40,
+        58,
+        121,
+        201,
+        159,
+        90,
+        170
     ));
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to