crypto_v1.c 4.8 KB

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