- ๐ Hi, Iโm @Netthaw
- ๐ Iโm interested in IoT, NAS
- ๐ซ How to reach me : [email protected]
netthaw / totp-mcu Goto Github PK
View Code? Open in Web Editor NEWOTP library for C (All MCU)(Pure C)
License: MIT License
OTP library for C (All MCU)(Pure C)
License: MIT License
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?
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
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.
possibly other libc implementations have similar conflicts. I could fix that by renaming the variable to _timeZone but I would assume that some other library implementation would have a similar conflict. I would suggest it gets renamed to something like _timeZoneOffset so it hopefully doesn't conflict with anything else.
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
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
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 ๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.