secure.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2022 QMK
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "secure.h"
  4. #include "timer.h"
  5. #include "util.h"
  6. #ifndef SECURE_UNLOCK_TIMEOUT
  7. # define SECURE_UNLOCK_TIMEOUT 5000
  8. #endif
  9. #ifndef SECURE_IDLE_TIMEOUT
  10. # define SECURE_IDLE_TIMEOUT 60000
  11. #endif
  12. #ifndef SECURE_UNLOCK_SEQUENCE
  13. # define SECURE_UNLOCK_SEQUENCE {{0, 0}}
  14. #endif
  15. static secure_status_t secure_status = SECURE_LOCKED;
  16. static uint32_t unlock_time = 0;
  17. static uint32_t idle_time = 0;
  18. static void secure_hook(secure_status_t secure_status) {
  19. secure_hook_quantum(secure_status);
  20. secure_hook_kb(secure_status);
  21. }
  22. secure_status_t secure_get_status(void) {
  23. return secure_status;
  24. }
  25. void secure_lock(void) {
  26. secure_status = SECURE_LOCKED;
  27. secure_hook(secure_status);
  28. }
  29. void secure_unlock(void) {
  30. secure_status = SECURE_UNLOCKED;
  31. idle_time = timer_read32();
  32. secure_hook(secure_status);
  33. }
  34. void secure_request_unlock(void) {
  35. if (secure_status == SECURE_LOCKED) {
  36. secure_status = SECURE_PENDING;
  37. unlock_time = timer_read32();
  38. }
  39. secure_hook(secure_status);
  40. }
  41. void secure_activity_event(void) {
  42. if (secure_status == SECURE_UNLOCKED) {
  43. idle_time = timer_read32();
  44. }
  45. }
  46. void secure_keypress_event(uint8_t row, uint8_t col) {
  47. static const uint8_t sequence[][2] = SECURE_UNLOCK_SEQUENCE;
  48. static const uint8_t sequence_len = ARRAY_SIZE(sequence);
  49. static uint8_t offset = 0;
  50. if ((sequence[offset][0] == row) && (sequence[offset][1] == col)) {
  51. offset++;
  52. if (offset == sequence_len) {
  53. offset = 0;
  54. secure_unlock();
  55. }
  56. } else {
  57. offset = 0;
  58. secure_lock();
  59. }
  60. }
  61. void secure_task(void) {
  62. #if SECURE_UNLOCK_TIMEOUT != 0
  63. // handle unlock timeout
  64. if (secure_status == SECURE_PENDING) {
  65. if (timer_elapsed32(unlock_time) >= SECURE_UNLOCK_TIMEOUT) {
  66. secure_lock();
  67. }
  68. }
  69. #endif
  70. #if SECURE_IDLE_TIMEOUT != 0
  71. // handle idle timeout
  72. if (secure_status == SECURE_UNLOCKED) {
  73. if (timer_elapsed32(idle_time) >= SECURE_IDLE_TIMEOUT) {
  74. secure_lock();
  75. }
  76. }
  77. #endif
  78. }
  79. __attribute__((weak)) bool secure_hook_user(secure_status_t secure_status) {
  80. return true;
  81. }
  82. __attribute__((weak)) bool secure_hook_kb(secure_status_t secure_status) {
  83. return secure_hook_user(secure_status);
  84. }