AuroraRuntime/Source/Crypto/ECC/PrivateECCImpl.cpp
Reece Wilson 67905a4192 [+] Network + Protocol + TLS - Initial Commit
=============================================================================
Network ]====================================================================
=============================================================================

[+] Added (very) early Aurora::IO::Net implementation
[+] AuNet::EHostnameType
[+] AuNet::EIPProtocol
[+] AuNet::ENetworkError
[+] AuNet::ETransportProtocol
[+] AuNet::INetInterface
[+] AuNet::INetSrvDatagram
[+] AuNet::INetSrvResolve
[+] AuNet::INetSrvSockets
[+] AuNet::INetSrvWorkers
[+] AuNet::INetWorker
[+] AuNet::IPAddress
[+] AuNet::IResolver
[+] AuNet::ISocket
[+] AuNet::IResolver
[+] AuNet::ISocketBase
[+] AuNet::ISocketChannel
[+] AuNet::ISocketDriver
[+] AuNet::ISocketDriverFactory
[+] AuNet::ISocketServer
[+] AuNet::ISocketServerDriver
[+] AuNet::NetEndpoint
[+] AuNet::NetError
[+] AuNet::NetHostname
(+implementation)

=============================================================================
Protocol ]===================================================================
=============================================================================

[+] IProtocolInterceptor
[+] IProtocolInterceptorEx
[+] IProtocolStack
(+implementation)

=============================================================================
TLS ]========================================================================
=============================================================================

[+] ITLSContext
[+] TLSProtocolRecv
[+] TLSProtocolSend
(+implementation)

=============================================================================
IO Bug Fixes ]===============================================================
=============================================================================

[*] IOProcessor::SubmitIOWorkItem should signal the CvEvent, forcing at least once future tick (wont optimize with if in tick & not yet dispatched work items)
[*] Split IOPipeWork in into IOPipeProcessor header
[+] IOPipeWork::GetBuffer (internal reallocation)
[*] Harden against IAsyncTransactions without a loop source
[*] Missing null `if (processor->listener)` in IOProcessor
[*] Solved some soft-lock conditions under Linux's LoopQueue (added deferred commits)
[*] Quick hack: IOProcessor::HasItems() should OR the early can-tick check function.

=============================================================================
Other ]======================================================================
=============================================================================

[+] Linux: LSSignalCatcher
[+] `static void AuResetMember(Aurora::Memory::ByteBuffer &ref)` for AuROXTL
[*] Attempt to enforce a normalization and don't overwrite-readptr-under-istreamwriters policy in ByteBuffer_ReadWrite (circular buffers)
[*] Bad ECC ctors

=============================================================================
Known issues ]===============================================================
=============================================================================

> Linux net is nowhere near done
> UDP socket emulation layer isn't implemented
> Ciphersuite API is a stub
> Private key API is a stub
> ...therefore no TLS servers
> Missing thread safety precautions under net
> Net implementation is still beri early
2022-08-28 20:02:06 +01:00

161 lines
4.1 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECCGeneric.cpp
Date: 2021-9-17
Author: Reece
***/
#include <Source/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), _type(type)
{
}
PrivateECCImpl::~PrivateECCImpl()
{
ecc_free(&_key);
}
EECCCurve PrivateECCImpl::GetType()
{
return _type;
}
bool PrivateECCImpl::Sign(const AuMemoryViewRead &plainText,
EHashType method,
AuByteBuffer &out)
{
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;
}
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 PrivateECCImpl::Sign(const AuMemoryViewRead &hash,
AuByteBuffer &out)
{
prng_state yarrow_prng;
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,
AuByteBuffer &sharedKey)
{
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 = ecc_shared_secret(&_key, &(AuReinterpretCast<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(AuByteBuffer &out)
{
return ExportECCKey(_key, true, out);
}
bool PrivateECCImpl::AsPrivateECC(AuByteBuffer &out)
{
return ExportECCKey(_key, false, out);
}
}