|
|
@@ -14,16 +14,12 @@
|
|
|
|
|
|
#include "esubghz_chat_icons.h"
|
|
|
|
|
|
-#include "crypto/gcm.h"
|
|
|
+#include "crypto_wrapper.h"
|
|
|
|
|
|
#define APPLICATION_NAME "ESubGhzChat"
|
|
|
|
|
|
#define DEFAULT_FREQ 433920000
|
|
|
|
|
|
-#define KEY_BITS 256
|
|
|
-#define IV_BYTES 12
|
|
|
-#define TAG_BYTES 16
|
|
|
-
|
|
|
#define RX_TX_BUFFER_SIZE 1024
|
|
|
|
|
|
#define CHAT_BOX_STORE_SIZE 4096
|
|
|
@@ -59,7 +55,7 @@ typedef struct {
|
|
|
|
|
|
// encryption
|
|
|
bool encrypted;
|
|
|
- gcm_context gcm_ctx;
|
|
|
+ ESubGhzChatCryptoCtx *crypto_ctx;
|
|
|
|
|
|
// RX and TX buffers
|
|
|
uint8_t rx_buffer[RX_TX_BUFFER_SIZE];
|
|
|
@@ -95,13 +91,6 @@ typedef enum {
|
|
|
ESubGhzChatEvent_MsgEntered
|
|
|
} ESubGhzChatEvent;
|
|
|
|
|
|
-/* Function to clear sensitive memory. */
|
|
|
-static void esubghz_chat_explicit_bzero(void *s, size_t len)
|
|
|
-{
|
|
|
- memset(s, 0, len);
|
|
|
- asm volatile("" ::: "memory");
|
|
|
-}
|
|
|
-
|
|
|
/* Callback for RX events from the Sub-GHz worker. Records the current ticks as
|
|
|
* the time of the last reception. */
|
|
|
static void have_read_cb(void* context)
|
|
|
@@ -115,21 +104,17 @@ static void have_read_cb(void* context)
|
|
|
/* Decrypts a message for post_rx(). */
|
|
|
static bool post_rx_decrypt(ESubGhzChatState *state, size_t rx_size)
|
|
|
{
|
|
|
- if (rx_size < IV_BYTES + TAG_BYTES + 1) {
|
|
|
- return false;
|
|
|
+ bool ret = crypto_ctx_decrypt(state->crypto_ctx,
|
|
|
+ state->rx_buffer, rx_size,
|
|
|
+ (uint8_t*) state->rx_str_buffer);
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ state->rx_str_buffer[rx_size - (MSG_OVERHEAD)] = 0;
|
|
|
+ } else {
|
|
|
+ state->rx_str_buffer[0] = 0;
|
|
|
}
|
|
|
|
|
|
- int ret = gcm_auth_decrypt(&(state->gcm_ctx),
|
|
|
- state->rx_buffer, IV_BYTES,
|
|
|
- NULL, 0,
|
|
|
- state->rx_buffer + IV_BYTES,
|
|
|
- (uint8_t *) state->rx_str_buffer,
|
|
|
- rx_size - (IV_BYTES + TAG_BYTES),
|
|
|
- state->rx_buffer + rx_size - TAG_BYTES,
|
|
|
- TAG_BYTES);
|
|
|
- state->rx_str_buffer[rx_size - (IV_BYTES + TAG_BYTES)] = 0;
|
|
|
-
|
|
|
- return (ret == 0);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/* Post RX handler, decrypts received messages, displays them in the text box
|
|
|
@@ -182,19 +167,14 @@ static void tx_msg_input(ESubGhzChatState *state)
|
|
|
size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
|
|
|
size_t tx_size = msg_len;
|
|
|
if (state->encrypted) {
|
|
|
- tx_size += IV_BYTES + TAG_BYTES;
|
|
|
+ tx_size += MSG_OVERHEAD;
|
|
|
furi_check(tx_size <= sizeof(state->tx_buffer));
|
|
|
|
|
|
- furi_hal_random_fill_buf(state->tx_buffer, IV_BYTES);
|
|
|
- gcm_crypt_and_tag(&(state->gcm_ctx), ENCRYPT,
|
|
|
- state->tx_buffer, IV_BYTES,
|
|
|
- NULL, 0,
|
|
|
- (unsigned char *)
|
|
|
+ crypto_ctx_encrypt(state->crypto_ctx,
|
|
|
+ (uint8_t *)
|
|
|
furi_string_get_cstr(state->msg_input),
|
|
|
- state->tx_buffer + IV_BYTES,
|
|
|
msg_len,
|
|
|
- state->tx_buffer + IV_BYTES + msg_len,
|
|
|
- TAG_BYTES);
|
|
|
+ state->tx_buffer);
|
|
|
} else {
|
|
|
tx_size += 2;
|
|
|
furi_check(tx_size <= sizeof(state->tx_buffer));
|
|
|
@@ -275,7 +255,7 @@ static void pass_input_cb(void *context)
|
|
|
(state->encrypted ? "yes" : "no"));
|
|
|
|
|
|
/* clear the text input buffer to remove the password */
|
|
|
- esubghz_chat_explicit_bzero(state->text_input_store,
|
|
|
+ crypto_explicit_bzero(state->text_input_store,
|
|
|
sizeof(state->text_input_store));
|
|
|
|
|
|
subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device,
|
|
|
@@ -326,15 +306,14 @@ static bool pass_input_validator(const char *text, FuriString *error,
|
|
|
/* derive a key from the password */
|
|
|
sha256((unsigned char *) text, strlen(text), key);
|
|
|
|
|
|
- /* initiate the AES-GCM context */
|
|
|
- int ret = gcm_setkey(&(state->gcm_ctx), key, KEY_BITS / 8);
|
|
|
+ /* initiate the crypto context */
|
|
|
+ bool ret = crypto_ctx_set_key(state->crypto_ctx, key);
|
|
|
|
|
|
/* cleanup */
|
|
|
- esubghz_chat_explicit_bzero(key, sizeof(key));
|
|
|
+ crypto_explicit_bzero(key, sizeof(key));
|
|
|
|
|
|
- if (ret != 0) {
|
|
|
- esubghz_chat_explicit_bzero(&(state->gcm_ctx),
|
|
|
- sizeof(state->gcm_ctx));
|
|
|
+ if (!ret) {
|
|
|
+ crypto_ctx_clear(state->crypto_ctx);
|
|
|
furi_string_printf(error, "Failed to\nset key!");
|
|
|
return false;
|
|
|
}
|
|
|
@@ -964,8 +943,8 @@ static void chat_box_free(ESubGhzChatState *state)
|
|
|
|
|
|
int32_t esubghz_chat(void)
|
|
|
{
|
|
|
- /* init the GCM and AES tables */
|
|
|
- gcm_initialize();
|
|
|
+ /* init the crypto system */
|
|
|
+ crypto_init();
|
|
|
|
|
|
int32_t err = -1;
|
|
|
|
|
|
@@ -1008,6 +987,11 @@ int32_t esubghz_chat(void)
|
|
|
goto err_alloc_worker;
|
|
|
}
|
|
|
|
|
|
+ state->crypto_ctx = crypto_ctx_alloc();
|
|
|
+ if (state->crypto_ctx == NULL) {
|
|
|
+ goto err_alloc_crypto;
|
|
|
+ }
|
|
|
+
|
|
|
/* set the have_read callback of the Sub-GHz worker */
|
|
|
subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker,
|
|
|
have_read_cb, state);
|
|
|
@@ -1089,9 +1073,9 @@ int32_t esubghz_chat(void)
|
|
|
furi_record_close(RECORD_NOTIFICATION);
|
|
|
|
|
|
/* clear the key and potential password */
|
|
|
- esubghz_chat_explicit_bzero(state->text_input_store,
|
|
|
+ crypto_explicit_bzero(state->text_input_store,
|
|
|
sizeof(state->text_input_store));
|
|
|
- esubghz_chat_explicit_bzero(&(state->gcm_ctx), sizeof(state->gcm_ctx));
|
|
|
+ crypto_ctx_clear(state->crypto_ctx);
|
|
|
|
|
|
/* deinit devices */
|
|
|
subghz_devices_deinit();
|
|
|
@@ -1101,6 +1085,9 @@ int32_t esubghz_chat(void)
|
|
|
|
|
|
/* free everything we allocated */
|
|
|
|
|
|
+ crypto_ctx_free(state->crypto_ctx);
|
|
|
+
|
|
|
+err_alloc_crypto:
|
|
|
subghz_tx_rx_worker_free(state->subghz_worker);
|
|
|
|
|
|
err_alloc_worker:
|