From: zandobersek@gmail.com Date: Sat, 3 Jun 2017 10:29:32 +0000 (+0000) Subject: [GCrypt] Gather SUBTLE_CRYPTO utility functions in a single header X-Git-Url: http://git.webkit.org/?p=WebKit-https.git;a=commitdiff_plain;h=6500fdbaa9e52945493104f6d677427b1dd79916;hp=9428f05dab4d2093c5c840fc5e3783aa8b8a15be [GCrypt] Gather SUBTLE_CRYPTO utility functions in a single header https://bugs.webkit.org/show_bug.cgi?id=172870 Reviewed by Jiewen Tan. Gather the helper functions used across different source files for libgcrypt-backed SUBTLE_CRYPTO implementations in a single header file. * crypto/gcrypt/CryptoAlgorithmECDSAGCrypt.cpp: (WebCore::hashCryptoDigestAlgorithm): Deleted. (WebCore::hashAlgorithmName): Deleted. (WebCore::mpiData): Deleted. * crypto/gcrypt/CryptoAlgorithmHKDFGCrypt.cpp: (WebCore::gcryptDeriveBits): (WebCore::macAlgorithmForHashFunction): Deleted. * crypto/gcrypt/CryptoAlgorithmPBKDF2GCrypt.cpp: (WebCore::gcryptDeriveBits): * crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp: (WebCore::mpiData): Deleted. * crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp: (WebCore::hashCryptoDigestAlgorithm): Deleted. (WebCore::hashAlgorithmName): Deleted. (WebCore::mpiData): Deleted. * crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp: (WebCore::hashAlgorithmName): Deleted. (WebCore::mpiData): Deleted. * crypto/gcrypt/GCryptUtilities.h: Added. (WebCore::hashAlgorithmName): (WebCore::hmacAlgorithm): (WebCore::digestAlgorithm): (WebCore::hashCryptoDigestAlgorithm): (WebCore::mpiData): git-svn-id: https://svn.webkit.org/repository/webkit/trunk@217754 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index e7d8000..8701071 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,5 +1,41 @@ 2017-06-03 Zan Dobersek + [GCrypt] Gather SUBTLE_CRYPTO utility functions in a single header + https://bugs.webkit.org/show_bug.cgi?id=172870 + + Reviewed by Jiewen Tan. + + Gather the helper functions used across different source files + for libgcrypt-backed SUBTLE_CRYPTO implementations in a single + header file. + + * crypto/gcrypt/CryptoAlgorithmECDSAGCrypt.cpp: + (WebCore::hashCryptoDigestAlgorithm): Deleted. + (WebCore::hashAlgorithmName): Deleted. + (WebCore::mpiData): Deleted. + * crypto/gcrypt/CryptoAlgorithmHKDFGCrypt.cpp: + (WebCore::gcryptDeriveBits): + (WebCore::macAlgorithmForHashFunction): Deleted. + * crypto/gcrypt/CryptoAlgorithmPBKDF2GCrypt.cpp: + (WebCore::gcryptDeriveBits): + * crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp: + (WebCore::mpiData): Deleted. + * crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp: + (WebCore::hashCryptoDigestAlgorithm): Deleted. + (WebCore::hashAlgorithmName): Deleted. + (WebCore::mpiData): Deleted. + * crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp: + (WebCore::hashAlgorithmName): Deleted. + (WebCore::mpiData): Deleted. + * crypto/gcrypt/GCryptUtilities.h: Added. + (WebCore::hashAlgorithmName): + (WebCore::hmacAlgorithm): + (WebCore::digestAlgorithm): + (WebCore::hashCryptoDigestAlgorithm): + (WebCore::mpiData): + +2017-06-03 Zan Dobersek + [GCrypt] Fix PK verification for ECDSA https://bugs.webkit.org/show_bug.cgi?id=172857 diff --git a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDSAGCrypt.cpp b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDSAGCrypt.cpp index dc8ce9b..276a95d 100644 --- a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDSAGCrypt.cpp +++ b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmECDSAGCrypt.cpp @@ -33,75 +33,12 @@ #include "CryptoAlgorithmEcdsaParams.h" #include "CryptoKeyEC.h" #include "ExceptionCode.h" +#include "GCryptUtilities.h" #include "ScriptExecutionContext.h" #include -#include -#include namespace WebCore { -static std::optional hashCryptoDigestAlgorithm(CryptoAlgorithmIdentifier identifier) -{ - switch (identifier) { - case CryptoAlgorithmIdentifier::SHA_1: - return PAL::CryptoDigest::Algorithm::SHA_1; - case CryptoAlgorithmIdentifier::SHA_224: - return PAL::CryptoDigest::Algorithm::SHA_224; - case CryptoAlgorithmIdentifier::SHA_256: - return PAL::CryptoDigest::Algorithm::SHA_256; - case CryptoAlgorithmIdentifier::SHA_384: - return PAL::CryptoDigest::Algorithm::SHA_384; - case CryptoAlgorithmIdentifier::SHA_512: - return PAL::CryptoDigest::Algorithm::SHA_512; - default: - return std::nullopt; - } -} - -static std::optional hashAlgorithmName(CryptoAlgorithmIdentifier identifier) -{ - switch (identifier) { - case CryptoAlgorithmIdentifier::SHA_1: - return "sha1"; - case CryptoAlgorithmIdentifier::SHA_224: - return "sha224"; - case CryptoAlgorithmIdentifier::SHA_256: - return "sha256"; - case CryptoAlgorithmIdentifier::SHA_384: - return "sha384"; - case CryptoAlgorithmIdentifier::SHA_512: - return "sha512"; - default: - return std::nullopt; - } -} - -std::optional> mpiData(gcry_sexp_t paramSexp) -{ - // Retrieve the MPI value stored in the s-expression: (name mpi-data) - PAL::GCrypt::Handle paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG)); - if (!paramMPI) - return std::nullopt; - - // Query the data length first to properly prepare the buffer. - size_t dataLength = 0; - gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - // Finally, copy the MPI data into a properly-sized buffer. - Vector output(dataLength); - error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - return output; -} - static std::optional> gcryptSign(gcry_sexp_t keySexp, const Vector& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier, size_t keySizeInBytes) { // Perform digest operation with the specified algorithm on the given data. diff --git a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmHKDFGCrypt.cpp b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmHKDFGCrypt.cpp index b98f9a7..11ab196 100644 --- a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmHKDFGCrypt.cpp +++ b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmHKDFGCrypt.cpp @@ -33,9 +33,8 @@ #include "CryptoAlgorithmHkdfParams.h" #include "CryptoKeyRaw.h" #include "ExceptionCode.h" +#include "GCryptUtilities.h" #include "ScriptExecutionContext.h" -#include -#include namespace WebCore { @@ -43,31 +42,13 @@ namespace WebCore { // We should switch to the libgcrypt-provided implementation once it's available. // https://bugs.webkit.org/show_bug.cgi?id=171536 -static std::optional macAlgorithmForHashFunction(CryptoAlgorithmIdentifier identifier) -{ - switch (identifier) { - case CryptoAlgorithmIdentifier::SHA_1: - return GCRY_MAC_HMAC_SHA1; - case CryptoAlgorithmIdentifier::SHA_224: - return GCRY_MAC_HMAC_SHA224; - case CryptoAlgorithmIdentifier::SHA_256: - return GCRY_MAC_HMAC_SHA256; - case CryptoAlgorithmIdentifier::SHA_384: - return GCRY_MAC_HMAC_SHA384; - case CryptoAlgorithmIdentifier::SHA_512: - return GCRY_MAC_HMAC_SHA512; - default: - return std::nullopt; - } -} - static std::optional> gcryptDeriveBits(const Vector& key, const Vector& salt, const Vector& info, size_t lengthInBytes, CryptoAlgorithmIdentifier identifier) { // libgcrypt doesn't provide HKDF support, so we have to implement // the functionality ourselves as specified in RFC5869. // https://www.ietf.org/rfc/rfc5869.txt - auto macAlgorithm = macAlgorithmForHashFunction(identifier); + auto macAlgorithm = hmacAlgorithm(identifier); if (!macAlgorithm) return std::nullopt; diff --git a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmPBKDF2GCrypt.cpp b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmPBKDF2GCrypt.cpp index 5362003..5fd9e8e 100644 --- a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmPBKDF2GCrypt.cpp +++ b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmPBKDF2GCrypt.cpp @@ -33,39 +33,22 @@ #include "CryptoAlgorithmPbkdf2Params.h" #include "CryptoKeyRaw.h" #include "ExceptionCode.h" +#include "GCryptUtilities.h" #include "ScriptExecutionContext.h" -#include namespace WebCore { static std::optional> gcryptDeriveBits(const Vector& keyData, const Vector& saltData, CryptoAlgorithmIdentifier hashIdentifier, size_t iterations, size_t length) { - int hashAlgorithm; - switch (hashIdentifier) { - case CryptoAlgorithmIdentifier::SHA_1: - hashAlgorithm = GCRY_MD_SHA1; - break; - case CryptoAlgorithmIdentifier::SHA_224: - hashAlgorithm = GCRY_MD_SHA224; - break; - case CryptoAlgorithmIdentifier::SHA_256: - hashAlgorithm = GCRY_MD_SHA256; - break; - case CryptoAlgorithmIdentifier::SHA_384: - hashAlgorithm = GCRY_MD_SHA384; - break; - case CryptoAlgorithmIdentifier::SHA_512: - hashAlgorithm = GCRY_MD_SHA512; - break; - default: + auto hashAlgorithm = digestAlgorithm(hashIdentifier); + if (!hashAlgorithm) return std::nullopt; - } // Length, in bits, is a multiple of 8, as guaranteed by CryptoAlgorithmPBKDF2::deriveBits(). ASSERT(!(length % 8)); Vector result(length / 8); - gcry_error_t error = gcry_kdf_derive(keyData.data(), keyData.size(), GCRY_KDF_PBKDF2, hashAlgorithm, saltData.data(), saltData.size(), iterations, result.size(), result.data()); + gcry_error_t error = gcry_kdf_derive(keyData.data(), keyData.size(), GCRY_KDF_PBKDF2, *hashAlgorithm, saltData.data(), saltData.size(), iterations, result.size(), result.data()); if (error != GPG_ERR_NO_ERROR) { PAL::GCrypt::logError(error); return std::nullopt; diff --git a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp index bff9241..379b9f4 100644 --- a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp +++ b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSAES_PKCS1_v1_5GCrypt.cpp @@ -30,39 +30,12 @@ #include "CryptoKeyRSA.h" #include "ExceptionCode.h" +#include "GCryptUtilities.h" #include "NotImplemented.h" #include "ScriptExecutionContext.h" -#include -#include namespace WebCore { -static std::optional> mpiData(gcry_sexp_t paramSexp) -{ - // Retrieve the MPI value stored in the s-expression: (name mpi-data) - PAL::GCrypt::Handle paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG)); - if (!paramMPI) - return std::nullopt; - - // Query the data length first to properly prepare the buffer. - size_t dataLength = 0; - gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - // Finally, copy the MPI data into a properly-sized buffer. - Vector output(dataLength); - error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - return output; -} - static std::optional> gcryptEncrypt(gcry_sexp_t keySexp, Vector&& plainText) { // Embed the plain-text data in a `data` s-expression using PKCS#1 padding. diff --git a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp index 27934e9..1066f01 100644 --- a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp +++ b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSASSA_PKCS1_v1_5GCrypt.cpp @@ -32,76 +32,12 @@ #include "CryptoAlgorithmRsaSsaParamsDeprecated.h" #include "CryptoKeyRSA.h" #include "ExceptionCode.h" +#include "GCryptUtilities.h" #include "NotImplemented.h" #include "ScriptExecutionContext.h" -#include -#include -#include namespace WebCore { -static std::optional hashCryptoDigestAlgorithm(CryptoAlgorithmIdentifier identifier) -{ - switch (identifier) { - case CryptoAlgorithmIdentifier::SHA_1: - return PAL::CryptoDigest::Algorithm::SHA_1; - case CryptoAlgorithmIdentifier::SHA_224: - return PAL::CryptoDigest::Algorithm::SHA_224; - case CryptoAlgorithmIdentifier::SHA_256: - return PAL::CryptoDigest::Algorithm::SHA_256; - case CryptoAlgorithmIdentifier::SHA_384: - return PAL::CryptoDigest::Algorithm::SHA_384; - case CryptoAlgorithmIdentifier::SHA_512: - return PAL::CryptoDigest::Algorithm::SHA_512; - default: - return std::nullopt; - } -} - -static std::optional hashAlgorithmName(CryptoAlgorithmIdentifier identifier) -{ - switch (identifier) { - case CryptoAlgorithmIdentifier::SHA_1: - return "sha1"; - case CryptoAlgorithmIdentifier::SHA_224: - return "sha224"; - case CryptoAlgorithmIdentifier::SHA_256: - return "sha256"; - case CryptoAlgorithmIdentifier::SHA_384: - return "sha384"; - case CryptoAlgorithmIdentifier::SHA_512: - return "sha512"; - default: - return std::nullopt; - } -} - -static std::optional> mpiData(gcry_sexp_t paramSexp) -{ - // Retrieve the MPI value stored in the s-expression: (name mpi-data) - PAL::GCrypt::Handle paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG)); - if (!paramMPI) - return std::nullopt; - - // Query the data length first to properly prepare the buffer. - size_t dataLength = 0; - gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - // Finally, copy the MPI data into a properly-sized buffer. - Vector output(dataLength); - error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - return output; -} - static std::optional> gcryptSign(gcry_sexp_t keySexp, const Vector& data, CryptoAlgorithmIdentifier hashAlgorithmIdentifier) { // Perform digest operation with the specified algorithm on the given data. diff --git a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp index 4e931bd..bf89711 100644 --- a/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp +++ b/Source/WebCore/crypto/gcrypt/CryptoAlgorithmRSA_OAEPGCrypt.cpp @@ -31,57 +31,12 @@ #include "CryptoAlgorithmRsaOaepParams.h" #include "CryptoKeyRSA.h" #include "ExceptionCode.h" +#include "GCryptUtilities.h" #include "NotImplemented.h" #include "ScriptExecutionContext.h" -#include -#include namespace WebCore { -static std::optional hashAlgorithmName(CryptoAlgorithmIdentifier identifier) -{ - switch (identifier) { - case CryptoAlgorithmIdentifier::SHA_1: - return "sha1"; - case CryptoAlgorithmIdentifier::SHA_224: - return "sha224"; - case CryptoAlgorithmIdentifier::SHA_256: - return "sha256"; - case CryptoAlgorithmIdentifier::SHA_384: - return "sha384"; - case CryptoAlgorithmIdentifier::SHA_512: - return "sha512"; - default: - return std::nullopt; - } -} - -static std::optional> mpiData(gcry_sexp_t paramSexp) -{ - // Retrieve the MPI value stored in the s-expression: (name mpi-data) - PAL::GCrypt::Handle paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG)); - if (!paramMPI) - return std::nullopt; - - // Query the data length first to properly prepare the buffer. - size_t dataLength = 0; - gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - // Finally, copy the MPI data into a properly-sized buffer. - Vector output(dataLength); - error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI); - if (error != GPG_ERR_NO_ERROR) { - PAL::GCrypt::logError(error); - return std::nullopt; - } - - return output; -} - static std::optional> gcryptEncrypt(CryptoAlgorithmIdentifier hashAlgorithmIdentifier, gcry_sexp_t keySexp, const Vector& labelVector, const Vector& plainText) { // Embed the plain-text data in a data s-expression using OAEP padding. diff --git a/Source/WebCore/crypto/gcrypt/GCryptUtilities.h b/Source/WebCore/crypto/gcrypt/GCryptUtilities.h new file mode 100644 index 0000000..551439e --- /dev/null +++ b/Source/WebCore/crypto/gcrypt/GCryptUtilities.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * Copyright (C) 2017 Metrological Group B.V. + * Copyright (C) 2017 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "CryptoAlgorithmIdentifier.h" +#include +#include +#include +#include + +namespace WebCore { + +static inline std::optional hashAlgorithmName(CryptoAlgorithmIdentifier identifier) +{ + switch (identifier) { + case CryptoAlgorithmIdentifier::SHA_1: + return "sha1"; + case CryptoAlgorithmIdentifier::SHA_224: + return "sha224"; + case CryptoAlgorithmIdentifier::SHA_256: + return "sha256"; + case CryptoAlgorithmIdentifier::SHA_384: + return "sha384"; + case CryptoAlgorithmIdentifier::SHA_512: + return "sha512"; + default: + return std::nullopt; + } +} + +static inline std::optional hmacAlgorithm(CryptoAlgorithmIdentifier identifier) +{ + switch (identifier) { + case CryptoAlgorithmIdentifier::SHA_1: + return GCRY_MAC_HMAC_SHA1; + case CryptoAlgorithmIdentifier::SHA_224: + return GCRY_MAC_HMAC_SHA224; + case CryptoAlgorithmIdentifier::SHA_256: + return GCRY_MAC_HMAC_SHA256; + case CryptoAlgorithmIdentifier::SHA_384: + return GCRY_MAC_HMAC_SHA384; + case CryptoAlgorithmIdentifier::SHA_512: + return GCRY_MAC_HMAC_SHA512; + default: + return std::nullopt; + } +} + +static inline std::optional digestAlgorithm(CryptoAlgorithmIdentifier identifier) +{ + switch (identifier) { + case CryptoAlgorithmIdentifier::SHA_1: + return GCRY_MD_SHA1; + case CryptoAlgorithmIdentifier::SHA_224: + return GCRY_MD_SHA224; + case CryptoAlgorithmIdentifier::SHA_256: + return GCRY_MD_SHA256; + case CryptoAlgorithmIdentifier::SHA_384: + return GCRY_MD_SHA384; + case CryptoAlgorithmIdentifier::SHA_512: + return GCRY_MD_SHA512; + default: + return std::nullopt; + } +} + +static inline std::optional hashCryptoDigestAlgorithm(CryptoAlgorithmIdentifier identifier) +{ + switch (identifier) { + case CryptoAlgorithmIdentifier::SHA_1: + return PAL::CryptoDigest::Algorithm::SHA_1; + case CryptoAlgorithmIdentifier::SHA_224: + return PAL::CryptoDigest::Algorithm::SHA_224; + case CryptoAlgorithmIdentifier::SHA_256: + return PAL::CryptoDigest::Algorithm::SHA_256; + case CryptoAlgorithmIdentifier::SHA_384: + return PAL::CryptoDigest::Algorithm::SHA_384; + case CryptoAlgorithmIdentifier::SHA_512: + return PAL::CryptoDigest::Algorithm::SHA_512; + default: + return std::nullopt; + } +} + +static inline std::optional> mpiData(gcry_sexp_t paramSexp) +{ + // Retrieve the MPI value stored in the s-expression: (name mpi-data) + PAL::GCrypt::Handle paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG)); + if (!paramMPI) + return std::nullopt; + + // Query the data length first to properly prepare the buffer. + size_t dataLength = 0; + gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI); + if (error != GPG_ERR_NO_ERROR) { + PAL::GCrypt::logError(error); + return std::nullopt; + } + + // Finally, copy the MPI data into a properly-sized buffer. + Vector output(dataLength); + error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI); + if (error != GPG_ERR_NO_ERROR) { + PAL::GCrypt::logError(error); + return std::nullopt; + } + + return output; +} + +} // namespace WebCore