Giter Club home page Giter Club logo

totp-mcu's Introduction

TOTP Pure C Library for ALL MCU

Library to generate Time-based One-Time Passwords.

Implements the Time-based One-Time Password algorithm specified in RFC 6238. Supports different time steps and is compatible with tokens that use the same standard (including software ones, like the Google Authenticator app).

Tested on MCUs: MSP430, RP2040

Installation & usage:

First include header to your file

#include <totp.h>

After included, define key ex. Key is MyLegoDoor

  • Note: The format of hmacKey is array of hexadecimal bytes.
  • Most websites provide the key encoded in base32 - RFC3548/RFC4648, either upper or lower case. You can use this site to convert the base32 string to hex (make sure you upcase it first if it's lowercase and remove all whitespaces).
uint8_t hmacKey[] = {0x4d, 0x79, 0x4c, 0x65, 0x67, 0x6f, 0x44, 0x6f, 0x6f, 0x72};               // Secret key

Instantiate the TOTP class by providing the secret hmacKey, the length of the hmacKey and the Timestep between codes.

TOTP(hmacKey, 10, 30);                                     // Secret key, Secret key length, Timestep (30s)

Use the getCodeFromTimestamp() function to get a TOTP from a unix epoch timestamp

uint32_t newCode = getCodeFromTimestamp(1557414000);       // Current timestamp since Unix epoch in seconds

Or getCodeFromTimeStruct() if you want to get a TOTP from a tm struct (Time Struct in C),

struct tm datetime;
datetime.tm_hour = 9;
datetime.tm_min = 0;
datetime.tm_sec = 0;
datetime.tm_mday = 13;
datetime.tm_mon = 5;
datetime.tm_year = 2019;
uint32_t newCode = getCodeFromTimeStruct(datetime);

If the provided unix timestamp isn't in UTC±0, use setTimezone() before getCodeFromTimestamp() or getCodeFromTimeStruct() to offset the time.

setTimezone(9);                                            // Set timezone +9 Japan

You can see an example in blink.c

Thanks to:

totp-mcu's People

Contributors

devnol avatar netthaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

totp-mcu's Issues

(RP2040) Library doesn't work

Having made changes after your feedback in #2 I tried using the RFC4226 Test numbers to generate OTP tokens and have reasoned that your library does not work at all under the RP2040 MCU

#include <TOTP.h>
#include <stdio.h>
    uint8_t hmacKey[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};
   uint8_t step = 0;
   TOTP(hmacKey, 6, 30);
    while (true) {
        
        uint32_t newCode = getCodeFromSteps(step);
        printf("Token: %d\n", newCode);
        step++;
        sleep_ms(1000);
    }

The above code snippet uses the shared hmac key ascii string "123456789012467890" and generates 10 codes with a step from 0 to 9 using your library.

According to Appendix D of the RFC4226, the OTP codes generated from those inputs should be:

Step OTP
0 755224
1 287082
2 359152
3 969429
4 338314
5 254676
6 287922
7 162583
8 399871
9 520489

However, using the above code and your library generates the following OTP codes:

Step OTP
0 186818
1 340335
2 781800
3 883048
4 082325
5 952379
6 546048
7 777669
8 736400
9 273848

This means that either your library doesn't work on the RP2040 MCU or that it doesn't correctly implement the HOTP and TOTP algorithms specified in the respective IETF RFC documents.

Could you please verify if this happens on your tested MCU or if it's an issue that is only present on my RP2040 MCU?

Thanks in advance.

OTP matching

I am using the library on atmega controller and the otp generated on my controller is not matching with the code generated online, I am using same Secret key on both online simulator and on my MCU.
I am using https://www.nayuki.io/page/time-based-one-time-password-tools
link to check the OTP where we can pass the time code manually also.
Can you confirm whether this library is supported as per the link which also says it is developed as per RFC 6238

Not compiling properly, and get wrong code in the end

I am trying to use your library to use with my Flipper Zero. I almost don't know C, I spent 7 hours straight trying to figure out how to use your library and ended up understanding most of the code now. However the one time password I generate is always wrong.
Here is my issue: I try to generate the code 191565, coming from the upcased BASE32 seed MYLEGODOOR.

https://www.nayuki.io/page/time-based-one-time-password-tools

image

So here is my code:

#include <stdio.h>
#include <TOTP.h>

int
main (void)
{
  uint8_t _hmacKey[] = {0x4d, 0x59, 0x4c, 0x45, 0x47, 0x4f, 0x44, 0x4f, 0x4f, 0x52};
  TOTP(_hmacKey, 10, 30);           
  uint32_t newCode = getCodeFromTimestamp(1557414000);
  printf(" %u \n", newCode);
  return 0;
}

The hmackey is correct. We can test it here: https://cryptii.com/pipes/base32-to-hex

image

To get it compiled, I cloned your project and ran gcc -I . main.c -o main -lm TOTP.c sha1.c

Then I get this error:

/usr/bin/ld: /tmp/ccfIQ8hj.o:(.bss+0x0): multiple definition of `buffer'; /tmp/ccqtE5YG.o:(.bss+0x0): first defined here
/usr/bin/ld: /tmp/ccfIQ8hj.o:(.bss+0x40): multiple definition of `state'; /tmp/ccqtE5YG.o:(.bss+0x40): first defined here
/usr/bin/ld: /tmp/ccfIQ8hj.o:(.bss+0x54): multiple definition of `bufferOffset'; /tmp/ccqtE5YG.o:(.bss+0x54): first defined here
/usr/bin/ld: /tmp/ccfIQ8hj.o:(.bss+0x58): multiple definition of `byteCount'; /tmp/ccqtE5YG.o:(.bss+0x58): first defined here
/usr/bin/ld: /tmp/ccfIQ8hj.o:(.bss+0x60): multiple definition of `keyBuffer'; /tmp/ccqtE5YG.o:(.bss+0x60): first defined here
/usr/bin/ld: /tmp/ccfIQ8hj.o:(.bss+0xa0): multiple definition of `innerHash'; /tmp/ccqtE5YG.o:(.bss+0xa0): first defined here

This is the exact same error when I try to push it to my Flipper Zero. To fix it, I followed @Astrrra
procedure here : https://github.com/wetox-team/flipperzero-firmware/blob/gen-totp/lib/TOTP-MCU/sha1.h

By moving a few lines from the sha1.h header to the sha1.c file on the top.

Those lines:

union _buffer {
  uint8_t b[BLOCK_LENGTH];
  uint32_t w[BLOCK_LENGTH/4];
} buffer;
union _state {
  uint8_t b[HASH_LENGTH];
  uint32_t w[HASH_LENGTH/4];
} state;

uint8_t bufferOffset;
uint32_t byteCount;
uint8_t keyBuffer[BLOCK_LENGTH];
uint8_t innerHash[HASH_LENGTH];

Once it's done, I can finaly compile it.

However the code I get is 364961, not 191565

I am out of ideas on how to make it work. I understand that moving those lines is actually corrupting the behaviour of the engine. Do you know how to fix the compilation ? Thank you very much for your help it's greatly appreciated 🙏

(RP204-) getCodeFromTimeStamp() returns incorrect code

MCU: RP2040
Compiler: arm-none-eabi-gcc
Compiler host machine: macOS

I have converted the base32 string provided by the 2fa server to hex using the Base32 (RFC 3548, RFC 4648) algorithm and provided it as hmacKey[] to the TOTP constructor.

I have also set the timezone to UTC+3 since it's summer and I'm in Greece using setTimezone(3), but the unix timestamp provided by the RP2040 RTC is already corrected to UTC±0. Is that how I'm supposed to do it?

Anyway, the provided timestamp from the RTC is correct but the generated token is invalid.
Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.