[+] More crypto copypasta

This commit is contained in:
Reece Wilson 2021-09-21 02:54:47 +01:00
parent 0bcaddc5c7
commit 60d2c59d6e
14 changed files with 693 additions and 314 deletions

View File

@ -7,14 +7,14 @@
***/
#pragma once
#include "EECCCurve.hpp"
#include "IECCPublic.hpp"
#include "IECCPrivate.hpp"
#include "EECCCurve.hpp"
namespace Aurora::Crypto::ECC
{
AUKN_SHARED_API(NewECC, IECCPrivate, EECCCurve curve);
AUKN_SHARED_API(OpenPrivateECC, IECCPrivate, EECCCurve curve, const Memory::MemoryViewRead &pk);
AUKN_SHARED_API(OpenPublicECC, IECCPublic, EECCCurve curve, const Memory::MemoryViewRead &pk);
AUKN_SHARED_API(OpenPublicECCFromCert, IECCPublic, EECCCurve curve, const Memory::MemoryViewRead &certificate);
AUKN_SHARED_API(OpenPrivateECC, IECCPrivate, const Memory::MemoryViewRead &pk);
AUKN_SHARED_API(OpenPublicECC, IECCPublic, const Memory::MemoryViewRead &pk);
AUKN_SHARED_API(OpenPublicECCFromCert, IECCPublic, const Memory::MemoryViewRead &certificate);
}

View File

@ -25,6 +25,6 @@ namespace Aurora::Crypto::ECC
virtual bool AsPublicECC(AuList<AuUInt8> &out) = 0;
virtual bool AsPrivateECC(AuList<AuUInt8> &out) = 0;
virtual EECCCurve GetType() override;
virtual EECCCurve GetType() = 0;
};
}

View File

@ -13,12 +13,12 @@ namespace Aurora::Crypto::RSA
class IRSAPrivate
{
public:
virtual bool Sign(const Memory::MemoryViewRead & payload,
virtual bool Sign(const Memory::MemoryViewRead &payload,
EHashType method,
EPaddingType type,
AuList<AuUInt8> &out) = 0;
virtual bool Decrypt(const Memory::MemoryViewRead & payload,
virtual bool Decrypt(const Memory::MemoryViewRead &payload,
EPaddingType type,
AuList<AuUInt8> &out) = 0;

View File

@ -13,12 +13,12 @@ namespace Aurora::Crypto::RSA
class IRSAPublic
{
public:
virtual bool Verify(const Memory::MemoryViewRead & payload,
const Memory::MemoryViewRead & signature,
virtual bool Verify(const Memory::MemoryViewRead &plainText,
const Memory::MemoryViewRead &signature,
EHashType method,
EPaddingType type) = 0;
virtual bool Encrypt(const Memory::MemoryViewRead & plainText,
virtual bool Encrypt(const Memory::MemoryViewRead &plainText,
EPaddingType type,
AuList<AuUInt8> &out) = 0;

View File

@ -389,7 +389,6 @@ namespace Aurora::Compression
AuStreamReadWrittenPair_t Ingest(AuUInt32 input) override
{
bool ret = true;
LZ4F_dctx *dctxPtr;
AuUInt32 inputStat = 0, outputStat = 0;
size_t bytesRemInFrame {};
LZ4F_decompressOptions_t opts {};

View File

@ -7,8 +7,105 @@
***/
#include <RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCGeneric.hpp"
#include "ECCCurves.hpp"
#include "PublicECCImpl.hpp"
#include "PrivateECCImpl.hpp"
namespace Aurora::Crypto::ECC
{
static void ReleasePublicECC(IECCPublic *pub)
{
switch (pub->GetType())
{
case EECCCurve::eCurveEd25519:
case EECCCurve::eCurveX25519:
return;
default:
SafeDelete<PublicECCImpl *>(pub);
return;
}
}
static void ReleasePrivateECC(IECCPrivate *priv)
{
switch (priv->GetType())
{
case EECCCurve::eCurveEd25519:
case EECCCurve::eCurveX25519:
return;
default:
SafeDelete<PrivateECCImpl *>(priv);
return;
}
}
AUKN_SYM IECCPrivate *NewECC(EECCCurve curve)
{
switch (curve)
{
case EECCCurve::eCurveEd25519:
case EECCCurve::eCurveX25519:
// TODO: Curve25519 is special
return {};
default:
return GenerateNewGenericECC(curve).value_or(nullptr);
}
}
AUKN_SYM IECCPrivate *OpenPrivateECC(const Memory::MemoryViewRead &pk)
{
if (auto ret = NewStdECC<PrivateECCImpl>({}/*no curve assertion*/, pk, false))
{
return ret;
}
// TODO: Curve25519 is special
return {};
}
AUKN_SYM IECCPublic *OpenPublicECC(const Memory::MemoryViewRead &pk)
{
if (auto ret = NewStdECC<PublicECCImpl>({}/*no curve assertion*/, pk, false))
{
return ret;
}
// TODO: Curve25519 is special
return {};
}
AUKN_SYM IECCPublic *OpenPublicECCFromCert(const Memory::MemoryViewRead &certificate)
{
if (auto ret = NewStdECC<PublicECCImpl>({}/*no curve assertion*/, certificate, true))
{
return ret;
}
// TODO: Curve25519 is special
return {};
}
AUKN_SYM void NewECCRelease(IECCPrivate *priv)
{
ReleasePrivateECC(priv);
}
AUKN_SYM void OpenPrivateECCRelease(IECCPrivate *priv)
{
ReleasePrivateECC(priv);
}
AUKN_SYM void OpenPublicECCRelease(IECCPublic *pub)
{
ReleasePublicECC(pub);
}
AUKN_SYM void OpenPublicECCFromCertRelease(IECCPublic *pub)
{
ReleasePublicECC(pub);
}
}

View File

@ -8,6 +8,7 @@
#include <RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCCurves.hpp"
#include "ECCGeneric.hpp"
#include <tomcrypt.h>
namespace Aurora::Crypto::ECC
@ -47,9 +48,65 @@ namespace Aurora::Crypto::ECC
/* cofactor */ 1,
/* OID */ "1.3.132.0.35"
};
static const EECCCurve kEccTypes[] = {EECCCurve::eCurve256, EECCCurve::eCurve384, EECCCurve::eCurve521};
static const ltc_ecc_curve *kEccCurves[] = {&kNistp256, &kNistp384, &kNistp521};
AuOptional<EECCCurve> OIDToCurve(unsigned long *oid, unsigned long oidlen)
{
char tempAgain[256];
unsigned long size = AuArraySize(tempAgain);
if (pk_oid_num_to_str(oid, oidlen, tempAgain, &size) != CRYPT_OK)
{
return {};
}
// TODO: EVIL
auto evil = AuString(tempAgain, tempAgain + size);
for (AU_ITERATE_ARRAY(i, kEccCurves))
{
if (kEccCurves[i]->OID == evil)
{
return kEccTypes[i];
}
}
return {};
}
AuOptional<const ltc_ecc_curve *> GetECCCurve(unsigned long *oid, unsigned long oidlen)
{
char tempAgain[256];
unsigned long size = AuArraySize(tempAgain);
if (pk_oid_num_to_str(oid, oidlen, tempAgain, &size) != CRYPT_OK)
{
return {};
}
// TODO: EVIL
return GetECCCurve(AuString(tempAgain, tempAgain + size));
}
AuOptional<const ltc_ecc_curve *> GetECCCurve(const AuString &oid)
{
for (AU_ITERATE_ARRAY(i, kEccCurves))
{
if (kEccCurves[i]->OID == oid)
{
return kEccCurves[i];
}
}
return {};
}
AuOptional<const ltc_ecc_curve *> GetECCCurve(EECCCurve curve)
{
// TODO: consider using ecc_find_curve, it's basically the same thing with strings
switch (curve)
{
case EECCCurve::eCurve256:

View File

@ -9,5 +9,8 @@
namespace Aurora::Crypto::ECC
{
AuOptional<const ltc_ecc_curve *> GetECCCurve(unsigned long *oid, unsigned long oidlen);
AuOptional<EECCCurve> OIDToCurve(unsigned long *oid, unsigned long oidlen);
AuOptional<const ltc_ecc_curve *> GetECCCurve(const AuString &oid);
AuOptional<const ltc_ecc_curve *> GetECCCurve(EECCCurve curve);
}

View File

@ -9,10 +9,99 @@
#include "ECC.hpp"
#include "ECCGeneric.hpp"
#include "ECCCurves.hpp"
#include "PrivateECCImpl.hpp"
namespace Aurora::Crypto::ECC
{
static bool ExportECCKey(const ecc_key &key, bool pub, DerBuffer &out)
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen)
{
unsigned long i, j, limit, oid_j;
size_t OID_len;
LTC_ARGCHK(oidlen != NULL);
limit = *oidlen;
*oidlen = 0; /* make sure that we return zero oidlen on error */
for (i = 0; i < limit; i++) oid[i] = 0;
if (OID == NULL) return CRYPT_OK;
OID_len = XSTRLEN(OID);
if (OID_len == 0) return CRYPT_OK;
for (i = 0, j = 0; i < OID_len; i++)
{
if (OID[i] == '.')
{
if (++j >= limit) continue;
}
else if ((OID[i] >= '0') && (OID[i] <= '9'))
{
if ((j >= limit) || (oid == NULL)) continue;
oid_j = oid[j];
oid[j] = oid[j] * 10 + (OID[i] - '0');
if (oid[j] < oid_j) return CRYPT_OVERFLOW;
}
else
{
return CRYPT_ERROR;
}
}
if (j == 0) return CRYPT_ERROR;
if (j >= limit)
{
*oidlen = j;
return CRYPT_BUFFER_OVERFLOW;
}
*oidlen = j + 1;
return CRYPT_OK;
}
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen)
{
int i;
unsigned long j, k;
char tmp[256] = {0};
LTC_ARGCHK(oid != NULL);
LTC_ARGCHK(OID != NULL);
LTC_ARGCHK(outlen != NULL);
for (i = oidlen - 1, k = 0; i >= 0; i--)
{
j = oid[i];
if (j == 0)
{
tmp[k] = '0';
if (++k >= sizeof(tmp)) return CRYPT_ERROR;
}
else
{
while (j > 0)
{
tmp[k] = '0' + (j % 10);
if (++k >= sizeof(tmp)) return CRYPT_ERROR;
j /= 10;
}
}
if (i > 0)
{
tmp[k] = '.';
if (++k >= sizeof(tmp)) return CRYPT_ERROR;
}
}
if (*outlen < k + 1)
{
*outlen = k + 1;
return CRYPT_BUFFER_OVERFLOW;
}
for (j = 0; j < k; j++) OID[j] = tmp[k - j - 1];
OID[k] = '\0';
*outlen = k; /* the length without terminating NUL byte */
return CRYPT_OK;
}
bool ExportECCKey(const ecc_key &key, bool pub, DerBuffer &out)
{
if (!AuTryResize(out, 4096))
{
@ -37,322 +126,33 @@ namespace Aurora::Crypto::ECC
return true;
}
class PublicECCImpl : public IECCPublic
std::optional<IECCPrivate *> GenerateNewGenericECC(EECCCurve curve)
{
public:
PublicECCImpl(EECCCurve type, ecc_key &key);
~PublicECCImpl();
ecc_key key = {};
const int prng_idx = register_prng(&sprng_desc);
bool Verify(const Memory::MemoryViewRead &hash,
const Memory::MemoryViewRead &signature) override;
bool Verify(const Memory::MemoryViewRead &plaintext,
const Memory::MemoryViewRead &signature,
EHashType method) override;
bool AsPublicECC(AuList<AuUInt8> &out) override;
bool Export(bool pub, DerBuffer &out);
EECCCurve GetType() override;
const ecc_key &GetKey();
private:
ecc_key _key;
EECCCurve _type;
};
PublicECCImpl::PublicECCImpl(EECCCurve type, ecc_key &key) : _key(key), _type(_type)
{
}
PublicECCImpl::~PublicECCImpl()
{
ecc_free(&_key);
}
EECCCurve PublicECCImpl::GetType()
{
return _type;
}
bool PublicECCImpl::Verify(const Memory::MemoryViewRead &hash,
const Memory::MemoryViewRead &signature)
{
int ok = 0;
if (!hash.HasMemory())
auto tc = GetECCCurve(curve);
if (!tc)
{
SysPushErrorParam();
return {};
}
if (!signature.HasMemory())
{
SysPushErrorParam();
SysPushErrorCrypt();
return {};
}
auto ret = ecc_verify_hash_ex(reinterpret_cast<const unsigned char *>(hash.ptr), hash.length,
reinterpret_cast<const unsigned char *>(signature.ptr), signature.length,
LTC_ECCSIG_ETH27, &ok, &_key);
if (ret != CRYPT_OK)
auto error = ecc_make_key_ex(NULL, prng_idx, &key, *tc);
if (error != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return ok == 1;
}
bool PublicECCImpl::Verify(const Memory::MemoryViewRead &plaintext,
const Memory::MemoryViewRead &signature,
EHashType method)
{
if (!plaintext.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!signature.HasMemory())
{
SysPushErrorParam();
SysPushErrorCrypt("{}", error);
return {};
}
int hash = HashMethodToId(method);
if (hash == 0xFF)
{
SysPushErrorCrypt("invalid hash {}", method);
return false;
}
AuList<AuUInt8> hashVec;
if (!AuTryResize(hashVec, 128))
auto ret = _new PrivateECCImpl(curve, key);
if (!ret)
{
ecc_free(&key);
SysPushErrorMem();
return false;
}
unsigned long hashSize = hashVec.size();
auto ret = hash_memory(hash,
reinterpret_cast<const unsigned char *>(plaintext.ptr), plaintext.length,
reinterpret_cast<unsigned char *>(hashVec.data()), &hashSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return Verify({hashVec}, signature);
}
bool PublicECCImpl::AsPublicECC(AuList<AuUInt8> &out)
{
return Export(true, out);
}
bool PublicECCImpl::Export(bool pub, DerBuffer &out)
{
return ExportECCKey(_key, pub, out);
}
const ecc_key &PublicECCImpl::GetKey()
{
return _key;
}
class PrivateECCImpl : public IECCPrivate
{
public:
PrivateECCImpl(EECCCurve type, ecc_key &key);
~PrivateECCImpl();
bool Sign(const Memory::MemoryViewRead &plainText,
EHashType method,
AuList<AuUInt8> &out) override;
bool Sign(const Memory::MemoryViewRead &hash,
AuList<AuUInt8> &out) override;
bool ECDH(const AuSPtr<IECCPublic> &partnerPublic,
AuList<AuUInt8> &sharedKey) override;
bool AsPublicECC(AuList<AuUInt8> &out) override;
bool AsPrivateECC(AuList<AuUInt8> &out) override;
EECCCurve GetType() override;
private:
ecc_key _key;
EECCCurve _type;
};
PrivateECCImpl::PrivateECCImpl(EECCCurve type, ecc_key &key) : _key(key)
{
}
PrivateECCImpl::~PrivateECCImpl()
{
ecc_free(&_key);
}
EECCCurve PrivateECCImpl::GetType()
{
return _type;
}
bool PrivateECCImpl::Sign(const Memory::MemoryViewRead &plainText,
EHashType method,
AuList<AuUInt8> &out)
{
prng_state yarrow_prng;
const int salt = 0;
if (!plainText.HasMemory())
{
SysPushErrorParam();
return {};
}
int hash = HashMethodToId(method);
if (hash == 0xFF)
{
SysPushErrorCrypt("invalid hash {}", method);
return false;
}
if (!AuTryResize(out, 1024))
{
SysPushErrorMem();
return false;
}
AuList<AuUInt8> hashVec;
if (!AuTryResize(hashVec, 128))
{
SysPushErrorMem();
return false;
}
unsigned long hashSize = hashVec.size();
auto ret = hash_memory(hash,
reinterpret_cast<const unsigned char *>(plainText.ptr), plainText.length,
reinterpret_cast<unsigned char *>(hashVec.data()), &hashSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return Sign(hashVec, out);
}
bool PrivateECCImpl::Sign(const Memory::MemoryViewRead &hash,
AuList<AuUInt8> &out)
{
prng_state yarrow_prng;
const int salt = 0;
if (!hash.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!AuTryResize(out, 1024))
{
SysPushErrorMem();
return false;
}
unsigned long len = out.size();
auto ret = ecc_sign_hash_ex(reinterpret_cast<const unsigned char *>(hash.ptr), hash.length,
out.data(), &len,
&yarrow_prng,
::Crypto::gPrngYarrow,
LTC_ECCSIG_ETH27,
nullptr,
&_key);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(out, len))
{
SysPushErrorMem();
return false;
}
return true;
}
bool PrivateECCImpl::ECDH(const AuSPtr<IECCPublic> &partnerPublic,
AuList<AuUInt8> &sharedKey)
{
AuList<AuUInt8> sharedSecret;
if (!AuTryResize(sharedSecret, 128))
{
SysPushErrorMem();
return false;
}
if (partnerPublic->GetType() == this->GetType())
{
SysPushErrorCrypto("Can not EDCH with incompatible curve curve type (noting, ed25519 requires translation to x25519)");
return false;
}
unsigned long actualSize = sharedSecret.size();
auto ret = ecc_shared_secret(&_key, &(std::reinterpret_pointer_cast<PublicECCImpl>(partnerPublic)->GetKey()), sharedSecret.data(), &actualSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
sharedSecret.resize(actualSize);
return true;
}
bool PrivateECCImpl::AsPublicECC(AuList<AuUInt8> &out)
{
return ExportECCKey(_key, true, out);
}
bool PrivateECCImpl::AsPrivateECC(AuList<AuUInt8> &out)
{
return ExportECCKey(_key, false, out);
}
template<typename Type_t>
static Type_t *NewECC(EECCCurve curve, const AuList<AuUInt8> &pub)
{
ecc_key in {};
auto ret = ecc_import_openssl(pub.data(), pub.size(), &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
auto out = _new Type_t(curve, in);
if (!out)
{
ecc_free(&in);
}
return out;
return ret;
}
}

View File

@ -7,7 +7,88 @@
***/
#pragma once
#include "ECCCurves.hpp"
namespace Aurora::Crypto::ECC
{
template<typename Type_t>
Type_t *NewECC(EECCCurve curve, const AuList<AuUInt8> &pub);
bool ExportECCKey(const ecc_key &key, bool pub, DerBuffer &out);
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen);
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);
template<typename Type_t>
static Type_t *NewStdECC(AuOptional<EECCCurve> curve, const Memory::MemoryViewRead &pk, bool cert = false)
{
ecc_key in {};
AuOptional<const ltc_ecc_curve *> ref;
if (curve)
{
ref = GetECCCurve(curve.value());
if (!ref)
{
SysPushErrorParam("This curve isn't supported here");
// wrong function, bucko
return nullptr;
}
}
if (cert)
{
auto ret = ecc_import_x509(pk.Begin<const unsigned char>(), pk.length, &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
}
else
{
auto ret = ecc_import_openssl(pk.Begin<const unsigned char>(), pk.length, &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
}
if (ref)
{
unsigned long oid[16] {};
unsigned long oidLength = AuArraySize(oid);
pk_oid_str_to_num(ref.value()->OID, oid, &oidLength);
if (oidLength != in.dp.oidlen ||
std::memcmp(in.dp.oid, oid, in.dp.oidlen * sizeof(unsigned long)))
{
SysPushErrorParam("Improper curve type, expected {}, got {}, for ECCCurveType: {}", ref.value()->OID, AuList<unsigned long>(in.dp.oid, in.dp.oid + in.dp.oidlen), curve.value());
ecc_free(&in);
return nullptr;
}
}
else
{
curve = OIDToCurve(in.dp.oid, in.dp.oidlen);
}
if (!curve)
{
SysPushErrorCrypt("Couldn't find curve");
return {};
}
Type_t *out = _new Type_t(curve.value(), in);
if (!out)
{
ecc_free(&in);
}
return out;
}
std::optional<IECCPrivate *> GenerateNewGenericECC(EECCCurve curve);
}

View File

@ -0,0 +1,163 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECCGeneric.cpp
Date: 2021-9-17
Author: Reece
***/
#include <RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCGeneric.hpp"
#include "ECCCurves.hpp"
#include "PrivateECCImpl.hpp"
#include "PublicECCImpl.hpp"
namespace Aurora::Crypto::ECC
{
PrivateECCImpl::PrivateECCImpl(EECCCurve type, ecc_key &key) : _key(key)
{
}
PrivateECCImpl::~PrivateECCImpl()
{
ecc_free(&_key);
}
EECCCurve PrivateECCImpl::GetType()
{
return _type;
}
bool PrivateECCImpl::Sign(const Memory::MemoryViewRead &plainText,
EHashType method,
AuList<AuUInt8> &out)
{
prng_state yarrow_prng;
const int salt = 0;
if (!plainText.HasMemory())
{
SysPushErrorParam();
return {};
}
int hash = HashMethodToId(method);
if (hash == 0xFF)
{
SysPushErrorCrypt("invalid hash {}", method);
return false;
}
if (!AuTryResize(out, 1024))
{
SysPushErrorMem();
return false;
}
AuList<AuUInt8> hashVec;
if (!AuTryResize(hashVec, 128))
{
SysPushErrorMem();
return false;
}
unsigned long hashSize = hashVec.size();
auto ret = hash_memory(hash,
reinterpret_cast<const unsigned char *>(plainText.ptr), plainText.length,
reinterpret_cast<unsigned char *>(hashVec.data()), &hashSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return Sign(hashVec, out);
}
bool PrivateECCImpl::Sign(const Memory::MemoryViewRead &hash,
AuList<AuUInt8> &out)
{
prng_state yarrow_prng;
const int salt = 0;
if (!hash.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!AuTryResize(out, 1024))
{
SysPushErrorMem();
return false;
}
unsigned long len = out.size();
auto ret = ecc_sign_hash_ex(reinterpret_cast<const unsigned char *>(hash.ptr), hash.length,
out.data(), &len,
&yarrow_prng,
::Crypto::gPrngYarrow,
LTC_ECCSIG_ETH27,
nullptr,
&_key);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(out, len))
{
SysPushErrorMem();
return false;
}
return true;
}
bool PrivateECCImpl::ECDH(const AuSPtr<IECCPublic> &partnerPublic,
AuList<AuUInt8> &sharedKey)
{
AuList<AuUInt8> sharedSecret;
if (!AuTryResize(sharedSecret, 128))
{
SysPushErrorMem();
return false;
}
if (partnerPublic->GetType() == this->GetType())
{
SysPushErrorCrypto("Can not EDCH with incompatible curve curve type (noting, ed25519 requires translation to x25519)");
return false;
}
unsigned long actualSize = sharedSecret.size();
auto ret = ecc_shared_secret(&_key, &(std::reinterpret_pointer_cast<PublicECCImpl>(partnerPublic)->GetKey()), sharedSecret.data(), &actualSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(sharedSecret, actualSize))
{
SysPushErrorMem();
return false;
}
return true;
}
bool PrivateECCImpl::AsPublicECC(AuList<AuUInt8> &out)
{
return ExportECCKey(_key, true, out);
}
bool PrivateECCImpl::AsPrivateECC(AuList<AuUInt8> &out)
{
return ExportECCKey(_key, false, out);
}
}

View File

@ -0,0 +1,31 @@
#pragma once
namespace Aurora::Crypto::ECC
{
class PrivateECCImpl : public IECCPrivate
{
public:
PrivateECCImpl(EECCCurve type, ecc_key &key);
~PrivateECCImpl();
bool Sign(const Memory::MemoryViewRead &plainText,
EHashType method,
AuList<AuUInt8> &out) override;
bool Sign(const Memory::MemoryViewRead &hash,
AuList<AuUInt8> &out) override;
bool ECDH(const AuSPtr<IECCPublic> &partnerPublic,
AuList<AuUInt8> &sharedKey) override;
bool AsPublicECC(AuList<AuUInt8> &out) override;
bool AsPrivateECC(AuList<AuUInt8> &out) override;
EECCCurve GetType() override;
private:
ecc_key _key;
EECCCurve _type;
};
}

View File

@ -0,0 +1,117 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECCGeneric.cpp
Date: 2021-9-17
Author: Reece
***/
#include <RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCGeneric.hpp"
#include "ECCCurves.hpp"
#include "PublicECCImpl.hpp"
namespace Aurora::Crypto::ECC
{
PublicECCImpl::PublicECCImpl(EECCCurve type, ecc_key &key) : _key(key), _type(_type)
{
}
PublicECCImpl::~PublicECCImpl()
{
ecc_free(&_key);
}
EECCCurve PublicECCImpl::GetType()
{
return _type;
}
bool PublicECCImpl::Verify(const Memory::MemoryViewRead &hash,
const Memory::MemoryViewRead &signature)
{
int ok = 0;
if (!hash.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!signature.HasMemory())
{
SysPushErrorParam();
return {};
}
auto ret = ecc_verify_hash_ex(reinterpret_cast<const unsigned char *>(hash.ptr), hash.length,
reinterpret_cast<const unsigned char *>(signature.ptr), signature.length,
LTC_ECCSIG_ETH27, &ok, &_key);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return ok == 1;
}
bool PublicECCImpl::Verify(const Memory::MemoryViewRead &plaintext,
const Memory::MemoryViewRead &signature,
EHashType method)
{
if (!plaintext.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!signature.HasMemory())
{
SysPushErrorParam();
return {};
}
int hash = HashMethodToId(method);
if (hash == 0xFF)
{
SysPushErrorCrypt("invalid hash {}", method);
return false;
}
AuList<AuUInt8> hashVec;
if (!AuTryResize(hashVec, 128))
{
SysPushErrorMem();
return false;
}
unsigned long hashSize = hashVec.size();
auto ret = hash_memory(hash,
reinterpret_cast<const unsigned char *>(plaintext.ptr), plaintext.length,
reinterpret_cast<unsigned char *>(hashVec.data()), &hashSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
return Verify({hashVec}, signature);
}
bool PublicECCImpl::AsPublicECC(AuList<AuUInt8> &out)
{
return Export(true, out);
}
bool PublicECCImpl::Export(bool pub, DerBuffer &out)
{
return ExportECCKey(_key, pub, out);
}
const ecc_key &PublicECCImpl::GetKey()
{
return _key;
}
}

View File

@ -0,0 +1,31 @@
#pragma once
namespace Aurora::Crypto::ECC
{
class PublicECCImpl : public IECCPublic
{
public:
PublicECCImpl(EECCCurve type, ecc_key &key);
~PublicECCImpl();
bool Verify(const Memory::MemoryViewRead &hash,
const Memory::MemoryViewRead &signature) override;
bool Verify(const Memory::MemoryViewRead &plaintext,
const Memory::MemoryViewRead &signature,
EHashType method) override;
bool AsPublicECC(AuList<AuUInt8> &out) override;
bool Export(bool pub, DerBuffer &out);
EECCCurve GetType() override;
const ecc_key &GetKey();
private:
ecc_key _key;
EECCCurve _type;
};
}