crypto_v1.c 5.1 KB

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