AuroraRuntime/Source/Crypto/ECC/ECCX25519Private.cpp

214 lines
5.4 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) : bIsX25519_(isX25519), key_(key)
{
}
PrivateCurve25519Impl::~PrivateCurve25519Impl()
{
}
bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &plainText,
AuHashing::EHashType method,
Memory::ByteBuffer &out)
{
const int salt = 0;
if (this->bIsX25519_)
{
return false;
}
if (!plainText.HasMemory())
{
SysPushErrorParam();
return {};
}
int hash = ::Crypto::HashMethodToId(method);
if (hash == 0xFF)
{
SysPushErrorCrypt("invalid hash {}", method);
return false;
}
AuByteBuffer hashVec;
if (!AuTryResize(hashVec, 128))
{
SysPushErrorMem();
return false;
}
unsigned long hashSize = 1024;
auto iRet = ::hash_memory(hash,
reinterpret_cast<const unsigned char *>(plainText.ptr), plainText.length,
reinterpret_cast<unsigned char *>(hashVec.data()), &hashSize);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);
return false;
}
return Sign(hashVec, out);
}
bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &hash,
Memory::ByteBuffer &out)
{
if (this->bIsX25519_)
{
return false;
}
if (!hash.HasMemory())
{
SysPushErrorParam();
return {};
}
if (!out.GetOrAllocateLinearWriteable(1024))
{
SysPushErrorMem();
return {};
}
unsigned long len = 1024;
auto iRet = ::ed25519_sign(AuReinterpretCast<const unsigned char *>(hash.ptr),
hash.length,
out.writePtr, &len,
&this->key_);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);
return false;
}
out.writePtr += len;
return true;
}
bool PrivateCurve25519Impl::ECDH(const AuSPtr<IECCPublic> &partnerPublic,
Memory::ByteBuffer &sharedKey)
{
if (!this->bIsX25519_)
{
return false;
}
auto writeView = sharedKey.GetOrAllocateLinearWriteable(128);
if (!writeView)
{
SysPushErrorMem();
return {};
}
if (partnerPublic->GetType() != this->GetType())
{
SysPushErrorCrypto("Can not EDCH with incompatible pairs curve (noting ed25519 requires translation to x25519)");
return false;
}
unsigned long actualSize = 128;
auto iRet = ::x25519_shared_secret(&this->key_,
&(AuReinterpretCast<PublicCurve25519Impl>(partnerPublic)->GetKey()),
sharedKey.writePtr,
&actualSize);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);
return false;
}
sharedKey.writePtr += actualSize;
return true;
}
bool PrivateCurve25519Impl::AsPublicECC(Memory::ByteBuffer &out)
{
auto writeView = out.GetOrAllocateLinearWriteable(4096);
if (!writeView)
{
SysPushErrorMem();
return {};
}
unsigned long actualSize;
int ret;
actualSize = 4096;
if (this->bIsX25519_)
{
ret = x25519_export(out.writePtr, &actualSize, PK_PUBLIC, &this->key_);
}
else
{
ret = ed25519_export(out.writePtr, &actualSize, PK_PUBLIC, &this->key_);
}
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
out.writePtr += actualSize;
return true;
}
bool PrivateCurve25519Impl::AsPrivateECC(Memory::ByteBuffer &out)
{
auto writeView = out.GetOrAllocateLinearWriteable(4096);
if (!writeView)
{
SysPushErrorMem();
return {};
}
unsigned long actualSize;
int ret;
actualSize = 4096;
if (this->bIsX25519_)
{
ret = x25519_export(out.writePtr, &actualSize, PK_PRIVATE, &this->key_);
}
else
{
ret = ed25519_export(out.writePtr, &actualSize, PK_PRIVATE, &this->key_);
}
if (ret != CRYPT_OK)
{
SysPushErrorCrypt("{}", ret);
return false;
}
out.writePtr += actualSize;
return true;
}
EECCCurve PrivateCurve25519Impl::GetType()
{
return this->bIsX25519_ ? EECCCurve::eCurveX25519 : EECCCurve::eCurveEd25519;
}
}