crypto_v3.c 6.8 KB

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