From a9ab0e979e84f0a01baea12fd35cf9b39d883cf3 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 8 May 2025 01:36:29 -0500 Subject: [PATCH] Crypto/SHA1: Fix past-the-last-element std::array access and modernize code. --- Source/Core/Common/Crypto/SHA1.cpp | 86 ++++++++++++------------------ 1 file changed, 35 insertions(+), 51 deletions(-) diff --git a/Source/Core/Common/Crypto/SHA1.cpp b/Source/Core/Common/Crypto/SHA1.cpp index 8c4aa646bd..d092f2a897 100644 --- a/Source/Core/Common/Crypto/SHA1.cpp +++ b/Source/Core/Common/Crypto/SHA1.cpp @@ -3,6 +3,7 @@ #include "SHA1.h" +#include #include #include @@ -67,75 +68,58 @@ protected: virtual void ProcessBlock(const u8* msg) = 0; virtual Digest GetDigest() = 0; - virtual void Update(const u8* msg, size_t len) override + void Update(const u8* msg, size_t len) override { - if (len == 0) - return; - msg_len += len; + m_msg_length += len; - if (block_used) + size_t count_to_fill_block = m_block.size() - m_block_position; + + while (len >= count_to_fill_block) { - if (block_used + len >= block.size()) - { - size_t rem = block.size() - block_used; - std::memcpy(&block[block_used], msg, rem); - ProcessBlock(&block[0]); - block_used = 0; - msg += rem; - len -= rem; - } - else - { - std::memcpy(&block[block_used], msg, len); - block_used += len; - return; - } - } - while (len >= BLOCK_LEN) - { - ProcessBlock(msg); - msg += BLOCK_LEN; - len -= BLOCK_LEN; - } - if (len) - { - std::memcpy(&block[0], msg, len); - block_used = len; + std::copy_n(msg, count_to_fill_block, m_block.data() + m_block_position); + ProcessBlock(m_block.data()); + + msg += count_to_fill_block; + len -= count_to_fill_block; + + m_block_position = 0; + count_to_fill_block = m_block.size(); } + + std::copy_n(msg, len, m_block.data() + m_block_position); + m_block_position += len; } - virtual Digest Finish() override + Digest Finish() override { - // block_used is guaranteed < BLOCK_LEN - block[block_used++] = 0x80; + // m_block_position is guaranteed < BLOCK_LEN + m_block[m_block_position++] = 0x80; constexpr size_t MSG_LEN_POS = BLOCK_LEN - sizeof(u64); - if (block_used > MSG_LEN_POS) + + if (m_block_position > MSG_LEN_POS) { // Pad current block and process it - std::memset(&block[block_used], 0, BLOCK_LEN - block_used); - ProcessBlock(&block[0]); - - // Pad a new block - std::memset(&block[0], 0, MSG_LEN_POS); - } - else - { - // Pad current block - std::memset(&block[block_used], 0, MSG_LEN_POS - block_used); + std::fill(m_block.begin() + m_block_position, m_block.end(), 0x00); + ProcessBlock(m_block.data()); + m_block_position = 0; } - Common::BigEndianValue msg_bitlen(msg_len * 8); - std::memcpy(&block[MSG_LEN_POS], &msg_bitlen, sizeof(msg_bitlen)); + // Pad block. + std::fill(m_block.data() + m_block_position, m_block.data() + MSG_LEN_POS, 0x00); + m_block_position = MSG_LEN_POS; - ProcessBlock(&block[0]); + // Write the message length. + const Common::BigEndianValue msg_bit_length{m_msg_length * CHAR_BIT}; + Update(reinterpret_cast(&msg_bit_length), sizeof(msg_bit_length)); return GetDigest(); } - alignas(64) std::array block{}; - size_t block_used{}; - size_t msg_len{}; +private: + alignas(64) std::array m_block{}; + size_t m_block_position{}; + size_t m_msg_length{}; }; template