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.

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