diff --git a/.github/workflows/secure_zero_odr.yml b/.github/workflows/secure_zero_odr.yml new file mode 100644 index 0000000..479bd85 --- /dev/null +++ b/.github/workflows/secure_zero_odr.yml @@ -0,0 +1,27 @@ +name: ODR checks + +on: + push + +jobs: + odr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential + + - name: Build secure_zero ODR sample + run: | + g++ -std=c++11 -Wall -Wextra -pedantic -DHMAC_CPP_STATIC -Iinclude \ + tests/odr/main.cpp \ + tests/odr/tu_memset.cpp \ + tests/odr/tu_explicit.cpp \ + tests/odr/platform_stubs.cpp \ + -o secure_zero_odr + + - name: Run secure_zero ODR sample + run: ./secure_zero_odr \ No newline at end of file diff --git a/include/hmac_cpp/secure_buffer.hpp b/include/hmac_cpp/secure_buffer.hpp index 9f109e7..c2d0c4b 100644 --- a/include/hmac_cpp/secure_buffer.hpp +++ b/include/hmac_cpp/secure_buffer.hpp @@ -30,7 +30,7 @@ namespace hmac_cpp { /// \brief Securely zeroes a memory region. /// \param ptr Pointer to the memory to wipe. /// \param len Number of bytes to set to zero. -inline void secure_zero(void* ptr, size_t len) { +static inline void secure_zero(void* ptr, size_t len) { #if defined(__STDC_LIB_EXT1__) (void)memset_s(ptr, len, 0, len); #elif defined(HAVE_EXPLICIT_BZERO) diff --git a/tests/odr/main.cpp b/tests/odr/main.cpp new file mode 100644 index 0000000..276f950 --- /dev/null +++ b/tests/odr/main.cpp @@ -0,0 +1,18 @@ +#include + +extern "C" bool secure_zero_memset_s_branch(); +extern "C" bool secure_zero_explicit_bzero_branch(); + +int main() { + const bool memset_ok = secure_zero_memset_s_branch(); + const bool explicit_ok = secure_zero_explicit_bzero_branch(); + + if (!memset_ok || !explicit_ok) { + std::cout << "secure_zero failed: memset_s=" << memset_ok + << ", explicit_bzero=" << explicit_ok << "\n"; + return 1; + } + + std::cout << "secure_zero zeroed buffers across translation units\n"; + return 0; +} \ No newline at end of file diff --git a/tests/odr/platform_stubs.cpp b/tests/odr/platform_stubs.cpp new file mode 100644 index 0000000..74b4d99 --- /dev/null +++ b/tests/odr/platform_stubs.cpp @@ -0,0 +1,12 @@ +#include +#include + +extern "C" int memset_s(void* dest, size_t destsz, int ch, size_t count) { + (void)destsz; + std::memset(dest, ch, count); + return 0; +} + +extern "C" void explicit_bzero(void* dest, size_t count) noexcept { + std::memset(dest, 0, count); +} \ No newline at end of file diff --git a/tests/odr/tu_explicit.cpp b/tests/odr/tu_explicit.cpp new file mode 100644 index 0000000..02c91fc --- /dev/null +++ b/tests/odr/tu_explicit.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +extern "C" void explicit_bzero(void* dest, size_t count) noexcept; + +#undef __STDC_WANT_LIB_EXT1__ +#undef __STDC_LIB_EXT1__ +#define HAVE_EXPLICIT_BZERO 1 + +#include + +extern "C" bool secure_zero_explicit_bzero_branch() { + std::array buffer{}; + buffer.fill(0xBB); + + hmac_cpp::secure_zero(buffer.data(), buffer.size()); + + return std::all_of(buffer.begin(), buffer.end(), [](unsigned char value) { + return value == 0; + }); +} \ No newline at end of file diff --git a/tests/odr/tu_memset.cpp b/tests/odr/tu_memset.cpp new file mode 100644 index 0000000..1517dc3 --- /dev/null +++ b/tests/odr/tu_memset.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +extern "C" int memset_s(void* dest, size_t destsz, int ch, size_t count); + +#define __STDC_WANT_LIB_EXT1__ 1 +#define __STDC_LIB_EXT1__ 1 +#undef HAVE_EXPLICIT_BZERO + +#include + +extern "C" bool secure_zero_memset_s_branch() { + std::array buffer{}; + buffer.fill(0xAA); + + hmac_cpp::secure_zero(buffer.data(), buffer.size()); + + return std::all_of(buffer.begin(), buffer.end(), [](unsigned char value) { + return value == 0; + }); +} \ No newline at end of file