mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-28 09:59:32 -06:00
Crypto/SHA1: Fix past-the-last-element std::array access and modernize code.
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "SHA1.h"
|
#include "SHA1.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -67,75 +68,58 @@ protected:
|
|||||||
virtual void ProcessBlock(const u8* msg) = 0;
|
virtual void ProcessBlock(const u8* msg) = 0;
|
||||||
virtual Digest GetDigest() = 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)
|
m_msg_length += len;
|
||||||
return;
|
|
||||||
msg_len += 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())
|
std::copy_n(msg, count_to_fill_block, m_block.data() + m_block_position);
|
||||||
{
|
ProcessBlock(m_block.data());
|
||||||
size_t rem = block.size() - block_used;
|
|
||||||
std::memcpy(&block[block_used], msg, rem);
|
msg += count_to_fill_block;
|
||||||
ProcessBlock(&block[0]);
|
len -= count_to_fill_block;
|
||||||
block_used = 0;
|
|
||||||
msg += rem;
|
m_block_position = 0;
|
||||||
len -= rem;
|
count_to_fill_block = m_block.size();
|
||||||
}
|
|
||||||
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, len, m_block.data() + m_block_position);
|
||||||
|
m_block_position += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Digest Finish() override
|
Digest Finish() override
|
||||||
{
|
{
|
||||||
// block_used is guaranteed < BLOCK_LEN
|
// m_block_position is guaranteed < BLOCK_LEN
|
||||||
block[block_used++] = 0x80;
|
m_block[m_block_position++] = 0x80;
|
||||||
|
|
||||||
constexpr size_t MSG_LEN_POS = BLOCK_LEN - sizeof(u64);
|
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
|
// Pad current block and process it
|
||||||
std::memset(&block[block_used], 0, BLOCK_LEN - block_used);
|
std::fill(m_block.begin() + m_block_position, m_block.end(), 0x00);
|
||||||
ProcessBlock(&block[0]);
|
ProcessBlock(m_block.data());
|
||||||
|
m_block_position = 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::BigEndianValue<u64> msg_bitlen(msg_len * 8);
|
// Pad block.
|
||||||
std::memcpy(&block[MSG_LEN_POS], &msg_bitlen, sizeof(msg_bitlen));
|
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();
|
return GetDigest();
|
||||||
}
|
}
|
||||||
|
|
||||||
alignas(64) std::array<u8, BLOCK_LEN> block{};
|
private:
|
||||||
size_t block_used{};
|
alignas(64) std::array<u8, BLOCK_LEN> m_block{};
|
||||||
size_t msg_len{};
|
size_t m_block_position{};
|
||||||
|
size_t m_msg_length{};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ValueType, size_t Size>
|
template <typename ValueType, size_t Size>
|
||||||
|
Reference in New Issue
Block a user