]> git.earman.xyz Git - sensor-watch.git/commitdiff
bring totp_face into Second Movement
authorEmilienCourt <EmilienCourt>
Sun, 29 Jun 2025 17:25:42 +0000 (19:25 +0200)
committerEmilienCourt <EmilienCourt>
Sun, 29 Jun 2025 17:25:42 +0000 (19:25 +0200)
33 files changed:
Makefile
legacy/lib/TOTP/LICENSE [deleted file]
legacy/lib/TOTP/README.md [deleted file]
legacy/lib/TOTP/TOTP.c [deleted file]
legacy/lib/TOTP/TOTP.h [deleted file]
legacy/lib/TOTP/example.c [deleted file]
legacy/lib/TOTP/sha1.c [deleted file]
legacy/lib/TOTP/sha1.h [deleted file]
legacy/lib/TOTP/sha256.c [deleted file]
legacy/lib/TOTP/sha256.h [deleted file]
legacy/lib/TOTP/sha512.c [deleted file]
legacy/lib/TOTP/sha512.h [deleted file]
legacy/lib/base32/base32.c [deleted file]
legacy/lib/base32/base32.h [deleted file]
legacy/watch_faces/complication/totp_face.c [deleted file]
legacy/watch_faces/complication/totp_face.h [deleted file]
lib/TOTP/LICENSE [new file with mode: 0644]
lib/TOTP/README.md [new file with mode: 0644]
lib/TOTP/TOTP.c [new file with mode: 0644]
lib/TOTP/TOTP.h [new file with mode: 0644]
lib/TOTP/example.c [new file with mode: 0644]
lib/TOTP/sha1.c [new file with mode: 0644]
lib/TOTP/sha1.h [new file with mode: 0644]
lib/TOTP/sha256.c [new file with mode: 0644]
lib/TOTP/sha256.h [new file with mode: 0644]
lib/TOTP/sha512.c [new file with mode: 0644]
lib/TOTP/sha512.h [new file with mode: 0644]
lib/base32/base32.c [new file with mode: 0644]
lib/base32/base32.h [new file with mode: 0644]
movement_faces.h
watch-faces.mk
watch-faces/complication/totp_face.c [new file with mode: 0644]
watch-faces/complication/totp_face.h [new file with mode: 0644]

index cefb6988047f525ef27b901e23c5416c79dfd933..7a469f350914f0c15edaba12b50c691c2e31016a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -67,6 +67,11 @@ INCLUDES += \
   -I./filesystem \
   -I./shell \
   -I./lib/sunriset \
+  -I./lib/sha1 \
+  -I./lib/sha256 \
+  -I./lib/sha512 \
+  -I./lib/base32 \
+  -I./lib/TOTP \
   -I./lib/chirpy_tx \
   -I./lib/base64 \
   -I./watch-library/shared/watch \
@@ -89,6 +94,11 @@ SRCS += \
   ./shell/shell.c \
   ./shell/shell_cmd_list.c \
   ./lib/sunriset/sunriset.c \
+  ./lib/base32/base32.c \
+  ./lib/TOTP/sha1.c \
+  ./lib/TOTP/sha256.c \
+  ./lib/TOTP/sha512.c \
+  ./lib/TOTP/TOTP.c \
   ./lib/chirpy_tx/chirpy_tx.c \
   ./lib/base64/base64.c \
   ./watch-library/shared/driver/thermistor_driver.c \
diff --git a/legacy/lib/TOTP/LICENSE b/legacy/lib/TOTP/LICENSE
deleted file mode 100644 (file)
index 6de4c0f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 Weravech
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/legacy/lib/TOTP/README.md b/legacy/lib/TOTP/README.md
deleted file mode 100644 (file)
index bb23122..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-TOTP Pure C Library
-====================
-
-Library to generate Time-based One-Time Passwords.
-
-Implements the Time-based One-Time Password algorithm specified in [RFC 6238](https://tools.ietf.org/html/rfc6238). 
-
-Supports different time steps and is compatible with tokens that use the same standard (including software ones, like the Google Authenticator app).
-
-The code is made of :
-
-- [TOTP-MCU](https://github.com/Netthaw/TOTP-MCU) for `TimeStruct2Timestamp`, `getCodeFromTimestamp`, `getCodeFromTimeStruct`, part of `getCodeFromSteps` and `TOTP_HMAC_SHA*` functions
-- [mbedtls](https://github.com/Mbed-TLS/mbedtls) for SHA1/SHA224/SHA256/SHA384/SHA512 implementations
-- [this project](https://github.com/mygityf/cipher/blob/master/cipher/hmac.c) as an inspiration for writing the code to compute the TOTP using the key and the text to hash
-
-
-
-Supported algorithms are SHA1/SHA224/SHA256/SHA384/SHA512.
-
-
-
-Installation & usage:
---------------------
-First include header to your file
-```c
-#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](https://cryptii.com/pipes/base32-to-hex) to convert the base32 string to hex (make sure you upcase it first if it's lowercase and remove all whitespaces).
-```c
-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, the Timestep between codes and the algorithm used (most of the time, `SHA1`).
-```c
-TOTP(hmacKey, 10, 30, SHA1);                                     // Secret key, Secret key length, Timestep (30s), Algorithm
-```
-Use the ```getCodeFromTimestamp()``` function to get a TOTP from a unix epoch timestamp
-```c
-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), 
-```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.
-
-```c
-setTimezone(9);                                            // Set timezone +9 Japan
-```
-
-You can see an example in example.c (compile it with `gcc -o example example.c sha1.c sha256.c sha512.c TOTP.c -I.`)
-
-Thanks to:
-----------
-
-* Netthaw, https://github.com/Netthaw/TOTP-MCU
-* Mbed-TLS, https://github.com/Mbed-TLS/mbedtls
-* mygityf, https://github.com/mygityf/cipher/blob/master/cipher/hmac.c
-* susam, https://github.com/susam/mintotp
diff --git a/legacy/lib/TOTP/TOTP.c b/legacy/lib/TOTP/TOTP.c
deleted file mode 100644 (file)
index 7f60133..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "TOTP.h"\r
-#include "sha1.h"\r
-#include "sha256.h"\r
-#include "sha512.h"\r
-#include <stdio.h>\r
-\r
-uint8_t* _hmacKey;\r
-uint8_t _keyLength;\r
-uint8_t _timeZoneOffset;\r
-uint32_t _timeStep;\r
-hmac_alg _algorithm;\r
-\r
-// Init the library with the private key, its length, the timeStep duration and the algorithm that should be used\r
-void TOTP(uint8_t* hmacKey, uint8_t keyLength, uint32_t timeStep, hmac_alg algorithm) {\r
-    _hmacKey = hmacKey;\r
-    _keyLength = keyLength;\r
-    _timeStep = timeStep;\r
-    _algorithm = algorithm;\r
-}\r
-\r
-void setTimezone(uint8_t timezone){\r
-    _timeZoneOffset = timezone;\r
-}\r
-\r
-static uint32_t TimeStruct2Timestamp(struct tm time){\r
-    //time.tm_mon -= 1;\r
-    //time.tm_year -= 1900;\r
-    return mktime(&(time)) - (_timeZoneOffset * 3600) - 2208988800;\r
-}\r
-\r
-// Generate a code, using the timestamp provided\r
-uint32_t getCodeFromTimestamp(uint32_t timeStamp) {\r
-    uint32_t steps = timeStamp / _timeStep;\r
-    return getCodeFromSteps(steps);\r
-}\r
-\r
-// Generate a code, using the timestamp provided\r
-uint32_t getCodeFromTimeStruct(struct tm time) {\r
-    return getCodeFromTimestamp(TimeStruct2Timestamp(time));\r
-}\r
-\r
-// Generate a code, using the number of steps provided\r
-uint32_t getCodeFromSteps(uint32_t steps) {\r
-    // STEP 0, map the number of steps in a 8-bytes array (counter value)\r
-    uint8_t _byteArray[8];\r
-    _byteArray[0] = 0x00;\r
-    _byteArray[1] = 0x00;\r
-    _byteArray[2] = 0x00;\r
-    _byteArray[3] = 0x00;\r
-    _byteArray[4] = (uint8_t)((steps >> 24) & 0xFF);\r
-    _byteArray[5] = (uint8_t)((steps >> 16) & 0xFF);\r
-    _byteArray[6] = (uint8_t)((steps >> 8) & 0XFF);\r
-    _byteArray[7] = (uint8_t)((steps & 0XFF));\r
-\r
-    switch(_algorithm){\r
-        case SHA1:\r
-            return(TOTP_HMAC_SHA1(_hmacKey, _keyLength, _byteArray, 8));\r
-        case SHA224:\r
-            return(TOTP_HMAC_SHA256(_hmacKey, _keyLength, _byteArray, 8, 1));\r
-        case SHA256:\r
-            return(TOTP_HMAC_SHA256(_hmacKey, _keyLength, _byteArray, 8, 0));\r
-        case SHA384:\r
-            return(TOTP_HMAC_SHA512(_hmacKey, _keyLength, _byteArray, 8, 1));\r
-        case SHA512:\r
-            return(TOTP_HMAC_SHA512(_hmacKey, _keyLength, _byteArray, 8, 0));\r
-        default:\r
-            return(0);\r
-    }\r
-}\r
diff --git a/legacy/lib/TOTP/TOTP.h b/legacy/lib/TOTP/TOTP.h
deleted file mode 100644 (file)
index adde66d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef TOTP_H_\r
-#define TOTP_H_\r
-\r
-#include <inttypes.h>\r
-#include "time.h"\r
-\r
-typedef enum __attribute__ ((__packed__)) {\r
-    SHA1,\r
-    SHA224,\r
-    SHA256,\r
-    SHA384,\r
-    SHA512\r
-} hmac_alg;\r
-\r
-void TOTP(uint8_t* hmacKey, uint8_t keyLength, uint32_t timeStep, hmac_alg algorithm);\r
-void setTimezone(uint8_t timezone);\r
-uint32_t getCodeFromTimestamp(uint32_t timeStamp);\r
-uint32_t getCodeFromTimeStruct(struct tm time);\r
-uint32_t getCodeFromSteps(uint32_t steps);\r
-\r
-#endif // TOTP_H_\r
diff --git a/legacy/lib/TOTP/example.c b/legacy/lib/TOTP/example.c
deleted file mode 100644 (file)
index a218ff8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "TOTP.h"\r
-#include <stdio.h>\r
-\r
-/**\r
- * example.c\r
- */\r
-void main(void)\r
-{\r
-       uint8_t hmacKey[] = {0x4d, 0x79, 0x4c, 0x65, 0x67, 0x6f, 0x44, 0x6f, 0x6f, 0x72};               // Secret key\r
-       TOTP(hmacKey, 10, 7200, SHA1);                                                                        // Secret key, Key length, Timestep (7200s - 2hours)\r
-\r
-       setTimezone(9);                                                                                 // Set timezone\r
-       uint32_t newCode = getCodeFromTimestamp(1557414000);                                            // Timestamp Now\r
-\r
-       ///////////////// For struct tm //////////////////\r
-    // struct tm datetime;\r
-    // datetime.tm_hour = 9;\r
-    // datetime.tm_min = 0;\r
-    // datetime.tm_sec = 0;\r
-    // datetime.tm_mday = 13;\r
-    // datetime.tm_mon = 5;\r
-    // datetime.tm_year = 2019;\r
-       //  uint32_t newCode = getCodeFromTimeStruct(datetime);\r
-       ///////////////////////////////////////////////////\r
-\r
-       printf("Code : %06u\n",newCode);\r
-}\r
diff --git a/legacy/lib/TOTP/sha1.c b/legacy/lib/TOTP/sha1.c
deleted file mode 100644 (file)
index 84fc83d..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/*\r
- *  FIPS-180-1 compliant SHA-1 implementation\r
- *\r
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
- *  SPDX-License-Identifier: Apache-2.0\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
- *  not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *  http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *\r
- *  This file is part of mbed TLS (https://tls.mbed.org)\r
- */\r
-/*\r
- *  The SHA-1 standard was published by NIST in 1993.\r
- *\r
- *  http://www.itl.nist.gov/fipspubs/fip180-1.htm\r
- */\r
-\r
-#include "sha1.h"\r
-#include <string.h>\r
-#include <stdio.h>\r
-\r
-/* Implementation that should never be optimized out by the compiler */\r
-static void mbedtls_zeroize( void *v, size_t n ) {\r
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;\r
-}\r
-\r
-/*\r
- * 32-bit integer manipulation macros (big endian)\r
- */\r
-#ifndef GET_UINT32_BE\r
-#define GET_UINT32_BE(n,b,i)                            \\r
-{                                                       \\r
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \\r
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \\r
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \\r
-        | ( (uint32_t) (b)[(i) + 3]       );            \\r
-}\r
-#endif\r
-\r
-#ifndef PUT_UINT32_BE\r
-#define PUT_UINT32_BE(n,b,i)                            \\r
-{                                                       \\r
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\r
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\r
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\r
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\r
-}\r
-#endif\r
-\r
-void mbedtls_sha1_init( mbedtls_sha1_context *ctx )\r
-{\r
-    memset( ctx, 0, sizeof( mbedtls_sha1_context ) );\r
-}\r
-\r
-void mbedtls_sha1_free( mbedtls_sha1_context *ctx )\r
-{\r
-    if( ctx == NULL )\r
-        return;\r
-\r
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );\r
-}\r
-\r
-/*\r
- * SHA-1 context setup\r
- */\r
-void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )\r
-{\r
-    ctx->total[0] = 0;\r
-    ctx->total[1] = 0;\r
-\r
-    ctx->state[0] = 0x67452301;\r
-    ctx->state[1] = 0xEFCDAB89;\r
-    ctx->state[2] = 0x98BADCFE;\r
-    ctx->state[3] = 0x10325476;\r
-    ctx->state[4] = 0xC3D2E1F0;\r
-}\r
-\r
-void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[SHA1_BLOCK_LENGTH] )\r
-{\r
-    uint32_t temp, W[16], A, B, C, D, E;\r
-\r
-    GET_UINT32_BE( W[ 0], data,  0 );\r
-    GET_UINT32_BE( W[ 1], data,  4 );\r
-    GET_UINT32_BE( W[ 2], data,  8 );\r
-    GET_UINT32_BE( W[ 3], data, 12 );\r
-    GET_UINT32_BE( W[ 4], data, 16 );\r
-    GET_UINT32_BE( W[ 5], data, 20 );\r
-    GET_UINT32_BE( W[ 6], data, 24 );\r
-    GET_UINT32_BE( W[ 7], data, 28 );\r
-    GET_UINT32_BE( W[ 8], data, 32 );\r
-    GET_UINT32_BE( W[ 9], data, 36 );\r
-    GET_UINT32_BE( W[10], data, 40 );\r
-    GET_UINT32_BE( W[11], data, 44 );\r
-    GET_UINT32_BE( W[12], data, 48 );\r
-    GET_UINT32_BE( W[13], data, 52 );\r
-    GET_UINT32_BE( W[14], data, 56 );\r
-    GET_UINT32_BE( W[15], data, 60 );\r
-\r
-#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))\r
-\r
-#define R(t)                                            \\r
-(                                                       \\r
-    temp = W[( t -  3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \\r
-           W[( t - 14 ) & 0x0F] ^ W[  t       & 0x0F],  \\r
-    ( W[t & 0x0F] = S(temp,1) )                         \\r
-)\r
-\r
-#define P(a,b,c,d,e,x)                                  \\r
-{                                                       \\r
-    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \\r
-}\r
-\r
-    A = ctx->state[0];\r
-    B = ctx->state[1];\r
-    C = ctx->state[2];\r
-    D = ctx->state[3];\r
-    E = ctx->state[4];\r
-\r
-#define F(x,y,z) (z ^ (x & (y ^ z)))\r
-#define K 0x5A827999\r
-\r
-    P( A, B, C, D, E, W[0]  );\r
-    P( E, A, B, C, D, W[1]  );\r
-    P( D, E, A, B, C, W[2]  );\r
-    P( C, D, E, A, B, W[3]  );\r
-    P( B, C, D, E, A, W[4]  );\r
-    P( A, B, C, D, E, W[5]  );\r
-    P( E, A, B, C, D, W[6]  );\r
-    P( D, E, A, B, C, W[7]  );\r
-    P( C, D, E, A, B, W[8]  );\r
-    P( B, C, D, E, A, W[9]  );\r
-    P( A, B, C, D, E, W[10] );\r
-    P( E, A, B, C, D, W[11] );\r
-    P( D, E, A, B, C, W[12] );\r
-    P( C, D, E, A, B, W[13] );\r
-    P( B, C, D, E, A, W[14] );\r
-    P( A, B, C, D, E, W[15] );\r
-    P( E, A, B, C, D, R(16) );\r
-    P( D, E, A, B, C, R(17) );\r
-    P( C, D, E, A, B, R(18) );\r
-    P( B, C, D, E, A, R(19) );\r
-\r
-#undef K\r
-#undef F\r
-\r
-#define F(x,y,z) (x ^ y ^ z)\r
-#define K 0x6ED9EBA1\r
-\r
-    P( A, B, C, D, E, R(20) );\r
-    P( E, A, B, C, D, R(21) );\r
-    P( D, E, A, B, C, R(22) );\r
-    P( C, D, E, A, B, R(23) );\r
-    P( B, C, D, E, A, R(24) );\r
-    P( A, B, C, D, E, R(25) );\r
-    P( E, A, B, C, D, R(26) );\r
-    P( D, E, A, B, C, R(27) );\r
-    P( C, D, E, A, B, R(28) );\r
-    P( B, C, D, E, A, R(29) );\r
-    P( A, B, C, D, E, R(30) );\r
-    P( E, A, B, C, D, R(31) );\r
-    P( D, E, A, B, C, R(32) );\r
-    P( C, D, E, A, B, R(33) );\r
-    P( B, C, D, E, A, R(34) );\r
-    P( A, B, C, D, E, R(35) );\r
-    P( E, A, B, C, D, R(36) );\r
-    P( D, E, A, B, C, R(37) );\r
-    P( C, D, E, A, B, R(38) );\r
-    P( B, C, D, E, A, R(39) );\r
-\r
-#undef K\r
-#undef F\r
-\r
-#define F(x,y,z) ((x & y) | (z & (x | y)))\r
-#define K 0x8F1BBCDC\r
-\r
-    P( A, B, C, D, E, R(40) );\r
-    P( E, A, B, C, D, R(41) );\r
-    P( D, E, A, B, C, R(42) );\r
-    P( C, D, E, A, B, R(43) );\r
-    P( B, C, D, E, A, R(44) );\r
-    P( A, B, C, D, E, R(45) );\r
-    P( E, A, B, C, D, R(46) );\r
-    P( D, E, A, B, C, R(47) );\r
-    P( C, D, E, A, B, R(48) );\r
-    P( B, C, D, E, A, R(49) );\r
-    P( A, B, C, D, E, R(50) );\r
-    P( E, A, B, C, D, R(51) );\r
-    P( D, E, A, B, C, R(52) );\r
-    P( C, D, E, A, B, R(53) );\r
-    P( B, C, D, E, A, R(54) );\r
-    P( A, B, C, D, E, R(55) );\r
-    P( E, A, B, C, D, R(56) );\r
-    P( D, E, A, B, C, R(57) );\r
-    P( C, D, E, A, B, R(58) );\r
-    P( B, C, D, E, A, R(59) );\r
-\r
-#undef K\r
-#undef F\r
-\r
-#define F(x,y,z) (x ^ y ^ z)\r
-#define K 0xCA62C1D6\r
-\r
-    P( A, B, C, D, E, R(60) );\r
-    P( E, A, B, C, D, R(61) );\r
-    P( D, E, A, B, C, R(62) );\r
-    P( C, D, E, A, B, R(63) );\r
-    P( B, C, D, E, A, R(64) );\r
-    P( A, B, C, D, E, R(65) );\r
-    P( E, A, B, C, D, R(66) );\r
-    P( D, E, A, B, C, R(67) );\r
-    P( C, D, E, A, B, R(68) );\r
-    P( B, C, D, E, A, R(69) );\r
-    P( A, B, C, D, E, R(70) );\r
-    P( E, A, B, C, D, R(71) );\r
-    P( D, E, A, B, C, R(72) );\r
-    P( C, D, E, A, B, R(73) );\r
-    P( B, C, D, E, A, R(74) );\r
-    P( A, B, C, D, E, R(75) );\r
-    P( E, A, B, C, D, R(76) );\r
-    P( D, E, A, B, C, R(77) );\r
-    P( C, D, E, A, B, R(78) );\r
-    P( B, C, D, E, A, R(79) );\r
-\r
-#undef K\r
-#undef F\r
-\r
-    ctx->state[0] += A;\r
-    ctx->state[1] += B;\r
-    ctx->state[2] += C;\r
-    ctx->state[3] += D;\r
-    ctx->state[4] += E;\r
-}\r
-\r
-/*\r
- * SHA-1 process buffer\r
- */\r
-void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )\r
-{\r
-    size_t fill;\r
-    uint32_t left;\r
-\r
-    if( ilen == 0 )\r
-        return;\r
-\r
-    left = ctx->total[0] & 0x3F;\r
-    fill = 64 - left;\r
-\r
-    ctx->total[0] += (uint32_t) ilen;\r
-    ctx->total[0] &= 0xFFFFFFFF;\r
-\r
-    if( ctx->total[0] < (uint32_t) ilen )\r
-        ctx->total[1]++;\r
-\r
-    if( left && ilen >= fill )\r
-    {\r
-        memcpy( (void *) (ctx->buffer + left), input, fill );\r
-        mbedtls_sha1_process( ctx, ctx->buffer );\r
-        input += fill;\r
-        ilen  -= fill;\r
-        left = 0;\r
-    }\r
-\r
-    while( ilen >= 64 )\r
-    {\r
-        mbedtls_sha1_process( ctx, input );\r
-        input += 64;\r
-        ilen  -= 64;\r
-    }\r
-\r
-    if( ilen > 0 )\r
-        memcpy( (void *) (ctx->buffer + left), input, ilen );\r
-}\r
-\r
-static const unsigned char sha1_padding[SHA1_BLOCK_LENGTH] =\r
-{\r
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
-};\r
-\r
-/*\r
- * SHA-1 final digest\r
- */\r
-void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[SHA1_DIGEST_LENGTH] )\r
-{\r
-    uint32_t last, padn;\r
-    uint32_t high, low;\r
-    unsigned char msglen[8];\r
-\r
-    high = ( ctx->total[0] >> 29 )\r
-         | ( ctx->total[1] <<  3 );\r
-    low  = ( ctx->total[0] <<  3 );\r
-\r
-    PUT_UINT32_BE( high, msglen, 0 );\r
-    PUT_UINT32_BE( low,  msglen, 4 );\r
-\r
-    last = ctx->total[0] & 0x3F;\r
-    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );\r
-\r
-    mbedtls_sha1_update( ctx, sha1_padding, padn );\r
-    mbedtls_sha1_update( ctx, msglen, 8 );\r
-\r
-    PUT_UINT32_BE( ctx->state[0], output,  0 );\r
-    PUT_UINT32_BE( ctx->state[1], output,  4 );\r
-    PUT_UINT32_BE( ctx->state[2], output,  8 );\r
-    PUT_UINT32_BE( ctx->state[3], output, 12 );\r
-    PUT_UINT32_BE( ctx->state[4], output, 16 );\r
-}\r
-\r
-/*\r
- * output = SHA-1( input buffer )\r
- */\r
-void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[SHA1_DIGEST_LENGTH] )\r
-{\r
-    mbedtls_sha1_context ctx;\r
-\r
-    mbedtls_sha1_init( &ctx );\r
-    mbedtls_sha1_starts( &ctx );\r
-    mbedtls_sha1_update( &ctx, input, ilen );\r
-    mbedtls_sha1_finish( &ctx, output );\r
-    mbedtls_sha1_free( &ctx );\r
-}\r
-\r
-/*\r
-* Compute HMAC_SHA1 using key, key length, text to hash, size of the text, and output buffer\r
-*/\r
-void HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t out[SHA1_DIGEST_LENGTH]){\r
-\r
-  uint8_t i;\r
-  uint8_t k_ipad[SHA1_BLOCK_LENGTH]; /* inner padding - key XORd with ipad */\r
-  uint8_t k_opad[SHA1_BLOCK_LENGTH]; /* outer padding - key XORd with opad */\r
-  uint8_t buffer[SHA1_BLOCK_LENGTH + SHA1_DIGEST_LENGTH];\r
-\r
-  /* start out by storing key in pads */\r
-  memset(k_ipad, 0, sizeof(k_ipad));\r
-  memset(k_opad, 0, sizeof(k_opad));\r
-\r
-  if (key_length <= SHA1_BLOCK_LENGTH) {\r
-      memcpy(k_ipad, key, key_length);\r
-      memcpy(k_opad, key, key_length);\r
-  }\r
-\r
-  else {\r
-      mbedtls_sha1(key, key_length, k_ipad);\r
-      memcpy(k_opad, k_ipad, SHA1_BLOCK_LENGTH);\r
-  }\r
-\r
-  /* XOR key with ipad and opad values */\r
-  for (i = 0; i < SHA1_BLOCK_LENGTH; i++) {\r
-      k_ipad[i] ^= HMAC_IPAD;\r
-      k_opad[i] ^= HMAC_OPAD;\r
-  }\r
-  \r
-  // perform inner SHA1\r
-  memcpy(buffer, k_ipad, SHA1_BLOCK_LENGTH);\r
-  memcpy(buffer + SHA1_BLOCK_LENGTH, in, n);\r
-  mbedtls_sha1(buffer, SHA1_BLOCK_LENGTH + n, out);\r
-  \r
-  memset(buffer, 0, SHA1_BLOCK_LENGTH + n);\r
-\r
-  // perform outer SHA1\r
-  memcpy(buffer, k_opad, SHA1_BLOCK_LENGTH);\r
-  memcpy(buffer + SHA1_BLOCK_LENGTH, out, SHA1_DIGEST_LENGTH);\r
-  mbedtls_sha1(buffer, SHA1_BLOCK_LENGTH + SHA1_DIGEST_LENGTH, out);\r
-}\r
-/*\r
-* Compute TOTP_HMAC_SHA1 using key, key length, text to hash, size of the text\r
-*/\r
-uint32_t TOTP_HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n){\r
-    // STEP 1, get the HMAC-SHA1 hash from counter and key\r
-    uint8_t hash[SHA1_DIGEST_LENGTH];\r
-    HMAC_SHA1(key, key_length, in, n, hash);\r
-\r
-    // STEP 2, apply dynamic truncation to obtain a 4-bytes string\r
-    uint32_t truncated_hash = 0;\r
-    uint8_t _offset = hash[SHA1_DIGEST_LENGTH - 1] & 0xF;\r
-    uint8_t j;\r
-    for (j = 0; j < 4; ++j) {\r
-        truncated_hash <<= 8;\r
-        truncated_hash  |= hash[_offset + j];\r
-    }\r
-\r
-    // STEP 3, compute the OTP value\r
-    truncated_hash &= 0x7FFFFFFF;    //Disabled\r
-    truncated_hash %= 1000000;\r
-\r
-    return truncated_hash;\r
-}\r
diff --git a/legacy/lib/TOTP/sha1.h b/legacy/lib/TOTP/sha1.h
deleted file mode 100644 (file)
index 2743c5a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/**\r
- * \file sha1.h\r
- *\r
- * \brief SHA-1 cryptographic hash function\r
- *\r
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
- *  SPDX-License-Identifier: Apache-2.0\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
- *  not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *  http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *\r
- *  This file is part of mbed TLS (https://tls.mbed.org)\r
- */\r
-#ifndef MBEDTLS_SHA1_H\r
-#define MBEDTLS_SHA1_H\r
-\r
-#define SHA1_DIGEST_LENGTH 20\r
-#define SHA1_BLOCK_LENGTH 64\r
-#define HMAC_IPAD 0x36\r
-#define HMAC_OPAD 0x5c\r
-\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/**\r
- * \brief          SHA-1 context structure\r
- */\r
-typedef struct\r
-{\r
-    uint32_t total[2];          /*!< number of bytes processed  */\r
-    uint32_t state[5];          /*!< intermediate digest state  */\r
-    unsigned char buffer[SHA1_BLOCK_LENGTH];   /*!< data block being processed */\r
-}\r
-mbedtls_sha1_context;\r
-\r
-/**\r
- * \brief          Initialize SHA-1 context\r
- *\r
- * \param ctx      SHA-1 context to be initialized\r
- */\r
-void mbedtls_sha1_init( mbedtls_sha1_context *ctx );\r
-\r
-/**\r
- * \brief          Clear SHA-1 context\r
- *\r
- * \param ctx      SHA-1 context to be cleared\r
- */\r
-void mbedtls_sha1_free( mbedtls_sha1_context *ctx );\r
-\r
-/**\r
- * \brief          SHA-1 context setup\r
- *\r
- * \param ctx      context to be initialized\r
- */\r
-void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );\r
-\r
-/**\r
- * \brief          SHA-1 process buffer\r
- *\r
- * \param ctx      SHA-1 context\r
- * \param input    buffer holding the  data\r
- * \param ilen     length of the input data\r
- */\r
-void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );\r
-\r
-/**\r
- * \brief          SHA-1 final digest\r
- *\r
- * \param ctx      SHA-1 context\r
- * \param output   SHA-1 checksum result\r
- */\r
-void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[SHA1_DIGEST_LENGTH] );\r
-\r
-/* Internal use */\r
-void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[SHA1_BLOCK_LENGTH] );\r
-\r
-/**\r
- * \brief          Output = SHA-1( input buffer )\r
- *\r
- * \param input    buffer holding the  data\r
- * \param ilen     length of the input data\r
- * \param output   SHA-1 checksum result\r
- */\r
-void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[SHA1_DIGEST_LENGTH] );\r
-void HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t out[SHA1_DIGEST_LENGTH]);\r
-uint32_t TOTP_HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n);\r
-\r
-\r
-#endif /* mbedtls_sha1.h */\r
diff --git a/legacy/lib/TOTP/sha256.c b/legacy/lib/TOTP/sha256.c
deleted file mode 100644 (file)
index cb83f53..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/*\r
- *  FIPS-180-2 compliant SHA-256 implementation\r
- *\r
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
- *  SPDX-License-Identifier: Apache-2.0\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
- *  not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *  http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *\r
- *  This file is part of mbed TLS (https://tls.mbed.org)\r
- */\r
-/*\r
- *  The SHA-256 Secure Hash Standard was published by NIST in 2002.\r
- *\r
- *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\r
- */\r
-\r
-#include "sha256.h"\r
-\r
-#include <string.h>\r
-#include <stdio.h>\r
-\r
-/* Implementation that should never be optimized out by the compiler */\r
-static void mbedtls_zeroize( void *v, size_t n ) {\r
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;\r
-}\r
-\r
-/*\r
- * 32-bit integer manipulation macros (big endian)\r
- */\r
-#ifndef GET_UINT32_BE\r
-#define GET_UINT32_BE(n,b,i)                            \\r
-do {                                                    \\r
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \\r
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \\r
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \\r
-        | ( (uint32_t) (b)[(i) + 3]       );            \\r
-} while( 0 )\r
-#endif\r
-\r
-#ifndef PUT_UINT32_BE\r
-#define PUT_UINT32_BE(n,b,i)                            \\r
-do {                                                    \\r
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\r
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\r
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\r
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\r
-} while( 0 )\r
-#endif\r
-\r
-void mbedtls_sha256_init( mbedtls_sha256_context *ctx )\r
-{\r
-    memset( ctx, 0, sizeof( mbedtls_sha256_context ) );\r
-}\r
-\r
-void mbedtls_sha256_free( mbedtls_sha256_context *ctx )\r
-{\r
-    if( ctx == NULL )\r
-        return;\r
-\r
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );\r
-}\r
-\r
-void mbedtls_sha256_clone( mbedtls_sha256_context *dst,\r
-                           const mbedtls_sha256_context *src )\r
-{\r
-    *dst = *src;\r
-}\r
-\r
-/*\r
- * SHA-256 context setup\r
- */\r
-void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )\r
-{\r
-    ctx->total[0] = 0;\r
-    ctx->total[1] = 0;\r
-\r
-    if( is224 == 0 )\r
-    {\r
-        /* SHA-256 */\r
-        ctx->state[0] = 0x6A09E667;\r
-        ctx->state[1] = 0xBB67AE85;\r
-        ctx->state[2] = 0x3C6EF372;\r
-        ctx->state[3] = 0xA54FF53A;\r
-        ctx->state[4] = 0x510E527F;\r
-        ctx->state[5] = 0x9B05688C;\r
-        ctx->state[6] = 0x1F83D9AB;\r
-        ctx->state[7] = 0x5BE0CD19;\r
-    }\r
-    else\r
-    {\r
-        /* SHA-224 */\r
-        ctx->state[0] = 0xC1059ED8;\r
-        ctx->state[1] = 0x367CD507;\r
-        ctx->state[2] = 0x3070DD17;\r
-        ctx->state[3] = 0xF70E5939;\r
-        ctx->state[4] = 0xFFC00B31;\r
-        ctx->state[5] = 0x68581511;\r
-        ctx->state[6] = 0x64F98FA7;\r
-        ctx->state[7] = 0xBEFA4FA4;\r
-    }\r
-\r
-    ctx->is224 = is224;\r
-}\r
-\r
-static const uint32_t K[] =\r
-{\r
-    0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,\r
-    0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,\r
-    0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,\r
-    0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,\r
-    0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,\r
-    0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,\r
-    0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,\r
-    0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,\r
-    0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,\r
-    0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,\r
-    0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,\r
-    0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,\r
-    0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,\r
-    0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,\r
-    0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,\r
-    0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,\r
-};\r
-\r
-#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)\r
-#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))\r
-\r
-#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))\r
-#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))\r
-\r
-#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))\r
-#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))\r
-\r
-#define F0(x,y,z) ((x & y) | (z & (x | y)))\r
-#define F1(x,y,z) (z ^ (x & (y ^ z)))\r
-\r
-#define R(t)                                    \\r
-(                                               \\r
-    W[t] = S1(W[t -  2]) + W[t -  7] +          \\r
-           S0(W[t - 15]) + W[t - 16]            \\r
-)\r
-\r
-#define P(a,b,c,d,e,f,g,h,x,K)                  \\r
-{                                               \\r
-    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \\r
-    temp2 = S2(a) + F0(a,b,c);                  \\r
-    d += temp1; h = temp1 + temp2;              \\r
-}\r
-\r
-void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[SHA256_BLOCK_LENGTH] )\r
-{\r
-    uint32_t temp1, temp2, W[64];\r
-    uint32_t A[8];\r
-    unsigned int i;\r
-\r
-    for( i = 0; i < 8; i++ )\r
-        A[i] = ctx->state[i];\r
-\r
-    for( i = 0; i < 16; i++ )\r
-        GET_UINT32_BE( W[i], data, 4 * i );\r
-\r
-    for( i = 0; i < 16; i += 8 )\r
-    {\r
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );\r
-        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );\r
-        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );\r
-        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );\r
-        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );\r
-        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );\r
-        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );\r
-        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );\r
-    }\r
-\r
-    for( i = 16; i < 64; i += 8 )\r
-    {\r
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );\r
-        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );\r
-        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );\r
-        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );\r
-        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );\r
-        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );\r
-        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );\r
-        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );\r
-    }\r
-\r
-    for( i = 0; i < 8; i++ )\r
-        ctx->state[i] += A[i];\r
-}\r
-\r
-/*\r
- * SHA-256 process buffer\r
- */\r
-void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,\r
-                    size_t ilen )\r
-{\r
-    size_t fill;\r
-    uint32_t left;\r
-\r
-    if( ilen == 0 )\r
-        return;\r
-\r
-    left = ctx->total[0] & 0x3F;\r
-    fill = 64 - left;\r
-\r
-    ctx->total[0] += (uint32_t) ilen;\r
-    ctx->total[0] &= 0xFFFFFFFF;\r
-\r
-    if( ctx->total[0] < (uint32_t) ilen )\r
-        ctx->total[1]++;\r
-\r
-    if( left && ilen >= fill )\r
-    {\r
-        memcpy( (void *) (ctx->buffer + left), input, fill );\r
-        mbedtls_sha256_process( ctx, ctx->buffer );\r
-        input += fill;\r
-        ilen  -= fill;\r
-        left = 0;\r
-    }\r
-\r
-    while( ilen >= 64 )\r
-    {\r
-        mbedtls_sha256_process( ctx, input );\r
-        input += 64;\r
-        ilen  -= 64;\r
-    }\r
-\r
-    if( ilen > 0 )\r
-        memcpy( (void *) (ctx->buffer + left), input, ilen );\r
-}\r
-\r
-static const unsigned char sha256_padding[SHA256_BLOCK_LENGTH] =\r
-{\r
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
-};\r
-\r
-/*\r
- * SHA-256 final digest\r
- */\r
-void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char* output )\r
-{\r
-    uint32_t last, padn;\r
-    uint32_t high, low;\r
-    unsigned char msglen[8];\r
-\r
-    high = ( ctx->total[0] >> 29 )\r
-         | ( ctx->total[1] <<  3 );\r
-    low  = ( ctx->total[0] <<  3 );\r
-\r
-    PUT_UINT32_BE( high, msglen, 0 );\r
-    PUT_UINT32_BE( low,  msglen, 4 );\r
-\r
-    last = ctx->total[0] & 0x3F;\r
-    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );\r
-\r
-    mbedtls_sha256_update( ctx, sha256_padding, padn );\r
-    mbedtls_sha256_update( ctx, msglen, 8 );\r
-\r
-    PUT_UINT32_BE( ctx->state[0], output,  0 );\r
-    PUT_UINT32_BE( ctx->state[1], output,  4 );\r
-    PUT_UINT32_BE( ctx->state[2], output,  8 );\r
-    PUT_UINT32_BE( ctx->state[3], output, 12 );\r
-    PUT_UINT32_BE( ctx->state[4], output, 16 );\r
-    PUT_UINT32_BE( ctx->state[5], output, 20 );\r
-    PUT_UINT32_BE( ctx->state[6], output, 24 );\r
-\r
-    if( ctx->is224 == 0 )\r
-        PUT_UINT32_BE( ctx->state[7], output, 28 );\r
-}\r
-\r
-/*\r
- * output = SHA-256( input buffer )\r
- */\r
-void mbedtls_sha256( const unsigned char *input, size_t ilen,\r
-             unsigned char* output, int is224 )\r
-{\r
-    mbedtls_sha256_context ctx;\r
-\r
-    mbedtls_sha256_init( &ctx );\r
-    mbedtls_sha256_starts( &ctx, is224 );\r
-    mbedtls_sha256_update( &ctx, input, ilen );\r
-    mbedtls_sha256_finish( &ctx, output );\r
-    mbedtls_sha256_free( &ctx );\r
-}\r
-\r
-/*\r
-* Compute HMAC_SHA224/256 using key, key length, text to hash, size of the text, output buffer and a switch for SHA224\r
-*/\r
-void HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is224){\r
-  int digest_length = SHA256_DIGEST_LENGTH;\r
-  if (is224 == 1) {\r
-    digest_length = SHA224_DIGEST_LENGTH;\r
-  }\r
-  \r
-  uint8_t i;\r
-  uint8_t k_ipad[SHA256_BLOCK_LENGTH]; /* inner padding - key XORd with ipad */\r
-  uint8_t k_opad[SHA256_BLOCK_LENGTH]; /* outer padding - key XORd with opad */\r
-  uint8_t buffer[SHA256_BLOCK_LENGTH + digest_length];\r
-\r
-  /* start out by storing key in pads */\r
-  memset(k_ipad, 0, sizeof(k_ipad));\r
-  memset(k_opad, 0, sizeof(k_opad));\r
-\r
-  if (key_length <= SHA256_BLOCK_LENGTH) {\r
-      memcpy(k_ipad, key, key_length);\r
-      memcpy(k_opad, key, key_length);\r
-  }\r
-\r
-  else {\r
-      mbedtls_sha256(key, key_length, k_ipad, is224);\r
-      memcpy(k_opad, k_ipad, SHA256_BLOCK_LENGTH);\r
-  }\r
-\r
-  /* XOR key with ipad and opad values */\r
-  for (i = 0; i < SHA256_BLOCK_LENGTH; i++) {\r
-      k_ipad[i] ^= HMAC_IPAD;\r
-      k_opad[i] ^= HMAC_OPAD;\r
-  }\r
-  \r
-  // perform inner SHA256\r
-  memcpy(buffer, k_ipad, SHA256_BLOCK_LENGTH);\r
-  memcpy(buffer + SHA256_BLOCK_LENGTH, in, n);\r
-  mbedtls_sha256(buffer, SHA256_BLOCK_LENGTH + n, out, is224);\r
-  \r
-  memset(buffer, 0, SHA256_BLOCK_LENGTH + n);\r
-\r
-  // perform outer SHA256\r
-  memcpy(buffer, k_opad, SHA256_BLOCK_LENGTH);\r
-  memcpy(buffer + SHA256_BLOCK_LENGTH, out, digest_length);\r
-  mbedtls_sha256(buffer, SHA256_BLOCK_LENGTH + digest_length, out, is224);\r
-}\r
-\r
-/*\r
-* Compute TOTP_HMAC_SHA224/256 using key, key length, text to hash, size of the text and a switch for SHA224\r
-*/\r
-uint32_t TOTP_HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is224){\r
-    int digest_length = SHA256_DIGEST_LENGTH;\r
-    if (is224 == 1) {\r
-      digest_length = SHA224_DIGEST_LENGTH;\r
-    }\r
-\r
-    // STEP 1, get the HMAC-SHA256 hash from counter and key\r
-    uint8_t hash[digest_length];\r
-    HMAC_SHA256(key, key_length, in, n, hash, is224);\r
-\r
-    // STEP 2, apply dynamic truncation to obtain a 4-bytes string\r
-    uint32_t truncated_hash = 0;\r
-    uint8_t _offset = hash[digest_length - 1] & 0xF;\r
-    uint8_t j;\r
-    for (j = 0; j < 4; ++j) {\r
-        truncated_hash <<= 8;\r
-        truncated_hash  |= hash[_offset + j];\r
-    }\r
-\r
-    // STEP 3, compute the OTP value\r
-    truncated_hash &= 0x7FFFFFFF;    //Disabled\r
-    truncated_hash %= 1000000;\r
-\r
-    return truncated_hash;\r
-}
\ No newline at end of file
diff --git a/legacy/lib/TOTP/sha256.h b/legacy/lib/TOTP/sha256.h
deleted file mode 100644 (file)
index 2f0febc..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/**\r
- * \file sha256.h\r
- *\r
- * \brief SHA-224 and SHA-256 cryptographic hash function\r
- *\r
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
- *  SPDX-License-Identifier: Apache-2.0\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
- *  not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *  http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *\r
- *  This file is part of mbed TLS (https://tls.mbed.org)\r
- */\r
-#ifndef MBEDTLS_SHA256_H\r
-#define MBEDTLS_SHA256_H\r
-\r
-#define SHA224_DIGEST_LENGTH 28\r
-#define SHA256_DIGEST_LENGTH 32\r
-#define SHA256_BLOCK_LENGTH 64\r
-#define HMAC_IPAD 0x36\r
-#define HMAC_OPAD 0x5c\r
-\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/**\r
- * \brief          SHA-256 context structure\r
- */\r
-typedef struct\r
-{\r
-    uint32_t total[2];          /*!< number of bytes processed  */\r
-    uint32_t state[8];          /*!< intermediate digest state  */\r
-    unsigned char buffer[SHA256_BLOCK_LENGTH];   /*!< data block being processed */\r
-    int is224;                  /*!< 0 => SHA-256, else SHA-224 */\r
-}\r
-mbedtls_sha256_context;\r
-\r
-/**\r
- * \brief          Initialize SHA-256 context\r
- *\r
- * \param ctx      SHA-256 context to be initialized\r
- */\r
-void mbedtls_sha256_init( mbedtls_sha256_context *ctx );\r
-\r
-/**\r
- * \brief          Clear SHA-256 context\r
- *\r
- * \param ctx      SHA-256 context to be cleared\r
- */\r
-void mbedtls_sha256_free( mbedtls_sha256_context *ctx );\r
-\r
-/**\r
- * \brief          Clone (the state of) a SHA-256 context\r
- *\r
- * \param dst      The destination context\r
- * \param src      The context to be cloned\r
- */\r
-void mbedtls_sha256_clone( mbedtls_sha256_context *dst,\r
-                           const mbedtls_sha256_context *src );\r
-\r
-/**\r
- * \brief          SHA-256 context setup\r
- *\r
- * \param ctx      context to be initialized\r
- * \param is224    0 = use SHA256, 1 = use SHA224\r
- */\r
-void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );\r
-\r
-/**\r
- * \brief          SHA-256 process buffer\r
- *\r
- * \param ctx      SHA-256 context\r
- * \param input    buffer holding the  data\r
- * \param ilen     length of the input data\r
- */\r
-void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,\r
-                    size_t ilen );\r
-\r
-/**\r
- * \brief          SHA-256 final digest\r
- *\r
- * \param ctx      SHA-256 context\r
- * \param output   SHA-224/256 checksum result\r
- */\r
-void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char* output );\r
-\r
-/* Internal use */\r
-void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[SHA256_BLOCK_LENGTH] );\r
-\r
-/**\r
- * \brief          Output = SHA-256( input buffer )\r
- *\r
- * \param input    buffer holding the  data\r
- * \param ilen     length of the input data\r
- * \param output   SHA-224/256 checksum result\r
- * \param is224    0 = use SHA256, 1 = use SHA224\r
- */\r
-void mbedtls_sha256( const unsigned char *input, size_t ilen,\r
-           unsigned char* output, int is224 );\r
-void HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is224);\r
-uint32_t TOTP_HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is224);\r
-\r
-#endif /* mbedtls_sha256.h */\r
diff --git a/legacy/lib/TOTP/sha512.c b/legacy/lib/TOTP/sha512.c
deleted file mode 100644 (file)
index d35462b..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/*\r
- *  FIPS-180-2 compliant SHA-384/512 implementation\r
- *\r
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
- *  SPDX-License-Identifier: Apache-2.0\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
- *  not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *  http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *\r
- *  This file is part of mbed TLS (https://tls.mbed.org)\r
- */\r
-/*\r
- *  The SHA-512 Secure Hash Standard was published by NIST in 2002.\r
- *\r
- *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\r
- */\r
-\r
-#include "sha512.h"\r
-\r
-#include <string.h>\r
-#include <stdio.h>\r
-\r
-#if defined(_MSC_VER) || defined(__WATCOMC__)\r
-  #define UL64(x) x##ui64\r
-#else\r
-  #define UL64(x) x##ULL\r
-#endif\r
-\r
-/* Implementation that should never be optimized out by the compiler */\r
-static void mbedtls_zeroize( void *v, size_t n ) {\r
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;\r
-}\r
-\r
-/*\r
- * 64-bit integer manipulation macros (big endian)\r
- */\r
-#ifndef GET_UINT64_BE\r
-#define GET_UINT64_BE(n,b,i)                            \\r
-{                                                       \\r
-    (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \\r
-        | ( (uint64_t) (b)[(i) + 1] << 48 )       \\r
-        | ( (uint64_t) (b)[(i) + 2] << 40 )       \\r
-        | ( (uint64_t) (b)[(i) + 3] << 32 )       \\r
-        | ( (uint64_t) (b)[(i) + 4] << 24 )       \\r
-        | ( (uint64_t) (b)[(i) + 5] << 16 )       \\r
-        | ( (uint64_t) (b)[(i) + 6] <<  8 )       \\r
-        | ( (uint64_t) (b)[(i) + 7]       );      \\r
-}\r
-#endif /* GET_UINT64_BE */\r
-\r
-#ifndef PUT_UINT64_BE\r
-#define PUT_UINT64_BE(n,b,i)                            \\r
-{                                                       \\r
-    (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \\r
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \\r
-    (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \\r
-    (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \\r
-    (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \\r
-    (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \\r
-    (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \\r
-    (b)[(i) + 7] = (unsigned char) ( (n)       );       \\r
-}\r
-#endif /* PUT_UINT64_BE */\r
-\r
-/*\r
- * Round constants\r
- */\r
-static const uint64_t K[80] =\r
-{\r
-    UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),\r
-    UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),\r
-    UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),\r
-    UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),\r
-    UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),\r
-    UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),\r
-    UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),\r
-    UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),\r
-    UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),\r
-    UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),\r
-    UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),\r
-    UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),\r
-    UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),\r
-    UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),\r
-    UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),\r
-    UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),\r
-    UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),\r
-    UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),\r
-    UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),\r
-    UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),\r
-    UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),\r
-    UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),\r
-    UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),\r
-    UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),\r
-    UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),\r
-    UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),\r
-    UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),\r
-    UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),\r
-    UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),\r
-    UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),\r
-    UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),\r
-    UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),\r
-    UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),\r
-    UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),\r
-    UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),\r
-    UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),\r
-    UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),\r
-    UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),\r
-    UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),\r
-    UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)\r
-};\r
-\r
-void mbedtls_sha512_init( mbedtls_sha512_context *ctx )\r
-{\r
-    memset( ctx, 0, sizeof( mbedtls_sha512_context ) );\r
-}\r
-\r
-void mbedtls_sha512_free( mbedtls_sha512_context *ctx )\r
-{\r
-    if( ctx == NULL )\r
-        return;\r
-\r
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );\r
-}\r
-\r
-void mbedtls_sha512_clone( mbedtls_sha512_context *dst,\r
-                           const mbedtls_sha512_context *src )\r
-{\r
-    *dst = *src;\r
-}\r
-\r
-/*\r
- * SHA-512 context setup\r
- */\r
-void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )\r
-{\r
-    ctx->total[0] = 0;\r
-    ctx->total[1] = 0;\r
-\r
-    if( is384 == 0 )\r
-    {\r
-        /* SHA-512 */\r
-        ctx->state[0] = UL64(0x6A09E667F3BCC908);\r
-        ctx->state[1] = UL64(0xBB67AE8584CAA73B);\r
-        ctx->state[2] = UL64(0x3C6EF372FE94F82B);\r
-        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);\r
-        ctx->state[4] = UL64(0x510E527FADE682D1);\r
-        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);\r
-        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);\r
-        ctx->state[7] = UL64(0x5BE0CD19137E2179);\r
-    }\r
-    else\r
-    {\r
-        /* SHA-384 */\r
-        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);\r
-        ctx->state[1] = UL64(0x629A292A367CD507);\r
-        ctx->state[2] = UL64(0x9159015A3070DD17);\r
-        ctx->state[3] = UL64(0x152FECD8F70E5939);\r
-        ctx->state[4] = UL64(0x67332667FFC00B31);\r
-        ctx->state[5] = UL64(0x8EB44A8768581511);\r
-        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);\r
-        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);\r
-    }\r
-\r
-    ctx->is384 = is384;\r
-}\r
-\r
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[SHA512_BLOCK_LENGTH] )\r
-{\r
-    int i;\r
-    uint64_t temp1, temp2, W[80];\r
-    uint64_t A, B, C, D, E, F, G, H;\r
-\r
-#define SHR(x,n) (x >> n)\r
-#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))\r
-\r
-#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))\r
-#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))\r
-\r
-#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))\r
-#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))\r
-\r
-#define F0(x,y,z) ((x & y) | (z & (x | y)))\r
-#define F1(x,y,z) (z ^ (x & (y ^ z)))\r
-\r
-#define P(a,b,c,d,e,f,g,h,x,K)                  \\r
-{                                               \\r
-    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \\r
-    temp2 = S2(a) + F0(a,b,c);                  \\r
-    d += temp1; h = temp1 + temp2;              \\r
-}\r
-\r
-    for( i = 0; i < 16; i++ )\r
-    {\r
-        GET_UINT64_BE( W[i], data, i << 3 );\r
-    }\r
-\r
-    for( ; i < 80; i++ )\r
-    {\r
-        W[i] = S1(W[i -  2]) + W[i -  7] +\r
-               S0(W[i - 15]) + W[i - 16];\r
-    }\r
-\r
-    A = ctx->state[0];\r
-    B = ctx->state[1];\r
-    C = ctx->state[2];\r
-    D = ctx->state[3];\r
-    E = ctx->state[4];\r
-    F = ctx->state[5];\r
-    G = ctx->state[6];\r
-    H = ctx->state[7];\r
-    i = 0;\r
-\r
-    do\r
-    {\r
-        P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;\r
-        P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;\r
-        P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;\r
-        P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;\r
-        P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;\r
-        P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;\r
-        P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;\r
-        P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;\r
-    }\r
-    while( i < 80 );\r
-\r
-    ctx->state[0] += A;\r
-    ctx->state[1] += B;\r
-    ctx->state[2] += C;\r
-    ctx->state[3] += D;\r
-    ctx->state[4] += E;\r
-    ctx->state[5] += F;\r
-    ctx->state[6] += G;\r
-    ctx->state[7] += H;\r
-}\r
-\r
-/*\r
- * SHA-512 process buffer\r
- */\r
-void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,\r
-                    size_t ilen )\r
-{\r
-    size_t fill;\r
-    unsigned int left;\r
-\r
-    if( ilen == 0 )\r
-        return;\r
-\r
-    left = (unsigned int) (ctx->total[0] & 0x7F);\r
-    fill = 128 - left;\r
-\r
-    ctx->total[0] += (uint64_t) ilen;\r
-\r
-    if( ctx->total[0] < (uint64_t) ilen )\r
-        ctx->total[1]++;\r
-\r
-    if( left && ilen >= fill )\r
-    {\r
-        memcpy( (void *) (ctx->buffer + left), input, fill );\r
-        mbedtls_sha512_process( ctx, ctx->buffer );\r
-        input += fill;\r
-        ilen  -= fill;\r
-        left = 0;\r
-    }\r
-\r
-    while( ilen >= 128 )\r
-    {\r
-        mbedtls_sha512_process( ctx, input );\r
-        input += 128;\r
-        ilen  -= 128;\r
-    }\r
-\r
-    if( ilen > 0 )\r
-        memcpy( (void *) (ctx->buffer + left), input, ilen );\r
-}\r
-\r
-static const unsigned char sha512_padding[SHA512_BLOCK_LENGTH] =\r
-{\r
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
-};\r
-\r
-/*\r
- * SHA-512 final digest\r
- */\r
-void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char* output )\r
-{\r
-    size_t last, padn;\r
-    uint64_t high, low;\r
-    unsigned char msglen[16];\r
-\r
-    high = ( ctx->total[0] >> 61 )\r
-         | ( ctx->total[1] <<  3 );\r
-    low  = ( ctx->total[0] <<  3 );\r
-\r
-    PUT_UINT64_BE( high, msglen, 0 );\r
-    PUT_UINT64_BE( low,  msglen, 8 );\r
-\r
-    last = (size_t)( ctx->total[0] & 0x7F );\r
-    padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );\r
-\r
-    mbedtls_sha512_update( ctx, sha512_padding, padn );\r
-    mbedtls_sha512_update( ctx, msglen, 16 );\r
-\r
-    PUT_UINT64_BE( ctx->state[0], output,  0 );\r
-    PUT_UINT64_BE( ctx->state[1], output,  8 );\r
-    PUT_UINT64_BE( ctx->state[2], output, 16 );\r
-    PUT_UINT64_BE( ctx->state[3], output, 24 );\r
-    PUT_UINT64_BE( ctx->state[4], output, 32 );\r
-    PUT_UINT64_BE( ctx->state[5], output, 40 );\r
-\r
-    if( ctx->is384 == 0 )\r
-    {\r
-        PUT_UINT64_BE( ctx->state[6], output, 48 );\r
-        PUT_UINT64_BE( ctx->state[7], output, 56 );\r
-    }\r
-}\r
-\r
-/*\r
- * output = SHA-512( input buffer )\r
- */\r
-void mbedtls_sha512( const unsigned char *input, size_t ilen,\r
-             unsigned char* output, int is384 )\r
-{\r
-    mbedtls_sha512_context ctx;\r
-\r
-    mbedtls_sha512_init( &ctx );\r
-    mbedtls_sha512_starts( &ctx, is384 );\r
-    mbedtls_sha512_update( &ctx, input, ilen );\r
-    mbedtls_sha512_finish( &ctx, output );\r
-    mbedtls_sha512_free( &ctx );\r
-}\r
-\r
-/*\r
-* Compute HMAC_SHA384/512 using key, key length, text to hash, size of the text, output buffer and a switch for SHA384\r
-*/\r
-void HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is384){\r
-  int digest_length = SHA512_DIGEST_LENGTH;\r
-  if (is384 == 1) {\r
-    digest_length = SHA384_DIGEST_LENGTH;\r
-  }\r
-\r
-  uint8_t i;\r
-  uint8_t k_ipad[SHA512_BLOCK_LENGTH]; /* inner padding - key XORd with ipad */\r
-  uint8_t k_opad[SHA512_BLOCK_LENGTH]; /* outer padding - key XORd with opad */\r
-  uint8_t buffer[SHA512_BLOCK_LENGTH + digest_length];\r
-\r
-  /* start out by storing key in pads */\r
-  memset(k_ipad, 0, sizeof(k_ipad));\r
-  memset(k_opad, 0, sizeof(k_opad));\r
-\r
-  if (key_length <= SHA512_BLOCK_LENGTH) {\r
-      memcpy(k_ipad, key, key_length);\r
-      memcpy(k_opad, key, key_length);\r
-  }\r
-\r
-  else {\r
-      mbedtls_sha512(key, key_length, k_ipad, is384);\r
-      memcpy(k_opad, k_ipad, SHA512_BLOCK_LENGTH);\r
-  }\r
-\r
-  /* XOR key with ipad and opad values */\r
-  for (i = 0; i < SHA512_BLOCK_LENGTH; i++) {\r
-      k_ipad[i] ^= HMAC_IPAD;\r
-      k_opad[i] ^= HMAC_OPAD;\r
-  }\r
-  \r
-  // perform inner SHA512\r
-  memcpy(buffer, k_ipad, SHA512_BLOCK_LENGTH);\r
-  memcpy(buffer + SHA512_BLOCK_LENGTH, in, n);\r
-  mbedtls_sha512(buffer, SHA512_BLOCK_LENGTH + n, out, is384);\r
-  \r
-  memset(buffer, 0, SHA512_BLOCK_LENGTH + n);\r
-\r
-  // perform outer SHA512\r
-  memcpy(buffer, k_opad, SHA512_BLOCK_LENGTH);\r
-  memcpy(buffer + SHA512_BLOCK_LENGTH, out, digest_length);\r
-  mbedtls_sha512(buffer, SHA512_BLOCK_LENGTH + digest_length, out, is384);\r
-}\r
-\r
-/*\r
-* Compute TOTP_HMAC_SHA384/512 using key, key length, text to hash, size of the text and a switch for SHA384\r
-*/\r
-uint32_t TOTP_HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is384){\r
-    int digest_length = SHA512_DIGEST_LENGTH;\r
-    if (is384 == 1) {\r
-      digest_length = SHA384_DIGEST_LENGTH;\r
-    }\r
-\r
-    // STEP 1, get the HMAC-SHA512 hash from counter and key\r
-    uint8_t hash[digest_length];\r
-    HMAC_SHA512(key, key_length, in, n, hash, is384);\r
-\r
-    // STEP 2, apply dynamic truncation to obtain a 4-bytes string\r
-    uint32_t truncated_hash = 0;\r
-    uint8_t _offset = hash[digest_length - 1] & 0xF;\r
-    uint8_t j;\r
-    for (j = 0; j < 4; ++j) {\r
-        truncated_hash <<= 8;\r
-        truncated_hash  |= hash[_offset + j];\r
-    }\r
-\r
-    // STEP 3, compute the OTP value\r
-    truncated_hash &= 0x7FFFFFFF;    //Disabled\r
-    truncated_hash %= 1000000;\r
-\r
-    return truncated_hash;\r
-}
\ No newline at end of file
diff --git a/legacy/lib/TOTP/sha512.h b/legacy/lib/TOTP/sha512.h
deleted file mode 100644 (file)
index 991ebfa..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/**\r
- * \file sha512.h\r
- *\r
- * \brief SHA-384 and SHA-512 cryptographic hash function\r
- *\r
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
- *  SPDX-License-Identifier: Apache-2.0\r
- *\r
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
- *  not use this file except in compliance with the License.\r
- *  You may obtain a copy of the License at\r
- *\r
- *  http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
- *\r
- *  This file is part of mbed TLS (https://tls.mbed.org)\r
- */\r
-#ifndef MBEDTLS_SHA512_H\r
-#define MBEDTLS_SHA512_H\r
-\r
-#define SHA384_DIGEST_LENGTH 48\r
-#define SHA512_DIGEST_LENGTH 64\r
-#define SHA512_BLOCK_LENGTH 128\r
-#define HMAC_IPAD 0x36\r
-#define HMAC_OPAD 0x5c\r
-\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-\r
-/**\r
- * \brief          SHA-512 context structure\r
- */\r
-typedef struct\r
-{\r
-    uint64_t total[2];          /*!< number of bytes processed  */\r
-    uint64_t state[8];          /*!< intermediate digest state  */\r
-    unsigned char buffer[SHA512_BLOCK_LENGTH];  /*!< data block being processed */\r
-    int is384;                  /*!< 0 => SHA-512, else SHA-384 */\r
-}\r
-mbedtls_sha512_context;\r
-\r
-/**\r
- * \brief          Initialize SHA-512 context\r
- *\r
- * \param ctx      SHA-512 context to be initialized\r
- */\r
-void mbedtls_sha512_init( mbedtls_sha512_context *ctx );\r
-\r
-/**\r
- * \brief          Clear SHA-512 context\r
- *\r
- * \param ctx      SHA-512 context to be cleared\r
- */\r
-void mbedtls_sha512_free( mbedtls_sha512_context *ctx );\r
-\r
-/**\r
- * \brief          Clone (the state of) a SHA-512 context\r
- *\r
- * \param dst      The destination context\r
- * \param src      The context to be cloned\r
- */\r
-void mbedtls_sha512_clone( mbedtls_sha512_context *dst,\r
-                           const mbedtls_sha512_context *src );\r
-\r
-/**\r
- * \brief          SHA-512 context setup\r
- *\r
- * \param ctx      context to be initialized\r
- * \param is384    0 = use SHA512, 1 = use SHA384\r
- */\r
-void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 );\r
-\r
-/**\r
- * \brief          SHA-512 process buffer\r
- *\r
- * \param ctx      SHA-512 context\r
- * \param input    buffer holding the  data\r
- * \param ilen     length of the input data\r
- */\r
-void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,\r
-                    size_t ilen );\r
-\r
-/**\r
- * \brief          SHA-512 final digest\r
- *\r
- * \param ctx      SHA-512 context\r
- * \param output   SHA-384/512 checksum result\r
- */\r
-void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char* output );\r
-\r
-/**\r
- * \brief          Output = SHA-512( input buffer )\r
- *\r
- * \param input    buffer holding the  data\r
- * \param ilen     length of the input data\r
- * \param output   SHA-384/512 checksum result\r
- * \param is384    0 = use SHA512, 1 = use SHA384\r
- */\r
-void mbedtls_sha512( const unsigned char *input, size_t ilen,\r
-             unsigned char* output, int is384 );\r
-\r
-/**\r
- * \brief          Checkup routine\r
- *\r
- * \return         0 if successful, or 1 if the test failed\r
- */\r
-int mbedtls_sha512_self_test( int verbose );\r
-\r
-/* Internal use */\r
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[SHA512_BLOCK_LENGTH] );\r
-void HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is384);\r
-uint32_t TOTP_HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is384);\r
-\r
-#endif /* mbedtls_sha512.h */\r
diff --git a/legacy/lib/base32/base32.c b/legacy/lib/base32/base32.c
deleted file mode 100644 (file)
index 548f9a4..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- * base32 (de)coder implementation as specified by RFC4648.
- *
- * Copyright (c) 2010 Adrien Kunysz
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- **/
-
-#include <assert.h>  // assert()
-#include <limits.h>  // CHAR_BIT
-
-#include "base32.h"
-
-/**
- * Let this be a sequence of plain data before encoding:
- *
- *  01234567 01234567 01234567 01234567 01234567
- * +--------+--------+--------+--------+--------+
- * |< 0 >< 1| >< 2 ><|.3 >< 4.|>< 5 ><.|6 >< 7 >|
- * +--------+--------+--------+--------+--------+
- *
- * There are 5 octets of 8 bits each in each sequence.
- * There are 8 blocks of 5 bits each in each sequence.
- *
- * You probably want to refer to that graph when reading the algorithms in this
- * file. We use "octet" instead of "byte" intentionnaly as we really work with
- * 8 bits quantities. This implementation will probably not work properly on
- * systems that don't have exactly 8 bits per (unsigned) char.
- **/
-
-static size_t min(size_t x, size_t y)
-{
-       return x < y ? x : y;
-}
-
-static const unsigned char PADDING_CHAR = '=';
-
-/**
- * Pad the given buffer with len padding characters.
- */
-static void pad(unsigned char *buf, int len)
-{
-       for (int i = 0; i < len; i++)
-               buf[i] = PADDING_CHAR;
-}
-
-/**
- * This convert a 5 bits value into a base32 character.
- * Only the 5 least significant bits are used.
- */
-static unsigned char encode_char(unsigned char c)
-{
-       static unsigned char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
-       return base32[c & 0x1F];  // 0001 1111
-}
-
-/**
- * Decode given character into a 5 bits value. 
- * Returns -1 iff the argument given was an invalid base32 character
- * or a padding character.
- */
-static int decode_char(unsigned char c)
-{
-       int retval = -1;
-
-       if (c >= 'A' && c <= 'Z')
-               retval = c - 'A';
-       if (c >= '2' && c <= '7')
-               retval = c - '2' + 26;
-
-       assert(retval == -1 || ((retval & 0x1F) == retval));
-
-       return  retval;
-}
-
-/**
- * Given a block id between 0 and 7 inclusive, this will return the index of
- * the octet in which this block starts. For example, given 3 it will return 1
- * because block 3 starts in octet 1:
- *
- * +--------+--------+
- * | ......<|.3 >....|
- * +--------+--------+
- *  octet 1 | octet 2
- */
-static int get_octet(int block)
-{
-       assert(block >= 0 && block < 8);
-       return (block*5) / 8;
-}
-
-/**
- * Given a block id between 0 and 7 inclusive, this will return how many bits
- * we can drop at the end of the octet in which this block starts. 
- * For example, given block 0 it will return 3 because there are 3 bits
- * we don't care about at the end:
- *
- *  +--------+-
- *  |< 0 >...|
- *  +--------+-
- *
- * Given block 1, it will return -2 because there
- * are actually two bits missing to have a complete block:
- *
- *  +--------+-
- *  |.....< 1|..
- *  +--------+-
- **/
-static int get_offset(int block)
-{
-       assert(block >= 0 && block < 8);
-       return (8 - 5 - (5*block) % 8);
-}
-
-/**
- * Like "b >> offset" but it will do the right thing with negative offset.
- * We need this as bitwise shifting by a negative offset is undefined
- * behavior.
- */
-static unsigned char shift_right(unsigned char byte, int offset)
-{
-       if (offset > 0)
-               return byte >>  offset;
-       else
-               return byte << -offset;
-}
-
-static unsigned char shift_left(unsigned char byte, int offset)
-{
-       return shift_right(byte, - offset);
-}
-
-/**
- * Encode a sequence. A sequence is no longer than 5 octets by definition.
- * Thus passing a length greater than 5 to this function is an error. Encoding
- * sequences shorter than 5 octets is supported and padding will be added to the
- * output as per the specification.
- */
-static void encode_sequence(const unsigned char *plain, int len, unsigned char *coded)
-{
-       assert(CHAR_BIT == 8);  // not sure this would work otherwise
-       assert(len >= 0 && len <= 5);
-
-       for (int block = 0; block < 8; block++) {
-               int octet = get_octet(block);  // figure out which octet this block starts in
-               int junk = get_offset(block);  // how many bits do we drop from this octet?
-
-               if (octet >= len) { // we hit the end of the buffer
-                       pad(&coded[block], 8 - block);
-                       return;
-               }
-
-               unsigned char c = shift_right(plain[octet], junk);  // first part
-
-               if (junk < 0  // is there a second part?
-               &&  octet < len - 1)  // is there still something to read?
-               {
-                       c |= shift_right(plain[octet+1], 8 + junk);
-               }
-               coded[block] = encode_char(c);
-       }
-}
-
-void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded)
-{
-       // All the hard work is done in encode_sequence(),
-       // here we just need to feed it the data sequence by sequence.
-       for (size_t i = 0, j = 0; i < len; i += 5, j += 8) {
-               encode_sequence(&plain[i], min(len - i, 5), &coded[j]);
-       }
-}
-
-static int decode_sequence(const unsigned char *coded, unsigned char *plain)
-{
-       assert(CHAR_BIT == 8);
-       assert(coded && plain);
-
-       plain[0] = 0;
-       for (int block = 0; block < 8; block++) {
-               int offset = get_offset(block);
-               int octet = get_octet(block);
-
-               int c = decode_char(coded[block]);
-               if (c < 0)  // invalid char, stop here
-                       return octet;
-
-               plain[octet] |= shift_left(c, offset);
-               if (offset < 0) {  // does this block overflows to next octet?
-                       assert(octet < 4);
-                       plain[octet+1] = shift_left(c, 8 + offset);
-               }
-       }
-       return 5;
-}
-
-size_t base32_decode(const unsigned char *coded, unsigned char *plain)
-{
-       size_t written = 0;
-       for (size_t i = 0, j = 0; ; i += 8, j += 5) {
-               int n = decode_sequence(&coded[i], &plain[j]);
-               written += n;
-               if (n < 5)
-                       return written;
-       }
-}
diff --git a/legacy/lib/base32/base32.h b/legacy/lib/base32/base32.h
deleted file mode 100644 (file)
index abf2d03..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * base32 (de)coder implementation as specified by RFC4648.
- *
- * Copyright (c) 2010 Adrien Kunysz
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- **/
-
-#ifndef __BASE32_H_
-#define __BASE32_H_
-
-#include <stddef.h>   // size_t
-
-/**
- * Returns the length of the output buffer required to encode len bytes of
- * data into base32. This is a macro to allow users to define buffer size at
- * compilation time.
- */
-#define BASE32_LEN(len)  (((len)/5)*8 + ((len) % 5 ? 8 : 0))
-
-/**
- * Returns the length of the output buffer required to decode a base32 string
- * of len characters. Please note that len must be a multiple of 8 as per
- * definition of a base32 string. This is a macro to allow users to define
- * buffer size at compilation time.
- */
-#define UNBASE32_LEN(len)  (((len)/8)*5)
-
-/**
- * Encode the data pointed to by plain into base32 and store the
- * result at the address pointed to by coded. The "coded" argument
- * must point to a location that has enough available space
- * to store the whole coded string. The resulting string will only
- * contain characters from the [A-Z2-7=] set. The "len" arguments
- * define how many bytes will be read from the "plain" buffer.
- **/
-void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded);
-
-/**
- * Decode the null terminated string pointed to by coded and write
- * the decoded data into the location pointed to by plain. The
- * "plain" argument must point to a location that has enough available
- * space to store the whole decoded string.
- * Returns the length of the decoded string. This may be less than
- * expected due to padding. If an invalid base32 character is found
- * in the coded string, decoding will stop at that point.
- **/
-size_t base32_decode(const unsigned char *coded, unsigned char *plain);
-
-#endif
diff --git a/legacy/watch_faces/complication/totp_face.c b/legacy/watch_faces/complication/totp_face.c
deleted file mode 100644 (file)
index c159f59..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-
-/*
- * MIT License
- *
- * Copyright © 2021 Wesley Ellis (https://github.com/tahnok)
- * Copyright © 2021-2023 Joey Castillo <joeycastillo@utexas.edu>
- * Copyright © 2022 Jack Bond-Preston <jackbondpreston@outlook.com>
- * Copyright © 2023 Alex Utter <ooterness@gmail.com>
- * Copyright © 2023 Emilien Court <emilien.court@telecomnancy.net>
- * Copyright © 2023 Jeremy O'Brien <neutral@fastmail.com>
- * Copyright © 2024 Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> (https://www.matheusmoreira.com/)
- * Copyright © 2024 Max Zettlmeißl <max@zettlmeissl.de>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "totp_face.h"
-#include "watch.h"
-#include "watch_utility.h"
-#include "TOTP.h"
-#include "base32.h"
-
-#ifndef TOTP_FACE_MAX_KEY_LENGTH
-#define TOTP_FACE_MAX_KEY_LENGTH 128
-#endif
-
-typedef struct {
-    unsigned char labels[2];
-    hmac_alg algorithm;
-    uint32_t period;
-    size_t encoded_key_length;
-    unsigned char *encoded_key;
-} totp_t;
-
-#define CREDENTIAL(label, key_array, algo, timestep) \
-    (const totp_t) { \
-        .encoded_key = ((unsigned char *) key_array), \
-        .encoded_key_length = sizeof(key_array) - 1, \
-        .period = (timestep), \
-        .labels = (#label), \
-        .algorithm = (algo), \
-    }
-
-////////////////////////////////////////////////////////////////////////////////
-// Enter your TOTP key data below
-
-static totp_t credentials[] = {
-    CREDENTIAL(2F, "JBSWY3DPEHPK3PXP", SHA1, 30),
-    CREDENTIAL(AC, "JBSWY3DPEHPK3PXP", SHA1, 30),
-};
-
-// END OF KEY DATA.
-////////////////////////////////////////////////////////////////////////////////
-
-static inline totp_t *totp_at(size_t i) {
-    return &credentials[i];
-}
-
-static inline totp_t *totp_current(totp_state_t *totp_state) {
-    return totp_at(totp_state->current_index);
-}
-
-static inline size_t totp_total(void) {
-    return sizeof(credentials) / sizeof(*credentials);
-}
-
-static void totp_validate_key_lengths(void) {
-    for (size_t n = totp_total(), i = 0; i < n; ++i) {
-        totp_t *totp = totp_at(i);
-
-        if (UNBASE32_LEN(totp->encoded_key_length) > TOTP_FACE_MAX_KEY_LENGTH) {
-            // Key exceeds static limits, turn it off by zeroing the length
-            totp->encoded_key_length = 0;
-        }
-    }
-}
-
-static void totp_generate(totp_state_t *totp_state) {
-    totp_t *totp = totp_current(totp_state);
-
-    if (totp->encoded_key_length <= 0) {
-        // Key exceeded static limits and was turned off
-        totp_state->current_decoded_key_length = 0;
-        return;
-    }
-
-    totp_state->current_decoded_key_length = base32_decode(totp->encoded_key, totp_state->current_decoded_key);
-
-    if (totp_state->current_decoded_key_length == 0) {
-        // Decoding failed for some reason
-        // Not a base 32 string?
-        return;
-    }
-
-    TOTP(
-        totp_state->current_decoded_key,
-        totp_state->current_decoded_key_length,
-        totp->period,
-        totp->algorithm
-    );
-}
-
-static void totp_display_error(totp_state_t *totp_state) {
-    char buf[10 + 1];
-    totp_t *totp = totp_current(totp_state);
-
-    snprintf(buf, sizeof(buf), "%c%c  ERROR ", totp->labels[0], totp->labels[1]);
-    watch_display_string(buf, 0);
-}
-
-static void totp_display_code(totp_state_t *totp_state) {
-    char buf[14];
-    div_t result;
-    uint8_t valid_for;
-    totp_t *totp = totp_current(totp_state);
-
-    result = div(totp_state->timestamp, totp->period);
-    if (result.quot != totp_state->steps) {
-        totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp);
-        totp_state->steps = result.quot;
-    }
-    valid_for = totp->period - result.rem;
-    sprintf(buf, "%c%c%2d%06lu", totp->labels[0], totp->labels[1], valid_for, totp_state->current_code);
-
-    watch_display_string(buf, 0);
-}
-
-static void totp_display(totp_state_t *totp_state) {
-    if (totp_state->current_decoded_key_length > 0) {
-        totp_display_code(totp_state);
-    } else {
-        totp_display_error(totp_state);
-    }
-}
-
-static void totp_generate_and_display(totp_state_t *totp_state) {
-    totp_generate(totp_state);
-    totp_display(totp_state);
-}
-
-static inline uint32_t totp_compute_base_timestamp() {
-    return watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_get_current_timezone_offset());
-}
-
-void totp_face_setup(uint8_t watch_face_index, void ** context_ptr) {
-    (void) watch_face_index;
-
-    totp_validate_key_lengths();
-
-    if (*context_ptr == NULL) {
-        totp_state_t *totp = malloc(sizeof(totp_state_t));
-        totp->current_decoded_key = malloc(TOTP_FACE_MAX_KEY_LENGTH);
-        *context_ptr = totp;
-    }
-}
-
-void totp_face_activate(void *context) {
-
-    totp_state_t *totp = (totp_state_t *) context;
-
-    totp->timestamp = totp_compute_base_timestamp();
-    totp->steps = 0;
-    totp->current_code = 0;
-    totp->current_index = 0;
-    totp->current_decoded_key_length = 0;
-    // totp->current_decoded_key is already initialized in setup
-
-    totp_generate_and_display(totp);
-}
-
-bool totp_face_loop(movement_event_t event, void *context) {
-
-    totp_state_t *totp_state = (totp_state_t *) context;
-
-    switch (event.event_type) {
-        case EVENT_TICK:
-            totp_state->timestamp++;
-            // fall through
-        case EVENT_ACTIVATE:
-            totp_display(totp_state);
-            break;
-        case EVENT_TIMEOUT:
-            movement_move_to_face(0);
-            break;
-        case EVENT_ALARM_BUTTON_UP:
-            if ((size_t)totp_state->current_index + 1 < totp_total()) {
-                totp_state->current_index++;
-            } else {
-                // wrap around to first key
-                totp_state->current_index = 0;
-            }
-
-            totp_generate_and_display(totp_state);
-
-            break;
-        case EVENT_LIGHT_BUTTON_UP:
-            if (totp_state->current_index == 0) {
-                // Wrap around to the last credential.
-                totp_state->current_index = totp_total() - 1;
-            } else {
-                totp_state->current_index--;
-            }
-
-            totp_generate_and_display(totp_state);
-
-            break;
-        case EVENT_ALARM_BUTTON_DOWN:
-        case EVENT_ALARM_LONG_PRESS:
-        case EVENT_LIGHT_BUTTON_DOWN:
-            break;
-        case EVENT_LIGHT_LONG_PRESS:
-            movement_illuminate_led();
-            break;
-        default:
-            movement_default_loop_handler(event);
-            break;
-    }
-
-    return true;
-}
-
-void totp_face_resign(void *context) {
-    (void) context;
-}
diff --git a/legacy/watch_faces/complication/totp_face.h b/legacy/watch_faces/complication/totp_face.h
deleted file mode 100644 (file)
index 0dc1b8e..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-
-/*
- * MIT License
- *
- * Copyright © 2021 Wesley Ellis (https://github.com/tahnok)
- * Copyright © 2021-2022 Joey Castillo <joeycastillo@utexas.edu>
- * Copyright © 2022 Alexsander Akers <me@a2.io>
- * Copyright © 2022 Jack Bond-Preston <jackbondpreston@outlook.com>
- * Copyright © 2023 Alex Utter <ooterness@gmail.com>
- * Copyright © 2024 Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> (https://www.matheusmoreira.com/)
- * Copyright © 2024 Max Zettlmeißl <max@zettlmeissl.de>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef TOTP_FACE_H_
-#define TOTP_FACE_H_
-
-/*
- * TOTP face
- * Time-based one-time password (TOTP) generator
- *
- * Generate one-time passwords often used for two-factor authentication.
- * The secret key must be set by hand, by editing "totp_face.c".
- *
- * Available algorithms:
- *  o SHA1 (most TOTP codes use this)
- *  o SHA224
- *  o SHA256
- *  o SHA384
- *  o SHA512
- *
- * Instructions:
- *  o Find your secret key(s).
- *      o Use https://github.com/susam/mintotp to generate test codes for
- *        verification
- *  o Edit global `credentials` variable in "totp_face.c" to configure your
- *    TOTP credentials. The file includes two examples that you can use as a
- *    reference. Credentials are added with the `CREDENTIAL` macro in the form
- *    `CREDENTIAL(label, key, algorithm, timestep)` where:
- *      o `label` is a 2 character label that is displayed in the weekday digits
- *        to identify the TOTP credential.
- *      o `key` is a string with the base32 encoded secret.
- *      o `algorithm` is one of the supported hashing algorithms listed above.
- *      o `timestep` is how often the TOTP refreshes in seconds. This is usually
- *        30 seconds.
- *
- * If you have more than one secret key, press ALARM to cycle through them.
- * Press LIGHT to cycle in the other direction or keep it pressed longer to
- * activate the light.
- */
-
-#include "movement.h"
-
-typedef struct {
-    uint32_t timestamp;
-    uint8_t steps;
-    uint32_t current_code;
-    uint8_t current_index;
-    uint8_t *current_decoded_key;
-    size_t current_decoded_key_length;
-} totp_state_t;
-
-void totp_face_setup(uint8_t watch_face_index, void ** context_ptr);
-void totp_face_activate(void *context);
-bool totp_face_loop(movement_event_t event, void *context);
-void totp_face_resign(void *context);
-
-#define totp_face ((const watch_face_t){ \
-    totp_face_setup, \
-    totp_face_activate, \
-    totp_face_loop, \
-    totp_face_resign, \
-    NULL, \
-})
-
-#endif // TOTP_FACE_H_
diff --git a/lib/TOTP/LICENSE b/lib/TOTP/LICENSE
new file mode 100644 (file)
index 0000000..6de4c0f
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Weravech
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/lib/TOTP/README.md b/lib/TOTP/README.md
new file mode 100644 (file)
index 0000000..bb23122
--- /dev/null
@@ -0,0 +1,68 @@
+TOTP Pure C Library
+====================
+
+Library to generate Time-based One-Time Passwords.
+
+Implements the Time-based One-Time Password algorithm specified in [RFC 6238](https://tools.ietf.org/html/rfc6238). 
+
+Supports different time steps and is compatible with tokens that use the same standard (including software ones, like the Google Authenticator app).
+
+The code is made of :
+
+- [TOTP-MCU](https://github.com/Netthaw/TOTP-MCU) for `TimeStruct2Timestamp`, `getCodeFromTimestamp`, `getCodeFromTimeStruct`, part of `getCodeFromSteps` and `TOTP_HMAC_SHA*` functions
+- [mbedtls](https://github.com/Mbed-TLS/mbedtls) for SHA1/SHA224/SHA256/SHA384/SHA512 implementations
+- [this project](https://github.com/mygityf/cipher/blob/master/cipher/hmac.c) as an inspiration for writing the code to compute the TOTP using the key and the text to hash
+
+
+
+Supported algorithms are SHA1/SHA224/SHA256/SHA384/SHA512.
+
+
+
+Installation & usage:
+--------------------
+First include header to your file
+```c
+#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](https://cryptii.com/pipes/base32-to-hex) to convert the base32 string to hex (make sure you upcase it first if it's lowercase and remove all whitespaces).
+```c
+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, the Timestep between codes and the algorithm used (most of the time, `SHA1`).
+```c
+TOTP(hmacKey, 10, 30, SHA1);                                     // Secret key, Secret key length, Timestep (30s), Algorithm
+```
+Use the ```getCodeFromTimestamp()``` function to get a TOTP from a unix epoch timestamp
+```c
+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), 
+```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.
+
+```c
+setTimezone(9);                                            // Set timezone +9 Japan
+```
+
+You can see an example in example.c (compile it with `gcc -o example example.c sha1.c sha256.c sha512.c TOTP.c -I.`)
+
+Thanks to:
+----------
+
+* Netthaw, https://github.com/Netthaw/TOTP-MCU
+* Mbed-TLS, https://github.com/Mbed-TLS/mbedtls
+* mygityf, https://github.com/mygityf/cipher/blob/master/cipher/hmac.c
+* susam, https://github.com/susam/mintotp
diff --git a/lib/TOTP/TOTP.c b/lib/TOTP/TOTP.c
new file mode 100644 (file)
index 0000000..7f60133
--- /dev/null
@@ -0,0 +1,69 @@
+#include "TOTP.h"\r
+#include "sha1.h"\r
+#include "sha256.h"\r
+#include "sha512.h"\r
+#include <stdio.h>\r
+\r
+uint8_t* _hmacKey;\r
+uint8_t _keyLength;\r
+uint8_t _timeZoneOffset;\r
+uint32_t _timeStep;\r
+hmac_alg _algorithm;\r
+\r
+// Init the library with the private key, its length, the timeStep duration and the algorithm that should be used\r
+void TOTP(uint8_t* hmacKey, uint8_t keyLength, uint32_t timeStep, hmac_alg algorithm) {\r
+    _hmacKey = hmacKey;\r
+    _keyLength = keyLength;\r
+    _timeStep = timeStep;\r
+    _algorithm = algorithm;\r
+}\r
+\r
+void setTimezone(uint8_t timezone){\r
+    _timeZoneOffset = timezone;\r
+}\r
+\r
+static uint32_t TimeStruct2Timestamp(struct tm time){\r
+    //time.tm_mon -= 1;\r
+    //time.tm_year -= 1900;\r
+    return mktime(&(time)) - (_timeZoneOffset * 3600) - 2208988800;\r
+}\r
+\r
+// Generate a code, using the timestamp provided\r
+uint32_t getCodeFromTimestamp(uint32_t timeStamp) {\r
+    uint32_t steps = timeStamp / _timeStep;\r
+    return getCodeFromSteps(steps);\r
+}\r
+\r
+// Generate a code, using the timestamp provided\r
+uint32_t getCodeFromTimeStruct(struct tm time) {\r
+    return getCodeFromTimestamp(TimeStruct2Timestamp(time));\r
+}\r
+\r
+// Generate a code, using the number of steps provided\r
+uint32_t getCodeFromSteps(uint32_t steps) {\r
+    // STEP 0, map the number of steps in a 8-bytes array (counter value)\r
+    uint8_t _byteArray[8];\r
+    _byteArray[0] = 0x00;\r
+    _byteArray[1] = 0x00;\r
+    _byteArray[2] = 0x00;\r
+    _byteArray[3] = 0x00;\r
+    _byteArray[4] = (uint8_t)((steps >> 24) & 0xFF);\r
+    _byteArray[5] = (uint8_t)((steps >> 16) & 0xFF);\r
+    _byteArray[6] = (uint8_t)((steps >> 8) & 0XFF);\r
+    _byteArray[7] = (uint8_t)((steps & 0XFF));\r
+\r
+    switch(_algorithm){\r
+        case SHA1:\r
+            return(TOTP_HMAC_SHA1(_hmacKey, _keyLength, _byteArray, 8));\r
+        case SHA224:\r
+            return(TOTP_HMAC_SHA256(_hmacKey, _keyLength, _byteArray, 8, 1));\r
+        case SHA256:\r
+            return(TOTP_HMAC_SHA256(_hmacKey, _keyLength, _byteArray, 8, 0));\r
+        case SHA384:\r
+            return(TOTP_HMAC_SHA512(_hmacKey, _keyLength, _byteArray, 8, 1));\r
+        case SHA512:\r
+            return(TOTP_HMAC_SHA512(_hmacKey, _keyLength, _byteArray, 8, 0));\r
+        default:\r
+            return(0);\r
+    }\r
+}\r
diff --git a/lib/TOTP/TOTP.h b/lib/TOTP/TOTP.h
new file mode 100644 (file)
index 0000000..adde66d
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef TOTP_H_\r
+#define TOTP_H_\r
+\r
+#include <inttypes.h>\r
+#include "time.h"\r
+\r
+typedef enum __attribute__ ((__packed__)) {\r
+    SHA1,\r
+    SHA224,\r
+    SHA256,\r
+    SHA384,\r
+    SHA512\r
+} hmac_alg;\r
+\r
+void TOTP(uint8_t* hmacKey, uint8_t keyLength, uint32_t timeStep, hmac_alg algorithm);\r
+void setTimezone(uint8_t timezone);\r
+uint32_t getCodeFromTimestamp(uint32_t timeStamp);\r
+uint32_t getCodeFromTimeStruct(struct tm time);\r
+uint32_t getCodeFromSteps(uint32_t steps);\r
+\r
+#endif // TOTP_H_\r
diff --git a/lib/TOTP/example.c b/lib/TOTP/example.c
new file mode 100644 (file)
index 0000000..a218ff8
--- /dev/null
@@ -0,0 +1,27 @@
+#include "TOTP.h"\r
+#include <stdio.h>\r
+\r
+/**\r
+ * example.c\r
+ */\r
+void main(void)\r
+{\r
+       uint8_t hmacKey[] = {0x4d, 0x79, 0x4c, 0x65, 0x67, 0x6f, 0x44, 0x6f, 0x6f, 0x72};               // Secret key\r
+       TOTP(hmacKey, 10, 7200, SHA1);                                                                        // Secret key, Key length, Timestep (7200s - 2hours)\r
+\r
+       setTimezone(9);                                                                                 // Set timezone\r
+       uint32_t newCode = getCodeFromTimestamp(1557414000);                                            // Timestamp Now\r
+\r
+       ///////////////// For struct tm //////////////////\r
+    // struct tm datetime;\r
+    // datetime.tm_hour = 9;\r
+    // datetime.tm_min = 0;\r
+    // datetime.tm_sec = 0;\r
+    // datetime.tm_mday = 13;\r
+    // datetime.tm_mon = 5;\r
+    // datetime.tm_year = 2019;\r
+       //  uint32_t newCode = getCodeFromTimeStruct(datetime);\r
+       ///////////////////////////////////////////////////\r
+\r
+       printf("Code : %06u\n",newCode);\r
+}\r
diff --git a/lib/TOTP/sha1.c b/lib/TOTP/sha1.c
new file mode 100644 (file)
index 0000000..84fc83d
--- /dev/null
@@ -0,0 +1,398 @@
+/*\r
+ *  FIPS-180-1 compliant SHA-1 implementation\r
+ *\r
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
+ *  SPDX-License-Identifier: Apache-2.0\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+ *  not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *  http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ *\r
+ *  This file is part of mbed TLS (https://tls.mbed.org)\r
+ */\r
+/*\r
+ *  The SHA-1 standard was published by NIST in 1993.\r
+ *\r
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm\r
+ */\r
+\r
+#include "sha1.h"\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+/* Implementation that should never be optimized out by the compiler */\r
+static void mbedtls_zeroize( void *v, size_t n ) {\r
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;\r
+}\r
+\r
+/*\r
+ * 32-bit integer manipulation macros (big endian)\r
+ */\r
+#ifndef GET_UINT32_BE\r
+#define GET_UINT32_BE(n,b,i)                            \\r
+{                                                       \\r
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \\r
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \\r
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \\r
+        | ( (uint32_t) (b)[(i) + 3]       );            \\r
+}\r
+#endif\r
+\r
+#ifndef PUT_UINT32_BE\r
+#define PUT_UINT32_BE(n,b,i)                            \\r
+{                                                       \\r
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\r
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\r
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\r
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\r
+}\r
+#endif\r
+\r
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx )\r
+{\r
+    memset( ctx, 0, sizeof( mbedtls_sha1_context ) );\r
+}\r
+\r
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx )\r
+{\r
+    if( ctx == NULL )\r
+        return;\r
+\r
+    mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );\r
+}\r
+\r
+/*\r
+ * SHA-1 context setup\r
+ */\r
+void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )\r
+{\r
+    ctx->total[0] = 0;\r
+    ctx->total[1] = 0;\r
+\r
+    ctx->state[0] = 0x67452301;\r
+    ctx->state[1] = 0xEFCDAB89;\r
+    ctx->state[2] = 0x98BADCFE;\r
+    ctx->state[3] = 0x10325476;\r
+    ctx->state[4] = 0xC3D2E1F0;\r
+}\r
+\r
+void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[SHA1_BLOCK_LENGTH] )\r
+{\r
+    uint32_t temp, W[16], A, B, C, D, E;\r
+\r
+    GET_UINT32_BE( W[ 0], data,  0 );\r
+    GET_UINT32_BE( W[ 1], data,  4 );\r
+    GET_UINT32_BE( W[ 2], data,  8 );\r
+    GET_UINT32_BE( W[ 3], data, 12 );\r
+    GET_UINT32_BE( W[ 4], data, 16 );\r
+    GET_UINT32_BE( W[ 5], data, 20 );\r
+    GET_UINT32_BE( W[ 6], data, 24 );\r
+    GET_UINT32_BE( W[ 7], data, 28 );\r
+    GET_UINT32_BE( W[ 8], data, 32 );\r
+    GET_UINT32_BE( W[ 9], data, 36 );\r
+    GET_UINT32_BE( W[10], data, 40 );\r
+    GET_UINT32_BE( W[11], data, 44 );\r
+    GET_UINT32_BE( W[12], data, 48 );\r
+    GET_UINT32_BE( W[13], data, 52 );\r
+    GET_UINT32_BE( W[14], data, 56 );\r
+    GET_UINT32_BE( W[15], data, 60 );\r
+\r
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))\r
+\r
+#define R(t)                                            \\r
+(                                                       \\r
+    temp = W[( t -  3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \\r
+           W[( t - 14 ) & 0x0F] ^ W[  t       & 0x0F],  \\r
+    ( W[t & 0x0F] = S(temp,1) )                         \\r
+)\r
+\r
+#define P(a,b,c,d,e,x)                                  \\r
+{                                                       \\r
+    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \\r
+}\r
+\r
+    A = ctx->state[0];\r
+    B = ctx->state[1];\r
+    C = ctx->state[2];\r
+    D = ctx->state[3];\r
+    E = ctx->state[4];\r
+\r
+#define F(x,y,z) (z ^ (x & (y ^ z)))\r
+#define K 0x5A827999\r
+\r
+    P( A, B, C, D, E, W[0]  );\r
+    P( E, A, B, C, D, W[1]  );\r
+    P( D, E, A, B, C, W[2]  );\r
+    P( C, D, E, A, B, W[3]  );\r
+    P( B, C, D, E, A, W[4]  );\r
+    P( A, B, C, D, E, W[5]  );\r
+    P( E, A, B, C, D, W[6]  );\r
+    P( D, E, A, B, C, W[7]  );\r
+    P( C, D, E, A, B, W[8]  );\r
+    P( B, C, D, E, A, W[9]  );\r
+    P( A, B, C, D, E, W[10] );\r
+    P( E, A, B, C, D, W[11] );\r
+    P( D, E, A, B, C, W[12] );\r
+    P( C, D, E, A, B, W[13] );\r
+    P( B, C, D, E, A, W[14] );\r
+    P( A, B, C, D, E, W[15] );\r
+    P( E, A, B, C, D, R(16) );\r
+    P( D, E, A, B, C, R(17) );\r
+    P( C, D, E, A, B, R(18) );\r
+    P( B, C, D, E, A, R(19) );\r
+\r
+#undef K\r
+#undef F\r
+\r
+#define F(x,y,z) (x ^ y ^ z)\r
+#define K 0x6ED9EBA1\r
+\r
+    P( A, B, C, D, E, R(20) );\r
+    P( E, A, B, C, D, R(21) );\r
+    P( D, E, A, B, C, R(22) );\r
+    P( C, D, E, A, B, R(23) );\r
+    P( B, C, D, E, A, R(24) );\r
+    P( A, B, C, D, E, R(25) );\r
+    P( E, A, B, C, D, R(26) );\r
+    P( D, E, A, B, C, R(27) );\r
+    P( C, D, E, A, B, R(28) );\r
+    P( B, C, D, E, A, R(29) );\r
+    P( A, B, C, D, E, R(30) );\r
+    P( E, A, B, C, D, R(31) );\r
+    P( D, E, A, B, C, R(32) );\r
+    P( C, D, E, A, B, R(33) );\r
+    P( B, C, D, E, A, R(34) );\r
+    P( A, B, C, D, E, R(35) );\r
+    P( E, A, B, C, D, R(36) );\r
+    P( D, E, A, B, C, R(37) );\r
+    P( C, D, E, A, B, R(38) );\r
+    P( B, C, D, E, A, R(39) );\r
+\r
+#undef K\r
+#undef F\r
+\r
+#define F(x,y,z) ((x & y) | (z & (x | y)))\r
+#define K 0x8F1BBCDC\r
+\r
+    P( A, B, C, D, E, R(40) );\r
+    P( E, A, B, C, D, R(41) );\r
+    P( D, E, A, B, C, R(42) );\r
+    P( C, D, E, A, B, R(43) );\r
+    P( B, C, D, E, A, R(44) );\r
+    P( A, B, C, D, E, R(45) );\r
+    P( E, A, B, C, D, R(46) );\r
+    P( D, E, A, B, C, R(47) );\r
+    P( C, D, E, A, B, R(48) );\r
+    P( B, C, D, E, A, R(49) );\r
+    P( A, B, C, D, E, R(50) );\r
+    P( E, A, B, C, D, R(51) );\r
+    P( D, E, A, B, C, R(52) );\r
+    P( C, D, E, A, B, R(53) );\r
+    P( B, C, D, E, A, R(54) );\r
+    P( A, B, C, D, E, R(55) );\r
+    P( E, A, B, C, D, R(56) );\r
+    P( D, E, A, B, C, R(57) );\r
+    P( C, D, E, A, B, R(58) );\r
+    P( B, C, D, E, A, R(59) );\r
+\r
+#undef K\r
+#undef F\r
+\r
+#define F(x,y,z) (x ^ y ^ z)\r
+#define K 0xCA62C1D6\r
+\r
+    P( A, B, C, D, E, R(60) );\r
+    P( E, A, B, C, D, R(61) );\r
+    P( D, E, A, B, C, R(62) );\r
+    P( C, D, E, A, B, R(63) );\r
+    P( B, C, D, E, A, R(64) );\r
+    P( A, B, C, D, E, R(65) );\r
+    P( E, A, B, C, D, R(66) );\r
+    P( D, E, A, B, C, R(67) );\r
+    P( C, D, E, A, B, R(68) );\r
+    P( B, C, D, E, A, R(69) );\r
+    P( A, B, C, D, E, R(70) );\r
+    P( E, A, B, C, D, R(71) );\r
+    P( D, E, A, B, C, R(72) );\r
+    P( C, D, E, A, B, R(73) );\r
+    P( B, C, D, E, A, R(74) );\r
+    P( A, B, C, D, E, R(75) );\r
+    P( E, A, B, C, D, R(76) );\r
+    P( D, E, A, B, C, R(77) );\r
+    P( C, D, E, A, B, R(78) );\r
+    P( B, C, D, E, A, R(79) );\r
+\r
+#undef K\r
+#undef F\r
+\r
+    ctx->state[0] += A;\r
+    ctx->state[1] += B;\r
+    ctx->state[2] += C;\r
+    ctx->state[3] += D;\r
+    ctx->state[4] += E;\r
+}\r
+\r
+/*\r
+ * SHA-1 process buffer\r
+ */\r
+void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )\r
+{\r
+    size_t fill;\r
+    uint32_t left;\r
+\r
+    if( ilen == 0 )\r
+        return;\r
+\r
+    left = ctx->total[0] & 0x3F;\r
+    fill = 64 - left;\r
+\r
+    ctx->total[0] += (uint32_t) ilen;\r
+    ctx->total[0] &= 0xFFFFFFFF;\r
+\r
+    if( ctx->total[0] < (uint32_t) ilen )\r
+        ctx->total[1]++;\r
+\r
+    if( left && ilen >= fill )\r
+    {\r
+        memcpy( (void *) (ctx->buffer + left), input, fill );\r
+        mbedtls_sha1_process( ctx, ctx->buffer );\r
+        input += fill;\r
+        ilen  -= fill;\r
+        left = 0;\r
+    }\r
+\r
+    while( ilen >= 64 )\r
+    {\r
+        mbedtls_sha1_process( ctx, input );\r
+        input += 64;\r
+        ilen  -= 64;\r
+    }\r
+\r
+    if( ilen > 0 )\r
+        memcpy( (void *) (ctx->buffer + left), input, ilen );\r
+}\r
+\r
+static const unsigned char sha1_padding[SHA1_BLOCK_LENGTH] =\r
+{\r
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+\r
+/*\r
+ * SHA-1 final digest\r
+ */\r
+void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[SHA1_DIGEST_LENGTH] )\r
+{\r
+    uint32_t last, padn;\r
+    uint32_t high, low;\r
+    unsigned char msglen[8];\r
+\r
+    high = ( ctx->total[0] >> 29 )\r
+         | ( ctx->total[1] <<  3 );\r
+    low  = ( ctx->total[0] <<  3 );\r
+\r
+    PUT_UINT32_BE( high, msglen, 0 );\r
+    PUT_UINT32_BE( low,  msglen, 4 );\r
+\r
+    last = ctx->total[0] & 0x3F;\r
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );\r
+\r
+    mbedtls_sha1_update( ctx, sha1_padding, padn );\r
+    mbedtls_sha1_update( ctx, msglen, 8 );\r
+\r
+    PUT_UINT32_BE( ctx->state[0], output,  0 );\r
+    PUT_UINT32_BE( ctx->state[1], output,  4 );\r
+    PUT_UINT32_BE( ctx->state[2], output,  8 );\r
+    PUT_UINT32_BE( ctx->state[3], output, 12 );\r
+    PUT_UINT32_BE( ctx->state[4], output, 16 );\r
+}\r
+\r
+/*\r
+ * output = SHA-1( input buffer )\r
+ */\r
+void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[SHA1_DIGEST_LENGTH] )\r
+{\r
+    mbedtls_sha1_context ctx;\r
+\r
+    mbedtls_sha1_init( &ctx );\r
+    mbedtls_sha1_starts( &ctx );\r
+    mbedtls_sha1_update( &ctx, input, ilen );\r
+    mbedtls_sha1_finish( &ctx, output );\r
+    mbedtls_sha1_free( &ctx );\r
+}\r
+\r
+/*\r
+* Compute HMAC_SHA1 using key, key length, text to hash, size of the text, and output buffer\r
+*/\r
+void HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t out[SHA1_DIGEST_LENGTH]){\r
+\r
+  uint8_t i;\r
+  uint8_t k_ipad[SHA1_BLOCK_LENGTH]; /* inner padding - key XORd with ipad */\r
+  uint8_t k_opad[SHA1_BLOCK_LENGTH]; /* outer padding - key XORd with opad */\r
+  uint8_t buffer[SHA1_BLOCK_LENGTH + SHA1_DIGEST_LENGTH];\r
+\r
+  /* start out by storing key in pads */\r
+  memset(k_ipad, 0, sizeof(k_ipad));\r
+  memset(k_opad, 0, sizeof(k_opad));\r
+\r
+  if (key_length <= SHA1_BLOCK_LENGTH) {\r
+      memcpy(k_ipad, key, key_length);\r
+      memcpy(k_opad, key, key_length);\r
+  }\r
+\r
+  else {\r
+      mbedtls_sha1(key, key_length, k_ipad);\r
+      memcpy(k_opad, k_ipad, SHA1_BLOCK_LENGTH);\r
+  }\r
+\r
+  /* XOR key with ipad and opad values */\r
+  for (i = 0; i < SHA1_BLOCK_LENGTH; i++) {\r
+      k_ipad[i] ^= HMAC_IPAD;\r
+      k_opad[i] ^= HMAC_OPAD;\r
+  }\r
+  \r
+  // perform inner SHA1\r
+  memcpy(buffer, k_ipad, SHA1_BLOCK_LENGTH);\r
+  memcpy(buffer + SHA1_BLOCK_LENGTH, in, n);\r
+  mbedtls_sha1(buffer, SHA1_BLOCK_LENGTH + n, out);\r
+  \r
+  memset(buffer, 0, SHA1_BLOCK_LENGTH + n);\r
+\r
+  // perform outer SHA1\r
+  memcpy(buffer, k_opad, SHA1_BLOCK_LENGTH);\r
+  memcpy(buffer + SHA1_BLOCK_LENGTH, out, SHA1_DIGEST_LENGTH);\r
+  mbedtls_sha1(buffer, SHA1_BLOCK_LENGTH + SHA1_DIGEST_LENGTH, out);\r
+}\r
+/*\r
+* Compute TOTP_HMAC_SHA1 using key, key length, text to hash, size of the text\r
+*/\r
+uint32_t TOTP_HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n){\r
+    // STEP 1, get the HMAC-SHA1 hash from counter and key\r
+    uint8_t hash[SHA1_DIGEST_LENGTH];\r
+    HMAC_SHA1(key, key_length, in, n, hash);\r
+\r
+    // STEP 2, apply dynamic truncation to obtain a 4-bytes string\r
+    uint32_t truncated_hash = 0;\r
+    uint8_t _offset = hash[SHA1_DIGEST_LENGTH - 1] & 0xF;\r
+    uint8_t j;\r
+    for (j = 0; j < 4; ++j) {\r
+        truncated_hash <<= 8;\r
+        truncated_hash  |= hash[_offset + j];\r
+    }\r
+\r
+    // STEP 3, compute the OTP value\r
+    truncated_hash &= 0x7FFFFFFF;    //Disabled\r
+    truncated_hash %= 1000000;\r
+\r
+    return truncated_hash;\r
+}\r
diff --git a/lib/TOTP/sha1.h b/lib/TOTP/sha1.h
new file mode 100644 (file)
index 0000000..2743c5a
--- /dev/null
@@ -0,0 +1,98 @@
+/**\r
+ * \file sha1.h\r
+ *\r
+ * \brief SHA-1 cryptographic hash function\r
+ *\r
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
+ *  SPDX-License-Identifier: Apache-2.0\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+ *  not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *  http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ *\r
+ *  This file is part of mbed TLS (https://tls.mbed.org)\r
+ */\r
+#ifndef MBEDTLS_SHA1_H\r
+#define MBEDTLS_SHA1_H\r
+\r
+#define SHA1_DIGEST_LENGTH 20\r
+#define SHA1_BLOCK_LENGTH 64\r
+#define HMAC_IPAD 0x36\r
+#define HMAC_OPAD 0x5c\r
+\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * \brief          SHA-1 context structure\r
+ */\r
+typedef struct\r
+{\r
+    uint32_t total[2];          /*!< number of bytes processed  */\r
+    uint32_t state[5];          /*!< intermediate digest state  */\r
+    unsigned char buffer[SHA1_BLOCK_LENGTH];   /*!< data block being processed */\r
+}\r
+mbedtls_sha1_context;\r
+\r
+/**\r
+ * \brief          Initialize SHA-1 context\r
+ *\r
+ * \param ctx      SHA-1 context to be initialized\r
+ */\r
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx );\r
+\r
+/**\r
+ * \brief          Clear SHA-1 context\r
+ *\r
+ * \param ctx      SHA-1 context to be cleared\r
+ */\r
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx );\r
+\r
+/**\r
+ * \brief          SHA-1 context setup\r
+ *\r
+ * \param ctx      context to be initialized\r
+ */\r
+void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );\r
+\r
+/**\r
+ * \brief          SHA-1 process buffer\r
+ *\r
+ * \param ctx      SHA-1 context\r
+ * \param input    buffer holding the  data\r
+ * \param ilen     length of the input data\r
+ */\r
+void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );\r
+\r
+/**\r
+ * \brief          SHA-1 final digest\r
+ *\r
+ * \param ctx      SHA-1 context\r
+ * \param output   SHA-1 checksum result\r
+ */\r
+void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[SHA1_DIGEST_LENGTH] );\r
+\r
+/* Internal use */\r
+void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[SHA1_BLOCK_LENGTH] );\r
+\r
+/**\r
+ * \brief          Output = SHA-1( input buffer )\r
+ *\r
+ * \param input    buffer holding the  data\r
+ * \param ilen     length of the input data\r
+ * \param output   SHA-1 checksum result\r
+ */\r
+void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[SHA1_DIGEST_LENGTH] );\r
+void HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t out[SHA1_DIGEST_LENGTH]);\r
+uint32_t TOTP_HMAC_SHA1(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n);\r
+\r
+\r
+#endif /* mbedtls_sha1.h */\r
diff --git a/lib/TOTP/sha256.c b/lib/TOTP/sha256.c
new file mode 100644 (file)
index 0000000..cb83f53
--- /dev/null
@@ -0,0 +1,372 @@
+/*\r
+ *  FIPS-180-2 compliant SHA-256 implementation\r
+ *\r
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
+ *  SPDX-License-Identifier: Apache-2.0\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+ *  not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *  http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ *\r
+ *  This file is part of mbed TLS (https://tls.mbed.org)\r
+ */\r
+/*\r
+ *  The SHA-256 Secure Hash Standard was published by NIST in 2002.\r
+ *\r
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\r
+ */\r
+\r
+#include "sha256.h"\r
+\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+/* Implementation that should never be optimized out by the compiler */\r
+static void mbedtls_zeroize( void *v, size_t n ) {\r
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;\r
+}\r
+\r
+/*\r
+ * 32-bit integer manipulation macros (big endian)\r
+ */\r
+#ifndef GET_UINT32_BE\r
+#define GET_UINT32_BE(n,b,i)                            \\r
+do {                                                    \\r
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \\r
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \\r
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \\r
+        | ( (uint32_t) (b)[(i) + 3]       );            \\r
+} while( 0 )\r
+#endif\r
+\r
+#ifndef PUT_UINT32_BE\r
+#define PUT_UINT32_BE(n,b,i)                            \\r
+do {                                                    \\r
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\r
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\r
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\r
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\r
+} while( 0 )\r
+#endif\r
+\r
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx )\r
+{\r
+    memset( ctx, 0, sizeof( mbedtls_sha256_context ) );\r
+}\r
+\r
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx )\r
+{\r
+    if( ctx == NULL )\r
+        return;\r
+\r
+    mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );\r
+}\r
+\r
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,\r
+                           const mbedtls_sha256_context *src )\r
+{\r
+    *dst = *src;\r
+}\r
+\r
+/*\r
+ * SHA-256 context setup\r
+ */\r
+void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )\r
+{\r
+    ctx->total[0] = 0;\r
+    ctx->total[1] = 0;\r
+\r
+    if( is224 == 0 )\r
+    {\r
+        /* SHA-256 */\r
+        ctx->state[0] = 0x6A09E667;\r
+        ctx->state[1] = 0xBB67AE85;\r
+        ctx->state[2] = 0x3C6EF372;\r
+        ctx->state[3] = 0xA54FF53A;\r
+        ctx->state[4] = 0x510E527F;\r
+        ctx->state[5] = 0x9B05688C;\r
+        ctx->state[6] = 0x1F83D9AB;\r
+        ctx->state[7] = 0x5BE0CD19;\r
+    }\r
+    else\r
+    {\r
+        /* SHA-224 */\r
+        ctx->state[0] = 0xC1059ED8;\r
+        ctx->state[1] = 0x367CD507;\r
+        ctx->state[2] = 0x3070DD17;\r
+        ctx->state[3] = 0xF70E5939;\r
+        ctx->state[4] = 0xFFC00B31;\r
+        ctx->state[5] = 0x68581511;\r
+        ctx->state[6] = 0x64F98FA7;\r
+        ctx->state[7] = 0xBEFA4FA4;\r
+    }\r
+\r
+    ctx->is224 = is224;\r
+}\r
+\r
+static const uint32_t K[] =\r
+{\r
+    0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,\r
+    0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,\r
+    0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,\r
+    0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,\r
+    0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,\r
+    0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,\r
+    0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,\r
+    0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,\r
+    0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,\r
+    0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,\r
+    0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,\r
+    0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,\r
+    0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,\r
+    0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,\r
+    0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,\r
+    0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,\r
+};\r
+\r
+#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)\r
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))\r
+\r
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))\r
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))\r
+\r
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))\r
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))\r
+\r
+#define F0(x,y,z) ((x & y) | (z & (x | y)))\r
+#define F1(x,y,z) (z ^ (x & (y ^ z)))\r
+\r
+#define R(t)                                    \\r
+(                                               \\r
+    W[t] = S1(W[t -  2]) + W[t -  7] +          \\r
+           S0(W[t - 15]) + W[t - 16]            \\r
+)\r
+\r
+#define P(a,b,c,d,e,f,g,h,x,K)                  \\r
+{                                               \\r
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \\r
+    temp2 = S2(a) + F0(a,b,c);                  \\r
+    d += temp1; h = temp1 + temp2;              \\r
+}\r
+\r
+void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[SHA256_BLOCK_LENGTH] )\r
+{\r
+    uint32_t temp1, temp2, W[64];\r
+    uint32_t A[8];\r
+    unsigned int i;\r
+\r
+    for( i = 0; i < 8; i++ )\r
+        A[i] = ctx->state[i];\r
+\r
+    for( i = 0; i < 16; i++ )\r
+        GET_UINT32_BE( W[i], data, 4 * i );\r
+\r
+    for( i = 0; i < 16; i += 8 )\r
+    {\r
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );\r
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );\r
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );\r
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );\r
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );\r
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );\r
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );\r
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );\r
+    }\r
+\r
+    for( i = 16; i < 64; i += 8 )\r
+    {\r
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );\r
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );\r
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );\r
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );\r
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );\r
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );\r
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );\r
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );\r
+    }\r
+\r
+    for( i = 0; i < 8; i++ )\r
+        ctx->state[i] += A[i];\r
+}\r
+\r
+/*\r
+ * SHA-256 process buffer\r
+ */\r
+void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,\r
+                    size_t ilen )\r
+{\r
+    size_t fill;\r
+    uint32_t left;\r
+\r
+    if( ilen == 0 )\r
+        return;\r
+\r
+    left = ctx->total[0] & 0x3F;\r
+    fill = 64 - left;\r
+\r
+    ctx->total[0] += (uint32_t) ilen;\r
+    ctx->total[0] &= 0xFFFFFFFF;\r
+\r
+    if( ctx->total[0] < (uint32_t) ilen )\r
+        ctx->total[1]++;\r
+\r
+    if( left && ilen >= fill )\r
+    {\r
+        memcpy( (void *) (ctx->buffer + left), input, fill );\r
+        mbedtls_sha256_process( ctx, ctx->buffer );\r
+        input += fill;\r
+        ilen  -= fill;\r
+        left = 0;\r
+    }\r
+\r
+    while( ilen >= 64 )\r
+    {\r
+        mbedtls_sha256_process( ctx, input );\r
+        input += 64;\r
+        ilen  -= 64;\r
+    }\r
+\r
+    if( ilen > 0 )\r
+        memcpy( (void *) (ctx->buffer + left), input, ilen );\r
+}\r
+\r
+static const unsigned char sha256_padding[SHA256_BLOCK_LENGTH] =\r
+{\r
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+\r
+/*\r
+ * SHA-256 final digest\r
+ */\r
+void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char* output )\r
+{\r
+    uint32_t last, padn;\r
+    uint32_t high, low;\r
+    unsigned char msglen[8];\r
+\r
+    high = ( ctx->total[0] >> 29 )\r
+         | ( ctx->total[1] <<  3 );\r
+    low  = ( ctx->total[0] <<  3 );\r
+\r
+    PUT_UINT32_BE( high, msglen, 0 );\r
+    PUT_UINT32_BE( low,  msglen, 4 );\r
+\r
+    last = ctx->total[0] & 0x3F;\r
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );\r
+\r
+    mbedtls_sha256_update( ctx, sha256_padding, padn );\r
+    mbedtls_sha256_update( ctx, msglen, 8 );\r
+\r
+    PUT_UINT32_BE( ctx->state[0], output,  0 );\r
+    PUT_UINT32_BE( ctx->state[1], output,  4 );\r
+    PUT_UINT32_BE( ctx->state[2], output,  8 );\r
+    PUT_UINT32_BE( ctx->state[3], output, 12 );\r
+    PUT_UINT32_BE( ctx->state[4], output, 16 );\r
+    PUT_UINT32_BE( ctx->state[5], output, 20 );\r
+    PUT_UINT32_BE( ctx->state[6], output, 24 );\r
+\r
+    if( ctx->is224 == 0 )\r
+        PUT_UINT32_BE( ctx->state[7], output, 28 );\r
+}\r
+\r
+/*\r
+ * output = SHA-256( input buffer )\r
+ */\r
+void mbedtls_sha256( const unsigned char *input, size_t ilen,\r
+             unsigned char* output, int is224 )\r
+{\r
+    mbedtls_sha256_context ctx;\r
+\r
+    mbedtls_sha256_init( &ctx );\r
+    mbedtls_sha256_starts( &ctx, is224 );\r
+    mbedtls_sha256_update( &ctx, input, ilen );\r
+    mbedtls_sha256_finish( &ctx, output );\r
+    mbedtls_sha256_free( &ctx );\r
+}\r
+\r
+/*\r
+* Compute HMAC_SHA224/256 using key, key length, text to hash, size of the text, output buffer and a switch for SHA224\r
+*/\r
+void HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is224){\r
+  int digest_length = SHA256_DIGEST_LENGTH;\r
+  if (is224 == 1) {\r
+    digest_length = SHA224_DIGEST_LENGTH;\r
+  }\r
+  \r
+  uint8_t i;\r
+  uint8_t k_ipad[SHA256_BLOCK_LENGTH]; /* inner padding - key XORd with ipad */\r
+  uint8_t k_opad[SHA256_BLOCK_LENGTH]; /* outer padding - key XORd with opad */\r
+  uint8_t buffer[SHA256_BLOCK_LENGTH + digest_length];\r
+\r
+  /* start out by storing key in pads */\r
+  memset(k_ipad, 0, sizeof(k_ipad));\r
+  memset(k_opad, 0, sizeof(k_opad));\r
+\r
+  if (key_length <= SHA256_BLOCK_LENGTH) {\r
+      memcpy(k_ipad, key, key_length);\r
+      memcpy(k_opad, key, key_length);\r
+  }\r
+\r
+  else {\r
+      mbedtls_sha256(key, key_length, k_ipad, is224);\r
+      memcpy(k_opad, k_ipad, SHA256_BLOCK_LENGTH);\r
+  }\r
+\r
+  /* XOR key with ipad and opad values */\r
+  for (i = 0; i < SHA256_BLOCK_LENGTH; i++) {\r
+      k_ipad[i] ^= HMAC_IPAD;\r
+      k_opad[i] ^= HMAC_OPAD;\r
+  }\r
+  \r
+  // perform inner SHA256\r
+  memcpy(buffer, k_ipad, SHA256_BLOCK_LENGTH);\r
+  memcpy(buffer + SHA256_BLOCK_LENGTH, in, n);\r
+  mbedtls_sha256(buffer, SHA256_BLOCK_LENGTH + n, out, is224);\r
+  \r
+  memset(buffer, 0, SHA256_BLOCK_LENGTH + n);\r
+\r
+  // perform outer SHA256\r
+  memcpy(buffer, k_opad, SHA256_BLOCK_LENGTH);\r
+  memcpy(buffer + SHA256_BLOCK_LENGTH, out, digest_length);\r
+  mbedtls_sha256(buffer, SHA256_BLOCK_LENGTH + digest_length, out, is224);\r
+}\r
+\r
+/*\r
+* Compute TOTP_HMAC_SHA224/256 using key, key length, text to hash, size of the text and a switch for SHA224\r
+*/\r
+uint32_t TOTP_HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is224){\r
+    int digest_length = SHA256_DIGEST_LENGTH;\r
+    if (is224 == 1) {\r
+      digest_length = SHA224_DIGEST_LENGTH;\r
+    }\r
+\r
+    // STEP 1, get the HMAC-SHA256 hash from counter and key\r
+    uint8_t hash[digest_length];\r
+    HMAC_SHA256(key, key_length, in, n, hash, is224);\r
+\r
+    // STEP 2, apply dynamic truncation to obtain a 4-bytes string\r
+    uint32_t truncated_hash = 0;\r
+    uint8_t _offset = hash[digest_length - 1] & 0xF;\r
+    uint8_t j;\r
+    for (j = 0; j < 4; ++j) {\r
+        truncated_hash <<= 8;\r
+        truncated_hash  |= hash[_offset + j];\r
+    }\r
+\r
+    // STEP 3, compute the OTP value\r
+    truncated_hash &= 0x7FFFFFFF;    //Disabled\r
+    truncated_hash %= 1000000;\r
+\r
+    return truncated_hash;\r
+}
\ No newline at end of file
diff --git a/lib/TOTP/sha256.h b/lib/TOTP/sha256.h
new file mode 100644 (file)
index 0000000..2f0febc
--- /dev/null
@@ -0,0 +1,112 @@
+/**\r
+ * \file sha256.h\r
+ *\r
+ * \brief SHA-224 and SHA-256 cryptographic hash function\r
+ *\r
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
+ *  SPDX-License-Identifier: Apache-2.0\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+ *  not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *  http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ *\r
+ *  This file is part of mbed TLS (https://tls.mbed.org)\r
+ */\r
+#ifndef MBEDTLS_SHA256_H\r
+#define MBEDTLS_SHA256_H\r
+\r
+#define SHA224_DIGEST_LENGTH 28\r
+#define SHA256_DIGEST_LENGTH 32\r
+#define SHA256_BLOCK_LENGTH 64\r
+#define HMAC_IPAD 0x36\r
+#define HMAC_OPAD 0x5c\r
+\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * \brief          SHA-256 context structure\r
+ */\r
+typedef struct\r
+{\r
+    uint32_t total[2];          /*!< number of bytes processed  */\r
+    uint32_t state[8];          /*!< intermediate digest state  */\r
+    unsigned char buffer[SHA256_BLOCK_LENGTH];   /*!< data block being processed */\r
+    int is224;                  /*!< 0 => SHA-256, else SHA-224 */\r
+}\r
+mbedtls_sha256_context;\r
+\r
+/**\r
+ * \brief          Initialize SHA-256 context\r
+ *\r
+ * \param ctx      SHA-256 context to be initialized\r
+ */\r
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx );\r
+\r
+/**\r
+ * \brief          Clear SHA-256 context\r
+ *\r
+ * \param ctx      SHA-256 context to be cleared\r
+ */\r
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx );\r
+\r
+/**\r
+ * \brief          Clone (the state of) a SHA-256 context\r
+ *\r
+ * \param dst      The destination context\r
+ * \param src      The context to be cloned\r
+ */\r
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,\r
+                           const mbedtls_sha256_context *src );\r
+\r
+/**\r
+ * \brief          SHA-256 context setup\r
+ *\r
+ * \param ctx      context to be initialized\r
+ * \param is224    0 = use SHA256, 1 = use SHA224\r
+ */\r
+void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );\r
+\r
+/**\r
+ * \brief          SHA-256 process buffer\r
+ *\r
+ * \param ctx      SHA-256 context\r
+ * \param input    buffer holding the  data\r
+ * \param ilen     length of the input data\r
+ */\r
+void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,\r
+                    size_t ilen );\r
+\r
+/**\r
+ * \brief          SHA-256 final digest\r
+ *\r
+ * \param ctx      SHA-256 context\r
+ * \param output   SHA-224/256 checksum result\r
+ */\r
+void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char* output );\r
+\r
+/* Internal use */\r
+void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[SHA256_BLOCK_LENGTH] );\r
+\r
+/**\r
+ * \brief          Output = SHA-256( input buffer )\r
+ *\r
+ * \param input    buffer holding the  data\r
+ * \param ilen     length of the input data\r
+ * \param output   SHA-224/256 checksum result\r
+ * \param is224    0 = use SHA256, 1 = use SHA224\r
+ */\r
+void mbedtls_sha256( const unsigned char *input, size_t ilen,\r
+           unsigned char* output, int is224 );\r
+void HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is224);\r
+uint32_t TOTP_HMAC_SHA256(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is224);\r
+\r
+#endif /* mbedtls_sha256.h */\r
diff --git a/lib/TOTP/sha512.c b/lib/TOTP/sha512.c
new file mode 100644 (file)
index 0000000..d35462b
--- /dev/null
@@ -0,0 +1,422 @@
+/*\r
+ *  FIPS-180-2 compliant SHA-384/512 implementation\r
+ *\r
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
+ *  SPDX-License-Identifier: Apache-2.0\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+ *  not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *  http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ *\r
+ *  This file is part of mbed TLS (https://tls.mbed.org)\r
+ */\r
+/*\r
+ *  The SHA-512 Secure Hash Standard was published by NIST in 2002.\r
+ *\r
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf\r
+ */\r
+\r
+#include "sha512.h"\r
+\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+#if defined(_MSC_VER) || defined(__WATCOMC__)\r
+  #define UL64(x) x##ui64\r
+#else\r
+  #define UL64(x) x##ULL\r
+#endif\r
+\r
+/* Implementation that should never be optimized out by the compiler */\r
+static void mbedtls_zeroize( void *v, size_t n ) {\r
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;\r
+}\r
+\r
+/*\r
+ * 64-bit integer manipulation macros (big endian)\r
+ */\r
+#ifndef GET_UINT64_BE\r
+#define GET_UINT64_BE(n,b,i)                            \\r
+{                                                       \\r
+    (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \\r
+        | ( (uint64_t) (b)[(i) + 1] << 48 )       \\r
+        | ( (uint64_t) (b)[(i) + 2] << 40 )       \\r
+        | ( (uint64_t) (b)[(i) + 3] << 32 )       \\r
+        | ( (uint64_t) (b)[(i) + 4] << 24 )       \\r
+        | ( (uint64_t) (b)[(i) + 5] << 16 )       \\r
+        | ( (uint64_t) (b)[(i) + 6] <<  8 )       \\r
+        | ( (uint64_t) (b)[(i) + 7]       );      \\r
+}\r
+#endif /* GET_UINT64_BE */\r
+\r
+#ifndef PUT_UINT64_BE\r
+#define PUT_UINT64_BE(n,b,i)                            \\r
+{                                                       \\r
+    (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \\r
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \\r
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \\r
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \\r
+    (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \\r
+    (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \\r
+    (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \\r
+    (b)[(i) + 7] = (unsigned char) ( (n)       );       \\r
+}\r
+#endif /* PUT_UINT64_BE */\r
+\r
+/*\r
+ * Round constants\r
+ */\r
+static const uint64_t K[80] =\r
+{\r
+    UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),\r
+    UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),\r
+    UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),\r
+    UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),\r
+    UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),\r
+    UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),\r
+    UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),\r
+    UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),\r
+    UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),\r
+    UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),\r
+    UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),\r
+    UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),\r
+    UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),\r
+    UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),\r
+    UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),\r
+    UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),\r
+    UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),\r
+    UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),\r
+    UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),\r
+    UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),\r
+    UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),\r
+    UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),\r
+    UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),\r
+    UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),\r
+    UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),\r
+    UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),\r
+    UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),\r
+    UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),\r
+    UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),\r
+    UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),\r
+    UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),\r
+    UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),\r
+    UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),\r
+    UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),\r
+    UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),\r
+    UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),\r
+    UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),\r
+    UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),\r
+    UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),\r
+    UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)\r
+};\r
+\r
+void mbedtls_sha512_init( mbedtls_sha512_context *ctx )\r
+{\r
+    memset( ctx, 0, sizeof( mbedtls_sha512_context ) );\r
+}\r
+\r
+void mbedtls_sha512_free( mbedtls_sha512_context *ctx )\r
+{\r
+    if( ctx == NULL )\r
+        return;\r
+\r
+    mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );\r
+}\r
+\r
+void mbedtls_sha512_clone( mbedtls_sha512_context *dst,\r
+                           const mbedtls_sha512_context *src )\r
+{\r
+    *dst = *src;\r
+}\r
+\r
+/*\r
+ * SHA-512 context setup\r
+ */\r
+void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )\r
+{\r
+    ctx->total[0] = 0;\r
+    ctx->total[1] = 0;\r
+\r
+    if( is384 == 0 )\r
+    {\r
+        /* SHA-512 */\r
+        ctx->state[0] = UL64(0x6A09E667F3BCC908);\r
+        ctx->state[1] = UL64(0xBB67AE8584CAA73B);\r
+        ctx->state[2] = UL64(0x3C6EF372FE94F82B);\r
+        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);\r
+        ctx->state[4] = UL64(0x510E527FADE682D1);\r
+        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);\r
+        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);\r
+        ctx->state[7] = UL64(0x5BE0CD19137E2179);\r
+    }\r
+    else\r
+    {\r
+        /* SHA-384 */\r
+        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);\r
+        ctx->state[1] = UL64(0x629A292A367CD507);\r
+        ctx->state[2] = UL64(0x9159015A3070DD17);\r
+        ctx->state[3] = UL64(0x152FECD8F70E5939);\r
+        ctx->state[4] = UL64(0x67332667FFC00B31);\r
+        ctx->state[5] = UL64(0x8EB44A8768581511);\r
+        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);\r
+        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);\r
+    }\r
+\r
+    ctx->is384 = is384;\r
+}\r
+\r
+void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[SHA512_BLOCK_LENGTH] )\r
+{\r
+    int i;\r
+    uint64_t temp1, temp2, W[80];\r
+    uint64_t A, B, C, D, E, F, G, H;\r
+\r
+#define SHR(x,n) (x >> n)\r
+#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))\r
+\r
+#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))\r
+#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))\r
+\r
+#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))\r
+#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))\r
+\r
+#define F0(x,y,z) ((x & y) | (z & (x | y)))\r
+#define F1(x,y,z) (z ^ (x & (y ^ z)))\r
+\r
+#define P(a,b,c,d,e,f,g,h,x,K)                  \\r
+{                                               \\r
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \\r
+    temp2 = S2(a) + F0(a,b,c);                  \\r
+    d += temp1; h = temp1 + temp2;              \\r
+}\r
+\r
+    for( i = 0; i < 16; i++ )\r
+    {\r
+        GET_UINT64_BE( W[i], data, i << 3 );\r
+    }\r
+\r
+    for( ; i < 80; i++ )\r
+    {\r
+        W[i] = S1(W[i -  2]) + W[i -  7] +\r
+               S0(W[i - 15]) + W[i - 16];\r
+    }\r
+\r
+    A = ctx->state[0];\r
+    B = ctx->state[1];\r
+    C = ctx->state[2];\r
+    D = ctx->state[3];\r
+    E = ctx->state[4];\r
+    F = ctx->state[5];\r
+    G = ctx->state[6];\r
+    H = ctx->state[7];\r
+    i = 0;\r
+\r
+    do\r
+    {\r
+        P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;\r
+        P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;\r
+        P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;\r
+        P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;\r
+        P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;\r
+        P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;\r
+        P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;\r
+        P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;\r
+    }\r
+    while( i < 80 );\r
+\r
+    ctx->state[0] += A;\r
+    ctx->state[1] += B;\r
+    ctx->state[2] += C;\r
+    ctx->state[3] += D;\r
+    ctx->state[4] += E;\r
+    ctx->state[5] += F;\r
+    ctx->state[6] += G;\r
+    ctx->state[7] += H;\r
+}\r
+\r
+/*\r
+ * SHA-512 process buffer\r
+ */\r
+void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,\r
+                    size_t ilen )\r
+{\r
+    size_t fill;\r
+    unsigned int left;\r
+\r
+    if( ilen == 0 )\r
+        return;\r
+\r
+    left = (unsigned int) (ctx->total[0] & 0x7F);\r
+    fill = 128 - left;\r
+\r
+    ctx->total[0] += (uint64_t) ilen;\r
+\r
+    if( ctx->total[0] < (uint64_t) ilen )\r
+        ctx->total[1]++;\r
+\r
+    if( left && ilen >= fill )\r
+    {\r
+        memcpy( (void *) (ctx->buffer + left), input, fill );\r
+        mbedtls_sha512_process( ctx, ctx->buffer );\r
+        input += fill;\r
+        ilen  -= fill;\r
+        left = 0;\r
+    }\r
+\r
+    while( ilen >= 128 )\r
+    {\r
+        mbedtls_sha512_process( ctx, input );\r
+        input += 128;\r
+        ilen  -= 128;\r
+    }\r
+\r
+    if( ilen > 0 )\r
+        memcpy( (void *) (ctx->buffer + left), input, ilen );\r
+}\r
+\r
+static const unsigned char sha512_padding[SHA512_BLOCK_LENGTH] =\r
+{\r
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+};\r
+\r
+/*\r
+ * SHA-512 final digest\r
+ */\r
+void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char* output )\r
+{\r
+    size_t last, padn;\r
+    uint64_t high, low;\r
+    unsigned char msglen[16];\r
+\r
+    high = ( ctx->total[0] >> 61 )\r
+         | ( ctx->total[1] <<  3 );\r
+    low  = ( ctx->total[0] <<  3 );\r
+\r
+    PUT_UINT64_BE( high, msglen, 0 );\r
+    PUT_UINT64_BE( low,  msglen, 8 );\r
+\r
+    last = (size_t)( ctx->total[0] & 0x7F );\r
+    padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );\r
+\r
+    mbedtls_sha512_update( ctx, sha512_padding, padn );\r
+    mbedtls_sha512_update( ctx, msglen, 16 );\r
+\r
+    PUT_UINT64_BE( ctx->state[0], output,  0 );\r
+    PUT_UINT64_BE( ctx->state[1], output,  8 );\r
+    PUT_UINT64_BE( ctx->state[2], output, 16 );\r
+    PUT_UINT64_BE( ctx->state[3], output, 24 );\r
+    PUT_UINT64_BE( ctx->state[4], output, 32 );\r
+    PUT_UINT64_BE( ctx->state[5], output, 40 );\r
+\r
+    if( ctx->is384 == 0 )\r
+    {\r
+        PUT_UINT64_BE( ctx->state[6], output, 48 );\r
+        PUT_UINT64_BE( ctx->state[7], output, 56 );\r
+    }\r
+}\r
+\r
+/*\r
+ * output = SHA-512( input buffer )\r
+ */\r
+void mbedtls_sha512( const unsigned char *input, size_t ilen,\r
+             unsigned char* output, int is384 )\r
+{\r
+    mbedtls_sha512_context ctx;\r
+\r
+    mbedtls_sha512_init( &ctx );\r
+    mbedtls_sha512_starts( &ctx, is384 );\r
+    mbedtls_sha512_update( &ctx, input, ilen );\r
+    mbedtls_sha512_finish( &ctx, output );\r
+    mbedtls_sha512_free( &ctx );\r
+}\r
+\r
+/*\r
+* Compute HMAC_SHA384/512 using key, key length, text to hash, size of the text, output buffer and a switch for SHA384\r
+*/\r
+void HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is384){\r
+  int digest_length = SHA512_DIGEST_LENGTH;\r
+  if (is384 == 1) {\r
+    digest_length = SHA384_DIGEST_LENGTH;\r
+  }\r
+\r
+  uint8_t i;\r
+  uint8_t k_ipad[SHA512_BLOCK_LENGTH]; /* inner padding - key XORd with ipad */\r
+  uint8_t k_opad[SHA512_BLOCK_LENGTH]; /* outer padding - key XORd with opad */\r
+  uint8_t buffer[SHA512_BLOCK_LENGTH + digest_length];\r
+\r
+  /* start out by storing key in pads */\r
+  memset(k_ipad, 0, sizeof(k_ipad));\r
+  memset(k_opad, 0, sizeof(k_opad));\r
+\r
+  if (key_length <= SHA512_BLOCK_LENGTH) {\r
+      memcpy(k_ipad, key, key_length);\r
+      memcpy(k_opad, key, key_length);\r
+  }\r
+\r
+  else {\r
+      mbedtls_sha512(key, key_length, k_ipad, is384);\r
+      memcpy(k_opad, k_ipad, SHA512_BLOCK_LENGTH);\r
+  }\r
+\r
+  /* XOR key with ipad and opad values */\r
+  for (i = 0; i < SHA512_BLOCK_LENGTH; i++) {\r
+      k_ipad[i] ^= HMAC_IPAD;\r
+      k_opad[i] ^= HMAC_OPAD;\r
+  }\r
+  \r
+  // perform inner SHA512\r
+  memcpy(buffer, k_ipad, SHA512_BLOCK_LENGTH);\r
+  memcpy(buffer + SHA512_BLOCK_LENGTH, in, n);\r
+  mbedtls_sha512(buffer, SHA512_BLOCK_LENGTH + n, out, is384);\r
+  \r
+  memset(buffer, 0, SHA512_BLOCK_LENGTH + n);\r
+\r
+  // perform outer SHA512\r
+  memcpy(buffer, k_opad, SHA512_BLOCK_LENGTH);\r
+  memcpy(buffer + SHA512_BLOCK_LENGTH, out, digest_length);\r
+  mbedtls_sha512(buffer, SHA512_BLOCK_LENGTH + digest_length, out, is384);\r
+}\r
+\r
+/*\r
+* Compute TOTP_HMAC_SHA384/512 using key, key length, text to hash, size of the text and a switch for SHA384\r
+*/\r
+uint32_t TOTP_HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is384){\r
+    int digest_length = SHA512_DIGEST_LENGTH;\r
+    if (is384 == 1) {\r
+      digest_length = SHA384_DIGEST_LENGTH;\r
+    }\r
+\r
+    // STEP 1, get the HMAC-SHA512 hash from counter and key\r
+    uint8_t hash[digest_length];\r
+    HMAC_SHA512(key, key_length, in, n, hash, is384);\r
+\r
+    // STEP 2, apply dynamic truncation to obtain a 4-bytes string\r
+    uint32_t truncated_hash = 0;\r
+    uint8_t _offset = hash[digest_length - 1] & 0xF;\r
+    uint8_t j;\r
+    for (j = 0; j < 4; ++j) {\r
+        truncated_hash <<= 8;\r
+        truncated_hash  |= hash[_offset + j];\r
+    }\r
+\r
+    // STEP 3, compute the OTP value\r
+    truncated_hash &= 0x7FFFFFFF;    //Disabled\r
+    truncated_hash %= 1000000;\r
+\r
+    return truncated_hash;\r
+}
\ No newline at end of file
diff --git a/lib/TOTP/sha512.h b/lib/TOTP/sha512.h
new file mode 100644 (file)
index 0000000..991ebfa
--- /dev/null
@@ -0,0 +1,119 @@
+/**\r
+ * \file sha512.h\r
+ *\r
+ * \brief SHA-384 and SHA-512 cryptographic hash function\r
+ *\r
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
+ *  SPDX-License-Identifier: Apache-2.0\r
+ *\r
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
+ *  not use this file except in compliance with the License.\r
+ *  You may obtain a copy of the License at\r
+ *\r
+ *  http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ *  Unless required by applicable law or agreed to in writing, software\r
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ *  See the License for the specific language governing permissions and\r
+ *  limitations under the License.\r
+ *\r
+ *  This file is part of mbed TLS (https://tls.mbed.org)\r
+ */\r
+#ifndef MBEDTLS_SHA512_H\r
+#define MBEDTLS_SHA512_H\r
+\r
+#define SHA384_DIGEST_LENGTH 48\r
+#define SHA512_DIGEST_LENGTH 64\r
+#define SHA512_BLOCK_LENGTH 128\r
+#define HMAC_IPAD 0x36\r
+#define HMAC_OPAD 0x5c\r
+\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * \brief          SHA-512 context structure\r
+ */\r
+typedef struct\r
+{\r
+    uint64_t total[2];          /*!< number of bytes processed  */\r
+    uint64_t state[8];          /*!< intermediate digest state  */\r
+    unsigned char buffer[SHA512_BLOCK_LENGTH];  /*!< data block being processed */\r
+    int is384;                  /*!< 0 => SHA-512, else SHA-384 */\r
+}\r
+mbedtls_sha512_context;\r
+\r
+/**\r
+ * \brief          Initialize SHA-512 context\r
+ *\r
+ * \param ctx      SHA-512 context to be initialized\r
+ */\r
+void mbedtls_sha512_init( mbedtls_sha512_context *ctx );\r
+\r
+/**\r
+ * \brief          Clear SHA-512 context\r
+ *\r
+ * \param ctx      SHA-512 context to be cleared\r
+ */\r
+void mbedtls_sha512_free( mbedtls_sha512_context *ctx );\r
+\r
+/**\r
+ * \brief          Clone (the state of) a SHA-512 context\r
+ *\r
+ * \param dst      The destination context\r
+ * \param src      The context to be cloned\r
+ */\r
+void mbedtls_sha512_clone( mbedtls_sha512_context *dst,\r
+                           const mbedtls_sha512_context *src );\r
+\r
+/**\r
+ * \brief          SHA-512 context setup\r
+ *\r
+ * \param ctx      context to be initialized\r
+ * \param is384    0 = use SHA512, 1 = use SHA384\r
+ */\r
+void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 );\r
+\r
+/**\r
+ * \brief          SHA-512 process buffer\r
+ *\r
+ * \param ctx      SHA-512 context\r
+ * \param input    buffer holding the  data\r
+ * \param ilen     length of the input data\r
+ */\r
+void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,\r
+                    size_t ilen );\r
+\r
+/**\r
+ * \brief          SHA-512 final digest\r
+ *\r
+ * \param ctx      SHA-512 context\r
+ * \param output   SHA-384/512 checksum result\r
+ */\r
+void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char* output );\r
+\r
+/**\r
+ * \brief          Output = SHA-512( input buffer )\r
+ *\r
+ * \param input    buffer holding the  data\r
+ * \param ilen     length of the input data\r
+ * \param output   SHA-384/512 checksum result\r
+ * \param is384    0 = use SHA512, 1 = use SHA384\r
+ */\r
+void mbedtls_sha512( const unsigned char *input, size_t ilen,\r
+             unsigned char* output, int is384 );\r
+\r
+/**\r
+ * \brief          Checkup routine\r
+ *\r
+ * \return         0 if successful, or 1 if the test failed\r
+ */\r
+int mbedtls_sha512_self_test( int verbose );\r
+\r
+/* Internal use */\r
+void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[SHA512_BLOCK_LENGTH] );\r
+void HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, uint8_t* out, int is384);\r
+uint32_t TOTP_HMAC_SHA512(const uint8_t* key, size_t key_length, const uint8_t *in, size_t n, int is384);\r
+\r
+#endif /* mbedtls_sha512.h */\r
diff --git a/lib/base32/base32.c b/lib/base32/base32.c
new file mode 100644 (file)
index 0000000..548f9a4
--- /dev/null
@@ -0,0 +1,221 @@
+/**
+ * base32 (de)coder implementation as specified by RFC4648.
+ *
+ * Copyright (c) 2010 Adrien Kunysz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+#include <assert.h>  // assert()
+#include <limits.h>  // CHAR_BIT
+
+#include "base32.h"
+
+/**
+ * Let this be a sequence of plain data before encoding:
+ *
+ *  01234567 01234567 01234567 01234567 01234567
+ * +--------+--------+--------+--------+--------+
+ * |< 0 >< 1| >< 2 ><|.3 >< 4.|>< 5 ><.|6 >< 7 >|
+ * +--------+--------+--------+--------+--------+
+ *
+ * There are 5 octets of 8 bits each in each sequence.
+ * There are 8 blocks of 5 bits each in each sequence.
+ *
+ * You probably want to refer to that graph when reading the algorithms in this
+ * file. We use "octet" instead of "byte" intentionnaly as we really work with
+ * 8 bits quantities. This implementation will probably not work properly on
+ * systems that don't have exactly 8 bits per (unsigned) char.
+ **/
+
+static size_t min(size_t x, size_t y)
+{
+       return x < y ? x : y;
+}
+
+static const unsigned char PADDING_CHAR = '=';
+
+/**
+ * Pad the given buffer with len padding characters.
+ */
+static void pad(unsigned char *buf, int len)
+{
+       for (int i = 0; i < len; i++)
+               buf[i] = PADDING_CHAR;
+}
+
+/**
+ * This convert a 5 bits value into a base32 character.
+ * Only the 5 least significant bits are used.
+ */
+static unsigned char encode_char(unsigned char c)
+{
+       static unsigned char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+       return base32[c & 0x1F];  // 0001 1111
+}
+
+/**
+ * Decode given character into a 5 bits value. 
+ * Returns -1 iff the argument given was an invalid base32 character
+ * or a padding character.
+ */
+static int decode_char(unsigned char c)
+{
+       int retval = -1;
+
+       if (c >= 'A' && c <= 'Z')
+               retval = c - 'A';
+       if (c >= '2' && c <= '7')
+               retval = c - '2' + 26;
+
+       assert(retval == -1 || ((retval & 0x1F) == retval));
+
+       return  retval;
+}
+
+/**
+ * Given a block id between 0 and 7 inclusive, this will return the index of
+ * the octet in which this block starts. For example, given 3 it will return 1
+ * because block 3 starts in octet 1:
+ *
+ * +--------+--------+
+ * | ......<|.3 >....|
+ * +--------+--------+
+ *  octet 1 | octet 2
+ */
+static int get_octet(int block)
+{
+       assert(block >= 0 && block < 8);
+       return (block*5) / 8;
+}
+
+/**
+ * Given a block id between 0 and 7 inclusive, this will return how many bits
+ * we can drop at the end of the octet in which this block starts. 
+ * For example, given block 0 it will return 3 because there are 3 bits
+ * we don't care about at the end:
+ *
+ *  +--------+-
+ *  |< 0 >...|
+ *  +--------+-
+ *
+ * Given block 1, it will return -2 because there
+ * are actually two bits missing to have a complete block:
+ *
+ *  +--------+-
+ *  |.....< 1|..
+ *  +--------+-
+ **/
+static int get_offset(int block)
+{
+       assert(block >= 0 && block < 8);
+       return (8 - 5 - (5*block) % 8);
+}
+
+/**
+ * Like "b >> offset" but it will do the right thing with negative offset.
+ * We need this as bitwise shifting by a negative offset is undefined
+ * behavior.
+ */
+static unsigned char shift_right(unsigned char byte, int offset)
+{
+       if (offset > 0)
+               return byte >>  offset;
+       else
+               return byte << -offset;
+}
+
+static unsigned char shift_left(unsigned char byte, int offset)
+{
+       return shift_right(byte, - offset);
+}
+
+/**
+ * Encode a sequence. A sequence is no longer than 5 octets by definition.
+ * Thus passing a length greater than 5 to this function is an error. Encoding
+ * sequences shorter than 5 octets is supported and padding will be added to the
+ * output as per the specification.
+ */
+static void encode_sequence(const unsigned char *plain, int len, unsigned char *coded)
+{
+       assert(CHAR_BIT == 8);  // not sure this would work otherwise
+       assert(len >= 0 && len <= 5);
+
+       for (int block = 0; block < 8; block++) {
+               int octet = get_octet(block);  // figure out which octet this block starts in
+               int junk = get_offset(block);  // how many bits do we drop from this octet?
+
+               if (octet >= len) { // we hit the end of the buffer
+                       pad(&coded[block], 8 - block);
+                       return;
+               }
+
+               unsigned char c = shift_right(plain[octet], junk);  // first part
+
+               if (junk < 0  // is there a second part?
+               &&  octet < len - 1)  // is there still something to read?
+               {
+                       c |= shift_right(plain[octet+1], 8 + junk);
+               }
+               coded[block] = encode_char(c);
+       }
+}
+
+void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded)
+{
+       // All the hard work is done in encode_sequence(),
+       // here we just need to feed it the data sequence by sequence.
+       for (size_t i = 0, j = 0; i < len; i += 5, j += 8) {
+               encode_sequence(&plain[i], min(len - i, 5), &coded[j]);
+       }
+}
+
+static int decode_sequence(const unsigned char *coded, unsigned char *plain)
+{
+       assert(CHAR_BIT == 8);
+       assert(coded && plain);
+
+       plain[0] = 0;
+       for (int block = 0; block < 8; block++) {
+               int offset = get_offset(block);
+               int octet = get_octet(block);
+
+               int c = decode_char(coded[block]);
+               if (c < 0)  // invalid char, stop here
+                       return octet;
+
+               plain[octet] |= shift_left(c, offset);
+               if (offset < 0) {  // does this block overflows to next octet?
+                       assert(octet < 4);
+                       plain[octet+1] = shift_left(c, 8 + offset);
+               }
+       }
+       return 5;
+}
+
+size_t base32_decode(const unsigned char *coded, unsigned char *plain)
+{
+       size_t written = 0;
+       for (size_t i = 0, j = 0; ; i += 8, j += 5) {
+               int n = decode_sequence(&coded[i], &plain[j]);
+               written += n;
+               if (n < 5)
+                       return written;
+       }
+}
diff --git a/lib/base32/base32.h b/lib/base32/base32.h
new file mode 100644 (file)
index 0000000..abf2d03
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * base32 (de)coder implementation as specified by RFC4648.
+ *
+ * Copyright (c) 2010 Adrien Kunysz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+#ifndef __BASE32_H_
+#define __BASE32_H_
+
+#include <stddef.h>   // size_t
+
+/**
+ * Returns the length of the output buffer required to encode len bytes of
+ * data into base32. This is a macro to allow users to define buffer size at
+ * compilation time.
+ */
+#define BASE32_LEN(len)  (((len)/5)*8 + ((len) % 5 ? 8 : 0))
+
+/**
+ * Returns the length of the output buffer required to decode a base32 string
+ * of len characters. Please note that len must be a multiple of 8 as per
+ * definition of a base32 string. This is a macro to allow users to define
+ * buffer size at compilation time.
+ */
+#define UNBASE32_LEN(len)  (((len)/8)*5)
+
+/**
+ * Encode the data pointed to by plain into base32 and store the
+ * result at the address pointed to by coded. The "coded" argument
+ * must point to a location that has enough available space
+ * to store the whole coded string. The resulting string will only
+ * contain characters from the [A-Z2-7=] set. The "len" arguments
+ * define how many bytes will be read from the "plain" buffer.
+ **/
+void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded);
+
+/**
+ * Decode the null terminated string pointed to by coded and write
+ * the decoded data into the location pointed to by plain. The
+ * "plain" argument must point to a location that has enough available
+ * space to store the whole decoded string.
+ * Returns the length of the decoded string. This may be less than
+ * expected due to padding. If an invalid base32 character is found
+ * in the coded string, decoding will stop at that point.
+ **/
+size_t base32_decode(const unsigned char *coded, unsigned char *plain);
+
+#endif
index d57506feb3c3177d171c41170bf8e566346d9bef..de97e043b5d99de673d79d5e0f012b5761952551 100644 (file)
@@ -51,4 +51,5 @@
 #include "nanosec_face.h"
 #include "mars_time_face.h"
 #include "peek_memory_face.h"
+#include "totp_face.h"
 // New includes go above this line.
index b95f4220f89d456032dcf199239fe422e44bc8a0..1dd7625027d2de45d244799ba5b4785c1a90b744 100644 (file)
@@ -11,6 +11,7 @@ SRCS += \
   ./watch-faces/complication/sunrise_sunset_face.c \
   ./watch-faces/complication/moon_phase_face.c \
   ./watch-faces/complication/days_since_face.c \
+  ./watch-faces/complication/totp_face.c \
   ./watch-faces/demo/all_segments_face.c \
   ./watch-faces/demo/character_set_face.c \
   ./watch-faces/demo/light_sensor_face.c \
diff --git a/watch-faces/complication/totp_face.c b/watch-faces/complication/totp_face.c
new file mode 100644 (file)
index 0000000..b45c62f
--- /dev/null
@@ -0,0 +1,244 @@
+/* SPDX-License-Identifier: MIT */
+
+/*
+ * MIT License
+ *
+ * Copyright © 2021 Wesley Ellis (https://github.com/tahnok)
+ * Copyright © 2021-2023 Joey Castillo <joeycastillo@utexas.edu>
+ * Copyright © 2022 Jack Bond-Preston <jackbondpreston@outlook.com>
+ * Copyright © 2023 Alex Utter <ooterness@gmail.com>
+ * Copyright © 2023 Emilien Court <emilien.court@telecomnancy.net>
+ * Copyright © 2023 Jeremy O'Brien <neutral@fastmail.com>
+ * Copyright © 2024 Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> (https://www.matheusmoreira.com/)
+ * Copyright © 2024 Max Zettlmeißl <max@zettlmeissl.de>
+ * Copyright © 2025 Emilien Court <emilien.court@telecomnancy.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "totp_face.h"
+#include "watch.h"
+#include "watch_utility.h"
+#include "TOTP.h"
+#include "base32.h"
+
+#ifndef TOTP_FACE_MAX_KEY_LENGTH
+#define TOTP_FACE_MAX_KEY_LENGTH 128
+#endif
+
+typedef struct {
+    unsigned char labels[2];
+    hmac_alg algorithm;
+    uint32_t period;
+    size_t encoded_key_length;
+    unsigned char *encoded_key;
+} totp_t;
+
+#define CREDENTIAL(label, key_array, algo, timestep) \
+    (const totp_t) { \
+        .encoded_key = ((unsigned char *) key_array), \
+        .encoded_key_length = sizeof(key_array) - 1, \
+        .period = (timestep), \
+        .labels = (#label), \
+        .algorithm = (algo), \
+    }
+
+////////////////////////////////////////////////////////////////////////////////
+// Enter your TOTP key data below
+
+static totp_t credentials[] = {
+    CREDENTIAL(2F, "JBSWY3DPEHPK3PXP", SHA1, 30),
+    CREDENTIAL(AC, "JBSWY3DPEHPK3PXP", SHA1, 30),
+};
+
+// END OF KEY DATA.
+////////////////////////////////////////////////////////////////////////////////
+
+static inline totp_t *totp_at(size_t i) {
+    return &credentials[i];
+}
+
+static inline totp_t *totp_current(totp_state_t *totp_state) {
+    return totp_at(totp_state->current_index);
+}
+
+static inline size_t totp_total(void) {
+    return sizeof(credentials) / sizeof(*credentials);
+}
+
+static void totp_validate_key_lengths(void) {
+    for (size_t n = totp_total(), i = 0; i < n; ++i) {
+        totp_t *totp = totp_at(i);
+
+        if (UNBASE32_LEN(totp->encoded_key_length) > TOTP_FACE_MAX_KEY_LENGTH) {
+            // Key exceeds static limits, turn it off by zeroing the length
+            totp->encoded_key_length = 0;
+        }
+    }
+}
+
+static void totp_generate(totp_state_t *totp_state) {
+    totp_t *totp = totp_current(totp_state);
+
+    if (totp->encoded_key_length <= 0) {
+        // Key exceeded static limits and was turned off
+        totp_state->current_decoded_key_length = 0;
+        return;
+    }
+
+    totp_state->current_decoded_key_length = base32_decode(totp->encoded_key, totp_state->current_decoded_key);
+
+    if (totp_state->current_decoded_key_length == 0) {
+        // Decoding failed for some reason
+        // Not a base 32 string?
+        return;
+    }
+
+    TOTP(
+        totp_state->current_decoded_key,
+        totp_state->current_decoded_key_length,
+        totp->period,
+        totp->algorithm
+    );
+}
+
+static void totp_display_error(totp_state_t *totp_state) {
+    char buf[10 + 1];
+    totp_t *totp = totp_current(totp_state);
+
+    snprintf(buf, sizeof(buf), "%c%c  ERROR ", totp->labels[0], totp->labels[1]);
+    watch_display_text(0, buf);
+}
+
+static void totp_display_code(totp_state_t *totp_state) {
+    char buf[14];
+    div_t result;
+    uint8_t valid_for;
+    totp_t *totp = totp_current(totp_state);
+
+    result = div(totp_state->timestamp, totp->period);
+    if (result.quot != totp_state->steps) {
+        totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp);
+        totp_state->steps = result.quot;
+    }
+    valid_for = totp->period - result.rem;
+    sprintf(buf, "%c%c%2d%06lu", totp->labels[0], totp->labels[1], valid_for, totp_state->current_code);
+
+    watch_display_text(0, buf);
+}
+
+static void totp_display(totp_state_t *totp_state) {
+    if (totp_state->current_decoded_key_length > 0) {
+        totp_display_code(totp_state);
+    } else {
+        totp_display_error(totp_state);
+    }
+}
+
+static void totp_generate_and_display(totp_state_t *totp_state) {
+    totp_generate(totp_state);
+    totp_display(totp_state);
+}
+
+static inline uint32_t totp_compute_base_timestamp() {
+    return watch_utility_date_time_to_unix_time(movement_get_utc_date_time(), 0);
+}
+
+void totp_face_setup(uint8_t watch_face_index, void ** context_ptr) {
+    (void) watch_face_index;
+
+    totp_validate_key_lengths();
+
+    if (*context_ptr == NULL) {
+        totp_state_t *totp = malloc(sizeof(totp_state_t));
+        totp->current_decoded_key = malloc(TOTP_FACE_MAX_KEY_LENGTH);
+        *context_ptr = totp;
+    }
+}
+
+void totp_face_activate(void *context) {
+
+    totp_state_t *totp = (totp_state_t *) context;
+
+    totp->timestamp = totp_compute_base_timestamp();
+    totp->steps = 0;
+    totp->current_code = 0;
+    totp->current_index = 0;
+    totp->current_decoded_key_length = 0;
+    // totp->current_decoded_key is already initialized in setup
+
+    totp_generate_and_display(totp);
+}
+
+bool totp_face_loop(movement_event_t event, void *context) {
+
+    totp_state_t *totp_state = (totp_state_t *) context;
+
+    switch (event.event_type) {
+        case EVENT_TICK:
+            totp_state->timestamp++;
+            // fall through
+        case EVENT_ACTIVATE:
+            totp_display(totp_state);
+            break;
+        case EVENT_TIMEOUT:
+            movement_move_to_face(0);
+            break;
+        case EVENT_ALARM_BUTTON_UP:
+            if ((size_t)totp_state->current_index + 1 < totp_total()) {
+                totp_state->current_index++;
+            } else {
+                // wrap around to first key
+                totp_state->current_index = 0;
+            }
+
+            totp_generate_and_display(totp_state);
+
+            break;
+        case EVENT_LIGHT_BUTTON_UP:
+            if (totp_state->current_index == 0) {
+                // Wrap around to the last credential.
+                totp_state->current_index = totp_total() - 1;
+            } else {
+                totp_state->current_index--;
+            }
+
+            totp_generate_and_display(totp_state);
+
+            break;
+        case EVENT_ALARM_BUTTON_DOWN:
+        case EVENT_ALARM_LONG_PRESS:
+        case EVENT_LIGHT_BUTTON_DOWN:
+            break;
+        case EVENT_LIGHT_LONG_PRESS:
+            movement_illuminate_led();
+            break;
+        default:
+            movement_default_loop_handler(event);
+            break;
+    }
+
+    return true;
+}
+
+void totp_face_resign(void *context) {
+    (void) context;
+}
diff --git a/watch-faces/complication/totp_face.h b/watch-faces/complication/totp_face.h
new file mode 100644 (file)
index 0000000..0dc1b8e
--- /dev/null
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: MIT */
+
+/*
+ * MIT License
+ *
+ * Copyright © 2021 Wesley Ellis (https://github.com/tahnok)
+ * Copyright © 2021-2022 Joey Castillo <joeycastillo@utexas.edu>
+ * Copyright © 2022 Alexsander Akers <me@a2.io>
+ * Copyright © 2022 Jack Bond-Preston <jackbondpreston@outlook.com>
+ * Copyright © 2023 Alex Utter <ooterness@gmail.com>
+ * Copyright © 2024 Matheus Afonso Martins Moreira <matheus.a.m.moreira@gmail.com> (https://www.matheusmoreira.com/)
+ * Copyright © 2024 Max Zettlmeißl <max@zettlmeissl.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef TOTP_FACE_H_
+#define TOTP_FACE_H_
+
+/*
+ * TOTP face
+ * Time-based one-time password (TOTP) generator
+ *
+ * Generate one-time passwords often used for two-factor authentication.
+ * The secret key must be set by hand, by editing "totp_face.c".
+ *
+ * Available algorithms:
+ *  o SHA1 (most TOTP codes use this)
+ *  o SHA224
+ *  o SHA256
+ *  o SHA384
+ *  o SHA512
+ *
+ * Instructions:
+ *  o Find your secret key(s).
+ *      o Use https://github.com/susam/mintotp to generate test codes for
+ *        verification
+ *  o Edit global `credentials` variable in "totp_face.c" to configure your
+ *    TOTP credentials. The file includes two examples that you can use as a
+ *    reference. Credentials are added with the `CREDENTIAL` macro in the form
+ *    `CREDENTIAL(label, key, algorithm, timestep)` where:
+ *      o `label` is a 2 character label that is displayed in the weekday digits
+ *        to identify the TOTP credential.
+ *      o `key` is a string with the base32 encoded secret.
+ *      o `algorithm` is one of the supported hashing algorithms listed above.
+ *      o `timestep` is how often the TOTP refreshes in seconds. This is usually
+ *        30 seconds.
+ *
+ * If you have more than one secret key, press ALARM to cycle through them.
+ * Press LIGHT to cycle in the other direction or keep it pressed longer to
+ * activate the light.
+ */
+
+#include "movement.h"
+
+typedef struct {
+    uint32_t timestamp;
+    uint8_t steps;
+    uint32_t current_code;
+    uint8_t current_index;
+    uint8_t *current_decoded_key;
+    size_t current_decoded_key_length;
+} totp_state_t;
+
+void totp_face_setup(uint8_t watch_face_index, void ** context_ptr);
+void totp_face_activate(void *context);
+bool totp_face_loop(movement_event_t event, void *context);
+void totp_face_resign(void *context);
+
+#define totp_face ((const watch_face_t){ \
+    totp_face_setup, \
+    totp_face_activate, \
+    totp_face_loop, \
+    totp_face_resign, \
+    NULL, \
+})
+
+#endif // TOTP_FACE_H_