Commits

Trammell Hudson committed 117ec67

converted to C and hacked it up a bit

Comments (0)

Files changed (6)

+#include <string.h>
+#include "sha1.h"
+
+#define HASH_LENGTH 20
+#define BLOCK_LENGTH 64
+
+typedef union
+{
+  uint8_t b[BLOCK_LENGTH];
+  uint32_t w[BLOCK_LENGTH/4];
+} _buffer;
+typedef union {
+  uint8_t b[HASH_LENGTH];
+  uint32_t w[HASH_LENGTH/4];
+} _state;
+
+static _buffer buffer;
+static uint8_t bufferOffset;
+static _state state;
+static uint32_t byteCount;
+static uint8_t keyBuffer[BLOCK_LENGTH];
+static uint8_t innerHash[HASH_LENGTH];
+    
+#define SHA1_K0 0x5a827999
+#define SHA1_K20 0x6ed9eba1
+#define SHA1_K40 0x8f1bbcdc
+#define SHA1_K60 0xca62c1d6
+
+static const 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
+};
+
+static void sha1_init(void) {
+  memcpy(state.b,sha1InitState,HASH_LENGTH);
+  byteCount = 0;
+  bufferOffset = 0;
+}
+
+static uint32_t sha1_rol32(uint32_t number, uint8_t bits) {
+  return ((number << bits) | (number >> (32-bits)));
+}
+
+static void sha1_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] = sha1_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+=sha1_rol32(a,5) + e + buffer.w[i&15];
+    e=d;
+    d=c;
+    c=sha1_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 sha1_addUncounted(uint8_t data) {
+  buffer.b[bufferOffset ^ 3] = data;
+  bufferOffset++;
+  if (bufferOffset == BLOCK_LENGTH) {
+    sha1_hashBlock();
+    bufferOffset = 0;
+  }
+}
+
+void sha1_write(uint8_t data) {
+  ++byteCount;
+  sha1_addUncounted(data);
+}
+
+void sha1_writebytes(const uint8_t* data, int length) {
+ for (int i=0; i<length; i++)
+ {
+   sha1_write(data[i]);
+ }
+}
+
+void sha1_pad() {
+  // Implement SHA-1 padding (fips180-2 §5.1.1)
+
+  // Pad with 0x80 followed by 0x00 until the end of the block
+  sha1_addUncounted(0x80);
+  while (bufferOffset != 56) sha1_addUncounted(0x00);
+
+  // Append length in the last 8 bytes
+  sha1_addUncounted(0); // We're only using 32 bit lengths
+  sha1_addUncounted(0); // But SHA-1 supports 64 bit lengths
+  sha1_addUncounted(0); // So zero pad the top bits
+  sha1_addUncounted(byteCount >> 29); // Shifting to multiply by 8
+  sha1_addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as
+  sha1_addUncounted(byteCount >> 13); // byte.
+  sha1_addUncounted(byteCount >> 5);
+  sha1_addUncounted(byteCount << 3);
+}
+
+
+uint8_t* sha1_result(void) {
+  // Pad to complete the last block
+  sha1_pad();
+  
+  // Swap byte order back
+  for (int 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 sha1_initHmac(const uint8_t* key, int keyLength) {
+  uint8_t i;
+  memset(keyBuffer,0,BLOCK_LENGTH);
+  if (keyLength > BLOCK_LENGTH) {
+    // Hash long keys
+    sha1_init();
+    for (;keyLength--;) sha1_write(*key++);
+    memcpy(keyBuffer,sha1_result(),HASH_LENGTH);
+  } else {
+    // Block length keys are used as is
+    memcpy(keyBuffer,key,keyLength);
+  }
+  // Start inner hash
+  sha1_init();
+  for (i=0; i<BLOCK_LENGTH; i++) {
+    sha1_write(keyBuffer[i] ^ HMAC_IPAD);
+  }
+}
+
+uint8_t* sha1_resultHmac(void) {
+  uint8_t i;
+  // Complete inner hash
+  memcpy(innerHash,sha1_result(),HASH_LENGTH);
+  // Calculate outer hash
+  sha1_init();
+  for (i=0; i<BLOCK_LENGTH; i++) sha1_write(keyBuffer[i] ^ HMAC_OPAD);
+  for (i=0; i<HASH_LENGTH; i++) sha1_write(innerHash[i]);
+  return sha1_result();
+}
+
+
+static const uint8_t hmacKey1[] = {
+// Generate your key from the QR code and base32 decoding the value
+#include "otp.do-not-checkin"
+};
+
+
+/** C function to do oauth computation */
+uint32_t
+oauth_calc(
+	uint32_t unix_epoch
+)
+{
+	const uint32_t now = unix_epoch / 30;
+
+	uint8_t byteArray[] = {
+		0,
+		0,
+		0,
+		0,
+		now >> 24,
+		now >> 16,
+		now >>  8,
+		now >>  0,
+	};
+
+	sha1_initHmac(hmacKey1,sizeof(hmacKey1));
+	sha1_writebytes(byteArray, 8);
+	const uint8_t * const hash = sha1_resultHmac();
+  
+	const unsigned offset = hash[20 - 1] & 0xF; 
+	uint32_t truncatedHash = 0;
+	for (int j = 0; j < 4; ++j) {
+		truncatedHash <<= 8;
+		truncatedHash  |= hash[offset + j];
+	}
+    
+	truncatedHash &= 0x7FFFFFFF;
+	truncatedHash %= 1000000;
+
+	return truncatedHash;
+}

sha1.cpp

-#include <string.h>
-#include "sha1.h"
-
-#define SHA1_K0 0x5a827999
-#define SHA1_K20 0x6ed9eba1
-#define SHA1_K40 0x8f1bbcdc
-#define SHA1_K60 0xca62c1d6
-
-static const 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 Sha1Class::init(void) {
-  memcpy(state.b,sha1InitState,HASH_LENGTH);
-  byteCount = 0;
-  bufferOffset = 0;
-}
-
-uint32_t Sha1Class::rol32(uint32_t number, uint8_t bits) {
-  return ((number << bits) | (number >> (32-bits)));
-}
-
-void Sha1Class::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 Sha1Class::addUncounted(uint8_t data) {
-  buffer.b[bufferOffset ^ 3] = data;
-  bufferOffset++;
-  if (bufferOffset == BLOCK_LENGTH) {
-    hashBlock();
-    bufferOffset = 0;
-  }
-}
-
-void Sha1Class::write(uint8_t data) {
-  ++byteCount;
-  addUncounted(data);
-}
-
-void Sha1Class::writebytes(const uint8_t* data, int length) {
- for (int i=0; i<length; i++)
- {
-   write(data[i]);
- }
-}
-
-void Sha1Class::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* Sha1Class::result(void) {
-  // Pad to complete the last block
-  pad();
-  
-  // Swap byte order back
-  for (int 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 Sha1Class::initHmac(const uint8_t* key, int 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* Sha1Class::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();
-}
-Sha1Class Sha1;
 #include <sys/types.h>
 #include <inttypes.h>
 
-#define HASH_LENGTH 20
-#define BLOCK_LENGTH 64
-
-union _buffer {
-  uint8_t b[BLOCK_LENGTH];
-  uint32_t w[BLOCK_LENGTH/4];
-};
-union _state {
-  uint8_t b[HASH_LENGTH];
-  uint32_t w[HASH_LENGTH/4];
-};
-
-class Sha1Class
-{
-  public:
-    void init(void);
-    void initHmac(const uint8_t* secret, int secretLength);
-    uint8_t* result(void);
-    uint8_t* resultHmac(void);
-    void writebytes(const uint8_t* data, int length);
-    void write(uint8_t);
-  private:
-    void pad();
-    void addUncounted(uint8_t data);
-    void hashBlock();
-    uint32_t rol32(uint32_t number, uint8_t bits);
-    _buffer buffer;
-    uint8_t bufferOffset;
-    _state state;
-    uint32_t byteCount;
-    uint8_t keyBuffer[BLOCK_LENGTH];
-    uint8_t innerHash[HASH_LENGTH];
-    
-};
-extern Sha1Class Sha1;
+uint32_t oauth_calc(uint32_t unix_epoch);
 
 #endif
+#include <stdio.h>
+#include <time.h>
+#include "sha1.h"
+
+int main(void)
+{
+	printf("%06d\n", oauth_calc(time(NULL)));
+	return 0;
+}
+/** \file
+ * Google Two Factor authentication watch face.
+ */
+#include "pebble_os.h"
+#include "pebble_app.h"
+#include "sha1.h"
+
+PBL_APP_INFO(
+	"Two Factor",
+	"hudson",
+	1, // Version
+	INVALID_RESOURCE,
+	APP_INFO_WATCH_FACE
+);
+
+
+
+static void
+handle_tick(
+	AppContextRef ctx,
+	PebbleTickEvent * const event
+)
+{
+	string_format_time(
+		time_buffer,
+		sizeof(time_buffer),
+		"%I:%M:%s %p",
+		event->tick_time
+	);
+
+	text_layer_set_text(&s_text, time_buffer);
+}
+
+
+static void
+handle_init(
+	AppContextRef ctx
+)
+{
+	(void) ctx;
+
+	window_init(&window, "RFC 6238");
+	window_stack_push(&s_window, true);
+
+	text_layer_init(&text_layer, window.layer.frame);
+	text_layer_set(&text_layer, time_buffer);
+	layer_add_child(&wndow.layer, &text_layer.layer);
+}
+
+
+static const PebbleAppHandlers handlers = {
+	.init_handler	= &handle_init,
+	.tick_info	= {
+		.tick_handler = &handle_tick,
+		.tick_units = SECOND_UNIT,
+	},
+};
+
+extern "C"
+void pbl_main(
+	void * const params
+)
+{
+	app_event_loop(params, &handlers);
+}

totp.cpp

-#include <stdio.h>
-#include <time.h>
-#include "sha1.h"
-
-// change to your secret
-static const uint8_t hmacKey1[]={
-0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe, 0xef
-};
-
-uint32_t auth_calc(void)
-{
-	const uint32_t now = time(NULL) / 30;
-
-	uint8_t byteArray[] = {
-		0,
-		0,
-		0,
-		0,
-		now >> 24,
-		now >> 16,
-		now >>  8,
-		now >>  0,
-	};
-
-    Sha1.initHmac(hmacKey1,sizeof(hmacKey1));
-    Sha1.writebytes(byteArray, 8);
-    const uint8_t * const hash = Sha1.resultHmac();
-  
-    const unsigned offset = hash[20 - 1] & 0xF; 
-    uint32_t truncatedHash = 0;
-    int j;
-    for (j = 0; j < 4; ++j) {
-     truncatedHash <<= 8;
-     truncatedHash  |= hash[offset + j];
-    }
-    
-    truncatedHash &= 0x7FFFFFFF;
-    truncatedHash %= 1000000;
-
-	return truncatedHash;
-}
-
-int main(void)
-{
-	printf("%06d\n", auth_calc());
-	return 0;
-}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.