crypto_v2.c 6.7 KB

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