From 93b7859827a20a1285dfd04f397970b523dfb7e6 Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Sat, 6 Sep 2025 00:59:53 +0300 Subject: [PATCH] build(api): hide symbols by default Introduce HMAC_CPP_API macro for exported functions and enable compiler options to hide other symbols. --- CMakeLists.txt | 15 ++++++++++++++- include/hmac_cpp/api.hpp | 18 +++++++++++++++++ include/hmac_cpp/hmac.hpp | 13 +++++++------ include/hmac_cpp/hmac_utils.hpp | 34 ++++++++++++++++----------------- include/hmac_cpp/sha1.hpp | 9 +++++---- include/hmac_cpp/sha256.hpp | 9 +++++---- include/hmac_cpp/sha512.hpp | 9 +++++---- 7 files changed, 71 insertions(+), 36 deletions(-) create mode 100644 include/hmac_cpp/api.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 097dee5..3999b52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(HMAC_SOURCES ) set(HMAC_HEADERS + include/hmac_cpp/api.hpp include/hmac_cpp/hmac.hpp include/hmac_cpp/hmac_utils.hpp include/hmac_cpp/sha1.hpp @@ -22,13 +23,25 @@ set(HMAC_HEADERS include/hmac_cpp/secure_buffer.hpp ) -add_library(hmac_cpp STATIC ${HMAC_SOURCES}) +add_library(hmac_cpp ${HMAC_SOURCES}) target_compile_features(hmac_cpp PUBLIC cxx_std_11) target_include_directories(hmac_cpp PUBLIC $ $ ) +if(BUILD_SHARED_LIBS) + target_compile_definitions(hmac_cpp PRIVATE HMAC_CPP_BUILD) +else() + target_compile_definitions(hmac_cpp PUBLIC HMAC_CPP_STATIC) +endif() + +if(MSVC) + target_compile_options(hmac_cpp PRIVATE /wd4251) +else() + target_compile_options(hmac_cpp PRIVATE -fvisibility=hidden) +endif() + if(NOT TARGET hmac_cpp::hmac_cpp) add_library(hmac_cpp::hmac_cpp ALIAS hmac_cpp) endif() diff --git a/include/hmac_cpp/api.hpp b/include/hmac_cpp/api.hpp new file mode 100644 index 0000000..ac21a80 --- /dev/null +++ b/include/hmac_cpp/api.hpp @@ -0,0 +1,18 @@ +#ifndef HMAC_CPP_API_HPP +#define HMAC_CPP_API_HPP + +#if defined(_WIN32) || defined(__CYGWIN__) + #if defined(HMAC_CPP_STATIC) + #define HMAC_CPP_API + #elif defined(HMAC_CPP_BUILD) + #define HMAC_CPP_API __declspec(dllexport) + #else + #define HMAC_CPP_API __declspec(dllimport) + #endif +#elif defined(__GNUC__) && __GNUC__ >= 4 + #define HMAC_CPP_API __attribute__((visibility("default"))) +#else + #define HMAC_CPP_API +#endif + +#endif // HMAC_CPP_API_HPP diff --git a/include/hmac_cpp/hmac.hpp b/include/hmac_cpp/hmac.hpp index b72ab3c..f935de3 100644 --- a/include/hmac_cpp/hmac.hpp +++ b/include/hmac_cpp/hmac.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "api.hpp" #include "sha1.hpp" #include "sha256.hpp" #include "sha512.hpp" @@ -22,20 +23,20 @@ namespace hmac_cpp { /// \param input Input string /// \param is_upper Flag for uppercase hex /// \return Hexadecimal string - std::string to_hex(const std::string& input, bool is_upper = false); + HMAC_CPP_API std::string to_hex(const std::string& input, bool is_upper = false); /// \brief Computes hash of the input string /// \param input Input string /// \param type Hash function type /// \return Hash result - std::string get_hash(const std::string &input, TypeHash type); + HMAC_CPP_API std::string get_hash(const std::string &input, TypeHash type); /// \brief Computes a hash of a raw buffer using the selected hash function /// \param data Pointer to input data /// \param length Length of the input data /// \param type Hash function type /// \return Binary hash result as std::vector - std::vector get_hash(const void* data, size_t length, TypeHash type); + HMAC_CPP_API std::vector get_hash(const void* data, size_t length, TypeHash type); /// \brief Computes a hash of a vector using the selected hash function. /// \tparam T Type of the vector element (char or uint8_t). @@ -51,7 +52,7 @@ namespace hmac_cpp { } /// \brief Streaming HMAC computation context. - class HmacContext { + class HMAC_CPP_API HmacContext { public: explicit HmacContext(TypeHash type) : type_(type), block_size_(0), digest_size_(0) {} @@ -88,7 +89,7 @@ namespace hmac_cpp { /// \param type Hash function type /// \return HMAC result as a vector of bytes /// \throws std::invalid_argument If any pointer is null while the corresponding length is non-zero - std::vector get_hmac(const void* key_ptr, size_t key_len, const void* msg_ptr, size_t msg_len, TypeHash type); + HMAC_CPP_API std::vector get_hmac(const void* key_ptr, size_t key_len, const void* msg_ptr, size_t msg_len, TypeHash type); /// \brief Computes HMAC from key and message byte vectors using the specified hash function /// \tparam T Byte type: must be either char or uint8_t @@ -111,7 +112,7 @@ namespace hmac_cpp { /// \param is_hex Return result in hex format /// \param is_upper Use uppercase hex /// \return HMAC result - std::string get_hmac(const std::vector& key, const std::string &msg, TypeHash type, bool is_hex = true, bool is_upper = false); + HMAC_CPP_API std::string get_hmac(const std::vector& key, const std::string &msg, TypeHash type, bool is_hex = true, bool is_upper = false); /// \brief Computes HMAC from secure_buffer key inline std::string get_hmac(const secure_buffer& key, const std::string &msg, TypeHash type, bool is_hex = true, bool is_upper = false) { diff --git a/include/hmac_cpp/hmac_utils.hpp b/include/hmac_cpp/hmac_utils.hpp index d4e1bd1..c11e6e6 100644 --- a/include/hmac_cpp/hmac_utils.hpp +++ b/include/hmac_cpp/hmac_utils.hpp @@ -21,7 +21,7 @@ namespace hmac_cpp { /// \param b Pointer to second array /// \param b_len Length of the second array /// \return true if both arrays are equal - bool constant_time_equals(const uint8_t* a, size_t a_len, + HMAC_CPP_API bool constant_time_equals(const uint8_t* a, size_t a_len, const uint8_t* b, size_t b_len); inline bool constant_time_equals(const std::vector& a, @@ -77,7 +77,7 @@ namespace hmac_cpp { /// \param dk_len Desired length of the derived key in bytes, must be positive /// \param hash_type Hash function to use (SHA1, SHA256, SHA512) /// \return Derived key as a vector of bytes - std::vector pbkdf2( + HMAC_CPP_API std::vector pbkdf2( const void* password_ptr, size_t password_len, const void* salt_ptr, size_t salt_len, uint32_t iterations, size_t dk_len, @@ -163,7 +163,7 @@ namespace hmac_cpp { /// \param out_ptr Output buffer for derived key /// \param dk_len Length of output buffer in bytes, must be positive /// \return true on success, false on invalid parameters - bool pbkdf2(Pbkdf2Hash prf, + HMAC_CPP_API bool pbkdf2(Pbkdf2Hash prf, const void* password_ptr, size_t password_len, const void* salt_ptr, size_t salt_len, uint32_t iterations, uint8_t* out_ptr, size_t dk_len) noexcept; @@ -211,7 +211,7 @@ namespace hmac_cpp { /// \param out_ptr Output buffer for derived key /// \param dk_len Length of output buffer in bytes, must be positive /// \return true on success, false on invalid parameters - bool pbkdf2_hmac_sha256(const void* password_ptr, size_t password_len, + HMAC_CPP_API bool pbkdf2_hmac_sha256(const void* password_ptr, size_t password_len, const void* salt_ptr, size_t salt_len, uint32_t iterations, uint8_t* out_ptr, size_t dk_len) noexcept; @@ -271,7 +271,7 @@ namespace hmac_cpp { /// \param dk_len Desired length of the derived key in bytes, must be positive. /// \param prf Hash function to use (SHA1, SHA256, SHA512). /// \return Derived key as a vector of bytes. - std::vector pbkdf2_with_pepper( + HMAC_CPP_API std::vector pbkdf2_with_pepper( const void* password_ptr, size_t password_len, const void* salt_ptr, size_t salt_len, const void* pepper_ptr, size_t pepper_len, @@ -343,7 +343,7 @@ namespace hmac_cpp { /// \param salt_ptr Pointer to optional salt buffer (may be null when salt_len is 0). /// \param salt_len Length of the salt in bytes. /// \return Pseudorandom key (PRK) as a byte vector. - std::vector hkdf_extract_sha256( + HMAC_CPP_API std::vector hkdf_extract_sha256( const void* ikm_ptr, size_t ikm_len, const void* salt_ptr, size_t salt_len); @@ -360,7 +360,7 @@ namespace hmac_cpp { /// \param info_len Length of the info buffer in bytes. /// \param L Length of output keying material in bytes. /// \return Output keying material as a byte vector. - std::vector hkdf_expand_sha256( + HMAC_CPP_API std::vector hkdf_expand_sha256( const void* prk_ptr, size_t prk_len, const void* info_ptr, size_t info_len, size_t L); @@ -401,7 +401,7 @@ namespace hmac_cpp { /// \param hash_type Hash function to use (SHA1, SHA256, SHA512). Default is SHA256 /// \return Hex-encoded HMAC-SHA256 of the rounded time value /// \throws std::runtime_error if the system time cannot be retrieved - std::string generate_time_token(const std::vector& key, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); + HMAC_CPP_API std::string generate_time_token(const std::vector& key, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); inline std::string generate_time_token(const secure_buffer& key, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256) { return generate_time_token(std::vector(key.begin(), key.end()), interval_sec, hash_type); } @@ -418,7 +418,7 @@ namespace hmac_cpp { /// \param hash_type Hash function to use (SHA1, SHA256, SHA512). Default is SHA256 /// \return true if the token is valid within the ±1 interval range; false otherwise /// \throws std::runtime_error if the system time cannot be retrieved - bool is_token_valid(const std::string &token, const std::vector& key, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); + HMAC_CPP_API bool is_token_valid(const std::string &token, const std::vector& key, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); inline bool is_token_valid(const std::string &token, const secure_buffer& key, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256) { return is_token_valid(token, std::vector(key.begin(), key.end()), interval_sec, hash_type); } @@ -435,7 +435,7 @@ namespace hmac_cpp { /// \param hash_type Hash function to use (SHA1, SHA256, SHA512). Default is SHA256 /// \return Hex-encoded HMAC-SHA256 of the concatenated timestamp and fingerprint /// \throws std::runtime_error if the system time cannot be retrieved - std::string generate_time_token(const std::vector& key, const std::string &fingerprint, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); + HMAC_CPP_API std::string generate_time_token(const std::vector& key, const std::string &fingerprint, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); inline std::string generate_time_token(const secure_buffer& key, const std::string &fingerprint, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256) { return generate_time_token(std::vector(key.begin(), key.end()), fingerprint, interval_sec, hash_type); } @@ -453,7 +453,7 @@ namespace hmac_cpp { /// \param hash_type Hash function to use (SHA1, SHA256, SHA512). Default is SHA256 /// \return true if the token is valid within the ±1 interval range; false otherwise /// \throws std::runtime_error if the system time cannot be retrieved - bool is_token_valid(const std::string &token, const std::vector& key, const std::string &fingerprint, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); + HMAC_CPP_API bool is_token_valid(const std::string &token, const std::vector& key, const std::string &fingerprint, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256); inline bool is_token_valid(const std::string &token, const secure_buffer& key, const std::string &fingerprint, int interval_sec = 60, TypeHash hash_type = TypeHash::SHA256) { return is_token_valid(token, std::vector(key.begin(), key.end()), fingerprint, interval_sec, hash_type); } @@ -470,7 +470,7 @@ namespace hmac_cpp { /// \param digits Desired number of digits in the OTP (typically 6–8, max 9) /// \param hash_type Hash function to use (SHA1, SHA256, SHA512). Default is SHA1 /// \return One-Time Password (OTP) as an integer in the range [0, 10^digits) - int get_hotp_code(const void* key_ptr, size_t key_len, uint64_t counter, int digits = 6, TypeHash hash_type = TypeHash::SHA1); + HMAC_CPP_API int get_hotp_code(const void* key_ptr, size_t key_len, uint64_t counter, int digits = 6, TypeHash hash_type = TypeHash::SHA1); /// \brief Computes HOTP code from a vector of bytes as key (RFC 4226) /// \tparam T Must be either `char` or `uint8_t` @@ -508,7 +508,7 @@ namespace hmac_cpp { /// \param digits Desired number of digits in the OTP (1-9) /// \return One-Time Password (OTP) as an integer /// \throws std::runtime_error if the digest is too short for dynamic truncation - int hotp_from_digest(const std::vector& hmac_result, int digits); + HMAC_CPP_API int hotp_from_digest(const std::vector& hmac_result, int digits); } /// \brief Computes TOTP (Time-Based One-Time Password) code for a specific timestamp @@ -521,7 +521,7 @@ namespace hmac_cpp { /// \param hash_type Hash function to use (SHA1, SHA256, SHA512; default: SHA1) /// \return TOTP code as an integer /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] - int get_totp_code_at( + HMAC_CPP_API int get_totp_code_at( const void* key_ptr, size_t key_len, uint64_t timestamp, @@ -587,7 +587,7 @@ namespace hmac_cpp { /// \return TOTP code as an integer. /// \throws std::invalid_argument if period <= 0 or digits not in [1,9]. /// \throws std::runtime_error if the system time cannot be retrieved. - int get_totp_code( + HMAC_CPP_API int get_totp_code( const void* key_ptr, size_t key_len, int period = 30, @@ -638,7 +638,7 @@ namespace hmac_cpp { /// The +1 step check is skipped when the computed counter equals /// std::numeric_limits::max(). /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] - bool is_totp_token_valid( + HMAC_CPP_API bool is_totp_token_valid( int token, const void* key_ptr, size_t key_len, @@ -728,7 +728,7 @@ namespace hmac_cpp { /// std::numeric_limits::max(). /// \throws std::invalid_argument if period <= 0 or digits not in [1,9] /// \throws std::runtime_error if the system time cannot be retrieved - bool is_totp_token_valid( + HMAC_CPP_API bool is_totp_token_valid( int token, const void* key_ptr, size_t key_len, diff --git a/include/hmac_cpp/sha1.hpp b/include/hmac_cpp/sha1.hpp index d08cfef..8b72b84 100644 --- a/include/hmac_cpp/sha1.hpp +++ b/include/hmac_cpp/sha1.hpp @@ -24,11 +24,12 @@ #include #include #include +#include "api.hpp" namespace hmac_hash { /// \brief Class for computing SHA1 hash - class SHA1 { + class HMAC_CPP_API SHA1 { public: /// \brief Initializes SHA1 context @@ -60,18 +61,18 @@ namespace hmac_hash { /// \param data Pointer to input data /// \param length Length of the input data /// \param digest Output buffer of size SHA1::DIGEST_SIZE - void sha1(const void* data, size_t length, uint8_t* digest); + HMAC_CPP_API void sha1(const void* data, size_t length, uint8_t* digest); /// \brief Computes SHA1 hash of a raw byte buffer /// \param data Pointer to input data /// \param length Length of the input data /// \return Vector containing the SHA1 digest - std::vector sha1(const void* data, size_t length); + HMAC_CPP_API std::vector sha1(const void* data, size_t length); /// \brief Computes SHA1 hash of a string /// \param input Input string /// \return Hash as a binary string - std::string sha1(const std::string &input); + HMAC_CPP_API std::string sha1(const std::string &input); /// \brief Computes SHA1 hash of a vector of bytes /// \tparam T Type of the vector element (char or uint8_t) diff --git a/include/hmac_cpp/sha256.hpp b/include/hmac_cpp/sha256.hpp index 6d5ffb5..5ad9bed 100644 --- a/include/hmac_cpp/sha256.hpp +++ b/include/hmac_cpp/sha256.hpp @@ -46,11 +46,12 @@ #include #include #include +#include "api.hpp" namespace hmac_hash { /// \brief Class for computing SHA256 hash - class SHA256 { + class HMAC_CPP_API SHA256 { protected: const static uint32_t sha256_k[]; @@ -83,18 +84,18 @@ namespace hmac_hash { /// \param data Pointer to input data /// \param length Length of the input data /// \param digest Output buffer of size SHA256::DIGEST_SIZE - void sha256(const void* data, size_t length, uint8_t* digest); + HMAC_CPP_API void sha256(const void* data, size_t length, uint8_t* digest); /// \brief Computes SHA256 hash of a raw byte buffer /// \param data Pointer to input data /// \param length Length of the input data /// \return Vector containing the SHA256 digest - std::vector sha256(const void* data, size_t length); + HMAC_CPP_API std::vector sha256(const void* data, size_t length); /// \brief Computes SHA256 hash of a string /// \param input Input string /// \return Hash as a binary string - std::string sha256(const std::string &input); + HMAC_CPP_API std::string sha256(const std::string &input); /// \brief Computes SHA256 hash of a vector of bytes /// \tparam T Type of the vector element (char or uint8_t) diff --git a/include/hmac_cpp/sha512.hpp b/include/hmac_cpp/sha512.hpp index b2e7681..a9ec90e 100644 --- a/include/hmac_cpp/sha512.hpp +++ b/include/hmac_cpp/sha512.hpp @@ -46,6 +46,7 @@ #include #include #include +#include "api.hpp" namespace hmac_hash { @@ -53,7 +54,7 @@ namespace hmac_hash { /// /// SHA-512 is the largest hash function in the SHA-2 family. /// It provides 256-bit security for digital signatures and hash-only applications. - class SHA512 { + class HMAC_CPP_API SHA512 { protected: const static uint64_t sha512_k[]; @@ -86,18 +87,18 @@ namespace hmac_hash { /// \param data Pointer to input data /// \param length Length of the input data /// \param digest Output buffer of size SHA512::DIGEST_SIZE - void sha512(const void* data, size_t length, uint8_t* digest); + HMAC_CPP_API void sha512(const void* data, size_t length, uint8_t* digest); /// \brief Computes SHA512 hash of a raw byte buffer /// \param data Pointer to input data /// \param length Length of the input data /// \return Vector containing the SHA512 digest - std::vector sha512(const void* data, size_t length); + HMAC_CPP_API std::vector sha512(const void* data, size_t length); /// \brief Computes SHA512 hash of a string /// \param input Input string /// \return Hash as a binary string - std::string sha512(const std::string &input); + HMAC_CPP_API std::string sha512(const std::string &input); /// \brief Computes SHA512 hash of a vector of bytes /// \tparam T Type of the vector element (char or uint8_t)