Explorar o código

Add demo encryption of messages

twisted_pear %!s(int64=2) %!d(string=hai) anos
pai
achega
bea1106276
Modificáronse 3 ficheiros con 92 adicións e 95 borrados
  1. 0 46
      crypto/aes-gcm.c
  2. 0 18
      crypto/aes-gcm.h
  3. 92 31
      esubghz_chat.c

+ 0 - 46
crypto/aes-gcm.c

@@ -1,46 +0,0 @@
-//
-//  aes-gcm.c
-//  Pods
-//
-//  Created by Markus Kosmal on 20/11/14.
-//
-//
-
-#include "aes-gcm.h"
-
-int aes_gcm_encrypt(unsigned char* output, const unsigned char* input, int input_length, const unsigned char* key, const size_t key_len, const unsigned char * iv, const size_t iv_len){
-    
-    int ret = 0;                // our return value
-    gcm_context ctx;            // includes the AES context structure
-    
-    size_t tag_len = 0;
-    unsigned char * tag_buf = NULL;
-    
-    gcm_setkey( &ctx, key, (const uint)key_len );
-    
-    ret = gcm_crypt_and_tag( &ctx, ENCRYPT, iv, iv_len, NULL, 0,
-                            input, output, input_length, tag_buf, tag_len);
-    
-    gcm_zero_ctx( &ctx );
-    
-    return( ret );
-}
-
-int aes_gcm_decrypt(unsigned char* output, const unsigned char* input, int input_length, const unsigned char* key, const size_t key_len, const unsigned char * iv, const size_t iv_len){
-    
-    int ret = 0;                // our return value
-    gcm_context ctx;            // includes the AES context structure
-    
-    size_t tag_len = 0;
-    unsigned char * tag_buf = NULL;
-    
-    gcm_setkey( &ctx, key, (const uint)key_len );
-    
-    ret = gcm_crypt_and_tag( &ctx, DECRYPT, iv, iv_len, NULL, 0,
-                            input, output, input_length, tag_buf, tag_len);
-    
-    gcm_zero_ctx( &ctx );
-    
-    return( ret );
-
-}

+ 0 - 18
crypto/aes-gcm.h

@@ -1,18 +0,0 @@
-//
-//  aes-gcm.h
-//  MKo
-//
-//  Created by Markus Kosmal on 20/11/14.
-//
-//
-
-#ifndef mko_aes_gcm_h
-#define mko_aes_gcm_h
-
-#include "gcm.h"  
-
-int aes_gcm_encrypt(unsigned char* output, const unsigned char* input, int input_length, const unsigned char* key, const size_t key_len, const unsigned char * iv, const size_t iv_len);
-
-int aes_gcm_decrypt(unsigned char* output, const unsigned char* input, int input_length, const unsigned char* key, const size_t key_len, const unsigned char * iv, const size_t iv_len);
-
-#endif

+ 92 - 31
esubghz_chat.c

@@ -7,12 +7,15 @@
 #include <gui/scene_manager.h>
 #include <toolbox/sha256.h>
 
-#include "crypto/aes-gcm.h"
+#include "crypto/gcm.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
 #define TEXT_INPUT_STORE_SIZE 512
@@ -28,7 +31,8 @@ typedef struct {
 	FuriString *msg_input;
 	bool encrypted;
 	uint32_t frequency;
-	unsigned char key[KEY_BITS / 8];
+	gcm_context gcm_ctx;
+	uint8_t tx_buffer[RX_TX_BUFFER_SIZE];
 } ESubGhzChatState;
 
 typedef enum {
@@ -61,7 +65,7 @@ static void freq_input_cb(void *context)
 	furi_assert(context);
 	ESubGhzChatState* state = context;
 
-	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu\n",
+	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
 			state->frequency);
 
 	scene_manager_handle_custom_event(state->scene_manager,
@@ -103,47 +107,104 @@ static void pass_input_cb(void *context)
 	furi_assert(context);
 	ESubGhzChatState* state = context;
 
-	if (strlen(state->text_input_store) == 0) {
-		state->encrypted = false;
-	} else {
-		state->encrypted = true;
-		sha256((unsigned char *) state->text_input_store,
-				strlen(state->text_input_store), state->key);
-
-		// TODO: remove this
-		furi_string_cat_printf(state->chat_box_store, "Key:");
-		int i;
-		for (i = 0; i < KEY_BITS / 8; i++) {
-			furi_string_cat_printf(state->chat_box_store, " %02x",
-					state->key[i]);
-		}
-		furi_string_cat_printf(state->chat_box_store, "\n");
-	}
-
-	furi_string_cat_printf(state->chat_box_store, "Encrypted: %s\n",
+	furi_string_cat_printf(state->chat_box_store, "\nEncrypted: %s",
 			(state->encrypted ? "true" : "false"));
 
 	scene_manager_handle_custom_event(state->scene_manager,
 			ESubGhzChatEvent_PassEntered);
 }
 
+static bool pass_input_validator(const char *text, FuriString *error,
+		void *context)
+{
+	furi_assert(text);
+	furi_assert(error);
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	if (strlen(text) == 0) {
+		state->encrypted = false;
+		return true;
+	}
+
+	unsigned char key[KEY_BITS / 8];
+
+	state->encrypted = true;
+	sha256((unsigned char *) text, strlen(text), key);
+
+	// TODO: remove this
+	furi_string_cat_printf(state->chat_box_store, "\nKey:");
+	int i;
+	for (i = 0; i < KEY_BITS / 8; i++) {
+		furi_string_cat_printf(state->chat_box_store, " %02x", key[i]);
+	}
+
+	int ret = gcm_setkey(&(state->gcm_ctx), key, KEY_BITS / 8);
+
+	esubghz_chat_explicit_bzero(key, sizeof(key));
+
+	if (ret != 0) {
+		gcm_zero_ctx(&(state->gcm_ctx));
+		furi_string_printf(error, "Failed to\nset key!");
+		return false;
+	}
+
+	return true;
+}
+
 static void chat_input_cb(void *context)
 {
 	furi_assert(context);
 	ESubGhzChatState* state = context;
 
-	if (strlen(state->text_input_store) > 0) {
-		furi_string_set(state->msg_input, state->name_prefix);
-		furi_string_cat_str(state->msg_input, state->text_input_store);
+	if (strlen(state->text_input_store) == 0) {
+		scene_manager_handle_custom_event(state->scene_manager,
+				ESubGhzChatEvent_MsgEntered);
+		return;
+	}
 
-		furi_string_cat_printf(state->chat_box_store, "%s\n",
-			furi_string_get_cstr(state->msg_input));
+	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, state->text_input_store);
+
+	furi_string_cat_printf(state->chat_box_store, "\n%s",
+		furi_string_get_cstr(state->msg_input));
+
+	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;
+		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 *)
+				furi_string_get_cstr(state->msg_input),
+				state->tx_buffer + IV_BYTES,
+				msg_len,
+				state->tx_buffer + IV_BYTES + msg_len,
+				TAG_BYTES);
+	} else {
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+		memcpy(state->tx_buffer,
+				furi_string_get_cstr(state->msg_input),
+				tx_size);
+	}
 
-		// TODO: actually transmit
+	furi_string_set_char(state->msg_input, 0, 0);
 
-		furi_string_set_char(state->msg_input, 0, 0);
+	// TODO: remove this
+	furi_string_cat_printf(state->chat_box_store, "\nTXed (HEX):");
+	size_t i;
+	for (i = 0; i < tx_size; i++) {
+		furi_string_cat_printf(state->chat_box_store, " %02x",
+				state->tx_buffer[i]);
 	}
 
+	// TODO: actually transmit
+
 	scene_manager_handle_custom_event(state->scene_manager,
 			ESubGhzChatEvent_MsgEntered);
 }
@@ -237,8 +298,8 @@ static void scene_on_enter_pass_input(void* context)
 			true);
 	text_input_set_validator(
 			state->text_input,
-			NULL,
-			NULL);
+			pass_input_validator,
+			state);
 	text_input_set_header_text(
 			state->text_input,
 			"Password (empty for no encr.)");
@@ -569,9 +630,9 @@ int32_t esubghz_chat(void)
 	view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_ChatBox);
 
 	// clear the key and potential password
-	esubghz_chat_explicit_bzero(state->key, sizeof(state->key));
 	esubghz_chat_explicit_bzero(state->text_input_store,
 			sizeof(state->text_input_store));
+	gcm_zero_ctx(&(state->gcm_ctx));
 
 	chat_box_free(state);