Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ project(hmac_cpp VERSION 0.3.0 LANGUAGES CXX)
option(HMACCPP_BUILD_EXAMPLES "Build the example program" OFF)
option(HMACCPP_BUILD_TESTS "Build the test suite" OFF)
option(HMACCPP_BUILD_BENCH "Build benchmarks" OFF)
option(HMACCPP_BUILD_SHARED "Build hmac_cpp as a shared library" OFF)

if(HMACCPP_BUILD_SHARED)
set(BUILD_SHARED_LIBS ON)
endif()

set(HMAC_SOURCES
src/sha1.cpp
Expand All @@ -23,6 +28,7 @@ set(HMAC_HEADERS
include/hmac_cpp/sha512.hpp
include/hmac_cpp/secure_buffer.hpp
include/hmac_cpp/encoding.hpp
include/hmac_cpp/version.hpp
)

add_library(hmac_cpp ${HMAC_SOURCES})
Expand Down Expand Up @@ -91,6 +97,9 @@ install(FILES
DESTINATION lib/cmake/hmac_cpp
)

configure_file(cmake/hmac_cpp.pc.in "${CMAKE_CURRENT_BINARY_DIR}/hmac_cpp.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/hmac_cpp.pc" DESTINATION lib/pkgconfig)

if(HMACCPP_BUILD_TESTS)
enable_testing()
include(FetchContent)
Expand Down
61 changes: 44 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ CI covers Linux/Windows/macOS. Tested with GCC, Clang, and MSVC; requires C++11.

---

## 📈 Versioning / SemVer policy

* Follows [Semantic Versioning](https://semver.org).
* MAJOR: breaking changes to headers or exported symbols.
* MINOR: backward-compatible additions.
* PATCH: bug fixes and internal changes.

Version macros live in `<hmac_cpp/version.hpp>`:
`HMAC_CPP_VERSION_MAJOR`, `HMAC_CPP_VERSION_MINOR`,
`HMAC_CPP_VERSION_PATCH`, and `HMAC_CPP_VERSION`.
See [CHANGELOG.md](CHANGELOG.md) for history.

---

## 🔧 Build & Installation

Examples, tests, and benchmarks are OFF by default. Enable via:
Expand All @@ -40,6 +54,10 @@ Examples, tests, and benchmarks are OFF by default. Enable via:
* `HMACCPP_BUILD_TESTS`
* `HMACCPP_BUILD_BENCH`

The library builds **static** by default. Use `-DHMACCPP_BUILD_SHARED=ON`
to produce a shared library. The `HMAC_CPP_API` macro is empty for static
builds and controls symbol export/import for shared builds.

### Build

```bash
Expand All @@ -51,23 +69,21 @@ cmake --build build

```bash
cmake --install build --prefix _install
# MSVC
cmake --install build --config Release --prefix _install
```

Install layout:

```
_install/
├─ include/hmac_cpp/
│ ├─ hmac.hpp
│ ├─ hmac_utils.hpp
│ ├─ sha1.hpp
│ ├─ sha256.hpp
│ ├─ sha512.hpp
│ └─ secure_buffer.hpp # if included in your build
└─ lib/
└─ libhmac_cpp.a
├── include/hmac_cpp/...
└── lib/
└── libhmac_cpp.a
```

A `hmac_cpp.pc` file is installed for `pkg-config`.

### Consume with CMake

```cmake
Expand All @@ -80,6 +96,10 @@ target_link_libraries(my_app PRIVATE hmac_cpp::hmac_cpp)
```bash
# adjust paths to your prefix
g++ example.cpp -std=c++11 -I_install/include -L_install/lib -lhmac_cpp
# MSVC
cl /EHsc example.cpp /I _install\include /link /LIBPATH:_install\lib hmac_cpp.lib
# pkg-config
c++ example.cpp $(pkg-config --cflags --libs hmac_cpp)
```

Predefined MinGW build scripts are available: `build_*.bat`.
Expand Down Expand Up @@ -154,6 +174,8 @@ auto key = hmac::pbkdf2_hmac_sha256(password, salt, iters, 32); // 32 = AES-256
* **Iterations**: tune for \~100–250 ms on target hardware (e.g., desktop ≈ 600k, laptop ≈ 300k, mobile ≈ 150k; adjust).
* **Derived key length**: 32 bytes; **PRF**: HMAC-SHA256.

> PBKDF2 is CPU-bound; for user passwords prefer memory-hard KDFs such as Argon2 or scrypt if available.

**Serialization example** (binary):

```
Expand Down Expand Up @@ -262,12 +284,14 @@ ctest --test-dir build --output-on-failure

Covered vectors:

* HMAC — **RFC 4231**
* PBKDF2 — **RFC 6070**
* HOTP — **RFC 4226** (Appendix D)
* TOTP — **RFC 6238** (Appendix B)
| Suite | RFC |
| ------ | --- |
| HMAC | RFC 4231 |
| PBKDF2 | RFC 6070 |
| HOTP | RFC 4226 (App D) |
| TOTP | RFC 6238 (App B) |

CI runs these on Linux/Windows/macOS.
CI: [GitHub Actions](https://github.com/NewYaroslav/hmac-cpp/actions).

---

Expand Down Expand Up @@ -302,15 +326,18 @@ g++ example.cpp -std=c++11 -I_install/include -L_install/lib -lhmac_cpp
MSVC:

```bat
cl /EHsc example.cpp /I _install\include /link /LIBPATH:_install\lib hmach_cpp.lib
cl /EHsc example.cpp /I _install\include /link /LIBPATH:_install\lib hmac_cpp.lib
```

---

## ⚠️ Exceptions & Contracts

* Functions may throw `std::invalid_argument` (bad params) and `std::runtime_error` (internal errors).
* `constant_time_equal` assumes lengths are public; compare sizes first.
* `pbkdf2`, `hkdf_*`, HOTP/TOTP, and time-token helpers validate parameters and throw
`std::invalid_argument`; time-token helpers also throw `std::runtime_error` if the
system clock fails.
* `base64_decode` and `base32_decode` are `noexcept` and return `false` on invalid input.
* `constant_time_equal` is `noexcept`; compare sizes first.
* PBKDF2 limits: `dkLen ≤ (2^32−1)·hLen`; iterations ≥ 1; salt length ≥ 16 recommended.
* HKDF limits: `L ≤ 255·HashLen`.
* Thread-safety: functions are stateless and thread-safe given separate buffers.
Expand Down
10 changes: 10 additions & 0 deletions cmake/hmac_cpp.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: hmac_cpp
Description: HMAC/PBKDF2/HKDF library
Version: @PROJECT_VERSION@
Libs: -L${libdir} -lhmac_cpp
Cflags: -I${includedir}
1 change: 1 addition & 0 deletions include/hmac_cpp/hmac_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ namespace hmac_cpp {

/// PBKDF2 Security Notes:
/// - Use a random salt of at least 16 bytes and never reuse it.
/// - PBKDF2 is CPU-bound; prefer Argon2 or scrypt for user passwords when available.
/// - Choose iterations so the derivation takes about 200–500 ms on 2025 hardware.
/// - Store {salt, iterations} with the ciphertext or hash; these values are public.
/// - Salts and iteration counts must be unique per password.
Expand Down
9 changes: 9 additions & 0 deletions include/hmac_cpp/version.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef HMAC_CPP_VERSION_HPP
#define HMAC_CPP_VERSION_HPP

#define HMAC_CPP_VERSION_MAJOR 0
#define HMAC_CPP_VERSION_MINOR 3
#define HMAC_CPP_VERSION_PATCH 0
#define HMAC_CPP_VERSION "0.3.0"

#endif // HMAC_CPP_VERSION_HPP
Loading