lucadentella / TOTP-Arduino

155 stars 33 forks source link

Made a few changes... #3

Closed Jeroen88 closed 4 years ago

Jeroen88 commented 7 years ago

I made some changes to your code for my own use, and publish it here, maybe some others can use it. The changes I made:

TOTP.h: `// OpenAuthentication Time-based One-time Password Algorithm (RFC 6238) // Arduino Library // // Luca Dentella (http://www.lucadentella.it)

include "Arduino.h"

ifndef _TOTP_H

define _TOTP_H

class TOTP { public: TOTP(const uint8_t hmacKey, int keyLength, int timeStep = 30); TOTP(const String &hmacKey, int timeStep = 30); ~TOTP(); const char getCode(long timeStamp); const char *getCodeFromSteps(long steps);

private: uint8_t _hmacKey; int _keyLength; int _timeStep; uint8_t _byteArray[8]; uint8_t _hash; int _offset; long _truncatedHash; char _code[7]; long _steps; };

endif`

TOTP.cpp: `// OpenAuthentication Time-based One-time Password Algorithm (RFC 6238) // For the complete description of the algorithm see // http://tools.ietf.org/html/rfc4226#section-5.3 // // Luca Dentella (http://www.lucadentella.it)

include "TOTP.h"

include "sha1.h"

// Init the library with the private key, its length and the timeStep duration TOTP::TOTP(const uint8_t hmacKey, int keyLength, int timeStep): _keyLength(keyLength), _timeStep(timeStep) { _hmacKey = (uint8_t ) malloc(_keyLength); if(_hmacKey != NULL) memcpy(_hmacKey, hmacKey, keyLength); }

TOTP::TOTP(const String &hmacKey, int timeStep): _timeStep(timeStep) { _keyLength = hmacKey.length(); _hmacKey = (uint8_t *) strdup(hmacKey.c_str());
}

TOTP::~TOTP() { free(_hmacKey); }

// Generate a code, using the timestamp provided const char *TOTP::getCode(long timeStamp) {

long steps = timeStamp / _timeStep; return steps != _steps ? getCodeFromSteps(steps) : _code; }

// Generate a code, using the number of steps provided const char *TOTP::getCodeFromSteps(long steps) {

// STEP 0, map the number of steps in a 8-bytes array (counter value) _byteArray[0] = 0x00; _byteArray[1] = 0x00; _byteArray[2] = 0x00; _byteArray[3] = 0x00; _byteArray[4] = (int)((steps >> 24) & 0xFF); _byteArray[5] = (int)((steps >> 16) & 0xFF); _byteArray[6] = (int)((steps >> 8) & 0XFF); _byteArray[7] = (int)((steps & 0XFF));

// STEP 1, get the HMAC-SHA1 hash from counter and key

Sha1.initHmac(_hmacKey, _keyLength); Sha1.write(_byteArray, 8); _hash = Sha1.resultHmac();

// STEP 2, apply dynamic truncation to obtain a 4-bytes string _offset = _hash[20 - 1] & 0xF; _truncatedHash = 0; for (int j = 0; j < 4; ++j) { _truncatedHash <<= 8; _truncatedHash |= _hash[_offset + j]; }

// STEP 3, compute the OTP value _truncatedHash &= 0x7FFFFFFF; _truncatedHash %= 1000000;

// convert the value in string, with heading zeroes sprintf(_code, "%06ld", _truncatedHash); _steps = steps; return _code; }`

lucadentella commented 4 years ago

I merged some code