Skip to content

Commit

Permalink
Merge pull request #179 from cppalliance/SHA512
Browse files Browse the repository at this point in the history
SHA512
  • Loading branch information
mborland authored Jan 10, 2025
2 parents d4244dd + ffe974e commit 0b0b254
Show file tree
Hide file tree
Showing 16 changed files with 957 additions and 188 deletions.
41 changes: 41 additions & 0 deletions fuzzing/fuzz_sha512.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/crypt2/hash/sha512.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::sha512(c_data_str);

std::string_view view {c_data_str};
boost::crypt::sha512(view);

std::span data_span {c_data, size};
boost::crypt::sha512(data_span);

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

return 0;
}
3 changes: 2 additions & 1 deletion include/boost/crypt/utility/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
// ---- Constexpr arrays -----

// ----- Assertions -----

#ifndef BOOST_CRYPT_ASSERT
#ifdef BOOST_CRYPT_NO_EXCEPTIONS
# define BOOST_CRYPT_ASSERT(x)
# define BOOST_CRYPT_ASSERT_MSG(expr, msg)
Expand All @@ -74,6 +74,7 @@
# define BOOST_CRYPT_ASSERT_MSG(expr, msg)
#endif
#endif
#endif
// ----- Assertions -----

// ----- Has something -----
Expand Down
180 changes: 180 additions & 0 deletions include/boost/crypt2/detail/assert.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright 2025 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#ifndef BOOST_CRYPT2_DETAIL_ASSERT_HPP
#define BOOST_CRYPT2_DETAIL_ASSERT_HPP

#include <boost/crypt2/detail/config.hpp>

// Check for C++23 stacktrace support
// TODO(mborland): Not ready for the mainstream as of 01/25. Manually enable for now
#ifdef BOOST_CRYPT_ENABLE_STACKTRACE
# if __has_include(<stacktrace>)
# ifndef BOOST_CRYPT_BUILD_MODULE
# include <stacktrace>
# endif
# endif
# if defined(__cpp_lib_stacktrace) && __cpp_lib_stacktrace >= 202011L
# define BOOST_CRYPT_HAS_STACKTRACE 1
# else
# define BOOST_CRYPT_HAS_STACKTRACE 0
# endif
#else
# define BOOST_CRYPT_HAS_STACKTRACE 0
#endif

#ifndef BOOST_CRYPT_BUILD_MODULE

#include <source_location>
#include <iostream>
#include <stdexcept>
#include <string_view>
#include <type_traits>
#include <sstream>

#endif

#if !defined(NDEBUG) && !defined(BOOST_CRYPT_HAS_CUDA)

namespace boost::crypt::assert_detail {

struct assertion_error : std::runtime_error
{
using std::runtime_error::runtime_error;
};

template<typename... Args>
[[nodiscard]] std::string format_assertion_message(
const char* condition_str,
const std::source_location& location,
#if BOOST_CRYPT_HAS_STACKTRACE
const std::stacktrace& trace,
#endif
Args&&... args)
{
std::stringstream ss;
ss << "Assertion failed: " << condition_str << '\n'
<< "File: " << location.file_name() << '\n'
<< "Line: " << location.line() << '\n'
<< "Function: " << location.function_name() << '\n'
<< "Column: " << location.column() << '\n';

// Fold expression to handle optional message
((ss << "Message: " << args << '\n'), ...);

#if BOOST_CRYPT_HAS_STACKTRACE
// Add stacktrace
ss << "Stacktrace:\n" << trace;
#endif

return ss.str();
}

// Version without message
constexpr void constexpr_assert_impl(
bool condition,
const char* condition_str,
const std::source_location& location = std::source_location::current())
{
if (!condition)
{
#if BOOST_CRYPT_HAS_STACKTRACE
if (!std::is_constant_evaluated())
{
throw assertion_error(
format_assertion_message(
condition_str,
location,
std::stacktrace::current()
)
);
}
else
{
throw assertion_error(
format_assertion_message(
condition_str,
location,
std::stacktrace{}
)
);
}
#else
throw assertion_error(
format_assertion_message(
condition_str,
location
)
);
#endif
}
}

// Version with message
constexpr void constexpr_assert_impl(
bool condition,
const char* condition_str,
const char* message,
const std::source_location& location = std::source_location::current())
{
if (!condition)
{
#if BOOST_CRYPT_HAS_STACKTRACE
if (!std::is_constant_evaluated())
{
throw assertion_error(
format_assertion_message(
condition_str,
location,
std::stacktrace::current(),
message
)
);
}
else
{
throw assertion_error(
format_assertion_message(
condition_str,
location,
std::stacktrace{},
message
)
);
}
#else
throw assertion_error(
format_assertion_message(
condition_str,
location,
message
)
);
#endif
}
}

} // namespace boost::crypt::assert_detail

// Macro overloading based on argument count
#define BOOST_CRYPT_ASSERT_1(condition) \
boost::crypt::assert_detail::constexpr_assert_impl((condition), #condition)

#define BOOST_CRYPT_ASSERT_2(condition, message) \
boost::crypt::assert_detail::constexpr_assert_impl((condition), #condition, message)

// Helper macros for argument counting
#define BOOST_CRYPT_ASSERT_GET_MACRO(_1, _2, NAME, ...) NAME

// Main macro that selects the appropriate version
#define BOOST_CRYPT_ASSERT(...) \
BOOST_CRYPT_ASSERT_GET_MACRO(__VA_ARGS__, BOOST_CRYPT_ASSERT_2, BOOST_CRYPT_ASSERT_1)(__VA_ARGS__)

#else

#define BOOST_CRYPT_ASSERT(...)

#endif // NDEBUG and CUDA

#endif // BOOST_CRYPT2_DETAIL_ASSERT_HPP
2 changes: 2 additions & 0 deletions include/boost/crypt2/detail/compat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ namespace boost::crypt::compat {
#ifdef BOOST_CRYPT_HAS_CUDA
using size_t = cuda::std::size_t;
using uint32_t = cuda::std::uint32_t;
using uint64_t = cuda::std::uint64_t;
#else
using size_t = std::size_t;
using uint32_t = std::uint32_t;
using uint64_t = std::uint64_t;
#endif

// Arrays and spans
Expand Down
2 changes: 1 addition & 1 deletion include/boost/crypt2/hash/detail/sha224_256_hasher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class sha_224_256_hasher final : public sha_1_2_hasher_base<digest_size, 8U>

namespace sha256_detail {

// On the host device we prefere this array to be static,
// On the host device we prefer this array to be static,
// but in a CUDA environment we move it into the function to make it available to host and device
#ifndef BOOST_CRYPT_HAS_CUDA
inline constexpr compat::array<compat::uint32_t, 64U> sha256_k {
Expand Down
Loading

0 comments on commit 0b0b254

Please sign in to comment.