From ffb0575eb81f989d0ba034f9ce9d74000bfb7844 Mon Sep 17 00:00:00 2001 From: zvecr Date: Mon, 11 Apr 2022 01:59:48 +0100 Subject: [PATCH] stub out secure data driven config --- data/mappings/info_config.json | 2 ++ data/mappings/info_rules.json | 1 + data/schemas/keyboard.jsonschema | 24 ++++++++++++++++++++ lib/python/qmk/info.py | 39 ++++++++++++++++++++++++++++++++ quantum/secure.c | 16 ++++++++++++- 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/data/mappings/info_config.json b/data/mappings/info_config.json index 2121741d19..ccc9cdbb5a 100644 --- a/data/mappings/info_config.json +++ b/data/mappings/info_config.json @@ -78,6 +78,8 @@ "QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int"}, "QMK_LED": {"info_key": "qmk_lufa_bootloader.led"}, "QMK_SPEAKER": {"info_key": "qmk_lufa_bootloader.speaker"}, + "SECURE_UNLOCK_TIMEOUT": {"info_key": "secure.unlock_timeout", "value_type": "int"}, + "SECURE_IDLE_TIMEOUT": {"info_key": "secure.idle_timeout", "value_type": "int"}, "SENDSTRING_BELL": {"info_key": "audio.macro_beep", "value_type": "bool"}, "SPLIT_MODS_ENABLE": {"info_key": "split.transport.sync_modifiers", "value_type": "bool"}, "SPLIT_TRANSPORT_MIRROR": {"info_key": "split.transport.sync_matrix_state", "value_type": "bool"}, diff --git a/data/mappings/info_rules.json b/data/mappings/info_rules.json index 237e9f1024..4b0fde5629 100644 --- a/data/mappings/info_rules.json +++ b/data/mappings/info_rules.json @@ -20,6 +20,7 @@ "MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"}, "NO_USB_STARTUP_CHECK": {"info_key": "usb.no_startup_check", "value_type": "bool"}, "PIN_COMPATIBLE": {"info_key": "pin_compatible"}, + "SECURE_ENABLE": {"info_key": "secure.enabled", "value_type": "bool"}, "SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"}, "SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false}, "WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"} diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index dce2e855a1..9cde658128 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -300,6 +300,30 @@ } } }, + "secure": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": {"type": "boolean"}, + "unlock_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"}, + "idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"}, + "unlock_sequence": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "items": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "type": "number", + "min": 0, + "multipleOf": 1 + } + } + } + } + }, "split": { "type": "object", "additionalProperties": false, diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 060404667d..7990504517 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -171,6 +171,29 @@ def _extract_pins(pins): return [_pin_name(pin) for pin in pins.split(',')] +def _parse_2d_array(raw): + """Return a 2d array of ints + """ + out_array = [] + + while raw[-1] != '}': + raw = raw[:-1] + + for row in raw.split('},{'): + if row.startswith('{'): + row = row[1:] + + if row.endswith('}'): + row = row[:-1] + + out_array.append([]) + + for val in row.split(','): + out_array[-1].append(int(val)) + + return out_array + + def _extract_direct_matrix(direct_pins): """ """ @@ -210,6 +233,21 @@ def _extract_audio(info_data, config_c): info_data['audio'] = {'pins': audio_pins} +def _extract_secure_unlock(info_data, config_c): + """Populate data about the secure unlock sequence + """ + unlock = config_c.get('SECURE_UNLOCK_SEQUENCE', '').replace(' ', '')[1:-1] + if unlock: + unlock_array = _parse_2d_array(unlock) + if 'secure' not in info_data: + info_data['secure'] = {} + + if 'unlock_sequence' in info_data['secure']: + _log_warning(info_data, 'Secure unlock sequence is specified in both config.h (SECURE_UNLOCK_SEQUENCE) and info.json (secure.unlock_sequence) (Value: %s), the config.h value wins.' % info_data['secure']['unlock_sequence']) + + info_data['secure']['unlock_sequence'] = unlock_array + + def _extract_split_main(info_data, config_c): """Populate data about the split configuration """ @@ -469,6 +507,7 @@ def _extract_config_h(info_data, config_c): # Pull data that easily can't be mapped in json _extract_matrix_info(info_data, config_c) _extract_audio(info_data, config_c) + _extract_secure_unlock(info_data, config_c) _extract_split_main(info_data, config_c) _extract_split_transport(info_data, config_c) _extract_split_right_pins(info_data, config_c) diff --git a/quantum/secure.c b/quantum/secure.c index 26a3246ccf..751977d351 100644 --- a/quantum/secure.c +++ b/quantum/secure.c @@ -12,6 +12,13 @@ # define SECURE_IDLE_TIMEOUT 60000 #endif +#ifndef SECURE_UNLOCK_SEQUENCE +# define SECURE_UNLOCK_SEQUENCE \ + { \ + { 0, 0 } \ + } +#endif + secure_status_t secure_status = SECURE_LOCKED; static uint32_t unlock_time = 0; static uint32_t idle_time = 0; @@ -41,8 +48,15 @@ void secure_request_unlock(void) { } void secure_keypress_event(uint8_t row, uint8_t col) { + static const uint8_t sequence[][2] = SECURE_UNLOCK_SEQUENCE; + // TODO: check keypress is actually part of unlock sequence - secure_unlock(); + uint8_t offset = 0; + if ((sequence[offset][0] == row) && (sequence[offset][1] == col)) { + secure_unlock(); + } else { + secure_lock(); + } } void secure_task(void) {