summaryrefslogtreecommitdiffstats
path: root/movement/lib/TOTP-MCU/sha1.c
diff options
context:
space:
mode:
Diffstat (limited to 'movement/lib/TOTP-MCU/sha1.c')
m---------movement/lib/TOTP-MCU0
-rw-r--r--movement/lib/TOTP-MCU/sha1.c155
2 files changed, 155 insertions, 0 deletions
diff --git a/movement/lib/TOTP-MCU b/movement/lib/TOTP-MCU
deleted file mode 160000
-Subproject 646474a8757e1fca490792e81082b2ad89b966a
diff --git a/movement/lib/TOTP-MCU/sha1.c b/movement/lib/TOTP-MCU/sha1.c
new file mode 100644
index 00000000..07ad697b
--- /dev/null
+++ b/movement/lib/TOTP-MCU/sha1.c
@@ -0,0 +1,155 @@
+#include <string.h>
+#include "sha1.h"
+
+#define SHA1_K0 0x5a827999
+#define SHA1_K20 0x6ed9eba1
+#define SHA1_K40 0x8f1bbcdc
+#define SHA1_K60 0xca62c1d6
+
+uint8_t sha1InitState[] = {
+ 0x01,0x23,0x45,0x67, // H0
+ 0x89,0xab,0xcd,0xef, // H1
+ 0xfe,0xdc,0xba,0x98, // H2
+ 0x76,0x54,0x32,0x10, // H3
+ 0xf0,0xe1,0xd2,0xc3 // H4
+};
+
+void init(void) {
+ memcpy(state.b,sha1InitState,HASH_LENGTH);
+ byteCount = 0;
+ bufferOffset = 0;
+}
+
+uint32_t rol32(uint32_t number, uint8_t bits) {
+ return ((number << bits) | (uint32_t)(number >> (32-bits)));
+}
+
+void hashBlock() {
+ uint8_t i;
+ uint32_t a,b,c,d,e,t;
+
+ a=state.w[0];
+ b=state.w[1];
+ c=state.w[2];
+ d=state.w[3];
+ e=state.w[4];
+ for (i=0; i<80; i++) {
+ if (i>=16) {
+ t = buffer.w[(i+13)&15] ^ buffer.w[(i+8)&15] ^ buffer.w[(i+2)&15] ^ buffer.w[i&15];
+ buffer.w[i&15] = rol32(t,1);
+ }
+ if (i<20) {
+ t = (d ^ (b & (c ^ d))) + SHA1_K0;
+ } else if (i<40) {
+ t = (b ^ c ^ d) + SHA1_K20;
+ } else if (i<60) {
+ t = ((b & c) | (d & (b | c))) + SHA1_K40;
+ } else {
+ t = (b ^ c ^ d) + SHA1_K60;
+ }
+ t+=rol32(a,5) + e + buffer.w[i&15];
+ e=d;
+ d=c;
+ c=rol32(b,30);
+ b=a;
+ a=t;
+ }
+ state.w[0] += a;
+ state.w[1] += b;
+ state.w[2] += c;
+ state.w[3] += d;
+ state.w[4] += e;
+}
+
+void addUncounted(uint8_t data) {
+ buffer.b[bufferOffset ^ 3] = data;
+ bufferOffset++;
+ if (bufferOffset == BLOCK_LENGTH) {
+ hashBlock();
+ bufferOffset = 0;
+ }
+}
+
+void write(uint8_t data) {
+ ++byteCount;
+ addUncounted(data);
+
+ return;
+}
+
+void writeArray(uint8_t *buffer, uint8_t size){
+ while (size--) {
+ write(*buffer++);
+ }
+}
+
+void pad() {
+ // Implement SHA-1 padding (fips180-2 5.1.1)
+
+ // Pad with 0x80 followed by 0x00 until the end of the block
+ addUncounted(0x80);
+ while (bufferOffset != 56) addUncounted(0x00);
+
+ // Append length in the last 8 bytes
+ addUncounted(0); // We're only using 32 bit lengths
+ addUncounted(0); // But SHA-1 supports 64 bit lengths
+ addUncounted(0); // So zero pad the top bits
+ addUncounted(byteCount >> 29); // Shifting to multiply by 8
+ addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as
+ addUncounted(byteCount >> 13); // byte.
+ addUncounted(byteCount >> 5);
+ addUncounted(byteCount << 3);
+}
+
+uint8_t* result(void) {
+ // Pad to complete the last block
+ pad();
+
+ // Swap byte order back
+ uint8_t i;
+ for (i=0; i<5; i++) {
+ uint32_t a,b;
+ a=state.w[i];
+ b=a<<24;
+ b|=(a<<8) & 0x00ff0000;
+ b|=(a>>8) & 0x0000ff00;
+ b|=a>>24;
+ state.w[i]=b;
+ }
+
+ // Return pointer to hash (20 characters)
+ return state.b;
+}
+
+#define HMAC_IPAD 0x36
+#define HMAC_OPAD 0x5c
+
+void initHmac(const uint8_t* key, uint8_t keyLength) {
+ uint8_t i;
+ memset(keyBuffer,0,BLOCK_LENGTH);
+ if (keyLength > BLOCK_LENGTH) {
+ // Hash long keys
+ init();
+ for (;keyLength--;) write(*key++);
+ memcpy(keyBuffer,result(),HASH_LENGTH);
+ } else {
+ // Block length keys are used as is
+ memcpy(keyBuffer,key,keyLength);
+ }
+ // Start inner hash
+ init();
+ for (i=0; i<BLOCK_LENGTH; i++) {
+ write(keyBuffer[i] ^ HMAC_IPAD);
+ }
+}
+
+uint8_t* resultHmac(void) {
+ uint8_t i;
+ // Complete inner hash
+ memcpy(innerHash,result(),HASH_LENGTH);
+ // Calculate outer hash
+ init();
+ for (i=0; i<BLOCK_LENGTH; i++) write(keyBuffer[i] ^ HMAC_OPAD);
+ for (i=0; i<HASH_LENGTH; i++) write(innerHash[i]);
+ return result();
+}