[+] More crypto copypasta
This commit is contained in:
parent
0bcaddc5c7
commit
60d2c59d6e
@ -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);
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
163
Source/Crypto/ECC/PrivateECCImpl.cpp
Normal file
163
Source/Crypto/ECC/PrivateECCImpl.cpp
Normal 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);
|
||||
}
|
||||
}
|
31
Source/Crypto/ECC/PrivateECCImpl.hpp
Normal file
31
Source/Crypto/ECC/PrivateECCImpl.hpp
Normal 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;
|
||||
};
|
||||
}
|
117
Source/Crypto/ECC/PublicECCImpl.cpp
Normal file
117
Source/Crypto/ECC/PublicECCImpl.cpp
Normal 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;
|
||||
}
|
||||
}
|
31
Source/Crypto/ECC/PublicECCImpl.hpp
Normal file
31
Source/Crypto/ECC/PublicECCImpl.hpp
Normal 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;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user