⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 275656 in webkit


Ignore:
Timestamp:
Apr 8, 2021, 3:53:44 AM (6 years ago)
Author:
youenn@apple.com
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.
Location:
trunk
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r275652 r275656  
     12021-04-08  Youenn Fablet  <youenn@apple.com>
     2
     3        Update SFrame implementation to latest version
     4        https://bugs.webkit.org/show_bug.cgi?id=224276
     5
     6        Reviewed by Eric Carlson.
     7
     8        * webrtc/sframe-test-vectors-expected.txt: Added.
     9        * webrtc/sframe-test-vectors.html: Added.
     10
    1112021-04-07  Julian Gonzalez  <julian_a_gonzalez@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r275654 r275656  
     12021-04-08  Youenn Fablet  <youenn@apple.com>
     2
     3        Update SFrame implementation to latest version
     4        https://bugs.webkit.org/show_bug.cgi?id=224276
     5
     6        Reviewed by Eric Carlson.
     7
     8        Update implementation according to latest draft at https://github.com/eomara/sframe/blob/master/draft-omara-sframe.md.
     9        In particular, we derive keys with new algorithm and the generation of the signature by including header and data length as well as nonce.
     10
     11        Test: webrtc/sframe-test-vectors.html
     12
     13        * Modules/mediastream/RTCRtpSFrameTransform.cpp:
     14        (WebCore::RTCRtpSFrameTransform::setCounterForTesting):
     15        * Modules/mediastream/RTCRtpSFrameTransform.h:
     16        * Modules/mediastream/RTCRtpSFrameTransformer.cpp:
     17        (WebCore::computeIV):
     18        (WebCore::RTCRtpSFrameTransformer::updateEncryptionKey):
     19        (WebCore::RTCRtpSFrameTransformer::decryptFrame):
     20        (WebCore::RTCRtpSFrameTransformer::encryptFrame):
     21        (WebCore::RTCRtpSFrameTransformer::computeEncryptedDataSignature):
     22        * Modules/mediastream/RTCRtpSFrameTransformer.h:
     23        * Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp:
     24        (WebCore::RTCRtpSFrameTransformer::computeSaltKey):
     25        (WebCore::createBaseSFrameKey):
     26        (WebCore::RTCRtpSFrameTransformer::computeAuthenticationKey):
     27        (WebCore::RTCRtpSFrameTransformer::computeEncryptionKey):
     28        (WebCore::encodeBigEndian):
     29        (WebCore::RTCRtpSFrameTransformer::computeEncryptedDataSignature):
     30        * testing/Internals.cpp:
     31        (WebCore::Internals::setSFrameCounter):
     32        * testing/Internals.h:
     33        * testing/Internals.idl:
     34
    1352021-04-08  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    236
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp

    r274709 r275656  
    7676}
    7777
     78void RTCRtpSFrameTransform::setCounterForTesting(uint64_t counter)
     79{
     80    m_transformer->setCounter(counter);
     81}
     82
    7883uint64_t RTCRtpSFrameTransform::counterForTesting() const
    7984{
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h

    r271690 r275656  
    6464    void willClearBackend(RTCRtpTransformBackend&);
    6565
     66    WEBCORE_EXPORT void setCounterForTesting(uint64_t);
    6667    WEBCORE_EXPORT uint64_t counterForTesting() const;
    6768    WEBCORE_EXPORT uint64_t keyIdForTesting() const;
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp

    r273158 r275656  
    3333namespace WebCore {
    3434
     35static constexpr unsigned AES_CM_128_HMAC_SHA256_NONCE_SIZE = 12;
     36
    3537static inline void writeUInt64(uint8_t* data, uint64_t value, uint8_t valueLength)
    3638{
    … …  
    7274static inline Vector<uint8_t> computeIV(uint64_t counter, const Vector<uint8_t>& saltKey)
    7375{
     76    // The saltKey is 12 bytes (AES_CM_128_HMAC_SHA256_NONCE_SIZE), we XOR with the counter as 12 bytes.
     77    // We then extend it to 16 bytes since that is what is expected by the crypto routines.
    7478    Vector<uint8_t> iv(16);
    75     for (unsigned i = 0; i < 8; ++i) {
    76         auto value = (counter >> ((7 - i) * 8)) & 0xff;
     79    for (unsigned i = 0; i < 4; ++i)
     80        iv[i] = saltKey[i];
     81    for (unsigned i = 11; i >= 4; --i) {
     82        auto value = counter & 0xff;
     83        counter = counter >> 8;
    7784        iv[i] = value ^ saltKey[i];
    7885    }
    79     for (unsigned i = 8; i < 16; ++i)
    80         iv[i] = saltKey[i];
     86    for (unsigned i = 12; i < 16; ++i)
     87        iv[i] = 0;
    8188    return iv;
    8289}
    … …  
    162169        return saltKeyResult.releaseException();
    163170
    164     ASSERT(saltKeyResult.returnValue().size() >= 16);
     171    ASSERT(saltKeyResult.returnValue().size() >= AES_CM_128_HMAC_SHA256_NONCE_SIZE);
    165172
    166173    auto authenticationKeyResult = computeAuthenticationKey(rawKey);
    … …  
    241248        return Exception { DataError, "Chunk is too small for authentication size" };
    242249
     250    auto iv = computeIV(m_counter, m_saltKey);
     251
    243252    // Compute signature
    244253    auto* transmittedSignature = frameData + frameSize - m_authenticationSize;
    245     auto signature = computeEncryptedDataSignature(frameData, frameSize  - m_authenticationSize, m_authenticationKey);
     254    auto signature = computeEncryptedDataSignature(iv, frameData, header->size, frameData + header->size, frameSize  - m_authenticationSize - header->size, m_authenticationKey);
    246255    for (size_t cptr = 0; cptr < m_authenticationSize; ++cptr) {
    247256        if (signature[cptr] != transmittedSignature[cptr]) {
    … …  
    252261
    253262    // Decrypt data
    254     auto iv = computeIV(m_counter, m_saltKey);
    255263    auto dataSize = frameSize - header->size - m_authenticationSize;
    256264    auto result = decryptData(frameData + header->size, dataSize, iv, m_encryptionKey);
    … …  
    312320
    313321    // Fill signature
    314     auto signature = computeEncryptedDataSignature(newDataPointer, frameSize + headerSize, m_authenticationKey);
     322    auto signature = computeEncryptedDataSignature(iv, newDataPointer, headerSize, newDataPointer + headerSize, frameSize, m_authenticationKey);
    315323    std::memcpy(newDataPointer + frameSize + headerSize, signature.data(), m_authenticationSize);
    316324
    … …  
    357365}
    358366
    359 Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const uint8_t*, size_t, const Vector<uint8_t>&)
     367Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const Vector<uint8_t>&, const uint8_t*, size_t, const uint8_t*, size_t, const Vector<uint8_t>&)
    360368{
    361369    return { };
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h

    r274709 r275656  
    7575    ExceptionOr<Vector<uint8_t>> encryptData(const uint8_t*, size_t, const Vector<uint8_t>& iv, const Vector<uint8_t>& key);
    7676    ExceptionOr<Vector<uint8_t>> decryptData(const uint8_t*, size_t, const Vector<uint8_t>& iv, const Vector<uint8_t>& key);
    77     Vector<uint8_t> computeEncryptedDataSignature(const uint8_t*, size_t, const Vector<uint8_t>& key);
     77    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);
    7878    void updateAuthenticationSize();
    7979
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp

    r270319 r275656  
    3636ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::computeSaltKey(const Vector<uint8_t>& rawKey)
    3737{
    38     uint8_t usage[] = "SFrameSaltKey";
    39     return deriveHDKFSHA256Bits(rawKey.data(), 16, rawKey.data() + 16, rawKey.size() - 16, usage, sizeof(usage) - 1, 128);
     38    uint8_t usage[] = "SFrame10";
     39    uint8_t info[] = "salt";
     40    return deriveHDKFSHA256Bits(rawKey.data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 96);
     41}
     42
     43static ExceptionOr<Vector<uint8_t>> createBaseSFrameKey(const Vector<uint8_t>& rawKey)
     44{
     45    uint8_t usage[] = "SFrame10";
     46    uint8_t info[] = "key";
     47    return deriveHDKFSHA256Bits(rawKey.data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 128);
    4048}
    4149
    4250ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::computeAuthenticationKey(const Vector<uint8_t>& rawKey)
    4351{
    44     uint8_t usage[] = "SFrameAuthenticationKey";
    45     return deriveHDKFSHA256Bits(rawKey.data(), 16, rawKey.data() + 16, rawKey.size() - 16, usage, sizeof(usage) - 1, 256);
     52    auto key = createBaseSFrameKey(rawKey);
     53    if (key.hasException())
     54        return key;
     55
     56    uint8_t usage[] = "SFrame10 AES CM AEAD";
     57    uint8_t info[] = "auth";
     58    return deriveHDKFSHA256Bits(key.returnValue().data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 256);
    4659}
    4760
    4861ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::computeEncryptionKey(const Vector<uint8_t>& rawKey)
    4962{
    50     uint8_t usage[] = "SFrameEncryptionKey";
    51     return deriveHDKFSHA256Bits(rawKey.data(), 16, rawKey.data() + 16, rawKey.size() - 16, usage, sizeof(usage) - 1, 128);
     63    auto key = createBaseSFrameKey(rawKey);
     64    if (key.hasException())
     65        return key;
     66
     67    uint8_t usage[] = "SFrame10 AES CM AEAD";
     68    uint8_t info[] = "enc";
     69    return deriveHDKFSHA256Bits(key.returnValue().data(), 16, usage, sizeof(usage) - 1, info, sizeof(info) - 1, 128);
    5270}
    5371
    … …  
    6280}
    6381
    64 Vector<uint8_t> RTCRtpSFrameTransformer::computeEncryptedDataSignature(const uint8_t* data, size_t size, const Vector<uint8_t>& key)
     82static inline Vector<uint8_t, 8> encodeBigEndian(uint64_t value)
    6583{
    66     return calculateSHA256Signature(key, data, size);
     84    Vector<uint8_t, 8> result(8);
     85    for (int i = 7; i >= 0; --i) {
     86        result.data()[i] = value & 0xff;
     87        value = value >> 8;
     88    }
     89    return result;
     90}
     91
     92Vector<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)
     93{
     94    auto headerLength = encodeBigEndian(headerSize);
     95    auto dataLength = encodeBigEndian(dataSize);
     96
     97    Vector<uint8_t> result(CC_SHA256_DIGEST_LENGTH);
     98    CCHmacContext context;
     99    CCHmacInit(&context, kCCHmacAlgSHA256, key.data(), key.size());
     100    CCHmacUpdate(&context, headerLength.data(), headerLength.size());
     101    CCHmacUpdate(&context, dataLength.data(), dataLength.size());
     102    CCHmacUpdate(&context, nonce.data(), 12);
     103    CCHmacUpdate(&context, header, headerSize);
     104    CCHmacUpdate(&context, data, dataSize);
     105    CCHmacFinal(&context, result.data());
     106
     107    return result;
    67108}
    68109
  • trunk/Source/WebCore/testing/Internals.cpp

    r275417 r275656  
    15961596}
    15971597
     1598void Internals::setSFrameCounter(RTCRtpSFrameTransform& transform, const String& counter)
     1599{
     1600    if (auto value = StringView(counter).toUInt64Strict())
     1601        transform.setCounterForTesting(*value);
     1602}
     1603
    15981604uint64_t Internals::sframeCounter(const RTCRtpSFrameTransform& transform)
    15991605{
  • trunk/Source/WebCore/testing/Internals.h

    r275417 r275656  
    618618    void setWebRTCVP9Support(bool supportVP9Profile0, bool supportVP9Profile2);
    619619    void setWebRTCVP9VTBSupport(bool);
     620    void setSFrameCounter(RTCRtpSFrameTransform&, const String&);
    620621    uint64_t sframeCounter(const RTCRtpSFrameTransform&);
    621622    uint64_t sframeKeyId(const RTCRtpSFrameTransform&);
  • trunk/Source/WebCore/testing/Internals.idl

    r275417 r275656  
    826826    [Conditional=WEB_RTC] undefined setWebRTCVP9Support(boolean supportVP9Profile0, boolean supportVP9Profile2);
    827827    [Conditional=WEB_RTC] undefined setWebRTCVP9VTBSupport(boolean allowed);
     828    [Conditional=WEB_RTC] undefined setSFrameCounter(RTCRtpSFrameTransform transform, DOMString counter);
    828829    [Conditional=WEB_RTC] unsigned long long sframeCounter(RTCRtpSFrameTransform transform);
    829830    [Conditional=WEB_RTC] unsigned long long sframeKeyId(RTCRtpSFrameTransform transform);
  • trunk/Tools/ChangeLog

    r275635 r275656  
     12021-04-08  Youenn Fablet  <youenn@apple.com>
     2
     3        Update SFrame implementation to latest version
     4        https://bugs.webkit.org/show_bug.cgi?id=224276
     5
     6        Reviewed by Eric Carlson.
     7
     8        Update tests according new way of deriving keys and generating the signature.
     9
     10        * TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp:
     11        (TestWebKitAPI::TEST):
     12
    1132021-04-07  Jonathan Bedard  <jbedard@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp

    r274709 r275656  
    117117    auto transformer = createVideoTransformer();
    118118    checkVectorsAreEqual(transformer->authenticationKey(), Vector<uint8_t>::from(
     119        4,
     120        98,
     121        231,
     122        89,
     123        19,
     124        177,
     125        253,
     126        241,
     127        246,
     128        85,
     129        193,
     130        64,
     131        19,
     132        72,
     133        211,
     134        48,
     135        57,
     136        235,
     137        63,
     138        57,
     139        165,
     140        252,
     141        130,
     142        58,
     143        142,
     144        14,
     145        142,
     146        223,
     147        134,
    119148        92,
    120         228,
     149        167,
     150        253
     151    ));
     152}
     153
     154TEST(RTCRtpSFrameTransformer, EncryptionKey)
     155{
     156    auto transformer = createVideoTransformer();
     157    checkVectorsAreEqual(transformer->encryptionKey(), Vector<uint8_t>::from(
     158        180,
     159        189,
     160        66,
     161        149,
     162        6,
     163        101,
     164        148,
     165        179,
     166        158,
     167        210,
     168        132,
     169        83,
     170        75,
     171        11,
     172        43,
     173        50
     174    ));
     175}
     176
     177TEST(RTCRtpSFrameTransformer, SaltKey)
     178{
     179    auto transformer = createVideoTransformer();
     180    checkVectorsAreEqual(transformer->saltKey(), Vector<uint8_t>::from(
     181        184,
     182        43,
     183        180,
     184        28,
     185        93,
    121186        139,
    122         195,
    123         98,
    124         16,
    125         4,
    126         193,
    127         221,
    128         248,
    129         232,
    130         178,
    131         135,
    132         22,
    133         141,
    134         150,
    135         165,
    136         242,
    137         73,
    138         72,
    139         10,
    140         197,
    141         15,
    142         87,
    143         181,
    144         34,
    145         120,
    146         71,
    147         42,
    148         174,
    149         131,
    150         72
    151     ));
    152 }
    153 
    154 TEST(RTCRtpSFrameTransformer, EncryptionKey)
    155 {
    156     auto transformer = createVideoTransformer();
    157     checkVectorsAreEqual(transformer->encryptionKey(), Vector<uint8_t>::from(
    158         207,
    159         251,
    160         52,
    161         21,
    162         101,
    163         50,
    164         232,
    165         48,
    166         211,
    167         115,
    168         11,
    169         155,
    170         101,
    171         116,
    172         153,
    173         71
    174     ));
    175 }
    176 
    177 TEST(RTCRtpSFrameTransformer, SaltKey)
    178 {
    179     auto transformer = createVideoTransformer();
    180     checkVectorsAreEqual(transformer->saltKey(), Vector<uint8_t>::from(
    181         229,
    182         19,
    183         42,
    184         93,
    185         164,
    186         103,
    187         120,
    188         53,
    189         25,
    190         26,
    191         237,
    192         204,
    193         79,
    194         138,
    195         138,
    196         231
     187        8,
     188        109,
     189        65,
     190        142,
     191        81,
     192        22
    197193    ));
    198194}
    … …  
    275271        51,
    276272        0,
    277         254,
    278         171,
    279         168,
    280         127,
    281         158,
    282         97,
    283         70,
    284         4,
    285         233,
    286         156,
    287         134,
    288         220,
    289         44,
    290         50,
    291         90,
    292         3,
    293         68,
    294         200,
    295         127,
    296         223,
    297         6
     273        176,
     274        194,
     275        94,
     276        42,
     277        248,
     278        190,
     279        103,
     280        74,
     281        123,
     282        208,
     283        120,
     284        249,
     285        75,
     286        63,
     287        244,
     288        81,
     289        244,
     290        71,
     291        64,
     292        46,
     293        28
    298294    ));
    299295}
    … …  
    310306        EXPECT_FALSE(result.hasException());
    311307    }
     308
    312309    checkVectorsAreEqual(result.releaseReturnValue(), Vector<uint8_t>::from(
    313310        31,
    … …  
    322319        1,
    323320        0,
    324         124,
    325         218,
    326         61,
    327         23,
    328         78,
    329         15,
    330         190,
    331         35,
    332         255,
    333         253,
    334         120,
    335         64,
    336         28,
    337         183,
    338         172,
    339         154,
    340         144,
    341         16,
    342         229,
    343         87,
    344         52
     321        37,
     322        39,
     323        205,
     324        106,
     325        44,
     326        155,
     327        25,
     328        174,
     329        2,
     330        206,
     331        198,
     332        89,
     333        82,
     334        57,
     335        224,
     336        232,
     337        26,
     338        29,
     339        98,
     340        176,
     341        57
    345342    ));
    346343}
    … …  
    368365        0,
    369366        0,
    370         98,
    371         212,
    372         137,
    373         244,
    374         209,
    375         16,
    376         89,
    377         234,
    378         21,
    379         171,
    380         15,
    381         107,
    382         50,
    383         145,
    384         73,
    385         107,
    386         165,
    387         45,
    388         190,
    389         25,
    390         82
     367        117,
     368        5,
     369        112,
     370        126,
     371        205,
     372        197,
     373        116,
     374        213,
     375        249,
     376        178,
     377        47,
     378        154,
     379        151,
     380        123,
     381        40,
     382        58,
     383        121,
     384        201,
     385        159,
     386        90,
     387        170
    391388    ));
    392389}
Note: See TracChangeset for help on using the changeset viewer.