1
+ #include "crypto.h"
2
+ #include <furi.h>
3
+ #include <furi_hal.h>
4
+ #include "../config/config.h"
5
+ #include "../../types/common.h"
6
+
7
+ #define CRYPTO_KEY_SLOT 2
8
+ #define CRYPTO_VERIFY_KEY "FFF_Crypto_pass"
9
+ #define CRYPTO_VERIFY_KEY_LENGTH 16
10
+ #define CRYPTO_ALIGNMENT_FACTOR 16
11
+
12
+ uint8_t * totp_crypto_encrypt (const uint8_t * plain_data , const uint8_t plain_data_length , const uint8_t * iv , uint8_t * encrypted_data_length ) {
13
+ uint8_t * encrypted_data ;
14
+ size_t remain = plain_data_length % CRYPTO_ALIGNMENT_FACTOR ;
15
+ if (remain ) {
16
+ uint8_t plain_data_aligned_length = plain_data_length - remain + CRYPTO_ALIGNMENT_FACTOR ;
17
+ uint8_t * plain_data_aligned = malloc (plain_data_aligned_length );
18
+ memset (plain_data_aligned , 0 , plain_data_aligned_length );
19
+ memcpy (plain_data_aligned , plain_data , plain_data_length );
20
+
21
+ encrypted_data = malloc (plain_data_aligned_length );
22
+ * encrypted_data_length = plain_data_aligned_length ;
23
+
24
+ furi_hal_crypto_store_load_key (CRYPTO_KEY_SLOT , iv );
25
+ furi_hal_crypto_encrypt (plain_data_aligned , encrypted_data , plain_data_aligned_length );
26
+ furi_hal_crypto_store_unload_key (CRYPTO_KEY_SLOT );
27
+
28
+ memset (plain_data_aligned , 0 , plain_data_aligned_length );
29
+ free (plain_data_aligned );
30
+ } else {
31
+ encrypted_data = malloc (plain_data_length );
32
+ * encrypted_data_length = plain_data_length ;
33
+
34
+ furi_hal_crypto_store_load_key (CRYPTO_KEY_SLOT , iv );
35
+ furi_hal_crypto_encrypt (plain_data , encrypted_data , plain_data_length );
36
+ furi_hal_crypto_store_unload_key (CRYPTO_KEY_SLOT );
37
+ }
38
+
39
+ return encrypted_data ;
40
+ }
41
+
42
+ uint8_t * totp_crypto_decrypt (const uint8_t * encrypted_data , const uint8_t encrypted_data_length , const uint8_t * iv , uint8_t * decrypted_data_length ) {
43
+ * decrypted_data_length = encrypted_data_length ;
44
+ uint8_t * decrypted_data = malloc (* decrypted_data_length );
45
+ furi_hal_crypto_store_load_key (CRYPTO_KEY_SLOT , iv );
46
+ furi_hal_crypto_decrypt (encrypted_data , decrypted_data , encrypted_data_length );
47
+ furi_hal_crypto_store_unload_key (CRYPTO_KEY_SLOT );
48
+ return decrypted_data ;
49
+ }
50
+
51
+ void totp_crypto_seed_iv (PluginState * plugin_state , uint8_t * pin , uint8_t pin_length ) {
52
+ if (plugin_state -> crypto_verify_data == NULL ) {
53
+ FURI_LOG_D (LOGGING_TAG , "Generating new IV" );
54
+ furi_hal_random_fill_buf (& plugin_state -> base_iv [0 ], TOTP_IV_SIZE );
55
+ }
56
+
57
+ memcpy (& plugin_state -> iv [0 ], & plugin_state -> base_iv [0 ], TOTP_IV_SIZE );
58
+ if (pin != NULL && pin_length > 0 ) {
59
+ for (uint8_t i = 0 ; i < pin_length ; i ++ ) {
60
+ plugin_state -> iv [i ] = plugin_state -> iv [i ] ^ (uint8_t )(pin [i ] * (i + 1 ));
61
+ }
62
+ }
63
+
64
+ if (plugin_state -> crypto_verify_data == NULL ) {
65
+ FURI_LOG_D (LOGGING_TAG , "Generating crypto verify data" );
66
+ plugin_state -> crypto_verify_data = malloc (CRYPTO_VERIFY_KEY_LENGTH );
67
+ plugin_state -> crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH ;
68
+ Storage * storage = totp_open_storage ();
69
+ FlipperFormat * config_file = totp_open_config_file (storage );
70
+
71
+ plugin_state -> crypto_verify_data = totp_crypto_encrypt ((uint8_t * )CRYPTO_VERIFY_KEY , CRYPTO_VERIFY_KEY_LENGTH , & plugin_state -> iv [0 ], & plugin_state -> crypto_verify_data_length );
72
+
73
+ flipper_format_insert_or_update_hex (config_file , TOTP_CONFIG_KEY_BASE_IV , plugin_state -> base_iv , TOTP_IV_SIZE );
74
+ flipper_format_insert_or_update_hex (config_file , TOTP_CONFIG_KEY_CRYPTO_VERIFY , plugin_state -> crypto_verify_data , CRYPTO_VERIFY_KEY_LENGTH );
75
+ plugin_state -> pin_set = pin != NULL && pin_length > 0 ;
76
+ flipper_format_insert_or_update_bool (config_file , TOTP_CONFIG_KEY_PINSET , & plugin_state -> pin_set , 1 );
77
+ totp_close_config_file (config_file );
78
+ totp_close_storage ();
79
+ }
80
+ }
81
+
82
+ bool totp_crypto_verify_key (const PluginState * plugin_state ) {
83
+ uint8_t decrypted_key_length ;
84
+ uint8_t * decrypted_key = totp_crypto_decrypt (plugin_state -> crypto_verify_data , plugin_state -> crypto_verify_data_length , & plugin_state -> iv [0 ], & decrypted_key_length );
85
+
86
+ bool key_valid = true;
87
+ for (uint8_t i = 0 ; i < CRYPTO_VERIFY_KEY_LENGTH && key_valid ; i ++ ) {
88
+ if (decrypted_key [i ] != CRYPTO_VERIFY_KEY [i ]) key_valid = false;
89
+ }
90
+
91
+ return key_valid ;
92
+ }
0 commit comments