AuroraRuntime/Source/Crypto/ECC/ECC.cpp
Reece Wilson 033f7e2453 [+] Aurora::Crypto::X509::CertRequest
[+] Aurora::Crypto::X509::GenerateCertificate
[*] Fix lazily copied gen1 RSA code
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP256R1
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP256K1
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP384R1
[+] Aurora::Crypto::ECC::EECCCurve::eCurveSECP521R1
[*] Unfuck ECC interop
[*] Tls pinning: use mbedtls_ssl_conf_verify for tls1.3 (when mbedtls is in a better state)
2022-11-18 21:03:11 +00:00

280 lines
7.9 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECC.cpp
Date: 2021-9-17
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCGeneric.hpp"
#include "ECCCurves.hpp"
#include "PublicECCImpl.hpp"
#include "PrivateECCImpl.hpp"
#include "ECCX25519Public.hpp"
#include "ECCX25519Private.hpp"
extern "C" int x509_decode_subject_public_key_info_2(const unsigned char *in, unsigned long inlen,
const unsigned long *oid,
void *parameters, unsigned long *parameters_len);
namespace Aurora::Crypto::ECC
{
static bool IsKeyGeneric(const void *ptr, AuUInt length, AuArray<unsigned long, 16> &curveOidm, unsigned long &oidLen)
{
const unsigned long oid[16]
{
1, 2, 840, 10045, 2, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
oidLen = 16;
return x509_decode_subject_public_key_info_2((const unsigned char *)ptr, length, oid, curveOidm.data(), &oidLen) == CRYPT_OK;
}
#define LTC_SET_ASN12(list, index, Type, Data, Size) \
do { \
int LTC_MACRO_temp = (index); \
ltc_asn1_list *LTC_MACRO_list = (list); \
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
LTC_MACRO_list[LTC_MACRO_temp].klass = {}; \
LTC_MACRO_list[LTC_MACRO_temp].pc = {}; \
LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \
} while (0)
static EECCCurve GetEdECCCurveType(const void *ptr, AuUInt length)
{
AuArray<unsigned long, 16> ec;
unsigned long ecLen;
if (IsKeyGeneric(ptr, length, ec, ecLen))
{
return OIDToCurve(ec.data(), ecLen);
}
return EECCCurve::kEnumInvalid;
}
static bool IsBlobCurveX25519(const void *ptr, AuUInt length)
{
const unsigned long oidX25519[16]
{
1, 3, 101, 110,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
return x509_decode_subject_public_key_info_2((const unsigned char *)ptr, length, oidX25519, NULL, 0) == CRYPT_OK;
}
static bool IsBlobCurveEd25519(const void *ptr, AuUInt length)
{
const unsigned long oidEd25519[16]
{
1, 3, 101, 112,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
return x509_decode_subject_public_key_info_2((const unsigned char *)ptr, length, oidEd25519, NULL, 0) == CRYPT_OK;
}
template<bool IsPublic, typename T>
static T New25519ECC(bool isX25519, const Memory::MemoryViewRead &pk, bool cert = false)
{
curve25519_key in {};
int ret;
if (cert)
{
if (!IsPublic)
{
SysPushErrorArg();
return nullptr;
}
ret = isX25519 ? x25519_import_x509(pk.Begin<const unsigned char>(), pk.length, &in) : ed25519_import_x509(pk.Begin<const unsigned char>(), pk.length, &in);
}
else
{
if (IsPublic)
{
ret = isX25519 ? x25519_import(pk.Begin<const unsigned char>(), pk.length, &in) :
ed25519_import(pk.Begin<const unsigned char>(), pk.length, &in);
}
else
{
ret = isX25519 ? x25519_import_pkcs8(pk.Begin<const unsigned char>(), pk.length, nullptr, 0, &in ) :
ed25519_import_pkcs8(pk.Begin<const unsigned char>(), pk.length, nullptr, 0, &in);
}
}
if (ret != CRYPT_OK)
{
return nullptr;
}
if constexpr (IsPublic)
{
return _new PublicCurve25519Impl(isX25519, AuMove(in));
}
else
{
return _new PrivateCurve25519Impl(isX25519, AuMove(in));
}
}
static IECCPrivate *Gen25519ECC(bool isX25519)
{
curve25519_key in {};
int ret;
const int prng_idx = register_prng(&sprng_desc);
prng_state yarrow_prng {};
ret = isX25519 ? x25519_make_key(&yarrow_prng, prng_idx, &in) : ed25519_make_key(&yarrow_prng, prng_idx, &in);
if (ret != CRYPT_OK)
{
SysPushErrorCrypto("{}", ret);
return nullptr;
}
return _new PrivateCurve25519Impl(isX25519, AuMove(in));
}
static void ReleasePublicECC(IECCPublic *pub)
{
switch (pub->GetType())
{
case EECCCurve::eCurveEd25519:
case EECCCurve::eCurveX25519:
AuSafeDelete<PublicCurve25519Impl *>(pub);
return;
default:
AuSafeDelete<PublicECCImpl *>(pub);
return;
}
}
static void ReleasePrivateECC(IECCPrivate *priv)
{
switch (priv->GetType())
{
case EECCCurve::eCurveEd25519:
case EECCCurve::eCurveX25519:
AuSafeDelete<PrivateCurve25519Impl *>(priv);
return;
default:
AuSafeDelete<PrivateECCImpl *>(priv);
return;
}
}
AUKN_SYM IECCPrivate *NewECCNew(EECCCurve curve)
{
switch (curve)
{
case EECCCurve::eCurveEd25519:
return Gen25519ECC(false);
case EECCCurve::eCurveX25519:
return Gen25519ECC(true);
default:
return GenerateNewGenericECC(curve).value_or(nullptr);
}
}
AUKN_SYM IECCPrivate *OpenPrivateECCNew(const AuMemoryViewRead &pk)
{
auto type = GetEdECCCurveType(pk.ptr, pk.length);
//if (type != EECCCurve::eEnumInvalid)
{
if (auto ret = NewStdECC<PrivateECCImpl>(type, pk, false))
{
return ret;
}
}
if (auto pTemp = New25519ECC<false, IECCPrivate *>(true, pk, false))
{
return pTemp;
}
if (auto pTemp = New25519ECC<false, IECCPrivate *>(false, pk, false))
{
return pTemp;
}
return {};
}
AUKN_SYM IECCPublic *OpenPublicECCNew(const AuMemoryViewRead &pk)
{
auto type = GetEdECCCurveType(pk.ptr, pk.length);
//if (type != EECCCurve::eEnumInvalid)
{
if (auto ret = NewStdECC<PublicECCImpl>(type, pk, false))
{
return ret;
}
}
if (auto pTemp = New25519ECC<true, IECCPublic *>(true, pk, false))
{
return pTemp;
}
if (auto pTemp = New25519ECC<true, IECCPublic *>(false, pk, false))
{
return pTemp;
}
return {};
}
AUKN_SYM IECCPublic *OpenPublicECCFromCertNew(const AuMemoryViewRead &certificate)
{
auto type = GetEdECCCurveType(certificate.ptr, certificate.length);
if (type != EECCCurve::eEnumInvalid)
{
if (auto ret = NewStdECC<PublicECCImpl>(type, certificate, true))
{
return ret;
}
}
if (auto pTemp = New25519ECC<true, IECCPublic *>(true, certificate, true))
{
return pTemp;
}
if (auto pTemp = New25519ECC<true, IECCPublic *>(false, certificate, true))
{
return pTemp;
}
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);
}
}