Skip to content

Commit

Permalink
Merge pull request #70 from cppalliance/SHA3-384
Browse files Browse the repository at this point in the history
Add support for SHA3-384
  • Loading branch information
mborland authored Oct 30, 2024
2 parents 4d02894 + ea9c159 commit 3cf1958
Show file tree
Hide file tree
Showing 16 changed files with 2,342 additions and 55 deletions.
46 changes: 46 additions & 0 deletions fuzzing/fuzz_sha3_384.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2024 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/crypt/hash/sha3_384.hpp>
#include <iostream>
#include <exception>
#include <string>

extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, std::size_t size)
{
try
{
auto c_data = reinterpret_cast<const char*>(data);
std::string c_data_str {c_data, size}; // Guarantee null termination since we can't pass the size argument

boost::crypt::sha3_384(c_data_str);
boost::crypt::sha3_384(c_data, size);
boost::crypt::sha3_384(data, size);

#ifdef BOOST_CRYPT_HAS_STRING_VIEW
std::string_view view {c_data_str};
boost::crypt::sha3_384(view);
#endif

#ifdef BOOST_CRYPT_HAS_SPAN
std::span data_span {c_data, size};
boost::crypt::sha3_384(data_span);
#endif

// Fuzz the hasher object
boost::crypt::sha3_384_hasher hasher;
hasher.process_bytes(data, size);
hasher.process_bytes(data, size);
hasher.process_bytes(data, size);
hasher.get_digest();
hasher.process_bytes(data, size); // State is invalid but should not crash
}
catch(...)
{
std::cerr << "Error with: " << data << std::endl;
std::terminate();
}

return 0;
}
18 changes: 18 additions & 0 deletions fuzzing/seedcorpus/fuzz_sha3_384/sha3_384.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"The quick brown fox jumps over the lazy dog"
"The quick brown fox jumps over the lazy dog."
""
"aB3$x9Yz"
"12345"
"!@#$%^&*()"
"FuzzTest123"
" "
"Lorem ipsum dolor sit amet"
"a"
"9876543210"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"ñÑáéíóúÁÉÍÓÚ"
"\n\r\t"
"0"
"ThisIsAVeryLongStringWithNoSpacesOrPunctuationToTestEdgeCases"
"<?php echo 'test'; ?>"
"SELECT * FROM users;"
66 changes: 32 additions & 34 deletions include/boost/crypt/hash/detail/sha3_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,73 +40,71 @@ class sha3_base

static_assert((!is_xof && (digest_size == 28U || digest_size == 32U || digest_size == 48U || digest_size == 64U)) || is_xof,
"Digest size must be 28 (SHA3-224), 32 (SHA3-256), 48 (SHA3-384), or 64(SHA3-512) or this must be an xof");

static constexpr boost::crypt::size_t buffer_size_ {200U - 2U * digest_size};

boost::crypt::array<boost::crypt::uint64_t, 25U> state_array_ {};
boost::crypt::array<boost::crypt::uint8_t, 200U> buffer_ {};
boost::crypt::array<boost::crypt::uint8_t, 200U - 2U * digest_size> buffer_ {};
boost::crypt::size_t buffer_index_ {};
bool computed_ {};
bool corrupted_ {};

template <typename ForwardIterator>
BOOST_CRYPT_GPU_ENABLED inline auto update(ForwardIterator data, boost::crypt::size_t size) noexcept -> hasher_state;
BOOST_CRYPT_GPU_ENABLED constexpr auto update(ForwardIterator data, boost::crypt::size_t size) noexcept -> hasher_state;

BOOST_CRYPT_GPU_ENABLED inline auto process_message_block() noexcept -> void;
BOOST_CRYPT_GPU_ENABLED constexpr auto process_message_block() noexcept -> void;


public:

using return_type = boost::crypt::array<boost::crypt::uint8_t, digest_size>;

BOOST_CRYPT_GPU_ENABLED sha3_base() noexcept { init(); };
BOOST_CRYPT_GPU_ENABLED constexpr sha3_base() noexcept { init(); };

BOOST_CRYPT_GPU_ENABLED inline auto init() noexcept -> void;
BOOST_CRYPT_GPU_ENABLED constexpr auto init() noexcept -> void;

template <typename ByteType>
BOOST_CRYPT_GPU_ENABLED inline auto process_byte(ByteType byte) noexcept -> hasher_state;
BOOST_CRYPT_GPU_ENABLED constexpr auto process_byte(ByteType byte) noexcept -> hasher_state;

template <typename ForwardIter, boost::crypt::enable_if_t<sizeof(typename utility::iterator_traits<ForwardIter>::value_type) == 1, bool> = true>
BOOST_CRYPT_GPU_ENABLED inline auto process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state;
BOOST_CRYPT_GPU_ENABLED constexpr auto process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state;

template <typename ForwardIter, boost::crypt::enable_if_t<sizeof(typename utility::iterator_traits<ForwardIter>::value_type) == 2, bool> = true>
BOOST_CRYPT_GPU_ENABLED inline auto process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state;
BOOST_CRYPT_GPU_ENABLED constexpr auto process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state;

template <typename ForwardIter, boost::crypt::enable_if_t<sizeof(typename utility::iterator_traits<ForwardIter>::value_type) == 4, bool> = true>
BOOST_CRYPT_GPU_ENABLED inline auto process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state;
BOOST_CRYPT_GPU_ENABLED constexpr auto process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state;

#ifdef BOOST_CRYPT_HAS_STRING_VIEW

inline auto process_bytes(std::string_view str) noexcept -> hasher_state;
constexpr auto process_bytes(std::string_view str) noexcept -> hasher_state;

inline auto process_bytes(std::u16string_view str) noexcept -> hasher_state;
constexpr auto process_bytes(std::u16string_view str) noexcept -> hasher_state;

inline auto process_bytes(std::u32string_view str) noexcept -> hasher_state;
constexpr auto process_bytes(std::u32string_view str) noexcept -> hasher_state;

inline auto process_bytes(std::wstring_view str) noexcept -> hasher_state;
constexpr auto process_bytes(std::wstring_view str) noexcept -> hasher_state;

#endif // BOOST_CRYPT_HAS_STRING_VIEW

#ifdef BOOST_CRYPT_HAS_SPAN

template <typename T, boost::crypt::size_t extent>
inline auto process_bytes(std::span<T, extent> data) noexcept -> hasher_state;
constexpr auto process_bytes(std::span<T, extent> data) noexcept -> hasher_state;

#endif // BOOST_CRYPT_HAS_SPAN

#ifdef BOOST_CRYPT_HAS_CUDA

template <typename T, boost::crypt::size_t extent>
BOOST_CRYPT_GPU_ENABLED inline auto process_bytes(cuda::std::span<T, extent> data) noexcept -> hasher_state;
BOOST_CRYPT_GPU_ENABLED constexpr auto process_bytes(cuda::std::span<T, extent> data) noexcept -> hasher_state;

#endif // BOOST_CRYPT_HAS_CUDA

BOOST_CRYPT_GPU_ENABLED inline auto get_digest() noexcept -> return_type;
BOOST_CRYPT_GPU_ENABLED constexpr auto get_digest() noexcept -> return_type;

};

template <boost::crypt::size_t digest_size, bool is_xof>
BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::init() noexcept -> void
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_base<digest_size, is_xof>::init() noexcept -> void
{
state_array_.fill(0);
buffer_.fill(0);
Expand All @@ -117,7 +115,7 @@ BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::init() noexc

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename ForwardIterator>
BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::update(ForwardIterator data, boost::crypt::size_t size) noexcept -> hasher_state
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_base<digest_size, is_xof>::update(ForwardIterator data, boost::crypt::size_t size) noexcept -> hasher_state
{
if (size == 0U)
{
Expand Down Expand Up @@ -145,7 +143,7 @@ BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::update(Forwa
#pragma GCC diagnostic pop
#endif

if (buffer_index_ == buffer_size_)
if (buffer_index_ == buffer_.size())
{
process_message_block();
}
Expand Down Expand Up @@ -188,7 +186,7 @@ BOOST_CRYPT_INLINE_CONSTEXPR boost::crypt::array<boost::crypt::uint64_t, num_rou
} // namespace sha3_detail

template <boost::crypt::size_t digest_size, bool is_xof>
BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::process_message_block() noexcept -> void
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_base<digest_size, is_xof>::process_message_block() noexcept -> void
{
#ifdef BOOST_CRYPT_HAS_CUDA

Expand Down Expand Up @@ -332,7 +330,7 @@ BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::process_mess
}

template <boost::crypt::size_t digest_size, bool is_xof>
BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::get_digest() noexcept -> sha3_base<digest_size, is_xof>::return_type
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_base<digest_size, is_xof>::get_digest() noexcept -> sha3_base<digest_size, is_xof>::return_type
{
return_type digest{};

Expand All @@ -343,7 +341,7 @@ BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::get_digest()
if (!computed_)
{
buffer_[buffer_index_] ^= static_cast<boost::crypt::uint8_t>(0x06U);
buffer_[buffer_size_ - 1U] ^= static_cast<boost::crypt::uint8_t>(0x80U);
buffer_.back() ^= static_cast<boost::crypt::uint8_t>(0x80U);
process_message_block();
computed_ = true;
}
Expand All @@ -361,7 +359,7 @@ BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::get_digest()

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename ByteType>
auto sha3_base<digest_size, is_xof>::process_byte(ByteType byte) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_byte(ByteType byte) noexcept -> hasher_state
{
static_assert(boost::crypt::is_convertible_v<ByteType, boost::crypt::uint8_t>, "Byte must be convertible to uint8_t");
const auto value {static_cast<boost::crypt::uint8_t>(byte)};
Expand All @@ -370,7 +368,7 @@ auto sha3_base<digest_size, is_xof>::process_byte(ByteType byte) noexcept -> has

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename ForwardIter, boost::crypt::enable_if_t<sizeof(typename utility::iterator_traits<ForwardIter>::value_type) == 1, bool>>
auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state
{
if (!utility::is_null(buffer))
{
Expand All @@ -384,7 +382,7 @@ auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::cr

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename ForwardIter, boost::crypt::enable_if_t<sizeof(typename utility::iterator_traits<ForwardIter>::value_type) == 2, bool>>
auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state
{
#ifndef BOOST_CRYPT_HAS_CUDA

Expand Down Expand Up @@ -416,7 +414,7 @@ auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::cr

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename ForwardIter, boost::crypt::enable_if_t<sizeof(typename utility::iterator_traits<ForwardIter>::value_type) == 4, bool>>
auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::crypt::size_t byte_count) noexcept -> hasher_state
{
#ifndef BOOST_CRYPT_HAS_CUDA

Expand Down Expand Up @@ -449,25 +447,25 @@ auto sha3_base<digest_size, is_xof>::process_bytes(ForwardIter buffer, boost::cr
#ifdef BOOST_CRYPT_HAS_STRING_VIEW

template <boost::crypt::size_t digest_size, bool is_xof>
inline auto sha3_base<digest_size, is_xof>::process_bytes(std::string_view str) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(std::string_view str) noexcept -> hasher_state
{
return process_bytes(str.begin(), str.size());
}

template <boost::crypt::size_t digest_size, bool is_xof>
inline auto sha3_base<digest_size, is_xof>::process_bytes(std::u16string_view str) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(std::u16string_view str) noexcept -> hasher_state
{
return process_bytes(str.begin(), str.size());
}

template <boost::crypt::size_t digest_size, bool is_xof>
inline auto sha3_base<digest_size, is_xof>::process_bytes(std::u32string_view str) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(std::u32string_view str) noexcept -> hasher_state
{
return process_bytes(str.begin(), str.size());
}

template <boost::crypt::size_t digest_size, bool is_xof>
inline auto sha3_base<digest_size, is_xof>::process_bytes(std::wstring_view str) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(std::wstring_view str) noexcept -> hasher_state
{
return process_bytes(str.begin(), str.size());
}
Expand All @@ -478,7 +476,7 @@ inline auto sha3_base<digest_size, is_xof>::process_bytes(std::wstring_view str)

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename T, boost::crypt::size_t extent>
inline auto sha3_base<digest_size, is_xof>::process_bytes(std::span<T, extent> data) noexcept -> hasher_state
constexpr auto sha3_base<digest_size, is_xof>::process_bytes(std::span<T, extent> data) noexcept -> hasher_state
{
return process_bytes(data.begin(), data.size());
}
Expand All @@ -489,7 +487,7 @@ inline auto sha3_base<digest_size, is_xof>::process_bytes(std::span<T, extent> d

template <boost::crypt::size_t digest_size, bool is_xof>
template <typename T, boost::crypt::size_t extent>
BOOST_CRYPT_GPU_ENABLED inline auto sha3_base<digest_size, is_xof>::process_bytes(cuda::std::span<T, extent> data) noexcept -> hasher_state
BOOST_CRYPT_GPU_ENABLED constexpr auto sha3_base<digest_size, is_xof>::process_bytes(cuda::std::span<T, extent> data) noexcept -> hasher_state
{
return process_bytes(data.begin(), data.size());
}
Expand Down
Loading

0 comments on commit 3cf1958

Please sign in to comment.