10#include <botan/exceptn.h>
11#include <botan/internal/loadstor.h>
19uint32_t hotp_truncate(uint32_t code,
size_t digits) {
22 return code % 1000000;
24 return code % 10000000;
26 return code % 100000000;
34HOTP::HOTP(
const uint8_t key[],
size_t key_len, std::string_view hash_algo,
size_t digits) : m_digits(digits) {
35 BOTAN_ARG_CHECK(m_digits == 6 || m_digits == 7 || m_digits == 8,
"Invalid HOTP digits");
41 if(hash_algo ==
"SHA-1") {
43 }
else if(hash_algo ==
"SHA-256") {
45 }
else if(hash_algo ==
"SHA-512") {
51 m_mac->set_key(key, key_len);
55 m_mac->update_be(counter);
58 const size_t offset = mac[mac.size() - 1] & 0x0F;
60 return hotp_truncate(code, m_digits);
63std::pair<bool, uint64_t>
HOTP::verify_hotp(uint32_t otp, uint64_t starting_counter,
size_t resync_range) {
64 for(
size_t i = 0; i <= resync_range; ++i) {
66 return std::make_pair(
true, starting_counter + i + 1);
69 return std::make_pair(
false, starting_counter);
#define BOTAN_ARG_CHECK(expr, msg)
#define BOTAN_ASSERT_UNREACHABLE()
uint32_t generate_hotp(uint64_t counter)
std::pair< bool, uint64_t > verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range=0)
BOTAN_FUTURE_EXPLICIT HOTP(const SymmetricKey &key, std::string_view hash_algo="SHA-1", size_t digits=6)
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
std::vector< T, secure_allocator< T > > secure_vector
constexpr auto load_be(ParamTs &&... params)