AuroraRuntime/Source/Crypto/ECC/ECCX25519Private.cpp
Reece b29be7b2d5 [*] Hardened line bufferer
[+] Unstaged changes from last commit
2022-02-19 11:50:14 +00:00

230 lines
5.5 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECCX25519Private.cpp
Date: 2022-2-15
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "ECC.hpp"
#include "ECCX25519Private.hpp"
#include "ECCX25519Public.hpp"
namespace Aurora::Crypto::ECC
{
PrivateCurve25519Impl::PrivateCurve25519Impl(bool isX25519, curve25519_key &&key) : isX25519_(isX25519), key_(key)
{
}
PrivateCurve25519Impl::~PrivateCurve25519Impl()
{
}
bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &plainText,
EHashType method,
Memory::ByteBuffer &out)
{
const int salt = 0;
if (this->isX25519_)
{
return false;
}
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;
}
AuByteBuffer 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 PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &hash,
Memory::ByteBuffer &out)
{
if (this->isX25519_)
{
return false;
}
if (!hash.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!AuTryResize(out, 1024))
{
SysPushErrorMem();
return false;
}
unsigned long len = out.size();
auto ret = ed25519_sign(reinterpret_cast<const unsigned char *>(hash.ptr), hash.length,
out.data(), &len,
&key_);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(out, len))
{
SysPushErrorMem();
return false;
}
return true;
}
bool PrivateCurve25519Impl::ECDH(const AuSPtr<IECCPublic> &partnerPublic,
Memory::ByteBuffer &sharedKey)
{
if (!this->isX25519_)
{
return false;
}
AuByteBuffer 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 = x25519_shared_secret(&key_, &(AuReinterpretCast<PublicCurve25519Impl>(partnerPublic)->GetKey()), sharedSecret.data(), &actualSize);
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(sharedSecret, actualSize))
{
SysPushErrorMem();
return false;
}
return true;
}
bool PrivateCurve25519Impl::AsPublicECC(Memory::ByteBuffer &out)
{
if (!AuTryResize(out, 1024))
{
return false;
}
unsigned long actualSize;
int ret;
if (this->isX25519_)
{
actualSize = out.size();
ret = x25519_export(out.data(), &actualSize, PK_PUBLIC, &this->key_);
}
else
{
actualSize = out.size();
ret = ed25519_export(out.data(), &actualSize, PK_PUBLIC, &this->key_);
}
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(out, actualSize))
{
SysPushErrorMem();
return false;
}
return true;
}
bool PrivateCurve25519Impl::AsPrivateECC(Memory::ByteBuffer &out)
{
if (!AuTryResize(out, 1024))
{
return false;
}
unsigned long actualSize;
int ret;
if (this->isX25519_)
{
actualSize = out.size();
ret = x25519_export(out.data(), &actualSize, PK_PRIVATE, &this->key_);
}
else
{
actualSize = out.size();
ret = ed25519_export(out.data(), &actualSize, PK_PRIVATE, &this->key_);
}
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
if (!AuTryResize(out, actualSize))
{
SysPushErrorMem();
return false;
}
return true;
}
EECCCurve PrivateCurve25519Impl::GetType()
{
return this->isX25519_ ? EECCCurve::eCurveX25519 : EECCCurve::eCurveEd25519;
}
}