From 5b979b8d48aaef10df99b4a67841ae9bd99928c3 Mon Sep 17 00:00:00 2001 From: Stefan Krulj Date: Sat, 30 Jun 2012 17:31:35 +0200 Subject: [PATCH] Made keystroke sending faster --- libcrypt/Makefile | 2 +- libcrypt/README | 24 +++++++++++++++++++----- libcrypt/buffer/buffer.h | 2 +- libcrypt/main.c | 37 ++++++++++++++++++++++++------------- libcrypt/usb_callback.c | 3 ++- 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/libcrypt/Makefile b/libcrypt/Makefile index 44ad4f7..14c847a 100644 --- a/libcrypt/Makefile +++ b/libcrypt/Makefile @@ -36,7 +36,7 @@ OBJS = main.o \ usbdrv/oddebug.o \ usbdrv/usbdrvasm.o -INCLUDE = -Isha1 -Ihmac-sha1 -Iusbdrv -Imem_eval -Ibuffer +INCLUDE = -Isha1 -Ihmac-sha1 -Iusbdrv -Imem_eval -Ibuffer #------------------------------------------------------------------------- # macros for the tools diff --git a/libcrypt/README b/libcrypt/README index 3cec4dc..3e95b27 100644 --- a/libcrypt/README +++ b/libcrypt/README @@ -4,8 +4,9 @@ What is this thing? This device is a hash-based-one-time-password (=HOTP, RFC 4226) generator. You can use them to make an existing authentication more secure or as a single -authentication barrier to enter a system. You can easily do both on linux -machines using the oath toolkit (http://www.nongnu.org/oath-toolkit/). +authentication barrier to enter a system (although I wouldn't recoment that). +You can easily do both on linux machines using the oath toolkit +(http://www.nongnu.org/oath-toolkit/). How does it work? ----------------- @@ -18,7 +19,7 @@ sequence usually happens like this: 3. Confirm the login by pressing the button on the device this will generate an ENTER-keystroke and the internal counter is icremented by one. - 4. Pressing the button again reset the device, and the sequence + 4. Pressing the button again resets the device, and the sequence repeats. Otherwise just unplug it. How to install the firmware? @@ -35,12 +36,25 @@ It is recomended to take a secret of length 20 (longer secrets are supported but do not provide additional security). This is basically a sha1 digest. I usually do the following to generate secrets: - + >head /dev/urandom | sha1sum + 11d64fc6fcff5f198976b86cc590fb58a04dc422 - + +The resulting define would be: -type make. If the compilation runs well, you will end up with some .hex files: + SECRET = -DSECLEN=20 -DSECRET="{0x11, 0xd6, 0x4f, 0xc6, 0xfc, 0xff, ...}" + +Once you're done simply type make. If the compilation runs well, you will end +up with some .hex files: - The main file: hotp.hex (this goes to the flash) - The eeprom init: eeprom.hex (this goes to the internal eeprom) +You can upload them by typing "make install". +Now configure the server side: Provide the secret you just used, the initial +counter value is 0 (Remember to keep a working terminal somewhere in case you +lock yourself out). After doing this try to login, if it works you should +remove the secret from the makefile and also prevent the microcontroller from +beeing read. Do this by typing "make lock" + Security considerations: ------------------------ diff --git a/libcrypt/buffer/buffer.h b/libcrypt/buffer/buffer.h index 331e04d..24e4ecc 100644 --- a/libcrypt/buffer/buffer.h +++ b/libcrypt/buffer/buffer.h @@ -2,7 +2,7 @@ #define _BUFFER_H #include "../usb_key_codes.h" -#include +#include #define BUFFER_SIZE 10 diff --git a/libcrypt/main.c b/libcrypt/main.c index e2a8fe7..793f009 100644 --- a/libcrypt/main.c +++ b/libcrypt/main.c @@ -17,9 +17,8 @@ #include uint8_t reportBuffer[2]; /* buffer for HID reports */ -uint8_t idleRate; -static uint8_t kbd_event_state=0; +static uint8_t next_key=0, prev_key=0xFF; uint32_t get_cnt(){ void* p=(void*)eeprom_read_word(CNTPOS_PTR); @@ -84,12 +83,13 @@ int main(void){ #endif //CALLIB usbDeviceDisconnect(); - _delay_ms(300); /* mustn't be that exact */ + /* just leave some time for a disconnect/connect sequence mustn't be that exact */ + /* TODO only do this if watchdog was activated*/ + _delay_ms(200); usbDeviceConnect(); wdt_enable(WDTO_500MS); - writeToBuffer(USB_KEY_NOP); writeToBuffer(USB_KEY_NOP); if( eeprom_read_word(CNTPOS_PTR)==ERROR ){ @@ -100,24 +100,35 @@ int main(void){ writeToBuffer(USB_KEY_R); }else{ cnt = get_cnt(); - buffer_unum(get_otp_from_cnt(cnt,8,sec,SECLEN)); + buffer_unum(get_otp_from_cnt(792,8,sec,SECLEN)); //inc_cnt(); } usbInit(); sei(); for(;;){ - wdt_reset(); - usbPoll(); - /* we can send another key */ + wdt_reset(); + usbPoll(); if(usbInterruptIsReady()){ - kbd_event_state=!kbd_event_state; - if(kbd_event_state && !buff_empty){ - buildReport(0x00, readBuffer()); + if(!buff_empty || next_key!=0){ + if(next_key==0){ + next_key=readBuffer(); + } + if(next_key==prev_key){ + /*we must send a NOP in between otherwise it will be + interpreted as only one keystroke*/ + buildReport(0x00, USB_KEY_NOP); + /*set the prev key to something different*/ + prev_key=!next_key; + }else{ + buildReport(0x00, next_key); + prev_key=next_key; + next_key=0; + } }else{ - buildReport(0x00, 0x00); + buildReport(0x00, USB_KEY_NOP); } - usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); + usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); } } return 0; diff --git a/libcrypt/usb_callback.c b/libcrypt/usb_callback.c index d52839f..2ee5758 100644 --- a/libcrypt/usb_callback.c +++ b/libcrypt/usb_callback.c @@ -6,7 +6,8 @@ extern void buildReport(uint8_t mod,uint8_t key); extern uint8_t reportBuffer[2]; -extern uint8_t idleRate; + +uint8_t idleRate; uint8_t usbFunctionSetup(uint8_t data[8]){ usbRequest_t *rq = (void *)data;