crypto.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "crypto.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include "../config/config.h"
  5. #include "../../types/common.h"
  6. #define CRYPTO_KEY_SLOT 2
  7. #define CRYPTO_VERIFY_KEY "FFF_Crypto_pass"
  8. #define CRYPTO_VERIFY_KEY_LENGTH 16
  9. #define CRYPTO_ALIGNMENT_FACTOR 16
  10. uint8_t* totp_crypto_encrypt(
  11. const uint8_t* plain_data,
  12. const uint8_t plain_data_length,
  13. const uint8_t* iv,
  14. uint8_t* encrypted_data_length) {
  15. uint8_t* encrypted_data;
  16. size_t remain = plain_data_length % CRYPTO_ALIGNMENT_FACTOR;
  17. if(remain) {
  18. uint8_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR;
  19. uint8_t* plain_data_aligned = malloc(plain_data_aligned_length);
  20. memset(plain_data_aligned, 0, plain_data_aligned_length);
  21. memcpy(plain_data_aligned, plain_data, plain_data_length);
  22. encrypted_data = malloc(plain_data_aligned_length);
  23. *encrypted_data_length = plain_data_aligned_length;
  24. furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
  25. furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length);
  26. furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
  27. memset(plain_data_aligned, 0, plain_data_aligned_length);
  28. free(plain_data_aligned);
  29. } else {
  30. encrypted_data = malloc(plain_data_length);
  31. *encrypted_data_length = plain_data_length;
  32. furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
  33. furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length);
  34. furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
  35. }
  36. return encrypted_data;
  37. }
  38. uint8_t* totp_crypto_decrypt(
  39. const uint8_t* encrypted_data,
  40. const uint8_t encrypted_data_length,
  41. const uint8_t* iv,
  42. uint8_t* decrypted_data_length) {
  43. *decrypted_data_length = encrypted_data_length;
  44. uint8_t* decrypted_data = malloc(*decrypted_data_length);
  45. furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
  46. furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length);
  47. furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
  48. return decrypted_data;
  49. }
  50. void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_length) {
  51. if(plugin_state->crypto_verify_data == NULL) {
  52. FURI_LOG_D(LOGGING_TAG, "Generating new IV");
  53. furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE);
  54. }
  55. memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE);
  56. if(pin != NULL && pin_length > 0) {
  57. uint8_t max_i;
  58. if(pin_length > TOTP_IV_SIZE) {
  59. max_i = TOTP_IV_SIZE;
  60. } else {
  61. max_i = pin_length;
  62. }
  63. for(uint8_t i = 0; i < max_i; i++) {
  64. plugin_state->iv[i] = plugin_state->iv[i] ^ (uint8_t)(pin[i] * (i + 1));
  65. }
  66. } else {
  67. uint8_t max_i;
  68. size_t uid_size = furi_hal_version_uid_size();
  69. if(uid_size > TOTP_IV_SIZE) {
  70. max_i = TOTP_IV_SIZE;
  71. } else {
  72. max_i = uid_size;
  73. }
  74. const uint8_t* uid = furi_hal_version_uid();
  75. for(uint8_t i = 0; i < max_i; i++) {
  76. plugin_state->iv[i] = plugin_state->iv[i] ^ uid[i];
  77. }
  78. }
  79. if(plugin_state->crypto_verify_data == NULL) {
  80. FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data");
  81. plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH);
  82. plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH;
  83. Storage* storage = totp_open_storage();
  84. FlipperFormat* config_file = totp_open_config_file(storage);
  85. plugin_state->crypto_verify_data = totp_crypto_encrypt(
  86. (uint8_t*)CRYPTO_VERIFY_KEY,
  87. CRYPTO_VERIFY_KEY_LENGTH,
  88. &plugin_state->iv[0],
  89. &plugin_state->crypto_verify_data_length);
  90. flipper_format_insert_or_update_hex(
  91. config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE);
  92. flipper_format_insert_or_update_hex(
  93. config_file,
  94. TOTP_CONFIG_KEY_CRYPTO_VERIFY,
  95. plugin_state->crypto_verify_data,
  96. CRYPTO_VERIFY_KEY_LENGTH);
  97. plugin_state->pin_set = pin != NULL && pin_length > 0;
  98. flipper_format_insert_or_update_bool(
  99. config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
  100. totp_close_config_file(config_file);
  101. totp_close_storage();
  102. }
  103. }
  104. bool totp_crypto_verify_key(const PluginState* plugin_state) {
  105. uint8_t decrypted_key_length;
  106. uint8_t* decrypted_key = totp_crypto_decrypt(
  107. plugin_state->crypto_verify_data,
  108. plugin_state->crypto_verify_data_length,
  109. &plugin_state->iv[0],
  110. &decrypted_key_length);
  111. bool key_valid = true;
  112. for(uint8_t i = 0; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid; i++) {
  113. if(decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false;
  114. }
  115. return key_valid;
  116. }