Botan 3.0.0
Crypto and TLS for C&
hotp.cpp
Go to the documentation of this file.
1/*
2* HOTP
3* (C) 2017 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/otp.h>
9#include <botan/internal/loadstor.h>
10#include <botan/exceptn.h>
11
12namespace Botan {
13
14HOTP::HOTP(const uint8_t key[], size_t key_len,
15 std::string_view hash_algo, size_t digits)
16 {
17 BOTAN_ARG_CHECK(digits == 6 || digits == 7 || digits == 8, "Invalid HOTP digits");
18
19 if(digits == 6)
20 m_digit_mod = 1000000;
21 else if(digits == 7)
22 m_digit_mod = 10000000;
23 else if(digits == 8)
24 m_digit_mod = 100000000;
25
26 /*
27 RFC 4228 only supports SHA-1 but TOTP allows SHA-256 and SHA-512
28 and some HOTP libs support one or both as extensions
29 */
30 if(hash_algo == "SHA-1")
31 m_mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-1)");
32 else if(hash_algo == "SHA-256")
33 m_mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
34 else if(hash_algo == "SHA-512")
35 m_mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-512)");
36 else
37 throw Invalid_Argument("Unsupported HOTP hash function");
38
39 m_mac->set_key(key, key_len);
40 }
41
42uint32_t HOTP::generate_hotp(uint64_t counter)
43 {
44 m_mac->update_be(counter);
45 const secure_vector<uint8_t> mac = m_mac->final();
46
47 const size_t offset = mac[mac.size()-1] & 0x0F;
48 const uint32_t code = load_be<uint32_t>(mac.data() + offset, 0) & 0x7FFFFFFF;
49 return code % m_digit_mod;
50 }
51
52std::pair<bool,uint64_t> HOTP::verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range)
53 {
54 for(size_t i = 0; i <= resync_range; ++i)
55 {
56 if(generate_hotp(starting_counter + i) == otp)
57 return std::make_pair(true, starting_counter + i + 1);
58 }
59 return std::make_pair(false, starting_counter);
60 }
61
62}
63
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:36
uint32_t generate_hotp(uint64_t counter)
Definition: hotp.cpp:42
HOTP(const SymmetricKey &key, std::string_view hash_algo="SHA-1", size_t digits=6)
Definition: otp.h:27
std::pair< bool, uint64_t > verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range=0)
Definition: hotp.cpp:52
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition: mac.cpp:134
Definition: alg_id.cpp:12
constexpr uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:190
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64