crypto.c 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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(const uint8_t* plain_data, const uint8_t plain_data_length, const uint8_t* iv, uint8_t* encrypted_data_length) {
  11. uint8_t* encrypted_data;
  12. size_t remain = plain_data_length % CRYPTO_ALIGNMENT_FACTOR;
  13. if(remain) {
  14. uint8_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR;
  15. uint8_t* plain_data_aligned = malloc(plain_data_aligned_length);
  16. memset(plain_data_aligned, 0, plain_data_aligned_length);
  17. memcpy(plain_data_aligned, plain_data, plain_data_length);
  18. encrypted_data = malloc(plain_data_aligned_length);
  19. *encrypted_data_length = plain_data_aligned_length;
  20. furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
  21. furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length);
  22. furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
  23. memset(plain_data_aligned, 0, plain_data_aligned_length);
  24. free(plain_data_aligned);
  25. } else {
  26. encrypted_data = malloc(plain_data_length);
  27. *encrypted_data_length = plain_data_length;
  28. furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
  29. furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length);
  30. furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
  31. }
  32. return encrypted_data;
  33. }
  34. uint8_t* totp_crypto_decrypt(const uint8_t* encrypted_data, const uint8_t encrypted_data_length, const uint8_t* iv, uint8_t* decrypted_data_length) {
  35. *decrypted_data_length = encrypted_data_length;
  36. uint8_t* decrypted_data = malloc(*decrypted_data_length);
  37. furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, iv);
  38. furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length);
  39. furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT);
  40. return decrypted_data;
  41. }
  42. void totp_crypto_seed_iv(PluginState* plugin_state, uint8_t* pin, uint8_t pin_length) {
  43. if (plugin_state->crypto_verify_data == NULL) {
  44. FURI_LOG_D(LOGGING_TAG, "Generating new IV");
  45. furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE);
  46. }
  47. memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE);
  48. if (pin != NULL && pin_length > 0) {
  49. for (uint8_t i = 0; i < pin_length; i++) {
  50. plugin_state->iv[i] = plugin_state->iv[i] ^ (uint8_t)(pin[i] * (i + 1));
  51. }
  52. }
  53. if (plugin_state->crypto_verify_data == NULL) {
  54. FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data");
  55. plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH);
  56. plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH;
  57. Storage* storage = totp_open_storage();
  58. FlipperFormat* config_file = totp_open_config_file(storage);
  59. plugin_state->crypto_verify_data = totp_crypto_encrypt((uint8_t* )CRYPTO_VERIFY_KEY, CRYPTO_VERIFY_KEY_LENGTH, &plugin_state->iv[0], &plugin_state->crypto_verify_data_length);
  60. flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE);
  61. flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, CRYPTO_VERIFY_KEY_LENGTH);
  62. plugin_state->pin_set = pin != NULL && pin_length > 0;
  63. flipper_format_insert_or_update_bool(config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
  64. totp_close_config_file(config_file);
  65. totp_close_storage();
  66. }
  67. }
  68. bool totp_crypto_verify_key(const PluginState* plugin_state) {
  69. uint8_t decrypted_key_length;
  70. uint8_t* decrypted_key = totp_crypto_decrypt(plugin_state->crypto_verify_data, plugin_state->crypto_verify_data_length, &plugin_state->iv[0], &decrypted_key_length);
  71. bool key_valid = true;
  72. for (uint8_t i = 0; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid; i++) {
  73. if (decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false;
  74. }
  75. return key_valid;
  76. }