crypto_v3.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "crypto_v3.h"
  2. #include <stdlib.h>
  3. #include <furi.h>
  4. #include <furi_hal_crypto.h>
  5. #include <furi_hal_random.h>
  6. #include <furi_hal_version.h>
  7. #include "../../types/common.h"
  8. #include "../../config/wolfssl/config.h"
  9. #include <wolfssl/wolfcrypt/hmac.h>
  10. #include <wolfssl/wolfcrypt/pwdbased.h>
  11. #include "memset_s.h"
  12. #include "constants.h"
  13. #define CRYPTO_ALIGNMENT_FACTOR (16)
  14. #define PBKDF2_ITERATIONS_COUNT (200)
  15. static const uint8_t* get_device_uid() {
  16. return (const uint8_t*)UID64_BASE; //-V566
  17. }
  18. static uint8_t get_device_uid_length() {
  19. return furi_hal_version_uid_size();
  20. }
  21. static const uint8_t* get_crypto_verify_key() {
  22. return get_device_uid();
  23. }
  24. static uint8_t get_crypto_verify_key_length() {
  25. return get_device_uid_length();
  26. }
  27. uint8_t* totp_crypto_encrypt_v3(
  28. const uint8_t* plain_data,
  29. const size_t plain_data_length,
  30. const CryptoSettings* crypto_settings,
  31. size_t* encrypted_data_length) {
  32. uint8_t* encrypted_data;
  33. size_t remain = plain_data_length % CRYPTO_ALIGNMENT_FACTOR;
  34. if(remain) {
  35. size_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR;
  36. uint8_t* plain_data_aligned = malloc(plain_data_aligned_length);
  37. furi_check(plain_data_aligned != NULL);
  38. memset(plain_data_aligned, 0, plain_data_aligned_length);
  39. memcpy(plain_data_aligned, plain_data, plain_data_length);
  40. encrypted_data = malloc(plain_data_aligned_length);
  41. furi_check(encrypted_data != NULL);
  42. *encrypted_data_length = plain_data_aligned_length;
  43. furi_check(
  44. furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
  45. "Encryption failed: enclave_load_key");
  46. furi_check(
  47. furi_hal_crypto_encrypt(plain_data_aligned, encrypted_data, plain_data_aligned_length),
  48. "Encryption failed: encrypt");
  49. furi_check(
  50. furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
  51. "Encryption failed: enclave_unload_key");
  52. memset_s(plain_data_aligned, plain_data_aligned_length, 0, plain_data_aligned_length);
  53. free(plain_data_aligned);
  54. } else {
  55. encrypted_data = malloc(plain_data_length);
  56. furi_check(encrypted_data != NULL);
  57. *encrypted_data_length = plain_data_length;
  58. furi_check(
  59. furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
  60. "Encryption failed: enclave_load_key");
  61. furi_check(
  62. furi_hal_crypto_encrypt(plain_data, encrypted_data, plain_data_length),
  63. "Encryption failed: encrypt");
  64. furi_check(
  65. furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
  66. "Encryption failed: enclave_unload_key");
  67. }
  68. return encrypted_data;
  69. }
  70. uint8_t* totp_crypto_decrypt_v3(
  71. const uint8_t* encrypted_data,
  72. const size_t encrypted_data_length,
  73. const CryptoSettings* crypto_settings,
  74. size_t* decrypted_data_length) {
  75. *decrypted_data_length = encrypted_data_length;
  76. uint8_t* decrypted_data = malloc(*decrypted_data_length);
  77. furi_check(decrypted_data != NULL);
  78. furi_check(
  79. furi_hal_crypto_enclave_load_key(crypto_settings->crypto_key_slot, crypto_settings->iv),
  80. "Decryption failed: enclave_load_key");
  81. furi_check(
  82. furi_hal_crypto_decrypt(encrypted_data, decrypted_data, encrypted_data_length),
  83. "Decryption failed: decrypt");
  84. furi_check(
  85. furi_hal_crypto_enclave_unload_key(crypto_settings->crypto_key_slot),
  86. "Decryption failed: enclave_unload_key");
  87. return decrypted_data;
  88. }
  89. CryptoSeedIVResult totp_crypto_seed_iv_v3(
  90. CryptoSettings* crypto_settings,
  91. const uint8_t* pin,
  92. uint8_t pin_length) {
  93. CryptoSeedIVResult result;
  94. if(crypto_settings->crypto_verify_data == NULL) {
  95. FURI_LOG_I(LOGGING_TAG, "Generating new salt");
  96. furi_hal_random_fill_buf(&crypto_settings->salt[0], CRYPTO_SALT_LENGTH);
  97. }
  98. const uint8_t* device_uid = get_device_uid();
  99. uint8_t device_uid_length = get_device_uid_length();
  100. uint8_t pbkdf_key_length = device_uid_length;
  101. if(pin != NULL && pin_length > 0) {
  102. pbkdf_key_length += pin_length;
  103. }
  104. uint8_t* pbkdf_key = malloc(pbkdf_key_length);
  105. furi_check(pbkdf_key != NULL);
  106. memcpy(pbkdf_key, device_uid, device_uid_length);
  107. if(pin != NULL && pin_length > 0) {
  108. memcpy(pbkdf_key + device_uid_length, pin, pin_length);
  109. }
  110. uint8_t pbkdf_output[WC_SHA512_DIGEST_SIZE] = {0};
  111. int pbkdf_result_code = wc_PBKDF2(
  112. &pbkdf_output[0],
  113. pbkdf_key,
  114. pbkdf_key_length,
  115. &crypto_settings->salt[0],
  116. CRYPTO_SALT_LENGTH,
  117. PBKDF2_ITERATIONS_COUNT,
  118. WC_SHA512_DIGEST_SIZE,
  119. WC_SHA512);
  120. memset_s(pbkdf_key, pbkdf_key_length, 0, pbkdf_key_length);
  121. free(pbkdf_key);
  122. if(pbkdf_result_code == 0) {
  123. uint8_t offset = pbkdf_output[WC_SHA512_DIGEST_SIZE - 1] %
  124. (WC_SHA512_DIGEST_SIZE - CRYPTO_IV_LENGTH - 1);
  125. memcpy(&crypto_settings->iv[0], &pbkdf_output[offset], CRYPTO_IV_LENGTH);
  126. result = CryptoSeedIVResultFlagSuccess;
  127. if(crypto_settings->crypto_verify_data == NULL) {
  128. const uint8_t* crypto_vkey = get_crypto_verify_key();
  129. uint8_t crypto_vkey_length = get_crypto_verify_key_length();
  130. FURI_LOG_I(LOGGING_TAG, "Generating crypto verify data");
  131. crypto_settings->crypto_verify_data = malloc(crypto_vkey_length);
  132. furi_check(crypto_settings->crypto_verify_data != NULL);
  133. crypto_settings->crypto_verify_data_length = crypto_vkey_length;
  134. crypto_settings->crypto_verify_data = totp_crypto_encrypt_v3(
  135. crypto_vkey,
  136. crypto_vkey_length,
  137. crypto_settings,
  138. &crypto_settings->crypto_verify_data_length);
  139. crypto_settings->pin_required = pin != NULL && pin_length > 0;
  140. result |= CryptoSeedIVResultFlagNewCryptoVerifyData;
  141. }
  142. } else {
  143. result = CryptoSeedIVResultFailed;
  144. }
  145. memset_s(&pbkdf_output[0], WC_SHA512_DIGEST_SIZE, 0, WC_SHA512_DIGEST_SIZE);
  146. return result;
  147. }
  148. bool totp_crypto_verify_key_v3(const CryptoSettings* crypto_settings) {
  149. size_t decrypted_key_length;
  150. uint8_t* decrypted_key = totp_crypto_decrypt_v3(
  151. crypto_settings->crypto_verify_data,
  152. crypto_settings->crypto_verify_data_length,
  153. crypto_settings,
  154. &decrypted_key_length);
  155. const uint8_t* crypto_vkey = get_crypto_verify_key();
  156. uint8_t crypto_vkey_length = get_crypto_verify_key_length();
  157. bool key_valid = true;
  158. for(uint8_t i = 0; i < crypto_vkey_length && key_valid; i++) {
  159. if(decrypted_key[i] != crypto_vkey[i]) key_valid = false;
  160. }
  161. free(decrypted_key);
  162. return key_valid;
  163. }