From d2c9b00b36faf8d38a2f0fb32f1464528f4e96bd Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 12 Nov 2018 13:19:26 +0900 Subject: Pairing confirmation: ignore special chars and "and" --- hexnoise.py | 4 ++- src/demo.c | 63 +++++++++++++++++++++++++++--------------- src/hid_keycodes.c | 81 ++++++++++++++++++++++++++++-------------------------- src/hid_keycodes.h | 26 +++++++++++++++++- 4 files changed, 111 insertions(+), 63 deletions(-) diff --git a/hexnoise.py b/hexnoise.py index d5bce09..6b0aad8 100755 --- a/hexnoise.py +++ b/hexnoise.py @@ -121,7 +121,9 @@ if __name__ == '__main__': from nouns import NOUNS from adjectives import ADJECTIVES def map_bytes_to_incantation(data): - return " ".join(f'{ADJECTIVES[a]:>16} {NOUNS[b]:<16}' for a, b in zip(data[0::2], data[1::2])) + elems = [ f'{ADJECTIVES[a]} {NOUNS[b]}' for a, b in zip(data[0::2], data[1::2]) ] + nfirst = ", ".join(elems[:-1]) + return f'{nfirst} and {elems[-1]}' print('Handshake channel binding incantation:') hhash = proto.get_handshake_hash() print(' ' + map_bytes_to_incantation(hhash[:8 ])) diff --git a/src/demo.c b/src/demo.c index ba76d2b..8febe9b 100644 --- a/src/demo.c +++ b/src/demo.c @@ -133,37 +133,41 @@ static char pairing_buf[512]; static size_t pairing_buf_pos = 0; int pairing_check(struct NoiseState *st, const char *buf); -void pairing_input(uint8_t keycode); +void pairing_input(uint8_t modbyte, uint8_t keycode); void pairing_parse_report(struct hid_report *buf, uint8_t len); /* Minimum number of bytes of handshake hash to confirm during pairing */ #define MIN_PAIRING_SEQUENCE_LENGTH 8 int pairing_check(struct NoiseState *st, const char *buf) { - LOG_PRINTF("Checking pairing\n"); + //LOG_PRINTF("Checking pairing\n"); const char *p = buf; int idx = 0; do { const char *found = strchr(p, ' '); size_t plen = found ? (size_t)(found - p) : strlen(p); /* p >= found */ - int num = -1; - /* FIXME ignore "and", ignore commata and dots, handle letter case correctly (currently it's ignored). */ - for (int i=0; i<256; i++) { - if ((!strncmp(p, adjectives[i], plen)) || (!strncmp(p, nouns[i], plen))) { - LOG_PRINTF(" idx=%02d h=%02x i=%02x adj=%s n=%s plen=%d s=%s\n", idx, st->handshake_hash[idx], i, adjectives[i], nouns[i], plen, p); - num = i; - break; + + if (strncasecmp(p, "and", plen)) { /* ignore "and" */ + int num = -1; + /* FIXME ignore "and", ignore commata and dots */ + for (int i=0; i<256; i++) { + if ((!strncasecmp(p, adjectives[i], plen)) || (!strncasecmp(p, nouns[i], plen))) { + //LOG_PRINTF(" idx=%02d h=%02x i=%02x adj=%s n=%s plen=%d s=%s\n", idx, st->handshake_hash[idx], i, adjectives[i], nouns[i], plen, p); + num = i; + break; + } } + if (num == -1) { + LOG_PRINTF("Pairing word \"%s\" not found in dictionary\n", p); + return -1; + } + if (st->handshake_hash[idx] != num) { + LOG_PRINTF("Pairing data does not match hash\n"); + return -1; + } + idx++; } - if (num == -1) { - LOG_PRINTF("Pairing word \"%s\" not found in dictionary\n", p); - return -1; - } - if (st->handshake_hash[idx] != num) { - LOG_PRINTF("Pairing data does not match hash\n"); - return -1; - } - idx++; + p = strchr(p, ' '); if (!p) break; /* end of string */ @@ -175,31 +179,46 @@ int pairing_check(struct NoiseState *st, const char *buf) { return -1; } + LOG_PRINTF("Pairing sequence match\n"); return 0; } -void pairing_input(uint8_t keycode) { +void pairing_input(uint8_t modbyte, uint8_t keycode) { + uint8_t level = modbyte & MOD_XSHIFT ? LEVEL_SHIFT : LEVEL_NONE; switch (keycode) { case KEY_ENTER: pairing_buf[pairing_buf_pos++] = '\0'; if (!pairing_check(&noise_state, pairing_buf)) { persist_remote_key(&noise_state); /* FIXME write key to backup memory */ + } else { + /* FIXME sound alarm */ } break; case KEY_BACKSPACE: - pairing_buf[pairing_buf_pos] = '\0'; /* FIXME debug */ if (pairing_buf_pos > 0) pairing_buf_pos--; + pairing_buf[pairing_buf_pos] = '\0'; /* FIXME debug */ break; default: for (size_t i=0; keycode_mapping[i].kc != KEY_NONE; i++) { if (keycode_mapping[i].kc == keycode) { + char ch = keycode_mapping[i].ch[level]; + /* FIXME send decoded char to host here instead of raw hid report to reduce buggability */ + if (!(('a' <= ch && ch <= 'z') || + ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || + (ch == ' '))) + break; /* ignore special chars */ + if (pairing_buf_pos < sizeof(pairing_buf)-1) /* allow for terminating null byte */ { - pairing_buf[pairing_buf_pos++] = keycode_mapping[i].ch; + pairing_buf[pairing_buf_pos++] = ch; pairing_buf[pairing_buf_pos] = '\0'; /* FIXME debug */ + } else { + LOG_PRINTF("Pairing confirmation user input buffer full\n"); + /* FIXME return error to host? */ } break; } @@ -224,7 +243,7 @@ void pairing_parse_report(struct hid_report *buf, uint8_t len) { } } if (!found) /* key pressed */ - pairing_input(buf->keycodes[i]); + pairing_input(buf->modifiers, buf->keycodes[i]); } memcpy(old_keycodes, buf->keycodes, 6); diff --git a/src/hid_keycodes.c b/src/hid_keycodes.c index 79acb72..ac3899a 100644 --- a/src/hid_keycodes.c +++ b/src/hid_keycodes.c @@ -2,44 +2,47 @@ #include "hid_keycodes.h" struct keymap_entry keycode_mapping[] = { - { KEY_A, 'a' }, - { KEY_B, 'b' }, - { KEY_C, 'c' }, - { KEY_D, 'd' }, - { KEY_E, 'e' }, - { KEY_F, 'f' }, - { KEY_G, 'g' }, - { KEY_H, 'h' }, - { KEY_I, 'i' }, - { KEY_J, 'j' }, - { KEY_K, 'k' }, - { KEY_L, 'l' }, - { KEY_M, 'm' }, - { KEY_N, 'n' }, - { KEY_O, 'o' }, - { KEY_P, 'p' }, - { KEY_Q, 'q' }, - { KEY_R, 'r' }, - { KEY_S, 's' }, - { KEY_T, 't' }, - { KEY_U, 'u' }, - { KEY_V, 'v' }, - { KEY_W, 'w' }, - { KEY_X, 'x' }, - { KEY_Y, 'y' }, - { KEY_Z, 'z' }, - { KEY_1, '1' }, - { KEY_2, '2' }, - { KEY_3, '3' }, - { KEY_4, '4' }, - { KEY_5, '5' }, - { KEY_6, '6' }, - { KEY_7, '7' }, - { KEY_8, '8' }, - { KEY_9, '9' }, - { KEY_0, '0' }, - { KEY_MINUS, '-' }, - { KEY_SPACE, ' ' }, - { KEY_NONE, 0 }, /* end marker */ + { KEY_A, {'a', 'A'}}, + { KEY_B, {'b', 'B'}}, + { KEY_C, {'c', 'C'}}, + { KEY_D, {'d', 'D'}}, + { KEY_E, {'e', 'E'}}, + { KEY_F, {'f', 'F'}}, + { KEY_G, {'g', 'G'}}, + { KEY_H, {'h', 'H'}}, + { KEY_I, {'i', 'I'}}, + { KEY_J, {'j', 'J'}}, + { KEY_K, {'k', 'K'}}, + { KEY_L, {'l', 'L'}}, + { KEY_M, {'m', 'M'}}, + { KEY_N, {'n', 'N'}}, + { KEY_O, {'o', 'O'}}, + { KEY_P, {'p', 'P'}}, + { KEY_Q, {'q', 'Q'}}, + { KEY_R, {'r', 'R'}}, + { KEY_S, {'s', 'S'}}, + { KEY_T, {'t', 'T'}}, + { KEY_U, {'u', 'U'}}, + { KEY_V, {'v', 'V'}}, + { KEY_W, {'w', 'W'}}, + { KEY_X, {'x', 'X'}}, + { KEY_Y, {'y', 'Y'}}, + { KEY_Z, {'z', 'Z'}}, + { KEY_1, {'1', '!'}}, + { KEY_2, {'2', '@'}}, + { KEY_3, {'3', '#'}}, + { KEY_4, {'4', '$'}}, + { KEY_5, {'5', '%'}}, + { KEY_6, {'6', '^'}}, + { KEY_7, {'7', '&'}}, + { KEY_8, {'8', '*'}}, + { KEY_9, {'9', '('}}, + { KEY_0, {'0', ')'}}, + { KEY_MINUS, {'-', '_'}}, + { KEY_SPACE, {' ', ' '}}, + { KEY_COMMA, {',', '<'}}, + { KEY_DOT, {'.', '>'}}, + { KEY_SEMICOLON, {';', ':'}}, + { KEY_NONE, {0, 0}}, /* end marker */ }; diff --git a/src/hid_keycodes.h b/src/hid_keycodes.h index 4cfe115..f269e5b 100644 --- a/src/hid_keycodes.h +++ b/src/hid_keycodes.h @@ -1,9 +1,33 @@ #ifndef __HID_KEYCODES_H__ #define __HID_KEYCODES_H__ +enum mod_levels { + LEVEL_NONE, + LEVEL_SHIFT, + LEVEL_NLEVELS +}; + +enum mod_bits { + MOD_LCTRL, + MOD_LSHIFT, + MOD_LALT, + MOD_LMETA, + MOD_RCTRL, + MOD_RSHIFT, + MOD_RALT, + MOD_RMETA, +}; + +enum mod_bitmaps { + MOD_XCTRL = MOD_LCTRL | MOD_RCTRL, + MOD_XSHIFT = MOD_LSHIFT | MOD_RSHIFT, + MOD_XALT = MOD_LALT | MOD_RALT, + MOD_XMETA = MOD_LMETA | MOD_RMETA, +}; + struct keymap_entry { unsigned char kc; - char ch; + char ch[LEVEL_NLEVELS]; }; extern struct keymap_entry keycode_mapping[]; -- cgit