diff --git a/libraries/libvapours/include/vapours/crypto/crypto_sha256_generator.hpp b/libraries/libvapours/include/vapours/crypto/crypto_sha256_generator.hpp index 9b6a54773..2585a35da 100644 --- a/libraries/libvapours/include/vapours/crypto/crypto_sha256_generator.hpp +++ b/libraries/libvapours/include/vapours/crypto/crypto_sha256_generator.hpp @@ -22,6 +22,11 @@ namespace ams::crypto { + struct Sha256Context { + u32 intermediate_hash[impl::Sha256Impl::HashSize / sizeof(u32)]; + u64 bits_consumed; + }; + class Sha256Generator { private: using Impl = impl::Sha256Impl; @@ -54,6 +59,22 @@ namespace ams::crypto { void GetHash(void *dst, size_t size) { this->impl.GetHash(dst, size); } + + void InitializeWithContext(const Sha256Context *context) { + this->impl.InitializeWithContext(context); + } + + size_t GetContext(Sha256Context *context) const { + return this->impl.GetContext(context); + } + + size_t GetBufferedDataSize() const { + return this->impl.GetBufferedDataSize(); + } + + void GetBufferedData(void *dst, size_t dst_size) const { + return this->impl.GetBufferedData(dst, dst_size); + } }; void GenerateSha256Hash(void *dst, size_t dst_size, const void *src, size_t src_size); diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp index 4fa60ca2d..bbd145efb 100644 --- a/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_sha256_impl.hpp @@ -21,6 +21,12 @@ #include #include +namespace ams::crypto { + + struct Sha256Context; + +} + namespace ams::crypto::impl { class Sha256Impl { @@ -47,6 +53,17 @@ namespace ams::crypto::impl { void Initialize(); void Update(const void *data, size_t size); void GetHash(void *dst, size_t size); + + void InitializeWithContext(const Sha256Context *context); + size_t GetContext(Sha256Context *context) const; + + size_t GetBufferedDataSize() const { return this->state.num_buffered; } + + void GetBufferedData(void *dst, size_t dst_size) const { + AMS_ASSERT(dst_size >= this->GetBufferedDataSize()); + + std::memcpy(dst, this->state.buffer, this->GetBufferedDataSize()); + } }; /* static_assert(HashFunction); */ diff --git a/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp b/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp index e68933354..d99c497c8 100644 --- a/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp @@ -35,6 +35,27 @@ namespace ams::crypto::impl { ::sha256ContextGetHash(reinterpret_cast<::Sha256Context *>(std::addressof(this->state)), dst); } + void Sha256Impl::InitializeWithContext(const Sha256Context *context) { + static_assert(sizeof(this->state) == sizeof(::Sha256Context)); + + /* Copy state in from the context. */ + std::memcpy(this->state.intermediate_hash, context->intermediate_hash, sizeof(this->state.intermediate_hash)); + this->state.bits_consumed = context->bits_consumed; + + /* Clear the rest of state. */ + std::memset(this->state.buffer, 0, sizeof(this->state.buffer)); + this->state.num_buffered = 0; + this->state.finalized = false; + } + + size_t Sha256Impl::GetContext(Sha256Context *context) const { + static_assert(sizeof(this->state) == sizeof(::Sha256Context)); + std::memcpy(context->intermediate_hash, this->state.intermediate_hash, sizeof(context->intermediate_hash)); + context->bits_consumed = this->state.bits_consumed; + + return this->state.num_buffered; + } + #else /* TODO: Non-EL0 implementation. */