diff --git a/Include/Aurora/Crypto/AES/AES.hpp b/Include/Aurora/Crypto/AES/AES.hpp index af36b783..6d27ceac 100644 --- a/Include/Aurora/Crypto/AES/AES.hpp +++ b/Include/Aurora/Crypto/AES/AES.hpp @@ -9,7 +9,7 @@ namespace Aurora::Crypto::AES { - AUKN_SYM AuUInt GetSafeCipherPadding(const Memory::MemoryViewRead & plainText); + AUKN_SYM AuUInt GetSafeCipherPadding(const Memory::MemoryViewRead &plainText); // Remember: AES works in chunks of 128 bits // IVS are 16 bytes long @@ -20,17 +20,17 @@ namespace Aurora::Crypto::AES // It is not the end of the world if an IV is made public by design // Keys must be random // Initialization vectors could be derived from SHA1, Tiger, or SHA2 digests - AUKN_SYM bool Encrypt(const Memory::MemoryViewRead & plainText, - const Memory::MemoryViewRead & inIv, - const Memory::MemoryViewWrite & outIv, - const Memory::MemoryViewRead & inKey, + AUKN_SYM bool Encrypt(const Memory::MemoryViewRead &plainText, + const Memory::MemoryViewRead &inIv, + const Memory::MemoryViewWrite &outIv, + const Memory::MemoryViewRead &inKey, AuList &out, bool auCoolCodePadding); - AUKN_SYM bool Decrypt(const Memory::MemoryViewRead & cipherText, - const Memory::MemoryViewRead & inIv, - const Memory::MemoryViewWrite & outIv, - const Memory::MemoryViewRead & inKey, - AuList& plainText, + AUKN_SYM bool Decrypt(const Memory::MemoryViewRead &cipherText, + const Memory::MemoryViewRead &inIv, + const Memory::MemoryViewWrite &outIv, + const Memory::MemoryViewRead &inKey, + AuList &plainText, bool auCoolCodePadding); } \ No newline at end of file diff --git a/Include/Aurora/Crypto/CA/CA.hpp b/Include/Aurora/Crypto/CA/CA.hpp index b228287e..f349e4f6 100644 --- a/Include/Aurora/Crypto/CA/CA.hpp +++ b/Include/Aurora/Crypto/CA/CA.hpp @@ -17,18 +17,18 @@ namespace Aurora::Crypto::CA class ICertificateStore { public: - virtual void AddSignature(const AuSPtr& CA, - const AuList& sig, + virtual void AddSignature(const AuSPtr &CA, + const AuList &sig, EHashType method, EPaddingType type) = 0; - virtual void AddPublicCert(const X509::Certificate& cert) = 0; + virtual void AddPublicCert(const X509::Certificate &cert) = 0; /// For future support of http gets of the CA list virtual bool& AllowHTTPTree() = 0; - virtual bool CheckKey(const AuSPtr& pub) = 0; - virtual bool CheckCert(const X509::Certificate& cert) = 0; + virtual bool CheckKey(const AuSPtr &pub) = 0; + virtual bool CheckCert(const X509::Certificate &cert) = 0; }; diff --git a/Include/Aurora/Crypto/ECC/25519/25519.hpp b/Include/Aurora/Crypto/ECC/25519/25519.hpp deleted file mode 100644 index 4fdf5984..00000000 --- a/Include/Aurora/Crypto/ECC/25519/25519.hpp +++ /dev/null @@ -1,13 +0,0 @@ -/*** - Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. - - File: 25519.hpp - Date: 2021-6-11 - Author: Reece -***/ -#pragma once - -namespace Aurora::Crypto::ECC::C25519 -{ - -} \ No newline at end of file diff --git a/Include/Aurora/Crypto/ECC/ECC.hpp b/Include/Aurora/Crypto/ECC/ECC.hpp index 34b2a111..7afa76c1 100644 --- a/Include/Aurora/Crypto/ECC/ECC.hpp +++ b/Include/Aurora/Crypto/ECC/ECC.hpp @@ -7,46 +7,14 @@ ***/ #pragma once +#include "IECCPublic.hpp" +#include "IECCPrivate.hpp" +#include "EECCCurve.hpp" + namespace Aurora::Crypto::ECC { - class IECCPublic - { - public: - virtual bool Verify(const Memory::MemoryViewRead &payload, - const Memory::MemoryViewRead &signature) = 0; - - - virtual bool AsPublicECC(AuList &out) = 0; - }; - - class IECCPrivate - { - public: - virtual bool Sign(const Memory::MemoryViewRead &payload, - EHashType method, - AuList &out) = 0; - - virtual bool ECDH(const AuSPtr &partnerPublic, - AuList &sharedKey) = 0; - - virtual bool AsPublicECC(AuList &out) = 0; - virtual bool AsPrivateECC(AuList &out) = 0; - }; - - enum EECCCurve - { - eCurve256, - eCurve384, - eCurve521, - eCurveX25519, - eCurveEd25519 - }; - 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); -} - -#include "25519/25519.hpp" -#include "NIST/NIST.hpp" \ No newline at end of file +} \ No newline at end of file diff --git a/Include/Aurora/Crypto/ECC/EECCCurve.hpp b/Include/Aurora/Crypto/ECC/EECCCurve.hpp new file mode 100644 index 00000000..3bab0804 --- /dev/null +++ b/Include/Aurora/Crypto/ECC/EECCCurve.hpp @@ -0,0 +1,20 @@ +/*** + Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: EECCCurve.hpp + Date: 2021-9-18 + Author: Reece +***/ +#pragma once + +namespace Aurora::Crypto::ECC +{ + enum EECCCurve + { + eCurve256, + eCurve384, + eCurve521, + eCurveX25519, + eCurveEd25519 + }; +} \ No newline at end of file diff --git a/Include/Aurora/Crypto/ECC/IECCPrivate.hpp b/Include/Aurora/Crypto/ECC/IECCPrivate.hpp new file mode 100644 index 00000000..60da8f35 --- /dev/null +++ b/Include/Aurora/Crypto/ECC/IECCPrivate.hpp @@ -0,0 +1,30 @@ +/*** + Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: IECCPrivate.hpp + Date: 2021-9-18 + Author: Reece +***/ +#pragma once + +namespace Aurora::Crypto::ECC +{ + class IECCPrivate + { + public: + virtual bool Sign(const Memory::MemoryViewRead &plainText, + EHashType method, + AuList &out) = 0; + + virtual bool Sign(const Memory::MemoryViewRead &hash, + AuList &out) = 0; + + virtual bool ECDH(const AuSPtr &partnerPublic, + AuList &sharedKey) = 0; + + virtual bool AsPublicECC(AuList &out) = 0; + virtual bool AsPrivateECC(AuList &out) = 0; + + virtual EECCCurve GetType() override; + }; +} \ No newline at end of file diff --git a/Include/Aurora/Crypto/ECC/IECCPublic.hpp b/Include/Aurora/Crypto/ECC/IECCPublic.hpp new file mode 100644 index 00000000..5c614142 --- /dev/null +++ b/Include/Aurora/Crypto/ECC/IECCPublic.hpp @@ -0,0 +1,27 @@ +/*** + Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: IECCPublic.hpp + Date: 2021-9-18 + Author: Reece +***/ +#pragma once + +namespace Aurora::Crypto::ECC +{ + class IECCPublic + { + public: + virtual bool Verify(const Memory::MemoryViewRead &hash, + const Memory::MemoryViewRead &signature) = 0; + + virtual bool Verify(const Memory::MemoryViewRead &plaintext, + const Memory::MemoryViewRead &signature, + EHashType method) = 0; + + + virtual bool AsPublicECC(AuList &out) = 0; + + virtual EECCCurve GetType() = 0; + }; +} \ No newline at end of file diff --git a/Include/Aurora/Crypto/ECC/NIST/NIST.hpp b/Include/Aurora/Crypto/ECC/NIST/NIST.hpp deleted file mode 100644 index 0943ed7b..00000000 --- a/Include/Aurora/Crypto/ECC/NIST/NIST.hpp +++ /dev/null @@ -1,13 +0,0 @@ -/*** - Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. - - File: NIST.hpp - Date: 2021-6-11 - Author: Reece -***/ -#pragma once - -namespace Aurora::Crypto::ECC::NIST -{ - -} \ No newline at end of file diff --git a/Include/Aurora/Memory/MemoryView.hpp b/Include/Aurora/Memory/MemoryView.hpp index cb5bfced..f15eb049 100644 --- a/Include/Aurora/Memory/MemoryView.hpp +++ b/Include/Aurora/Memory/MemoryView.hpp @@ -73,34 +73,39 @@ namespace Aurora::Memory this->length = length; } - AuUInt ToPointer() + AuUInt ToPointer() const { return reinterpret_cast(ptr); } - AuUInt ToLength() + AuUInt ToLength() const { return length; } template - AuUInt ToCount() + AuUInt ToCount() const { return length / sizeof(T); } template - T *Begin() + T *Begin() const { return reinterpret_cast(ptr); } template - T *End() + T *End() const { return Begin() + ToCount(); } + bool HasMemory() const + { + return ptr && length; + } + Void_t /*const*/ ptr; AuUInt /*const*/ length; }; diff --git a/Include/Aurora/Registry/IRegistry.hpp b/Include/Aurora/Registry/IRegistry.hpp index acf40f2b..c8390ee0 100644 --- a/Include/Aurora/Registry/IRegistry.hpp +++ b/Include/Aurora/Registry/IRegistry.hpp @@ -14,7 +14,7 @@ namespace Aurora::Registry /** * This registry implementation is a fairly reliable, small scale, preference, and app variable database - * Do not consider this as a replacement for a "real" high performance kvp database, it is not, it's a small cache backed document serializer for settings + * Do not consider this as a replacement for a "real" high performance kvp database, it is not, it's a small cache backed document serializer for user profiles * * Basic use case:-------------------------------------------------------------- * -> AllocRegistry() diff --git a/Include/AuroraUtils.hpp b/Include/AuroraUtils.hpp index 6d8e57ff..67153556 100644 --- a/Include/AuroraUtils.hpp +++ b/Include/AuroraUtils.hpp @@ -448,6 +448,28 @@ static inline bool AuTryResize(T &list, AuUInt length) } } +template +static inline bool AuTryDownsize(T &list, AuUInt length) +{ + try + { + if constexpr (std::is_same_v) + { + return list.Resize(length); + } + else + { + list.resize(length); + list.shrink_to_fit(); + return true; + } + } + catch (...) + { + return false; + } +} + static inline AuString AuReplaceAll(AuString &str, const AuString &from, const AuString &to) { size_t start_pos = 0; diff --git a/Source/Crypto/AES/Aes.cpp b/Source/Crypto/AES/Aes.cpp index 06e4c10a..6145fb9c 100644 --- a/Source/Crypto/AES/Aes.cpp +++ b/Source/Crypto/AES/Aes.cpp @@ -13,7 +13,7 @@ namespace Aurora::Crypto::AES { - AUKN_SYM AuUInt GetSafeCipherPadding(const Memory::MemoryViewRead & parameters) + AUKN_SYM AuUInt GetSafeCipherPadding(const Memory::MemoryViewRead ¶meters) { auto tptr = reinterpret_cast(parameters.ptr); @@ -139,10 +139,10 @@ namespace Aurora::Crypto::AES return true; } - AUKN_SYM bool Encrypt(const Memory::MemoryViewRead & plainText, - const Memory::MemoryViewRead & inIv, + AUKN_SYM bool Encrypt(const Memory::MemoryViewRead &plainText, + const Memory::MemoryViewRead &inIv, const Memory::MemoryViewWrite & outIv, - const Memory::MemoryViewRead & inKey, + const Memory::MemoryViewRead &inKey, AuList &out, bool auCoolCodePadding) { @@ -254,10 +254,10 @@ namespace Aurora::Crypto::AES } - AUKN_SYM bool Decrypt(const Memory::MemoryViewRead & cipherText, - const Memory::MemoryViewRead & inIv, - const Memory::MemoryViewWrite & outIv, - const Memory::MemoryViewRead & inKey, + AUKN_SYM bool Decrypt(const Memory::MemoryViewRead &cipherText, + const Memory::MemoryViewRead &inIv, + const Memory::MemoryViewWrite &outIv, + const Memory::MemoryViewRead &inKey, AuList &plainText, bool safe) { diff --git a/Source/Crypto/Crypto.cpp b/Source/Crypto/Crypto.cpp index 68145517..d538fcb1 100644 --- a/Source/Crypto/Crypto.cpp +++ b/Source/Crypto/Crypto.cpp @@ -5,4 +5,5 @@ Date: 2021-6-12 Author: Reece ***/ +#include #include "Crypto.hpp" \ No newline at end of file diff --git a/Source/Crypto/Crypto.hpp b/Source/Crypto/Crypto.hpp index 1ec53445..1c6affa3 100644 --- a/Source/Crypto/Crypto.hpp +++ b/Source/Crypto/Crypto.hpp @@ -7,3 +7,45 @@ ***/ #pragma once +#include +#include +#include + +namespace Aurora::Crypto +{ + static int PaddingToType(EPaddingType type) + { + switch (type) + { + case EPaddingType::ePaddingNone: + return 0; + case EPaddingType::ePKCS_1_5: + return LTC_PKCS_1_V1_5; + case EPaddingType::ePKCS_1_5_NA1: + return LTC_PKCS_1_V1_5_NA1; + case EPaddingType::ePKCS_OAEP: + return LTC_PKCS_1_OAEP; + case EPaddingType::ePKCS_1_PSS: + return LTC_PKCS_1_PSS; + default: + return 0xFF; + } + } + + static int HashMethodToId(EHashType type) + { + switch (type) + { + case EHashType::eTiger_24_192: + return ::Crypto::gHashTiger; + case EHashType::eSHA1_20_160: + return ::Crypto::gHashSha1; + case EHashType::eSHA2_32_256: + return ::Crypto::gHashSha256; + case EHashType::eSHA2_64_512: + return ::Crypto::gHashSha512; + default: + return 0xFF; + } + } +} \ No newline at end of file diff --git a/Source/Crypto/ECC/ECC.hpp b/Source/Crypto/ECC/ECC.hpp index f233ade4..ea742997 100644 --- a/Source/Crypto/ECC/ECC.hpp +++ b/Source/Crypto/ECC/ECC.hpp @@ -6,6 +6,7 @@ Author: Reece ***/ #pragma once +#include "../Crypto.hpp" namespace Aurora::Crypto::ECC { diff --git a/Source/Crypto/ECC/ECCCurves.cpp b/Source/Crypto/ECC/ECCCurves.cpp index 95fe8a25..59ee49cf 100644 --- a/Source/Crypto/ECC/ECCCurves.cpp +++ b/Source/Crypto/ECC/ECCCurves.cpp @@ -8,8 +8,58 @@ #include #include "ECC.hpp" #include "ECCCurves.hpp" +#include namespace Aurora::Crypto::ECC { + static const ltc_ecc_curve kNistp256 = + { + /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + /* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + /* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + /* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + /* cofactor */ 1, + /* OID */ "1.2.840.10045.3.1.7" + }; + + static const ltc_ecc_curve kNistp384 = + { + /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + /* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", + /* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + /* cofactor */ 1, + /* OID */ "1.3.132.0.34" + }; + static const ltc_ecc_curve kNistp521 = + { + /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + /* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + /* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", + /* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + /* cofactor */ 1, + /* OID */ "1.3.132.0.35" + }; + + AuOptional GetECCCurve(EECCCurve curve) + { + switch (curve) + { + case EECCCurve::eCurve256: + return &kNistp256; + case EECCCurve::eCurve384: + return &kNistp384; + case EECCCurve::eCurve521: + return &kNistp521; + default: + return {}; + } + } } \ No newline at end of file diff --git a/Source/Crypto/ECC/ECCCurves.hpp b/Source/Crypto/ECC/ECCCurves.hpp index d14ecc59..33774de3 100644 --- a/Source/Crypto/ECC/ECCCurves.hpp +++ b/Source/Crypto/ECC/ECCCurves.hpp @@ -9,5 +9,5 @@ namespace Aurora::Crypto::ECC { - + AuOptional GetECCCurve(EECCCurve curve); } \ No newline at end of file diff --git a/Source/Crypto/ECC/ECCGeneric.cpp b/Source/Crypto/ECC/ECCGeneric.cpp index 8c963268..4280f50c 100644 --- a/Source/Crypto/ECC/ECCGeneric.cpp +++ b/Source/Crypto/ECC/ECCGeneric.cpp @@ -12,5 +12,347 @@ namespace Aurora::Crypto::ECC { + static bool ExportECCKey(const ecc_key &key, bool pub, DerBuffer &out) + { + if (!AuTryResize(out, 4096)) + { + return false; + } + unsigned long actualSize = out.size(); + auto ret = ecc_export_openssl(out.data(), &actualSize, pub ? PK_PUBLIC : PK_PRIVATE, &key); + + if (ret != CRYPT_OK) + { + SysPushErrorCrypt("{}", ret); + return false; + } + + if (!AuTryResize(out, actualSize)) + { + SysPushErrorMem(); + return false; + } + + return true; + } + + 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 &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()) + { + SysPushErrorParam(); + return {}; + } + + if (!signature.HasMemory()) + { + SysPushErrorParam(); + return {}; + } + + auto ret = ecc_verify_hash_ex(reinterpret_cast(hash.ptr), hash.length, + reinterpret_cast(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 hashVec; + if (!AuTryResize(hashVec, 128)) + { + SysPushErrorMem(); + return false; + } + + unsigned long hashSize = hashVec.size(); + auto ret = hash_memory(hash, + reinterpret_cast(plaintext.ptr), plaintext.length, + reinterpret_cast(hashVec.data()), &hashSize); + if (ret != CRYPT_OK) + { + SysPushErrorCrypt("{}", ret); + return false; + } + + return Verify({hashVec}, signature); + } + + bool PublicECCImpl::AsPublicECC(AuList &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 &out) override; + + bool Sign(const Memory::MemoryViewRead &hash, + AuList &out) override; + + bool ECDH(const AuSPtr &partnerPublic, + AuList &sharedKey) override; + + bool AsPublicECC(AuList &out) override; + + bool AsPrivateECC(AuList &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 &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 hashVec; + + if (!AuTryResize(hashVec, 128)) + { + SysPushErrorMem(); + return false; + } + + unsigned long hashSize = hashVec.size(); + auto ret = hash_memory(hash, + reinterpret_cast(plainText.ptr), plainText.length, + reinterpret_cast(hashVec.data()), &hashSize); + if (ret != CRYPT_OK) + { + SysPushErrorCrypt("{}", ret); + return false; + } + + return Sign(hashVec, out); + } + + bool PrivateECCImpl::Sign(const Memory::MemoryViewRead &hash, + AuList &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(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 &partnerPublic, + AuList &sharedKey) + { + AuList 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(partnerPublic)->GetKey()), sharedSecret.data(), &actualSize); + if (ret != CRYPT_OK) + { + SysPushErrorCrypt("{}", ret); + return false; + } + + sharedSecret.resize(actualSize); + + return true; + } + + bool PrivateECCImpl::AsPublicECC(AuList &out) + { + return ExportECCKey(_key, true, out); + } + + bool PrivateECCImpl::AsPrivateECC(AuList &out) + { + return ExportECCKey(_key, false, out); + } + + template + static Type_t *NewECC(EECCCurve curve, const AuList &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; + } } \ No newline at end of file diff --git a/Source/Crypto/RSA/RSA.hpp b/Source/Crypto/RSA/RSA.hpp index a7b814c7..a1a9fa58 100644 --- a/Source/Crypto/RSA/RSA.hpp +++ b/Source/Crypto/RSA/RSA.hpp @@ -6,9 +6,7 @@ Author: Reece ***/ #pragma once -#include -#include -#include +#include "../Crypto.hpp" namespace Aurora::Crypto::RSA { @@ -85,40 +83,4 @@ namespace Aurora::Crypto::RSA return true; } - - static int PaddingToType(EPaddingType type) - { - switch (type) - { - case EPaddingType::ePaddingNone: - return 0; - case EPaddingType::ePKCS_1_5: - return LTC_PKCS_1_V1_5; - case EPaddingType::ePKCS_1_5_NA1: - return LTC_PKCS_1_V1_5_NA1; - case EPaddingType::ePKCS_OAEP: - return LTC_PKCS_1_OAEP; - case EPaddingType::ePKCS_1_PSS: - return LTC_PKCS_1_PSS; - default: - return 0xFF; - } - } - - static int HashMethodToId(EHashType type) - { - switch (type) - { - case EHashType::eTiger_24_192: - return ::Crypto::gHashTiger; - case EHashType::eSHA1_20_160: - return ::Crypto::gHashSha1; - case EHashType::eSHA2_32_256: - return ::Crypto::gHashSha256; - case EHashType::eSHA2_64_512: - return ::Crypto::gHashSha512; - default: - return 0xFF; - } - } } diff --git a/Source/Crypto/RSA/RSAPrivate.cpp b/Source/Crypto/RSA/RSAPrivate.cpp index b932a1bb..94fa9b55 100644 --- a/Source/Crypto/RSA/RSAPrivate.cpp +++ b/Source/Crypto/RSA/RSAPrivate.cpp @@ -30,6 +30,12 @@ namespace Aurora::Crypto::RSA { prng_state yarrow_prng; const int salt = 0; + + if (!payload.HasMemory()) + { + SysPushErrorParam(); + return {}; + } int padding = PaddingToType(type); if (padding == 0xFF) @@ -88,10 +94,16 @@ namespace Aurora::Crypto::RSA return true; } - bool PrivateRSA::Decrypt(const Memory::MemoryViewRead & payload, + bool PrivateRSA::Decrypt(const Memory::MemoryViewRead &payload, EPaddingType type, AuList &out) { + if (!payload.HasMemory()) + { + SysPushErrorParam(); + return {}; + } + int padding = PaddingToType(type); if (padding == 0xFF) { diff --git a/Source/Crypto/RSA/RSAPublic.cpp b/Source/Crypto/RSA/RSAPublic.cpp index 60f0749d..8c8ebc0b 100644 --- a/Source/Crypto/RSA/RSAPublic.cpp +++ b/Source/Crypto/RSA/RSAPublic.cpp @@ -25,11 +25,24 @@ namespace Aurora::Crypto::RSA } } - bool PublicRSA::Verify(const Memory::MemoryViewRead & payload, - const Memory::MemoryViewRead & signature, + bool PublicRSA::Verify(const Memory::MemoryViewRead &payload, + const Memory::MemoryViewRead &signature, EHashType method, EPaddingType type) { + + if (!payload.HasMemory()) + { + SysPushErrorParam(); + return {}; + } + + if (!signature.HasMemory()) + { + SysPushErrorParam(); + return {}; + } + int padding = PaddingToType(type); if (padding == 0xFF) { @@ -75,11 +88,17 @@ namespace Aurora::Crypto::RSA return ok == 1; } - bool PublicRSA::Encrypt(const Memory::MemoryViewRead & plainText, + bool PublicRSA::Encrypt(const Memory::MemoryViewRead &plainText, EPaddingType type, AuList &out) { prng_state yarrow_prng; + + if (!plainText.HasMemory()) + { + SysPushErrorParam(); + return {}; + } int padding = PaddingToType(type); if (padding == 0xFF) diff --git a/Source/IO/FS/Async.NT.cpp b/Source/IO/FS/Async.NT.cpp index a6388d96..1d92b810 100644 --- a/Source/IO/FS/Async.NT.cpp +++ b/Source/IO/FS/Async.NT.cpp @@ -120,7 +120,6 @@ namespace Aurora::IO::FS return true; } - AuSPtr NtAsyncFileStream::GetHandle() { return handle_; @@ -184,6 +183,10 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::StartRead(AuUInt64 offset, void *buffer, AuUInt32 length) { + if (this->latch_) + { + return {}; + } this->latch_ = {}; this->lastAbstractStat_ = length; this->lastAbstractOffset_ = offset; @@ -196,6 +199,10 @@ namespace Aurora::IO::FS bool NtAsyncFileTransaction::StartWrite(AuUInt64 offset, const void *buffer, AuUInt32 length) { + if (this->latch_) + { + return {}; + } this->latch_ = {}; this->lastAbstractStat_ = length; this->lastAbstractOffset_ = offset; diff --git a/readme.txt b/readme.txt index ec61d46c..2a120dc8 100644 --- a/readme.txt +++ b/readme.txt @@ -86,10 +86,10 @@ Problem one: Problem Two: Moving to or from linux, macos, bsd, and win32 under varous kernels, there is no one - standard (even in posix land) for the key thread primitives everybody be using. + standard (even in posix land) for the key thread primitives. Bonus point NT: - The userland CriticalSection set of APIs generally suck, lacking timeouts and try lock + The userland CriticalSection/CV set of APIs suck, lacking timeouts and try lock Bonus point UNIX: No wait multiple mechanism @@ -134,21 +134,23 @@ The networking stack supports a handful of architectural paradigms We suspect most developers delegate IO to a worker thread, don't wish to deal with an extern async model nor want excessively buffered streams, therefore the FIO API implements a read/write -seekable C-like interface in a file stream object. An alternative AFIO namespace exists for the -few platforms that provide posix AIO, win32 overlap, or linux's io syscalls. +seekable C-like file stream interface. An alternative AFIO namespace exists for the few platforms +that provide posix AIO, win32 overlap, or linux's io syscalls. -File stream, buffered read/write utilities, stat, exists, copy, move, remove, and itr backed +File stream, buffered read/write utilities, stat, exists, copy, move, remove, and readdir backed by the best platform specific blocking apis. + Guaranteed 64-bit file pointer safety across seek functions. + [Open]Write to a file under a path of missing directories guarantees creation of missing sub -directorieis. +directories. ### Paths We assume all paths are messy. Incorrect splitters, double splitters, relative paths, and keywords are resolved internally. No such URL or path builder, data structure to hold a tokenized representation, or similar concept exists in the codebase. All string 'paths' are -simply expanded, similar to 'fullpath', at time of usage. +simply expanded, similar to MSCRT 'fullpath'/UNIX 'realpath', at time of usage. Path tokens include: [0] == '.' = cwd @@ -184,14 +186,15 @@ process spawning, file opening, and url opening functionality. ## Locale Encoding and decoding UTF-8, UTF-16, UTF-32, GBK, GB-2312, and SJIS support using platform -specific APIs. Fetch system language and country backed by environment variables, platform -specific apis, the unix locale env variable, and/or the provided overload mechanism. +specific APIs. Fetch system language and country backed by environment variables, the OS +system configuration, the unix locale env variable, and/or the provided overload mechanism. ## Philosophies - Assume C++17 language support in the language driver -- To avoid reinventing the wheel, solve the large issues nobody is tackling +- To avoid reinventing the wheel, solve the large issues nobody is tackling, and accept + third party solutions weighted against relevant legal constraints and developer time - Use AuXXX type bindings for std types, allow customers to overload the std namespace @@ -220,4 +223,4 @@ specific apis, the unix locale env variable, and/or the provided overload mechan -> Writing a [D]TLS/allocator stack would take too much time -> Linking against external allocators, small cross-platform utilities, and so on is probably fine - -> Feel free to shim libcurl instead of inventing yet another http stack + -> Shim libcurl instead of inventing yet another http stack