crypto_v2.c 6.6 KB

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