summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-05-08 01:36:29 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2025-05-08 03:03:59 -0500
commita9ab0e979e84f0a01baea12fd35cf9b39d883cf3 (patch)
tree94cc66a8d351ce35f40041c9984a9ca7f04a6d70
parent8a9a082c6960754e514a05147184678855254cf6 (diff)
Crypto/SHA1: Fix past-the-last-element std::array access and modernize code.
-rw-r--r--Source/Core/Common/Crypto/SHA1.cpp86
1 files 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 <algorithm>
#include <array>
#include <memory>
@@ -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)
- {
- 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)
+ size_t count_to_fill_block = m_block.size() - m_block_position;
+
+ while (len >= count_to_fill_block)
{
- 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)
- {
- // 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
+ if (m_block_position > MSG_LEN_POS)
{
- // Pad current block
- std::memset(&block[block_used], 0, MSG_LEN_POS - block_used);
+ // Pad current block and process it
+ std::fill(m_block.begin() + m_block_position, m_block.end(), 0x00);
+ ProcessBlock(m_block.data());
+ m_block_position = 0;
}
- Common::BigEndianValue<u64> 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<u64> msg_bit_length{m_msg_length * CHAR_BIT};
+ Update(reinterpret_cast<const u8*>(&msg_bit_length), sizeof(msg_bit_length));
return GetDigest();
}
- alignas(64) std::array<u8, BLOCK_LEN> block{};
- size_t block_used{};
- size_t msg_len{};
+private:
+ alignas(64) std::array<u8, BLOCK_LEN> m_block{};
+ size_t m_block_position{};
+ size_t m_msg_length{};
};
template <typename ValueType, size_t Size>