#include "trunc.h" int32_t get_otp_from_cnt(uint64_t cnt, uint8_t digits, uint8_t* secret, uint8_t sec_len){ uint8_t tmp[8]={((uint8_t*)&cnt)[7],((uint8_t*)&cnt)[6],((uint8_t*)&cnt)[5],((uint8_t*)&cnt)[4],((uint8_t*)&cnt)[3],((uint8_t*)&cnt)[2],((uint8_t*)&cnt)[1],((uint8_t*)&cnt)[0]}; /*Step 1 generate HMAC-SHA1*/ hmac(tmp,8,secret,sec_len); return get_otp(hmac_result,digits); } int32_t get_otp(uint8_t* hmac, uint8_t digits){ uint8_t n; uint32_t dt; /*Step 1 generate HMAC-SHA1*/ /*Step 2 get DT(HMAC) */ /* get the lower 4-bits and treat them as a number n*/ /* DT is the 31bit integer at HMAC[n]+HMAC[n+1]+HMAC[n+2]+HMAC[n+3]*/ /* the MSB is ignored */ n=hmac[0] & 0x0F; dt= (uint32_t)(hmac[SHA1_SIZE-1-n]&0x7F)<<(uint32_t)24 | (uint32_t)(hmac[SHA1_SIZE-2-n])<<(uint32_t)16 | (uint32_t)(hmac[SHA1_SIZE-3-n])<<(uint32_t)8 | (uint32_t)(hmac[SHA1_SIZE-4-n]); /*Step 3 return dt mod 10^digits*/ switch(digits){ case 6: return dt % 1000000; case 7: return dt % 10000000; default: case 8: return dt % 100000000; } }