You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.4 KiB

  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 \
  14. { \
  15. { 0, 0 } \
  16. }
  17. #endif
  18. static secure_status_t secure_status = SECURE_LOCKED;
  19. static uint32_t unlock_time = 0;
  20. static uint32_t idle_time = 0;
  21. static void secure_hook(secure_status_t secure_status) {
  22. secure_hook_quantum(secure_status);
  23. secure_hook_kb(secure_status);
  24. }
  25. secure_status_t secure_get_status(void) {
  26. return secure_status;
  27. }
  28. void secure_lock(void) {
  29. secure_status = SECURE_LOCKED;
  30. secure_hook(secure_status);
  31. }
  32. void secure_unlock(void) {
  33. secure_status = SECURE_UNLOCKED;
  34. idle_time = timer_read32();
  35. secure_hook(secure_status);
  36. }
  37. void secure_request_unlock(void) {
  38. if (secure_status == SECURE_LOCKED) {
  39. secure_status = SECURE_PENDING;
  40. unlock_time = timer_read32();
  41. }
  42. secure_hook(secure_status);
  43. }
  44. void secure_activity_event(void) {
  45. if (secure_status == SECURE_UNLOCKED) {
  46. idle_time = timer_read32();
  47. }
  48. }
  49. void secure_keypress_event(uint8_t row, uint8_t col) {
  50. static const uint8_t sequence[][2] = SECURE_UNLOCK_SEQUENCE;
  51. static const uint8_t sequence_len = ARRAY_SIZE(sequence);
  52. static uint8_t offset = 0;
  53. if ((sequence[offset][0] == row) && (sequence[offset][1] == col)) {
  54. offset++;
  55. if (offset == sequence_len) {
  56. offset = 0;
  57. secure_unlock();
  58. }
  59. } else {
  60. offset = 0;
  61. secure_lock();
  62. }
  63. }
  64. void secure_task(void) {
  65. #if SECURE_UNLOCK_TIMEOUT != 0
  66. // handle unlock timeout
  67. if (secure_status == SECURE_PENDING) {
  68. if (timer_elapsed32(unlock_time) >= SECURE_UNLOCK_TIMEOUT) {
  69. secure_lock();
  70. }
  71. }
  72. #endif
  73. #if SECURE_IDLE_TIMEOUT != 0
  74. // handle idle timeout
  75. if (secure_status == SECURE_UNLOCKED) {
  76. if (timer_elapsed32(idle_time) >= SECURE_IDLE_TIMEOUT) {
  77. secure_lock();
  78. }
  79. }
  80. #endif
  81. }
  82. __attribute__((weak)) bool secure_hook_user(secure_status_t secure_status) {
  83. return true;
  84. }
  85. __attribute__((weak)) bool secure_hook_kb(secure_status_t secure_status) {
  86. return secure_hook_user(secure_status);
  87. }