From 64f486437e6ca9d28bda4559dc322d34ea217210 Mon Sep 17 00:00:00 2001 From: bg Date: Sun, 20 Oct 2013 06:10:15 +0200 Subject: [PATCH] seems to be working ok --- firmware/hotp.c | 36 ++++++++++---- firmware/hotp.h | 2 +- firmware/main.c | 57 +++++++++++++++++----- firmware/requests.h | 1 + firmware/usb_keyboard_codes.h | 90 +++++++++++++++++++++++++++++++++++ firmware/usbconfig.h | 6 +++ 6 files changed, 169 insertions(+), 23 deletions(-) create mode 100644 firmware/usb_keyboard_codes.h diff --git a/firmware/hotp.c b/firmware/hotp.c index f0e7c3c..1f8096a 100644 --- a/firmware/hotp.c +++ b/firmware/hotp.c @@ -19,6 +19,7 @@ #include +#include #include #include @@ -38,6 +39,19 @@ uint32_t dtrunc(uint8_t* buffer) { return r.w32; } +static +void reverse_string(char *str) { + char *end; + end = str + strlen(str) - 1; + while (end > str) { + *str ^= *end; + *end ^= *str; + *str ^= *end; + ++str; + --end; + } +} + static void to_digits(char *buffer, uint32_t value, uint8_t digits) { ldiv_t t; @@ -52,24 +66,28 @@ void to_digits(char *buffer, uint32_t value, uint8_t digits) { *buffer = '\0'; } -void hotp(char *buffer, void* secret, uint16_t secret_length_b, uint32_t counter, uint8_t digits) { +void hotp(char *buffer, const void* secret, uint16_t secret_length_b, uint32_t counter, uint8_t digits) { union { uint8_t mac[20]; uint8_t ctr_buffer[8]; } d; uint32_t s; - d.ctr_buffer[7] = 0; - d.ctr_buffer[6] = 0; - d.ctr_buffer[5] = 0; - d.ctr_buffer[4] = 0; - d.ctr_buffer[3] = counter & 0xff; + d.ctr_buffer[7] = counter & 0xff; counter >>= 8; - d.ctr_buffer[2] = counter & 0xff; + d.ctr_buffer[6] = counter & 0xff; counter >>= 8; - d.ctr_buffer[1] = counter & 0xff; + d.ctr_buffer[5] = counter & 0xff; counter >>= 8; - d.ctr_buffer[0] = counter & 0xff; + d.ctr_buffer[4] = counter & 0xff; + d.ctr_buffer[3] = 0; + d.ctr_buffer[2] = 0; + d.ctr_buffer[1] = 0; + d.ctr_buffer[0] = 0; + if (digits > 9) { + digits = 9; + } hmac_sha1(d.mac, secret, secret_length_b, d.ctr_buffer, 64); s = dtrunc(d.mac); to_digits(buffer, s, digits); + reverse_string(buffer); } diff --git a/firmware/hotp.h b/firmware/hotp.h index 8265e0c..49b42b6 100644 --- a/firmware/hotp.h +++ b/firmware/hotp.h @@ -22,6 +22,6 @@ #include -void hotp(char *buffer, void* secret, uint16_t secret_length_b, uint32_t counter, uint8_t digits); +void hotp(char *buffer, const void* secret, uint16_t secret_length_b, uint32_t counter, uint8_t digits); #endif /* HOTP_H_ */ diff --git a/firmware/main.c b/firmware/main.c index 5bcb934..b1afcdc 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -15,10 +15,11 @@ different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or at least be connected to INT0 as well. */ -#define BUTTON_PIN 4 - +#define BUTTON_PIN 5 +#define DEBOUNCE_DELAY 50 #define SIMPLE_COUNTER 1 #define NO_CHECK 1 +#define ALLOW_SECRET_READ 0 #include #include @@ -34,6 +35,7 @@ at least be connected to INT0 as well. #include "usbdrv.h" #include "requests.h" /* The custom request numbers we use */ #include "hotp.h" +#include "special_functions.h" #if !SIMPLE_COUNTER #include "percnt2.h" #endif @@ -207,14 +209,23 @@ void counter_init(void) { static void token_generate(void) { + uint16_t s_length_b; + uint8_t digits; counter_inc(); eeprom_busy_wait(); eeprom_read_block(secret, secret_ee, 32); eeprom_busy_wait(); + s_length_b = eeprom_read_word(&secret_length_ee); + if (s_length_b > 256) { + s_length_b = 256; + } + eeprom_busy_wait(); + digits = eeprom_read_byte(&digits_ee); #if SIMPLE_COUNTER - hotp(token, secret, eeprom_read_word(&secret_length_ee), eeprom_read_dword(&counter_ee), eeprom_read_byte(&digits_ee)); + eeprom_busy_wait(); + hotp(token, secret, s_length_b, eeprom_read_dword(&counter_ee) - 1, digits); #else - hotp(token, secret, eeprom_read_word(&secret_length_ee), percnt_get(0), eeprom_read_byte(&digits_ee)); + hotp(token, secret, s_length_b, percnt_get(0) - 1, digits); #endif memory_clean(); } @@ -223,7 +234,6 @@ void token_generate(void) { static void buildReport(uchar send_key) { keyboard_report.modifier = 0; - switch (send_key) { case '1' ... '9': keyboard_report.keycode[0] = KEY_1 + (send_key-'1'); @@ -237,13 +247,13 @@ void buildReport(uchar send_key) { } static -int8_t button_get_debounced(volatile uint8_t debounce_count) { +int8_t button_get_debounced(volatile int8_t debounce_count) { uint8_t v; v = PINB & _BV(BUTTON_PIN); - while (debounce_count-- && v == (PINB & _BV(BUTTON_PIN))) { + while (debounce_count-- && (v == (PINB & _BV(BUTTON_PIN)))) { ; } - if (debounce_count) { + if (debounce_count != -1) { return -1; } return v ? 0 : 1; @@ -342,8 +352,11 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) soft_reset((uint8_t)(rq->wValue.word)); break; case CUSTOM_RQ_READ_BUTTON: - uni_buffer.w8[0] = button_get_debounced(25); + uni_buffer.w8[0] = button_get_debounced(DEBOUNCE_DELAY); return 1; + case CUSTOM_RQ_GET_SECRET: + uni_buffer.w8[0] = 0; + return USB_NO_MSG; } } @@ -382,8 +395,25 @@ uchar usbFunctionWrite(uchar *data, uchar len) } return 0; } + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + uchar usbFunctionRead(uchar *data, uchar len){ - return 0; +#if ALLOW_SECRET_READ + uchar r; + uint8_t s_length_B; + switch(current_command){ + case CUSTOM_RQ_GET_SECRET: + eeprom_busy_wait(); + s_length_B = (eeprom_read_word(&secret_length_ee) + 7) / 8; + r = MIN(len, s_length_B - uni_buffer.w8[0]); + eeprom_busy_wait(); + eeprom_read_block(data, secret_ee + uni_buffer.w8[0], r); + uni_buffer.w8[0] += r; + return r; + } +#endif + return 0; } static void calibrateOscillator(void) @@ -440,8 +470,6 @@ int main(void) * additional hardware initialization. */ - DDRB &= ~_BV(BUTTON_PIN); /* make button pin input */ - PORTB |= _BV(BUTTON_PIN); /* turn on pull-up resistor */ counter_init(); usbInit(); usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ @@ -452,14 +480,17 @@ int main(void) usbDeviceConnect(); sei(); + DDRB &= ~_BV(BUTTON_PIN); /* make button pin input */ + PORTB |= _BV(BUTTON_PIN); /* turn on pull-up resistor */ for(;;){ /* main event loop */ wdt_reset(); usbPoll(); - i = button_get_debounced(25); + i = button_get_debounced(DEBOUNCE_DELAY); if (i != -1) { if (last_stable_button_state == 0 && i == 1) { + token_generate(); key_state = STATE_SEND_KEY; } last_stable_button_state = i; diff --git a/firmware/requests.h b/firmware/requests.h index 7cee31d..32e9eb4 100644 --- a/firmware/requests.h +++ b/firmware/requests.h @@ -42,6 +42,7 @@ #define CUSTOM_RQ_GET_TOKEN 0x69 +#define CUSTOM_RQ_GET_SECRET 0x61 diff --git a/firmware/usb_keyboard_codes.h b/firmware/usb_keyboard_codes.h new file mode 100644 index 0000000..d8f3f6e --- /dev/null +++ b/firmware/usb_keyboard_codes.h @@ -0,0 +1,90 @@ +/* usb_keyboard_codes.h */ +/* + This file is part of the AVR-Crypto-Lib. + Copyright (C) 2013 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef USB_KEYBOARD_CODES_H_ +#define USB_KEYBOARD_CODES_H_ + +/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter + * 10 Keyboard/Keypad Page for more codes. + */ +#define MOD_CONTROL_LEFT (1<<0) +#define MOD_SHIFT_LEFT (1<<1) +#define MOD_ALT_LEFT (1<<2) +#define MOD_GUI_LEFT (1<<3) +#define MOD_CONTROL_RIGHT (1<<4) +#define MOD_SHIFT_RIGHT (1<<5) +#define MOD_ALT_RIGHT (1<<6) +#define MOD_GUI_RIGHT (1<<7) + +#define KEY_A 4 +#define KEY_B 5 +#define KEY_C 6 +#define KEY_D 7 +#define KEY_E 8 +#define KEY_F 9 +#define KEY_G 10 +#define KEY_H 11 +#define KEY_I 12 +#define KEY_J 13 +#define KEY_K 14 +#define KEY_L 15 +#define KEY_M 16 +#define KEY_N 17 +#define KEY_O 18 +#define KEY_P 19 +#define KEY_Q 20 +#define KEY_R 21 +#define KEY_S 22 +#define KEY_T 23 +#define KEY_U 24 +#define KEY_V 25 +#define KEY_W 26 +#define KEY_X 27 +#define KEY_Y 28 +#define KEY_Z 29 +#define KEY_1 30 +#define KEY_2 31 +#define KEY_3 32 +#define KEY_4 33 +#define KEY_5 34 +#define KEY_6 35 +#define KEY_7 36 +#define KEY_8 37 +#define KEY_9 38 +#define KEY_0 39 + +#define KEY_F1 58 +#define KEY_F2 59 +#define KEY_F3 60 +#define KEY_F4 61 +#define KEY_F5 62 +#define KEY_F6 63 +#define KEY_F7 64 +#define KEY_F8 65 +#define KEY_F9 66 +#define KEY_F10 67 +#define KEY_F11 68 +#define KEY_F12 69 + +#define NUM_LOCK 1 +#define CAPS_LOCK 2 +#define SCROLL_LOCK 4 + + +#endif /* USB_KEYBOARD_CODES_H_ */ diff --git a/firmware/usbconfig.h b/firmware/usbconfig.h index 8250251..5857861 100644 --- a/firmware/usbconfig.h +++ b/firmware/usbconfig.h @@ -33,11 +33,17 @@ section at the end of this file). /* This is the port where the USB bus is connected. When you configure it to * "B", the registers PORTB, PINB and DDRB will be used. */ +#if 1 #define USB_CFG_DMINUS_BIT 0 /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. * This may be any bit in the port. */ #define USB_CFG_DPLUS_BIT 2 +#else +# define USB_CFG_DMINUS_BIT 3 +# define USB_CFG_DPLUS_BIT 4 +#endif + /* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. * This may be any bit in the port. Please note that D+ must also be connected * to interrupt pin INT0! [You can also use other interrupts, see section -- 2.39.5