+void memory_clean(void) {
+ memset(secret, 0, 32);
+ secret_length_b = 0;
+}
+
+uint8_t secret_set(void){
+ uint8_t r;
+ union {
+ uint8_t w8[32];
+ uint16_t w16[16];
+ } read_back;
+ const uint8_t length_B = (secret_length_b + 7) / 8;
+
+ eeprom_busy_wait();
+ eeprom_write_block(secret, secret_ee, length_B);
+ eeprom_busy_wait();
+ eeprom_read_block(read_back.w8, secret_ee, length_B);
+ r = memcmp(secret, read_back.w8, length_B);
+ memory_clean();
+ memset(read_back.w8, 0, 32);
+ if (r) {
+ return 1;
+ }
+ eeprom_busy_wait();
+ eeprom_write_word(&secret_length_ee, secret_length_b);
+ eeprom_busy_wait();
+ r = eeprom_read_word(&secret_length_ee) == secret_length_b;
+ memory_clean();
+ *read_back.w16 = 0;
+ if (!r) {
+ return 1;
+ }
+ return 0;
+}
+
+void token_generate(void) {
+ percnt_inc(0);
+ eeprom_busy_wait();
+ eeprom_read_block(secret, secret_ee, 32);
+ eeprom_busy_wait();
+ hotp(token, secret, eeprom_read_word(&secret_length_ee), percnt_get(0), eeprom_read_byte(&digits_ee));
+ memory_clean();
+}
+
+void counter_reset(void) {
+ uint8_t reset_counter;
+ eeprom_busy_wait();
+ reset_counter = eeprom_read_byte(&reset_counter_ee);
+ percnt_reset(0);
+ eeprom_busy_wait();
+ eeprom_write_byte(&reset_counter_ee, reset_counter + 1);
+}
+
+void counter_init(void) {
+ eeprom_busy_wait();
+ if (eeprom_read_byte(&reset_counter_ee) == 0) {
+ counter_reset();
+ }
+ percnt_init(0);
+}
+