facil.io

#OTP (TOTP)

c
#define FIO_OTP
#include "fio-stl.h"

Time-based One-Time Password helper. Implements the TOTP algorithm over HMAC-SHA-1, compatible with common authenticator apps. It can generate keys, encode them as Base32, and compute codes for the current time or a fixed timestamp.

#Types

#fio_otp_settings_s

c
typedef struct {
  /** The time interval for TOTP rotation. */
  size_t interval; /* 30 == Google OTP */
  /** The number of digits in the OTP. */
  size_t digits; /* 6 == Google OTP */
  /** The time offset (in `interval` units) from the current time. */
  int64_t offset; /* 0 == Google OTP */
  /** Set to true if the secret / key is in Hex instead of Base32. */
  uint8_t is_hex;
  /** Set to true if the secret / key is raw bit data (no encoding). */
  uint8_t is_raw;
} fio_otp_settings_s;

Configuration for OTP generation. Fields omitted in the named-argument macro call default to zero; the implementation then substitutes the Google-OTP defaults (30-second interval, 6 digits, zero offset).

#API Functions

#fio_otp_generate_key

c
FIO_IFUNC fio_u128 fio_otp_generate_key(void);

Generates a cryptographically secure random 128-bit key.

Returns: a 16-byte random key suitable for TOTP secrets.

#fio_otp_print_key

c
FIO_IFUNC size_t fio_otp_print_key(char *dest, uint8_t *key, size_t len);

Encodes a key as a Base32 string for sharing with authenticator apps.

Parameters:

  • dest — output buffer. Must be at least len * 2 + 1 bytes.
  • key — key bytes; if NULL, a new random key is generated and encoded.
  • len — key length in bytes.

Returns: length of the encoded string written to dest.

#fio_otp

c
SFUNC uint32_t fio_otp(fio_buf_info_s secret, fio_otp_settings_s settings);
/* Named arguments using macro. */
#define fio_otp(secret, ...) fio_otp(secret, (fio_otp_settings_s){__VA_ARGS__})

Computes a TOTP for the current wall-clock time.

Parameters:

  • secret — shared secret as a fio_buf_info_s.

Named Arguments:

Argument Type Description
interval size_t rotation interval in seconds; defaults to 30
digits size_t number of output digits; defaults to 6
offset int64_t interval offset from now; defaults to 0
is_hex uint8_t set if secret is Hex encoded
is_raw uint8_t set if secret is raw bytes

Returns: the OTP value.

#fio_otp_at

c
SFUNC uint32_t fio_otp_at(fio_buf_info_s secret,
                          uint64_t unix_time,
                          fio_otp_settings_s settings);
/* Named arguments using macro. */
#define fio_otp_at(secret, unix_time, ...)                                     \
  fio_otp_at(secret, unix_time, (fio_otp_settings_s){__VA_ARGS__})

Computes a TOTP for a specific Unix timestamp. Useful for tests and RFC vectors.

Parameters:

  • secret — shared secret as a fio_buf_info_s.
  • unix_time — timestamp to compute the OTP for.

Named Arguments: same as fio_otp.

Returns: the OTP value.

#Example

c
#define FIO_OTP
#include "fio-stl.h"

int main(void) {
  /* Generate and print a new Base32 secret. */
  char key_str[64];
  fio_otp_print_key(key_str, NULL, 0);
  printf("secret: %s\n", key_str);

  /* Compute the current 6-digit code. */
  uint32_t code = fio_otp(FIO_BUF_INFO1(key_str));
  printf("code: %06u\n", code);
  return 0;
}