Title: [260655] trunk
Revision
260655
Author
[email protected]
Date
2020-04-24 10:56:59 -0700 (Fri, 24 Apr 2020)

Log Message

[OpenSSL] Implement WebCrypto APIs for HMAC
https://bugs.webkit.org/show_bug.cgi?id=210902

Patch by Tomoki Imai <[email protected]> on 2020-04-24
Reviewed by Don Olmstead.

Source/WebCore:

Support WebCrypto HMAC sign/verify with OpenSSL.
The design and some functions are inherited from the other ports.

* crypto/openssl/CryptoAlgorithmHMACOpenSSL.cpp:
(WebCore::HMACAlgorithm): Added. Helper function to map CryptoAlgorithmIdentifier to OpenSSL EVP_MD type.
(WebCore::calculateSignature): Added. Helper function to calculate the signature for sign/verify.
(WebCore::CryptoAlgorithmHMAC::platformSign): Implemented, mostly same as the other ports.
(WebCore::CryptoAlgorithmHMAC::platformVerify): Implemented, mostly same as the other ports.
* crypto/openssl/CryptoAlgorithmRegistryOpenSSL.cpp:
(WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms): Added CryptoAlgorithmHMAC support.
* crypto/openssl/OpenSSLCryptoUniquePtr.h: Added specialized unique_ptrs for EVP_MD_CTX and EVP_PKEY.
(WebCore::OpenSSLCryptoPtrDeleter<EVP_MD_CTX>::operator() const):
(WebCore::OpenSSLCryptoPtrDeleter<EVP_PKEY>::operator() const):

LayoutTests:

Enabled WebCrypto LayoutTests for HMAC along with the implementation.

* platform/wincairo/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (260654 => 260655)


--- trunk/LayoutTests/ChangeLog	2020-04-24 17:53:26 UTC (rev 260654)
+++ trunk/LayoutTests/ChangeLog	2020-04-24 17:56:59 UTC (rev 260655)
@@ -1,3 +1,14 @@
+2020-04-24  Tomoki Imai  <[email protected]>
+
+        [OpenSSL] Implement WebCrypto APIs for HMAC
+        https://bugs.webkit.org/show_bug.cgi?id=210902
+
+        Reviewed by Don Olmstead.
+
+        Enabled WebCrypto LayoutTests for HMAC along with the implementation.
+
+        * platform/wincairo/TestExpectations:
+
 2020-04-24  Jacob Uphoff  <[email protected]>
 
         [ Mac wk2 ] tiled-drawing/simple-document-with-margin-tiles.html is flaky failing.

Modified: trunk/LayoutTests/platform/wincairo/TestExpectations (260654 => 260655)


--- trunk/LayoutTests/platform/wincairo/TestExpectations	2020-04-24 17:53:26 UTC (rev 260654)
+++ trunk/LayoutTests/platform/wincairo/TestExpectations	2020-04-24 17:56:59 UTC (rev 260655)
@@ -947,46 +947,6 @@
 crypto/subtle/hkdf-import-key-derive-bits.html [ Skip ]
 crypto/subtle/hkdf-import-key-derive-hmac-key.html [ Skip ]
 crypto/subtle/hkdf-import-key-malformed-parameters.html [ Skip ]
-crypto/subtle/hmac-export-key-malformed-parameters.html [ Skip ]
-crypto/subtle/hmac-generate-export-key-jwk-sha1.html [ Skip ]
-crypto/subtle/hmac-generate-export-key-jwk-sha224.html [ Skip ]
-crypto/subtle/hmac-generate-export-key-jwk-sha256.html [ Skip ]
-crypto/subtle/hmac-generate-export-key-jwk-sha384.html [ Skip ]
-crypto/subtle/hmac-generate-export-key-jwk-sha512.html [ Skip ]
-crypto/subtle/hmac-generate-export-raw-key.html [ Skip ]
-crypto/subtle/hmac-generate-key-customized-length.html [ Skip ]
-crypto/subtle/hmac-generate-key-hash-object.html [ Skip ]
-crypto/subtle/hmac-generate-key-malformed-parameters.html [ Skip ]
-crypto/subtle/hmac-generate-key-sha1.html [ Skip ]
-crypto/subtle/hmac-generate-key-sha224.html [ Skip ]
-crypto/subtle/hmac-generate-key-sha256.html [ Skip ]
-crypto/subtle/hmac-generate-key-sha384.html [ Skip ]
-crypto/subtle/hmac-generate-key-sha512.html [ Skip ]
-crypto/subtle/hmac-generate-key-sign-verify.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-export-jwk-key.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-export-raw-key.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-minimum.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-non-extractable.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-sha1.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-sha224.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-sha256.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-sha384.html [ Skip ]
-crypto/subtle/hmac-import-jwk-key-sha512.html [ Skip ]
-crypto/subtle/hmac-import-key-malformed-parameters.html [ Skip ]
-crypto/subtle/hmac-import-key-sign-sha1.html [ Skip ]
-crypto/subtle/hmac-import-key-sign-sha224.html [ Skip ]
-crypto/subtle/hmac-import-key-sign-sha256.html [ Skip ]
-crypto/subtle/hmac-import-key-sign-sha384.html [ Skip ]
-crypto/subtle/hmac-import-key-sign-sha512.html [ Skip ]
-crypto/subtle/hmac-import-key-verify-sha1.html [ Skip ]
-crypto/subtle/hmac-import-key-verify-sha224.html [ Skip ]
-crypto/subtle/hmac-import-key-verify-sha256.html [ Skip ]
-crypto/subtle/hmac-import-key-verify-sha384.html [ Skip ]
-crypto/subtle/hmac-import-key-verify-sha512.html [ Skip ]
-crypto/subtle/hmac-import-raw-key.html [ Skip ]
-crypto/subtle/hmac-import-raw-key-customized-length.html [ Skip ]
-crypto/subtle/hmac-import-raw-key-export-jwk-key.html [ Skip ]
-crypto/subtle/hmac-import-raw-key-export-raw-key.html [ Skip ]
 crypto/subtle/import-key-malformed-parameters.html [ Skip ]
 crypto/subtle/pbkdf2-derive-bits-malformed-parametrs.html [ Skip ]
 crypto/subtle/pbkdf2-import-key.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (260654 => 260655)


--- trunk/Source/WebCore/ChangeLog	2020-04-24 17:53:26 UTC (rev 260654)
+++ trunk/Source/WebCore/ChangeLog	2020-04-24 17:56:59 UTC (rev 260655)
@@ -1,3 +1,24 @@
+2020-04-24  Tomoki Imai  <[email protected]>
+
+        [OpenSSL] Implement WebCrypto APIs for HMAC
+        https://bugs.webkit.org/show_bug.cgi?id=210902
+
+        Reviewed by Don Olmstead.
+
+        Support WebCrypto HMAC sign/verify with OpenSSL.
+        The design and some functions are inherited from the other ports.
+
+        * crypto/openssl/CryptoAlgorithmHMACOpenSSL.cpp:
+        (WebCore::HMACAlgorithm): Added. Helper function to map CryptoAlgorithmIdentifier to OpenSSL EVP_MD type.
+        (WebCore::calculateSignature): Added. Helper function to calculate the signature for sign/verify.
+        (WebCore::CryptoAlgorithmHMAC::platformSign): Implemented, mostly same as the other ports.
+        (WebCore::CryptoAlgorithmHMAC::platformVerify): Implemented, mostly same as the other ports.
+        * crypto/openssl/CryptoAlgorithmRegistryOpenSSL.cpp:
+        (WebCore::CryptoAlgorithmRegistry::platformRegisterAlgorithms): Added CryptoAlgorithmHMAC support.
+        * crypto/openssl/OpenSSLCryptoUniquePtr.h: Added specialized unique_ptrs for EVP_MD_CTX and EVP_PKEY.
+        (WebCore::OpenSSLCryptoPtrDeleter<EVP_MD_CTX>::operator() const):
+        (WebCore::OpenSSLCryptoPtrDeleter<EVP_PKEY>::operator() const):
+
 2020-04-24  Brian Burg  <[email protected]>
 
         Web Automation: timeout underneath Automation.evaluateJavaScriptFunction in Selenium test frame_switching_tests.py::testShouldNotBeAbleToDoAnythingTheFrameIsDeletedFromUnderUs[Safari]

Modified: trunk/Source/WebCore/crypto/openssl/CryptoAlgorithmHMACOpenSSL.cpp (260654 => 260655)


--- trunk/Source/WebCore/crypto/openssl/CryptoAlgorithmHMACOpenSSL.cpp	2020-04-24 17:53:26 UTC (rev 260654)
+++ trunk/Source/WebCore/crypto/openssl/CryptoAlgorithmHMACOpenSSL.cpp	2020-04-24 17:56:59 UTC (rev 260655)
@@ -29,22 +29,87 @@
 #if ENABLE(WEB_CRYPTO)
 
 #include "CryptoKeyHMAC.h"
-#include "NotImplemented.h"
+#include "OpenSSLCryptoUniquePtr.h"
+#include <openssl/evp.h>
+#include <wtf/CryptographicUtilities.h>
 
 namespace WebCore {
 
-ExceptionOr<Vector<uint8_t>> CryptoAlgorithmHMAC::platformSign(const CryptoKeyHMAC&, const Vector<uint8_t>&)
+static const EVP_MD* HMACAlgorithm(CryptoAlgorithmIdentifier hashFunction)
 {
-    notImplemented();
-    return Exception { NotSupportedError };
+    switch (hashFunction) {
+    case CryptoAlgorithmIdentifier::SHA_1:
+        return EVP_sha1();
+    case CryptoAlgorithmIdentifier::SHA_224:
+        return EVP_sha224();
+    case CryptoAlgorithmIdentifier::SHA_256:
+        return EVP_sha256();
+    case CryptoAlgorithmIdentifier::SHA_384:
+        return EVP_sha384();
+    case CryptoAlgorithmIdentifier::SHA_512:
+        return EVP_sha512();
+    default:
+        return nullptr;
+    }
 }
 
-ExceptionOr<bool> CryptoAlgorithmHMAC::platformVerify(const CryptoKeyHMAC&, const Vector<uint8_t>&, const Vector<uint8_t>&)
+static Optional<Vector<uint8_t>> calculateSignature(const EVP_MD* algorithm, const Vector<uint8_t>& key, const uint8_t* data, size_t dataLength)
 {
-    notImplemented();
-    return Exception { NotSupportedError };
+    // Create the Message Digest Context
+    EvpDigestCtxPtr ctx;
+    if (!(ctx = EvpDigestCtxPtr(EVP_MD_CTX_create())))
+        return WTF::nullopt;
+
+    // Initialize the DigestSign operation
+    EvpPKeyPtr hkey;
+    if (!(hkey = EvpPKeyPtr(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, key.data(), key.size()))))
+        return WTF::nullopt;
+
+    if (1 != EVP_DigestSignInit(ctx.get(), nullptr, algorithm, nullptr, hkey.get()))
+        return WTF::nullopt;
+
+    // Call update with the message
+    if (1 != EVP_DigestSignUpdate(ctx.get(), data, dataLength))
+        return WTF::nullopt;
+
+    // Finalize the DigestSign operation
+    size_t len = 0;
+    if (1 != EVP_DigestSignFinal(ctx.get(), nullptr, &len))
+        return WTF::nullopt;
+
+    // Obtain the signature
+    Vector<uint8_t> cipherText(len);
+    if (1 != EVP_DigestSignFinal(ctx.get(), cipherText.data(), &len))
+        return WTF::nullopt;
+
+    return cipherText;
 }
 
+ExceptionOr<Vector<uint8_t>> CryptoAlgorithmHMAC::platformSign(const CryptoKeyHMAC& key, const Vector<uint8_t>& data)
+{
+    auto algorithm = HMACAlgorithm(key.hashAlgorithmIdentifier());
+    if (!algorithm)
+        return Exception { OperationError };
+
+    auto result = calculateSignature(algorithm, key.key(), data.data(), data.size());
+    if (!result)
+        return Exception { OperationError };
+    return WTFMove(*result);
+}
+
+ExceptionOr<bool> CryptoAlgorithmHMAC::platformVerify(const CryptoKeyHMAC& key, const Vector<uint8_t>& signature, const Vector<uint8_t>& data)
+{
+    auto algorithm = HMACAlgorithm(key.hashAlgorithmIdentifier());
+    if (!algorithm)
+        return Exception { OperationError };
+
+    auto expectedSignature = calculateSignature(algorithm, key.key(), data.data(), data.size());
+    if (!expectedSignature)
+        return Exception { OperationError };
+    // Using a constant time comparison to prevent timing attacks.
+    return signature.size() == expectedSignature->size() && !constantTimeMemcmp(expectedSignature->data(), signature.data(), expectedSignature->size());
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEB_CRYPTO)

Modified: trunk/Source/WebCore/crypto/openssl/CryptoAlgorithmRegistryOpenSSL.cpp (260654 => 260655)


--- trunk/Source/WebCore/crypto/openssl/CryptoAlgorithmRegistryOpenSSL.cpp	2020-04-24 17:53:26 UTC (rev 260654)
+++ trunk/Source/WebCore/crypto/openssl/CryptoAlgorithmRegistryOpenSSL.cpp	2020-04-24 17:56:59 UTC (rev 260655)
@@ -33,6 +33,7 @@
 #include "CryptoAlgorithmAES_CTR.h"
 #include "CryptoAlgorithmAES_GCM.h"
 #include "CryptoAlgorithmAES_KW.h"
+#include "CryptoAlgorithmHMAC.h"
 #include "CryptoAlgorithmSHA1.h"
 #include "CryptoAlgorithmSHA224.h"
 #include "CryptoAlgorithmSHA256.h"
@@ -48,6 +49,7 @@
     registerAlgorithm<CryptoAlgorithmAES_CTR>();
     registerAlgorithm<CryptoAlgorithmAES_GCM>();
     registerAlgorithm<CryptoAlgorithmAES_KW>();
+    registerAlgorithm<CryptoAlgorithmHMAC>();
     registerAlgorithm<CryptoAlgorithmSHA1>();
     registerAlgorithm<CryptoAlgorithmSHA224>();
     registerAlgorithm<CryptoAlgorithmSHA256>();

Modified: trunk/Source/WebCore/crypto/openssl/OpenSSLCryptoUniquePtr.h (260654 => 260655)


--- trunk/Source/WebCore/crypto/openssl/OpenSSLCryptoUniquePtr.h	2020-04-24 17:53:26 UTC (rev 260654)
+++ trunk/Source/WebCore/crypto/openssl/OpenSSLCryptoUniquePtr.h	2020-04-24 17:56:59 UTC (rev 260655)
@@ -49,4 +49,24 @@
 
 using EvpCipherCtxPtr = OpenSSLCryptoPtr<EVP_CIPHER_CTX>;
 
+template <>
+struct OpenSSLCryptoPtrDeleter<EVP_MD_CTX> {
+    void operator()(EVP_MD_CTX* ptr) const
+    {
+        EVP_MD_CTX_free(ptr);
+    }
+};
+
+using EvpDigestCtxPtr = OpenSSLCryptoPtr<EVP_MD_CTX>;
+
+template <>
+struct OpenSSLCryptoPtrDeleter<EVP_PKEY> {
+    void operator()(EVP_PKEY* ptr) const
+    {
+        EVP_PKEY_free(ptr);
+    }
+};
+
+using EvpPKeyPtr = OpenSSLCryptoPtr<EVP_PKEY>;
+
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to