├── README ├── TOTP.cpp ├── TOTP.h ├── examples └── GetCode │ └── GetCode.ino └── keywords.txt /README: -------------------------------------------------------------------------------- 1 | This is an Arduino library to generate TOTP codes based on the OpenAuthentication Time-based One-time Password Algorithm (RFC 6238) 2 | 3 | 4 | Description & usage: 5 | 6 | http://www.lucadentella.it/totp-libreria-per-arduino/ 7 | 8 | A simple project: 9 | 10 | http://www.lucadentella.it/2013/09/14/serratura-otp/ 11 | 12 | 13 | Thanks to: 14 | 15 | Jose Damico, https://github.com/damico/ARDUINO-OATH-TOKEN 16 | Peter Knight, https://github.com/Cathedrow/Cryptosuite 17 | Maniacbug, https://github.com/maniacbug/Cryptosuite 18 | -------------------------------------------------------------------------------- /TOTP.cpp: -------------------------------------------------------------------------------- 1 | // OpenAuthentication Time-based One-time Password Algorithm (RFC 6238) 2 | // Arduino Library 3 | // 4 | // Luca Dentella (http://www.lucadentella.it) 5 | 6 | #include "TOTP.h" 7 | #include "sha1.h" 8 | 9 | // Init the library with the private key and its length 10 | TOTP::TOTP(uint8_t* hmacKey, int keyLength) { 11 | 12 | _hmacKey = hmacKey; 13 | _keyLength = keyLength; 14 | }; 15 | 16 | // Generate a code, using the timestamp provided 17 | // for the complete description of the algorithm see 18 | // http://tools.ietf.org/html/rfc4226#section-5.3 19 | char* TOTP::getCode(long timeStamp) { 20 | 21 | // STEP 0, number of steps (one every 30 seconds) from the Epoch 22 | _timeStep = timeStamp / 30; 23 | 24 | // STEP 0, map the number of steps in a 8-bytes array (counter value) 25 | _byteArray[0] = 0x00; 26 | _byteArray[1] = 0x00; 27 | _byteArray[2] = 0x00; 28 | _byteArray[3] = 0x00; 29 | _byteArray[4] = (int)((_timeStep >> 24) & 0xFF); 30 | _byteArray[5] = (int)((_timeStep >> 16) & 0xFF); 31 | _byteArray[6] = (int)((_timeStep >> 8) & 0XFF); 32 | _byteArray[7] = (int)((_timeStep & 0XFF)); 33 | 34 | // STEP 1, get the HMAC-SHA1 hash from counter and key 35 | Sha1.initHmac(_hmacKey, _keyLength); 36 | Sha1.write(_byteArray, 8); 37 | _hash = Sha1.resultHmac(); 38 | 39 | // STEP 2, apply dynamic truncation to obtain a 4-bytes string 40 | _offset = _hash[20 - 1] & 0xF; 41 | _truncatedHash = 0; 42 | for (int j = 0; j < 4; ++j) { 43 | _truncatedHash <<= 8; 44 | _truncatedHash |= _hash[_offset + j]; 45 | } 46 | 47 | // STEP 3, compute the OTP value 48 | _truncatedHash &= 0x7FFFFFFF; 49 | _truncatedHash %= 1000000; 50 | 51 | // convert the value in string, with heading zeroes 52 | sprintf(_code, "%06ld", _truncatedHash); 53 | return _code; 54 | } 55 | -------------------------------------------------------------------------------- /TOTP.h: -------------------------------------------------------------------------------- 1 | // OpenAuthentication Time-based One-time Password Algorithm (RFC 6238) 2 | // Arduino Library 3 | // 4 | // Luca Dentella (http://www.lucadentella.it) 5 | 6 | #include "Arduino.h" 7 | 8 | #ifndef _TOTP_H 9 | #define _TOTP_H 10 | 11 | 12 | class TOTP { 13 | 14 | public: 15 | 16 | TOTP(uint8_t* hmacKey, int keyLength); 17 | char* getCode(long timeStamp); 18 | 19 | private: 20 | 21 | uint8_t* _hmacKey; 22 | int _keyLength; 23 | long _timeStep; 24 | uint8_t _byteArray[8]; 25 | uint8_t* _hash; 26 | int _offset; 27 | long _truncatedHash; 28 | char _code[7]; 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /examples/GetCode/GetCode.ino: -------------------------------------------------------------------------------- 1 | // GetCode.ino 2 | // 3 | // Basic example for the TOTP library 4 | // 5 | // This example uses the opensource SwRTC library as a software real-time clock 6 | // you can download from https://github.com/leomil72/swRTC 7 | // for real implementation it's suggested the use of an hardware RTC 8 | 9 | #include "sha1.h" 10 | #include "TOTP.h" 11 | #include "swRTC.h" 12 | 13 | // The shared secret is MyLegoDoor 14 | uint8_t hmacKey[] = {0x4d, 0x79, 0x4c, 0x65, 0x67, 0x6f, 0x44, 0x6f, 0x6f, 0x72}; 15 | 16 | TOTP totp = TOTP(hmacKey, 10); 17 | swRTC rtc; 18 | char code[7]; 19 | 20 | 21 | void setup() { 22 | 23 | Serial.begin(9600); 24 | rtc.stopRTC(); 25 | 26 | // Adjust the following values to match the current date and time 27 | // and power on Arduino at the time set (use GMT timezone!) 28 | rtc.setDate(27, 8, 2013); 29 | rtc.setTime(21, 25, 00); 30 | 31 | rtc.startRTC(); 32 | } 33 | 34 | void loop() { 35 | 36 | long GMT = rtc.getTimestamp(); 37 | char* newCode = totp.getCode(GMT); 38 | if(strcmp(code, newCode) != 0) { 39 | strcpy(code, newCode); 40 | Serial.println(code); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For TOTP 3 | ####################################### 4 | # Datatypes (KEYWORD1) 5 | ####################################### 6 | 7 | TOTP KEYWORD1 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | getCode KEYWORD2 --------------------------------------------------------------------------------