// Copyright 2022 QMK // SPDX-License-Identifier: GPL-2.0-or-later #include "secure.h" #include "timer.h" #include "util.h" #ifndef SECURE_UNLOCK_TIMEOUT # define SECURE_UNLOCK_TIMEOUT 5000 #endif #ifndef SECURE_IDLE_TIMEOUT # define SECURE_IDLE_TIMEOUT 60000 #endif #ifndef SECURE_UNLOCK_SEQUENCE # define SECURE_UNLOCK_SEQUENCE \ { \ { 0, 0 } \ } #endif static secure_status_t secure_status = SECURE_LOCKED; static uint32_t unlock_time = 0; static uint32_t idle_time = 0; static void secure_hook(secure_status_t secure_status) { secure_hook_quantum(secure_status); secure_hook_kb(secure_status); } secure_status_t secure_get_status(void) { return secure_status; } void secure_lock(void) { secure_status = SECURE_LOCKED; secure_hook(secure_status); } void secure_unlock(void) { secure_status = SECURE_UNLOCKED; idle_time = timer_read32(); secure_hook(secure_status); } void secure_request_unlock(void) { if (secure_status == SECURE_LOCKED) { secure_status = SECURE_PENDING; unlock_time = timer_read32(); } secure_hook(secure_status); } void secure_activity_event(void) { if (secure_status == SECURE_UNLOCKED) { idle_time = timer_read32(); } } void secure_keypress_event(uint8_t row, uint8_t col) { static const uint8_t sequence[][2] = SECURE_UNLOCK_SEQUENCE; static const uint8_t sequence_len = ARRAY_SIZE(sequence); static uint8_t offset = 0; if ((sequence[offset][0] == row) && (sequence[offset][1] == col)) { offset++; if (offset == sequence_len) { offset = 0; secure_unlock(); } } else { offset = 0; secure_lock(); } } void secure_task(void) { #if SECURE_UNLOCK_TIMEOUT != 0 // handle unlock timeout if (secure_status == SECURE_PENDING) { if (timer_elapsed32(unlock_time) >= SECURE_UNLOCK_TIMEOUT) { secure_lock(); } } #endif #if SECURE_IDLE_TIMEOUT != 0 // handle idle timeout if (secure_status == SECURE_UNLOCKED) { if (timer_elapsed32(idle_time) >= SECURE_IDLE_TIMEOUT) { secure_lock(); } } #endif } __attribute__((weak)) bool secure_hook_user(secure_status_t secure_status) { return true; } __attribute__((weak)) bool secure_hook_kb(secure_status_t secure_status) { return secure_hook_user(secure_status); }