10#include <botan/exceptn.h>
11#include <botan/internal/loadstor.h>
15HOTP::HOTP(
const uint8_t key[],
size_t key_len, std::string_view hash_algo,
size_t digits) {
16 BOTAN_ARG_CHECK(digits == 6 || digits == 7 || digits == 8,
"Invalid HOTP digits");
19 m_digit_mod = 1000000;
20 }
else if(digits == 7) {
21 m_digit_mod = 10000000;
22 }
else if(digits == 8) {
23 m_digit_mod = 100000000;
30 if(hash_algo ==
"SHA-1") {
32 }
else if(hash_algo ==
"SHA-256") {
34 }
else if(hash_algo ==
"SHA-512") {
40 m_mac->set_key(key, key_len);
44 m_mac->update_be(counter);
47 const size_t offset = mac[mac.size() - 1] & 0x0F;
49 return code % m_digit_mod;
52std::pair<bool, uint64_t>
HOTP::verify_hotp(uint32_t otp, uint64_t starting_counter,
size_t resync_range) {
53 for(
size_t i = 0; i <= resync_range; ++i) {
55 return std::make_pair(
true, starting_counter + i + 1);
58 return std::make_pair(
false, starting_counter);
#define BOTAN_ARG_CHECK(expr, msg)
uint32_t generate_hotp(uint64_t counter)
HOTP(const SymmetricKey &key, std::string_view hash_algo="SHA-1", size_t digits=6)
std::pair< bool, uint64_t > verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range=0)
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)