CryptoAlgorithmECDHGCrypt.cpp [plain text]
#include "config.h"
#include "CryptoAlgorithmECDH.h"
#if ENABLE(WEB_CRYPTO)
#include "CryptoKeyEC.h"
#include "GCryptUtilities.h"
#include <pal/crypto/gcrypt/Handle.h>
#include <pal/crypto/gcrypt/Utilities.h>
namespace WebCore {
static Optional<Vector<uint8_t>> gcryptDerive(gcry_sexp_t baseKeySexp, gcry_sexp_t publicKeySexp, size_t keySizeInBytes)
{
PAL::GCrypt::Handle<gcry_sexp_t> dataSexp;
{
PAL::GCrypt::Handle<gcry_sexp_t> dSexp(gcry_sexp_find_token(baseKeySexp, "d", 0));
if (!dSexp)
return WTF::nullopt;
auto data = mpiData(dSexp);
if (!data)
return WTF::nullopt;
gcry_sexp_build(&dataSexp, nullptr, "(data(flags raw)(value %b))", data->size(), data->data());
if (!dataSexp)
return WTF::nullopt;
}
PAL::GCrypt::Handle<gcry_sexp_t> cipherSexp;
gcry_error_t error = gcry_pk_encrypt(&cipherSexp, dataSexp, publicKeySexp);
if (error != GPG_ERR_NO_ERROR) {
PAL::GCrypt::logError(error);
return WTF::nullopt;
}
PAL::GCrypt::Handle<gcry_mpi_t> xMPI(gcry_mpi_new(0));
if (!xMPI)
return WTF::nullopt;
{
PAL::GCrypt::Handle<gcry_sexp_t> sSexp(gcry_sexp_find_token(cipherSexp, "s", 0));
if (!sSexp)
return WTF::nullopt;
PAL::GCrypt::Handle<gcry_mpi_t> sMPI(gcry_sexp_nth_mpi(sSexp, 1, GCRYMPI_FMT_USG));
if (!sMPI)
return WTF::nullopt;
PAL::GCrypt::Handle<gcry_mpi_point_t> point(gcry_mpi_point_new(0));
if (!point)
return WTF::nullopt;
error = gcry_mpi_ec_decode_point(point, sMPI, nullptr);
if (error != GPG_ERR_NO_ERROR)
return WTF::nullopt;
gcry_mpi_point_snatch_get(xMPI, nullptr, nullptr, point.release());
}
return mpiZeroPrefixedData(xMPI, keySizeInBytes);
}
Optional<Vector<uint8_t>> CryptoAlgorithmECDH::platformDeriveBits(const CryptoKeyEC& baseKey, const CryptoKeyEC& publicKey)
{
return gcryptDerive(baseKey.platformKey(), publicKey.platformKey(), (baseKey.keySizeInBits() + 7) / 8);
}
}
#endif // ENABLE(WEB_CRYPTO)