Diff
Modified: trunk/LayoutTests/ChangeLog (233137 => 233138)
--- trunk/LayoutTests/ChangeLog 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/LayoutTests/ChangeLog 2018-06-25 07:05:51 UTC (rev 233138)
@@ -1,3 +1,13 @@
+2018-06-25 Zan Dobersek <zdober...@igalia.com>
+
+ [GCrypt] Zero-prefix (if necessary) RSA-OAEP encryption, RSA-PSS signing output
+ https://bugs.webkit.org/show_bug.cgi?id=186967
+
+ Reviewed by Michael Catanzaro.
+
+ * platform/gtk/TestExpectations: Remove flaky failures for RSA-OAEP and RSA-PSS tests.
+ * platform/wpe/TestExpectations: Ditto.
+
2018-06-24 Simon Fraser <simon.fra...@apple.com>
Fix the composition underline to be transformed by -apple-color-filter
Modified: trunk/LayoutTests/platform/gtk/TestExpectations (233137 => 233138)
--- trunk/LayoutTests/platform/gtk/TestExpectations 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/LayoutTests/platform/gtk/TestExpectations 2018-06-25 07:05:51 UTC (rev 233138)
@@ -1847,10 +1847,6 @@
webkit.org/b/176757 fast/hidpi/filters-invert.html [ Pass ImageOnlyFailure ]
webkit.org/b/176757 fast/hidpi/filters-multiple.html [ Pass ImageOnlyFailure ]
-webkit.org/b/176759 crypto/subtle/rsa-oaep-import-key-wrap-jwk-oct-key.html [ Pass Failure ]
-webkit.org/b/176759 crypto/workers/subtle/rsa-oaep-import-key-encrypt.html [ Pass Failure ]
-webkit.org/b/176759 crypto/subtle/rsa-oaep-import-key-encrypt-label.html [ Pass Failure ]
-
webkit.org/b/177527 [ Release ] fast/hidpi/filters-blur.html [ Pass ImageOnlyFailure ]
webkit.org/b/177530 imported/w3c/web-platform-tests/XMLHttpRequest/setrequestheader-header-allowed.htm [ Pass Failure ]
@@ -1866,8 +1862,6 @@
webkit.org/b/179755 media/video-empty-source.html [ Pass Crash ]
-webkit.org/b/180095 imported/w3c/web-platform-tests/WebCryptoAPI/sign_verify/test_rsa_pss.https.html [ Pass Failure ]
-
webkit.org/b/180369 http/tests/security/mixedContent/insecure-xhr-in-main-frame.html [ Pass Crash ]
webkit.org/b/179174 inspector/console/webcore-logging.html [ Failure Crash ]
@@ -1876,8 +1870,6 @@
webkit.org/b/179948 [ Release ] fast/hidpi/filters-reference.html [ Pass ImageOnlyFailure ]
webkit.org/b/181031 fast/frames/crash-when-iframe-is-remove-in-eventhandler.html [ Pass Crash ]
-webkit.org/b/181139 imported/w3c/web-platform-tests/WebCryptoAPI/encrypt_decrypt/test_rsa_oaep.https.html [ Pass Failure ]
-
webkit.org/b/181528 http/tests/cache/memory-cache-pruning.html [ Pass Crash ]
webkit.org/b/181529 imported/blink/http/tests/webfont/animation-assert.html [ Pass Crash ]
@@ -1954,7 +1946,6 @@
webkit.org/b/186638 imported/w3c/web-platform-tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.https.worker.html [ Failure Pass ]
webkit.org/b/186638 imported/w3c/web-platform-tests/XMLHttpRequest/send-timeout-events.htm [ Failure Pass ]
webkit.org/b/186638 imported/w3c/web-platform-tests/IndexedDB/interleaved-cursors-large.html [ Failure Pass ]
-webkit.org/b/186638 imported/w3c/web-platform-tests/WebCryptoAPI/sign_verify/rsa_pss.https.worker.html [ Failure Pass ]
webkit.org/b/186638 imported/w3c/web-platform-tests/html/webappapis/timers/negative-settimeout.html [ Failure Pass ]
webkit.org/b/186638 fast/selectors/hover-invalidation-descendant-dynamic.html [ Failure Pass ]
webkit.org/b/186638 fast/selectors/hover-quirks.html [ Failure Pass ]
@@ -1962,7 +1953,6 @@
webkit.org/b/186638 fast/selectors/unqualified-hover-strict.html [ Failure Pass ]
webkit.org/b/186638 compositing/patterns/direct-pattern-compositing.html [ ImageOnlyFailure Pass ]
webkit.org/b/186638 imported/w3c/web-platform-tests/mathml/relations/html5-tree/color-attributes-1.html [ Timeout Pass ]
-webkit.org/b/186638 imported/w3c/web-platform-tests/WebCryptoAPI/encrypt_decrypt/rsa.https.worker.html [ Failure Pass ]
webkit.org/b/186664 media/video-playsinline.html [ Failure Pass ]
Modified: trunk/LayoutTests/platform/wpe/TestExpectations (233137 => 233138)
--- trunk/LayoutTests/platform/wpe/TestExpectations 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/LayoutTests/platform/wpe/TestExpectations 2018-06-25 07:05:51 UTC (rev 233138)
@@ -1026,8 +1026,6 @@
webkit.org/b/172815 imported/w3c/i18n/bidi/bidi-plaintext-011.html [ Pass ImageOnlyFailure ]
webkit.org/b/176174 media/event-queue-crash.html [ Pass Failure ]
-
-webkit.org/b/176358 imported/w3c/web-platform-tests/WebCryptoAPI/encrypt_decrypt/rsa.https.worker.html [ Failure Pass ]
webkit.org/b/177226 imported/w3c/web-platform-tests/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.https.worker.html [ Pass Failure ]
# Apparently fails on Mac, but I don't know for what reasons. It passes on GTK/WPE.
@@ -1186,8 +1184,6 @@
webkit.org/b/182240 svg/animations/svgenum-animation-7.html [ Pass Crash ]
-webkit.org/b/181139 imported/w3c/web-platform-tests/WebCryptoAPI/encrypt_decrypt/test_rsa_oaep.https.html [ Pass Failure ]
-
webkit.org/b/184086 imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/accumulation-per-property.html [ Failure ]
webkit.org/b/184086 imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property.html [ Failure ]
Modified: trunk/Source/WebCore/ChangeLog (233137 => 233138)
--- trunk/Source/WebCore/ChangeLog 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/ChangeLog 2018-06-25 07:05:51 UTC (rev 233138)
@@ -1,3 +1,44 @@
+2018-06-25 Zan Dobersek <zdober...@igalia.com>
+
+ [GCrypt] Zero-prefix (if necessary) output of RSA-based encryption and signing operations
+ https://bugs.webkit.org/show_bug.cgi?id=186967
+
+ Reviewed by Michael Catanzaro.
+
+ Output for RSA-based encryption and signing operations should match the
+ length of the RSA key. The way we retrieve the MPI data means libgcrypt
+ can ignore the high-bit zero values and leave us with a valid result
+ that's shorter in length compared to the RSA key. For instance, if the
+ output MPI fits into 2040 bits while a 2048-bit key was used we'll end
+ up with MPI data that will be fitted into a 255-byte Vector, one byte
+ short of the expected output length.
+
+ To avoid this, mpiZeroPrefixedData() is now used when retrieving output
+ of these RSA operations, and the value of the key size in bytes is
+ passed to it. This efficiently prepares the output Vector and then
+ copies the MPI data into it, respecting the MPI data length as well as
+ the desired length of the output.
+
+ No new tests -- relevant tests are now stable (i.e. not sporadically
+ failing anymore), associated expectations are removed.
+
+ * crypto/gcrypt/CryptoAlgorithmECDHGCrypt.cpp:
+ (WebCore::gcryptDerive): Also use mpiZeroPrefixedData().
+ * crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp:
+ (WebCore::gcryptEncrypt):
+ (WebCore::CryptoAlgorithmRSAES_PKCS1_v1_5::platformEncrypt):
+ * crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp:
+ (WebCore::gcryptSign):
+ (WebCore::CryptoAlgorithmRSASSA_PKCS1_v1_5::platformSign):
+ * crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp:
+ (WebCore::gcryptEncrypt):
+ (WebCore::CryptoAlgorithmRSA_OAEP::platformEncrypt):
+ * crypto/gcrypt/CryptoAlgorithmRSA_PSSGCrypt.cpp:
+ (WebCore::gcryptSign):
+ (WebCore::CryptoAlgorithmRSA_PSS::platformSign):
+ * crypto/gcrypt/GCryptUtilities.h:
+ (WebCore::mpiZeroPrefixedData):
+
2018-06-24 Simon Fraser <simon.fra...@apple.com>
Fix the DUMP_NODE_STATISTICS code so that it compiles
Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDHGCrypt.cpp (233137 => 233138)
--- trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDHGCrypt.cpp 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDHGCrypt.cpp 2018-06-25 07:05:51 UTC (rev 233138)
@@ -97,17 +97,7 @@
gcry_mpi_point_snatch_get(xMPI, nullptr, nullptr, point.release());
}
- auto data = ""
- if (!data)
- return std::nullopt;
-
- if (data->size() < keySizeInBytes) {
- Vector<uint8_t> paddedData(keySizeInBytes - data->size(), 0);
- paddedData.appendVector(*data);
- *data = ""
- }
-
- return data;
+ return mpiZeroPrefixedData(xMPI, keySizeInBytes);
}
std::optional<Vector<uint8_t>> CryptoAlgorithmECDH::platformDeriveBits(const CryptoKeyEC& baseKey, const CryptoKeyEC& publicKey)
Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp (233137 => 233138)
--- trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp 2018-06-25 07:05:51 UTC (rev 233138)
@@ -33,7 +33,7 @@
namespace WebCore {
-static std::optional<Vector<uint8_t>> gcryptEncrypt(gcry_sexp_t keySexp, const Vector<uint8_t>& plainText)
+static std::optional<Vector<uint8_t>> gcryptEncrypt(gcry_sexp_t keySexp, const Vector<uint8_t>& plainText, size_t keySizeInBytes)
{
// Embed the plain-text data in a `data` s-_expression_ using PKCS#1 padding.
PAL::GCrypt::Handle<gcry_sexp_t> dataSexp;
@@ -60,7 +60,7 @@
if (!aSexp)
return std::nullopt;
- return mpiData(aSexp);
+ return mpiZeroPrefixedData(aSexp, keySizeInBytes);
}
static std::optional<Vector<uint8_t>> gcryptDecrypt(gcry_sexp_t keySexp, const Vector<uint8_t>& cipherText)
@@ -95,7 +95,8 @@
ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSAES_PKCS1_v1_5::platformEncrypt(const CryptoKeyRSA& key, const Vector<uint8_t>& plainText)
{
- auto output = gcryptEncrypt(key.platformKey(), plainText);
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!(key.keySizeInBits() % 8));
+ auto output = gcryptEncrypt(key.platformKey(), plainText, key.keySizeInBits() / 8);
if (!output)
return Exception { OperationError };
return WTFMove(*output);
Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp (233137 => 233138)
--- trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp 2018-06-25 07:05:51 UTC (rev 233138)
@@ -35,7 +35,7 @@
namespace WebCore {
-static std::optional<Vector<uint8_t>> gcryptSign(gcry_sexp_t keySexp, const Vector<uint8_t>& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier)
+static std::optional<Vector<uint8_t>> gcryptSign(gcry_sexp_t keySexp, const Vector<uint8_t>& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier, size_t keySizeInBytes)
{
// Perform digest operation with the specified algorithm on the given data.
Vector<uint8_t> dataHash;
@@ -83,7 +83,7 @@
if (!sSexp)
return std::nullopt;
- return mpiData(sSexp);
+ return mpiZeroPrefixedData(sSexp, keySizeInBytes);
}
static std::optional<bool> gcryptVerify(gcry_sexp_t keySexp, const Vector<uint8_t>& signature, const Vector<uint8_t>& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier)
@@ -136,7 +136,8 @@
ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSASSA_PKCS1_v1_5::platformSign(const CryptoKeyRSA& key, const Vector<uint8_t>& data)
{
- auto output = gcryptSign(key.platformKey(), data, key.hashAlgorithmIdentifier());
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!(key.keySizeInBits() % 8));
+ auto output = gcryptSign(key.platformKey(), data, key.hashAlgorithmIdentifier(), key.keySizeInBits() / 8);
if (!output)
return Exception { OperationError };
return WTFMove(*output);
Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp (233137 => 233138)
--- trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp 2018-06-25 07:05:51 UTC (rev 233138)
@@ -35,7 +35,7 @@
namespace WebCore {
-static std::optional<Vector<uint8_t>> gcryptEncrypt(CryptoAlgorithmIdentifier hashAlgorithmIdentifier, gcry_sexp_t keySexp, const Vector<uint8_t>& labelVector, const Vector<uint8_t>& plainText)
+static std::optional<Vector<uint8_t>> gcryptEncrypt(CryptoAlgorithmIdentifier hashAlgorithmIdentifier, gcry_sexp_t keySexp, const Vector<uint8_t>& labelVector, const Vector<uint8_t>& plainText, size_t keySizeInBytes)
{
// Embed the plain-text data in a data s-_expression_ using OAEP padding.
// Empty label data is properly handled by gcry_sexp_build().
@@ -70,7 +70,7 @@
if (!aSexp)
return std::nullopt;
- return mpiData(aSexp);
+ return mpiZeroPrefixedData(aSexp, keySizeInBytes);
}
static std::optional<Vector<uint8_t>> gcryptDecrypt(CryptoAlgorithmIdentifier hashAlgorithmIdentifier, gcry_sexp_t keySexp, const Vector<uint8_t>& labelVector, const Vector<uint8_t>& cipherText)
@@ -112,7 +112,8 @@
ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSA_OAEP::platformEncrypt(CryptoAlgorithmRsaOaepParams& parameters, const CryptoKeyRSA& key, const Vector<uint8_t>& plainText)
{
- auto output = gcryptEncrypt(key.hashAlgorithmIdentifier(), key.platformKey(), parameters.labelVector(), plainText);
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!(key.keySizeInBits() % 8));
+ auto output = gcryptEncrypt(key.hashAlgorithmIdentifier(), key.platformKey(), parameters.labelVector(), plainText, key.keySizeInBits() / 8);
if (!output)
return Exception { OperationError };
return WTFMove(*output);
Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_PSSGCrypt.cpp (233137 => 233138)
--- trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_PSSGCrypt.cpp 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_PSSGCrypt.cpp 2018-06-25 07:05:51 UTC (rev 233138)
@@ -36,7 +36,7 @@
namespace WebCore {
-static std::optional<Vector<uint8_t>> gcryptSign(gcry_sexp_t keySexp, size_t keyLength, const Vector<uint8_t>& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier, size_t saltLength)
+static std::optional<Vector<uint8_t>> gcryptSign(gcry_sexp_t keySexp, const Vector<uint8_t>& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier, size_t saltLength, size_t keySizeInBytes)
{
// Perform digest operation with the specified algorithm on the given data.
Vector<uint8_t> dataHash;
@@ -84,12 +84,7 @@
if (!sSexp)
return std::nullopt;
- // Validate the MPI data size -- it should match the key length in bytes.
- auto signature = mpiData(sSexp);
- if (!signature || signature->size() != keyLength / 8)
- return std::nullopt;
-
- return signature;
+ return mpiZeroPrefixedData(sSexp, keySizeInBytes);
}
static std::optional<bool> gcryptVerify(gcry_sexp_t keySexp, const Vector<uint8_t>& signature, const Vector<uint8_t>& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier, size_t saltLength)
@@ -142,7 +137,8 @@
ExceptionOr<Vector<uint8_t>> CryptoAlgorithmRSA_PSS::platformSign(CryptoAlgorithmRsaPssParams& parameters, const CryptoKeyRSA& key, const Vector<uint8_t>& data)
{
- auto output = gcryptSign(key.platformKey(), key.keySizeInBits(), data, key.hashAlgorithmIdentifier(), parameters.saltLength);
+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!(key.keySizeInBits() % 8));
+ auto output = gcryptSign(key.platformKey(), data, key.hashAlgorithmIdentifier(), parameters.saltLength, key.keySizeInBits() / 8);
if (!output)
return Exception { OperationError };
return WTFMove(*output);
Modified: trunk/Source/WebCore/crypto/gcrypt/GCryptUtilities.h (233137 => 233138)
--- trunk/Source/WebCore/crypto/gcrypt/GCryptUtilities.h 2018-06-25 06:31:15 UTC (rev 233137)
+++ trunk/Source/WebCore/crypto/gcrypt/GCryptUtilities.h 2018-06-25 07:05:51 UTC (rev 233138)
@@ -180,6 +180,26 @@
return output;
}
+static inline std::optional<Vector<uint8_t>> mpiZeroPrefixedData(gcry_mpi_t paramMPI, size_t targetLength)
+{
+ // Retrieve the MPI length. Bail if the retrieved length is longer than target length.
+ auto length = mpiLength(paramMPI);
+ if (!length || *length > targetLength)
+ return std::nullopt;
+
+ // Fill out the output buffer with zeros. Properly determine the zero prefix length,
+ // and copy the MPI data into memory area following the prefix (if any).
+ Vector<uint8_t> output(targetLength, 0);
+ size_t prefixLength = targetLength - *length;
+ gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data() + prefixLength, targetLength, nullptr, paramMPI);
+ if (error != GPG_ERR_NO_ERROR) {
+ PAL::GCrypt::logError(error);
+ return std::nullopt;
+ }
+
+ return output;
+}
+
static inline std::optional<Vector<uint8_t>> mpiData(gcry_sexp_t paramSexp)
{
// Retrieve the MPI value stored in the s-_expression_: (name mpi-data)
@@ -190,6 +210,16 @@
return mpiData(paramMPI);
}
+static inline std::optional<Vector<uint8_t>> mpiZeroPrefixedData(gcry_sexp_t paramSexp, size_t targetLength)
+{
+ // Retrieve the MPI value stored in the s-_expression_: (name mpi-data)
+ PAL::GCrypt::Handle<gcry_mpi_t> paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG));
+ if (!paramMPI)
+ return std::nullopt;
+
+ return mpiZeroPrefixedData(paramMPI, targetLength);
+}
+
static inline std::optional<Vector<uint8_t>> mpiSignedData(gcry_mpi_t mpi)
{
auto data = ""