Skip to content

[Completed] TOTP implemented with RFC2104, RFC3174, RFC4226, RFC6234, RFC6238

License

Notifications You must be signed in to change notification settings

jameshi16/Bad-TOTP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bad-TOTP

Tests

Prefixed with "Bad" because this is not meant to be used in production.

Bad-TOTP is a small educational-only project that I decided to do in a weekend to learn about Time-based One Time Passwords (TOTP), and how they work. I then made the decision to implement everything required for TOTPs from scratch (i.e. using nothing but standard C and some standard library functions), including the SHA-1 hash algorithm (and its brothers, SHA-256 and SHA-512), Hash-based Message Authentication Code (HMAC), and Hash-based One Time Passwords (HOTP).

This repository contains all the code created from the aftermath.

Usage

This project uses header files only. Default parameters from RFC 6238 are used, such as the time step (30 seconds), and T0 = 0; these parameters are widely used in all forms of TOTPs on the internet.

You would minimally need totp.h, hotp.h, and one of sha1.h, sha256.h or sha512.h. Here is sample code utilizing sha1.h as the hash header:

#include "sha1.h"
#include "hotp.h"
#include "totp.h"

#include <stdio.h>

int main() {
  const char secret[] = "a very secret key!!!";

  hotp_context ctx;
  ctx.secret = (const uint8_t*) secret;
  ctx.secretSize = sizeof(secret) - 1;
  ctx.hashFn = (void* (*) (const void*, size_t)) method_two;
  ctx.blockSize = 64;
  ctx.outputLength = 20;

  printf("%d\n", totp(&ctx, 6));
  return 0;
}

Given that your secret is the perfect length, i.e. divisible by the output length of the hash function, this OTP should be consistent with other RFC6238 implementations. However, if the secret isn't aligned to the output length perfectly, 0s will be padded to the end of the string until the output length is perfect-lengthed (as defined in RFC2104 page 3).

Relevant blog post

Implementing TOTPs from scratch