Botan  2.9.0
Crypto and TLS for C++11
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/hotp.h>
9 #include <botan/exceptn.h>
10 
11 namespace Botan {
12 
13 HOTP::HOTP(const uint8_t key[], size_t key_len,
14  const std::string& hash_algo, size_t digits)
15  {
16  BOTAN_ARG_CHECK(digits == 6 || digits == 7 || digits == 8, "Invalid HOTP digits");
17 
18  if(digits == 6)
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;
24 
25  /*
26  RFC 4228 only supports SHA-1 but TOTP allows SHA-256 and SHA-512
27  and some HOTP libs support one or both as extensions
28  */
29  if(hash_algo == "SHA-1")
30  m_mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-1)");
31  else if(hash_algo == "SHA-256")
32  m_mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
33  else if(hash_algo == "SHA-512")
34  m_mac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-512)");
35  else
36  throw Invalid_Argument("Unsupported HOTP hash function");
37 
38  m_mac->set_key(key, key_len);
39  }
40 
41 uint32_t HOTP::generate_hotp(uint64_t counter)
42  {
43  m_mac->update_be(counter);
44  const secure_vector<uint8_t> mac = m_mac->final();
45 
46  const size_t offset = mac[mac.size()-1] & 0x0F;
47  const uint32_t code = load_be<uint32_t>(mac.data() + offset, 0) & 0x7FFFFFFF;
48  return code % m_digit_mod;
49  }
50 
51 std::pair<bool,uint64_t> HOTP::verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range)
52  {
53  for(size_t i = 0; i <= resync_range; ++i)
54  {
55  if(generate_hotp(starting_counter + i) == otp)
56  return std::make_pair(true, starting_counter + i + 1);
57  }
58  return std::make_pair(false, starting_counter);
59  }
60 
61 }
62 
uint32_t load_be< uint32_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:177
Definition: alg_id.cpp:13
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:37
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:23
HOTP(const SymmetricKey &key, const std::string &hash_algo="SHA-1", size_t digits=6)
Definition: hotp.h:26
std::pair< bool, uint64_t > verify_hotp(uint32_t otp, uint64_t starting_counter, size_t resync_range=0)
Definition: hotp.cpp:51
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:141
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
uint32_t generate_hotp(uint64_t counter)
Definition: hotp.cpp:41