diff options
| author | Per Larsson <[email protected]> | 2022-02-02 19:08:10 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-02-02 19:08:10 +0100 |
| commit | 10ab6d8c768b54dfcd085ec94aa959dc9d1103ce (patch) | |
| tree | c48a96d8a1ea8d4267906af76e72e1e95f70fc78 /zencore | |
| parent | Changed OIDC token endpoint. (diff) | |
| parent | Merge branch 'main' of https://github.com/EpicGames/zen (diff) | |
| download | zen-10ab6d8c768b54dfcd085ec94aa959dc9d1103ce.tar.xz zen-10ab6d8c768b54dfcd085ec94aa959dc9d1103ce.zip | |
Merged main.
Diffstat (limited to 'zencore')
| -rw-r--r-- | zencore/compactbinary.cpp | 4 | ||||
| -rw-r--r-- | zencore/crypto.cpp | 235 | ||||
| -rw-r--r-- | zencore/filesystem.cpp | 2 | ||||
| -rw-r--r-- | zencore/include/zencore/crypto.h | 50 | ||||
| -rw-r--r-- | zencore/include/zencore/refcount.h | 7 | ||||
| -rw-r--r-- | zencore/include/zencore/trace.h | 1 | ||||
| -rw-r--r-- | zencore/include/zencore/zencore.h | 15 | ||||
| -rw-r--r-- | zencore/iobuffer.cpp | 2 | ||||
| -rw-r--r-- | zencore/thread.cpp | 6 | ||||
| -rw-r--r-- | zencore/trace.cpp | 11 | ||||
| -rw-r--r-- | zencore/zencore.cpp | 2 |
11 files changed, 316 insertions, 19 deletions
diff --git a/zencore/compactbinary.cpp b/zencore/compactbinary.cpp index cded378a1..902ec26c8 100644 --- a/zencore/compactbinary.cpp +++ b/zencore/compactbinary.cpp @@ -54,7 +54,7 @@ GetPlatformToDateTimeBiasInSeconds() #if ZEN_PLATFORM_WINDOWS const uint64_t PlatformEpochYear = 1601; #else - const uint64_t PlatformEpochYear = 1970; + const uint64_t PlatformEpochYear = 1970; #endif const uint64_t DateTimeEpochYear = 1; return uint64_t(double(PlatformEpochYear - DateTimeEpochYear) * 365.2425) * 86400; @@ -71,7 +71,7 @@ DateTime::Now() GetSystemTimeAsFileTime(&SysTime); return DateTime{(EpochBias * SecsTo100nsTicks) + (uint64_t(SysTime.dwHighDateTime) << 32) | SysTime.dwLowDateTime}; #else - int64_t SecondsSinceUnixEpoch = time(nullptr); + int64_t SecondsSinceUnixEpoch = time(nullptr); return DateTime{(EpochBias + SecondsSinceUnixEpoch) * SecsTo100nsTicks}; #endif } diff --git a/zencore/crypto.cpp b/zencore/crypto.cpp new file mode 100644 index 000000000..880d7b495 --- /dev/null +++ b/zencore/crypto.cpp @@ -0,0 +1,235 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <zencore/crypto.h> +#include <zencore/intmath.h> +#include <zencore/testing.h> + +#include <openssl/conf.h> +#include <openssl/err.h> +#include <openssl/evp.h> + +#include <string> +#include <string_view> + +#if ZEN_PLATFORM_WINDOWS +# pragma comment(lib, "crypt32.lib") +# pragma comment(lib, "ws2_32.lib") +#endif + +namespace zen { + +class NullCipher final : public SymmetricCipher +{ +public: + NullCipher() = default; + virtual ~NullCipher() = default; + + virtual bool Initialize(MemoryView, MemoryView) override final { return true; } + + virtual CipherSettings Settings() override final { return {}; } + + virtual MemoryView Encrypt(MemoryView Data, MutableMemoryView) override final { return Data; } + + virtual MemoryView Decrypt(MemoryView Data, MutableMemoryView) override final { return Data; } +}; + +std::unique_ptr<SymmetricCipher> +MakeNullCipher() +{ + return std::make_unique<NullCipher>(); +} + +#if ZEN_PLATFORM_WINDOWS +class Aes final : public SymmetricCipher +{ +public: + Aes(const EVP_CIPHER* Cipher = EVP_aes_256_cbc()) : m_Cipher(Cipher) + { + ZEN_ASSERT(Cipher); + m_KeySize = static_cast<size_t>(EVP_CIPHER_key_length(m_Cipher)); + m_InitVectorSize = static_cast<size_t>(EVP_CIPHER_iv_length(m_Cipher)); + m_BlockSize = static_cast<size_t>(EVP_CIPHER_block_size(m_Cipher)); + } + + virtual ~Aes() + { + if (m_EncryptionCtx) + { + EVP_CIPHER_CTX_free(m_EncryptionCtx); + } + + if (m_DecryptionCtx) + { + EVP_CIPHER_CTX_free(m_DecryptionCtx); + } + } + + virtual bool Initialize(MemoryView Key, MemoryView InitVector) override final + { + ZEN_ASSERT(m_EncryptionCtx == nullptr && m_DecryptionCtx == nullptr); + ZEN_ASSERT(Key.GetSize() == m_KeySize); + ZEN_ASSERT(InitVector.GetSize() == m_InitVectorSize); + + m_EncryptionCtx = EVP_CIPHER_CTX_new(); + m_DecryptionCtx = EVP_CIPHER_CTX_new(); + + if (int ErrorCode = EVP_EncryptInit_ex(m_EncryptionCtx, + m_Cipher, + nullptr, + reinterpret_cast<const unsigned char*>(Key.GetData()), + reinterpret_cast<const unsigned char*>(InitVector.GetData())); + ErrorCode != 1) + { + return false; + } + + if (int ErrorCode = EVP_DecryptInit_ex(m_DecryptionCtx, + m_Cipher, + nullptr, + reinterpret_cast<const unsigned char*>(Key.GetData()), + reinterpret_cast<const unsigned char*>(InitVector.GetData())); + ErrorCode != 1) + { + return false; + } + + return true; + } + + virtual CipherSettings Settings() override final + { + return {.KeySize = m_KeySize, .InitVectorSize = m_InitVectorSize, .BlockSize = m_BlockSize}; + } + + virtual MemoryView Encrypt(MemoryView Data, MutableMemoryView EncryptionBuffer) + { + ZEN_ASSERT(m_EncryptionCtx); + + const uint64_t InputSize = Data.GetSize(); + const uint64_t NeededSize = RoundUp(InputSize, m_BlockSize); + + if (NeededSize > EncryptionBuffer.GetSize()) + { + return MemoryView(); + } + + int TotalSize = 0; + int EncryptedSize = 0; + int ErrorCode = EVP_EncryptUpdate(m_EncryptionCtx, + reinterpret_cast<unsigned char*>(EncryptionBuffer.GetData()), + &EncryptedSize, + reinterpret_cast<const unsigned char*>(Data.GetData()), + static_cast<int>(Data.GetSize())); + + if (ErrorCode != 1) + { + return MemoryView(); + } + + TotalSize = EncryptedSize; + MutableMemoryView Remaining = EncryptionBuffer.RightChop(uint64_t(EncryptedSize)); + + ErrorCode = EVP_EncryptFinal_ex(m_EncryptionCtx, reinterpret_cast<unsigned char*>(Remaining.GetData()), &EncryptedSize); + + if (ErrorCode != 1) + { + return MemoryView(); + } + + TotalSize += EncryptedSize; + + return EncryptionBuffer.Left(uint64_t(TotalSize)); + } + + virtual MemoryView Decrypt(MemoryView Data, MutableMemoryView DecryptionBuffer) override final + { + ZEN_ASSERT(m_DecryptionCtx); + + int TotalSize = 0; + int DecryptedSize = 0; + int ErrorCode = EVP_DecryptUpdate(m_DecryptionCtx, + reinterpret_cast<unsigned char*>(DecryptionBuffer.GetData()), + &DecryptedSize, + reinterpret_cast<const unsigned char*>(Data.GetData()), + static_cast<int>(Data.GetSize())); + + if (ErrorCode != 1) + { + return MemoryView(); + } + + TotalSize = DecryptedSize; + MutableMemoryView Remaining = DecryptionBuffer.RightChop(uint64_t(DecryptedSize)); + + ErrorCode = EVP_DecryptFinal_ex(m_DecryptionCtx, reinterpret_cast<unsigned char*>(Remaining.GetData()), &DecryptedSize); + + TotalSize += DecryptedSize; + + return DecryptionBuffer.Left(uint64_t(TotalSize)); + } + +private: + const EVP_CIPHER* m_Cipher = nullptr; + EVP_CIPHER_CTX* m_EncryptionCtx = nullptr; + EVP_CIPHER_CTX* m_DecryptionCtx = nullptr; + size_t m_BlockSize = 0; + size_t m_KeySize = 0; + size_t m_InitVectorSize = 0; +}; + +std::unique_ptr<SymmetricCipher> +MakeAesCipher() +{ + return std::make_unique<Aes>(); +} + +#endif // ZEN_PLATFORM_WINDOWS + +#if ZEN_WITH_TESTS + +using namespace std::literals; + +void +crypto_forcelink() +{ +} + +TEST_CASE("crypto.aes") +{ + SUBCASE("basic") + { +# if ZEN_PLATFORM_WINDOWS + auto Cipher = std::make_unique<Aes>(); + + std::string_view PlainText = "The quick brown fox jumps over the lazy dog"sv; + + std::vector<uint8_t> Key = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + std::vector<uint8_t> Seed = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + + std::vector<uint8_t> EncryptionBuffer; + std::vector<uint8_t> DecryptionBuffer; + + bool Ok = Cipher->Initialize(MakeMemoryView(Key), MakeMemoryView(Seed)); + CHECK(Ok); + + EncryptionBuffer.resize(PlainText.size() + Cipher->Settings().BlockSize); + DecryptionBuffer.resize(PlainText.size() + Cipher->Settings().BlockSize); + + MemoryView EncryptedView = Cipher->Encrypt(MakeMemoryView(PlainText), MakeMutableMemoryView(EncryptionBuffer)); + CHECK(EncryptedView.IsEmpty() == false); + + MemoryView DecryptedView = Cipher->Decrypt(EncryptedView, MakeMutableMemoryView(DecryptionBuffer)); + CHECK(DecryptedView.IsEmpty() == false); + + std::string_view EncryptedDecryptedText = + std::string_view(reinterpret_cast<const char*>(DecryptedView.GetData()), DecryptedView.GetSize()); + + CHECK(EncryptedDecryptedText == PlainText); + } +# endif +} + +#endif + +} // namespace zen diff --git a/zencore/filesystem.cpp b/zencore/filesystem.cpp index ee49aa474..ab606301c 100644 --- a/zencore/filesystem.cpp +++ b/zencore/filesystem.cpp @@ -703,7 +703,7 @@ ScanFile(std::filesystem::path Path, const uint64_t ChunkSize, std::function<voi ProcessFunc(ReadBuffer.data(), dwBytesRead); } #else - int Fd = open(Path.c_str(), O_RDONLY | O_CLOEXEC); + int Fd = open(Path.c_str(), O_RDONLY | O_CLOEXEC); if (Fd < 0) { return false; diff --git a/zencore/include/zencore/crypto.h b/zencore/include/zencore/crypto.h new file mode 100644 index 000000000..4d6ddba47 --- /dev/null +++ b/zencore/include/zencore/crypto.h @@ -0,0 +1,50 @@ + +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/memory.h> +#include <zencore/zencore.h> + +#include <memory> + +namespace zen { + +/** + * Experimental interface for a symmetric encryption/decryption algorithm. + * Currenlty only AES 256 bit CBC is supported using OpenSSL. + */ +class SymmetricCipher +{ +public: + virtual ~SymmetricCipher() = default; + + virtual bool Initialize(MemoryView Key, MemoryView InitVector) = 0; + + struct CipherSettings + { + size_t KeySize = 0; + size_t InitVectorSize = 0; + size_t BlockSize = 0; + }; + + virtual CipherSettings Settings() = 0; + + virtual MemoryView Encrypt(MemoryView Data, MutableMemoryView EncryptionBuffer) = 0; + + virtual MemoryView Decrypt(MemoryView Data, MutableMemoryView DecryptionBuffer) = 0; +}; + +std::unique_ptr<SymmetricCipher> MakeNullCipher(); + +#if ZEN_PLATFORM_WINDOWS +/** + * Create a new instance of a 256 bit AES CBC symmetric cipher. + * NOTE: Currenlty only tested on Windows + */ +std::unique_ptr<SymmetricCipher> MakeAesCipher(); +#endif + +void crypto_forcelink(); + +} // namespace zen diff --git a/zencore/include/zencore/refcount.h b/zencore/include/zencore/refcount.h index 254a22db5..7befbb338 100644 --- a/zencore/include/zencore/refcount.h +++ b/zencore/include/zencore/refcount.h @@ -114,7 +114,7 @@ public: private: T* m_Ref = nullptr; - template <typename U> + template<typename U> friend class RefPtr; }; @@ -135,8 +135,9 @@ public: inline ~Ref() { m_Ref && m_Ref->Release(); } template<typename DerivedType> - requires DerivedFrom<DerivedType, T> - inline Ref(const Ref<DerivedType>& Rhs) : Ref(Rhs.m_Ref) {} + requires DerivedFrom<DerivedType, T> inline Ref(const Ref<DerivedType>& Rhs) : Ref(Rhs.m_Ref) + { + } [[nodiscard]] inline bool IsNull() const { return m_Ref == nullptr; } inline explicit operator bool() const { return m_Ref != nullptr; } diff --git a/zencore/include/zencore/trace.h b/zencore/include/zencore/trace.h index f28fdeeaf..0af490f23 100644 --- a/zencore/include/zencore/trace.h +++ b/zencore/include/zencore/trace.h @@ -22,6 +22,7 @@ enum class TraceType { File, Network, + None }; void TraceInit(const char* HostOrPath, TraceType Type); diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 023b237cd..bd5e5a531 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -153,7 +153,7 @@ concept DerivedFrom = std::derived_from<D, B>; template<class T> concept Integral = std::is_integral_v<T>; template<class T> -concept SignedIntegral = Integral<T> && std::is_signed_v<T>; +concept SignedIntegral = Integral<T>&& std::is_signed_v<T>; template<class T> concept UnsignedIntegral = Integral<T> && !std::is_signed_v<T>; template<class F, class... A> @@ -162,7 +162,7 @@ concept Invocable = requires(F&& f, A&&... a) std::invoke(std::forward<F>(f), std::forward<A>(a)...); }; template<class D, class B> -concept DerivedFrom = std::is_base_of_v<B, D> && std::is_convertible_v<const volatile D*, const volatile B*>; +concept DerivedFrom = std::is_base_of_v<B, D>&& std::is_convertible_v<const volatile D*, const volatile B*>; #endif #if defined(__cpp_lib_ranges) @@ -239,13 +239,12 @@ static_assert(sizeof(wchar_t) == 2, "wchar_t is expected to be two bytes in size # define ZEN_DEBUG_SECTION ZEN_CODE_SECTION(".zcold") #endif -namespace zen +namespace zen { +class AssertException : public std::logic_error { - class AssertException : public std::logic_error - { - public: - AssertException(const char* Msg) : std::logic_error(Msg) {} - }; +public: + AssertException(const char* Msg) : std::logic_error(Msg) {} +}; } // namespace zen diff --git a/zencore/iobuffer.cpp b/zencore/iobuffer.cpp index e2aaa3169..57abbfb48 100644 --- a/zencore/iobuffer.cpp +++ b/zencore/iobuffer.cpp @@ -513,7 +513,7 @@ IoBufferBuilder::MakeFromTemporaryFile(const std::filesystem::path& FileName) Handle = DataFile.Detach(); #else - int Fd = open(FileName.native().c_str(), O_RDONLY); + int Fd = open(FileName.native().c_str(), O_RDONLY); if (Fd < 0) { return {}; diff --git a/zencore/thread.cpp b/zencore/thread.cpp index 2cc4d8a96..a123eec82 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -163,7 +163,7 @@ Event::Set() #if ZEN_PLATFORM_WINDOWS SetEvent(m_EventHandle); #else - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = (EventInner*)m_EventHandle; { std::unique_lock Lock(Inner->Mutex); Inner->bSet = true; @@ -316,7 +316,7 @@ NamedEvent::Close() #if ZEN_PLATFORM_WINDOWS CloseHandle(m_EventHandle); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC - int Fd = int(intptr_t(m_EventHandle) & 0xffff'ffff); + int Fd = int(intptr_t(m_EventHandle) & 0xffff'ffff); if (flock(Fd, LOCK_EX | LOCK_NB) == 0) { @@ -580,7 +580,7 @@ ProcessHandle::Terminate(int ExitCode) bSuccess = (WaitResult != WAIT_OBJECT_0); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC ZEN_UNUSED(ExitCode); - bSuccess = (kill(m_Pid, SIGKILL) == 0); + bSuccess = (kill(m_Pid, SIGKILL) == 0); #endif if (!bSuccess) diff --git a/zencore/trace.cpp b/zencore/trace.cpp index 6a35571e6..788dcec07 100644 --- a/zencore/trace.cpp +++ b/zencore/trace.cpp @@ -12,6 +12,8 @@ void TraceInit(const char* HostOrPath, TraceType Type) { + bool EnableEvents = true; + switch (Type) { case TraceType::Network: @@ -21,6 +23,10 @@ TraceInit(const char* HostOrPath, TraceType Type) case TraceType::File: trace::WriteTo(HostOrPath); break; + + case TraceType::None: + EnableEvents = false; + break; } trace::FInitializeDesc Desc = { @@ -28,7 +34,10 @@ TraceInit(const char* HostOrPath, TraceType Type) }; trace::Initialize(Desc); - trace::ToggleChannel("cpu", true); + if (EnableEvents) + { + trace::ToggleChannel("cpu", true); + } } #endif // ZEN_WITH_TRACE diff --git a/zencore/zencore.cpp b/zencore/zencore.cpp index 19acdd1f5..8b45d273d 100644 --- a/zencore/zencore.cpp +++ b/zencore/zencore.cpp @@ -16,6 +16,7 @@ #include <zencore/compactbinarypackage.h> #include <zencore/compositebuffer.h> #include <zencore/compress.h> +#include <zencore/crypto.h> #include <zencore/filesystem.h> #include <zencore/intmath.h> #include <zencore/iobuffer.h> @@ -117,6 +118,7 @@ zencore_forcelinktests() zen::uson_forcelink(); zen::usonbuilder_forcelink(); zen::usonpackage_forcelink(); + zen::crypto_forcelink(); } #endif |