diff --git a/firmware/fsm.c b/firmware/fsm.c
index 7d9b72d440..0b08e1d18b 100644
--- a/firmware/fsm.c
+++ b/firmware/fsm.c
@@ -46,6 +46,7 @@
 #include "ripemd160.h"
 #include "curves.h"
 #include "secp256k1.h"
+#include <libopencm3/stm32/flash.h>
 
 // message methods
 
@@ -975,4 +976,41 @@ void fsm_msgDebugLinkStop(DebugLinkStop *msg)
 	(void)msg;
 }
 
+void fsm_msgDebugLinkMemoryRead(DebugLinkMemoryRead *msg)
+{
+	RESP_INIT(DebugLinkMemory);
+
+	uint32_t length = 1024;
+	if (msg->has_length && msg->length < length)
+		length = msg->length;
+	resp->has_memory = true;
+	memcpy(resp->memory.bytes, (void*) msg->address, length);
+	resp->memory.size = length;
+	msg_debug_write(MessageType_MessageType_DebugLinkMemory, resp);
+}
+
+void fsm_msgDebugLinkMemoryWrite(DebugLinkMemoryWrite *msg)
+{
+	uint32_t length = msg->memory.size;
+	if (msg->flash) {
+		flash_clear_status_flags();
+		flash_unlock();
+		uint32_t* src = (uint32_t *) msg->memory.bytes;
+		for (unsigned int i = 0; i < length; i += 4) {
+			flash_program_word(msg->address +  i, *src);
+			src++;
+		}
+		flash_lock();
+	} else {
+		memcpy((void *) msg->address, msg->memory.bytes, length);
+	}
+}
+
+void fsm_msgDebugLinkFlashErase(DebugLinkFlashErase *msg)
+{
+	flash_clear_status_flags();
+	flash_unlock();
+	flash_erase_sector(msg->sector, FLASH_CR_PROGRAM_X32);
+	flash_lock();
+}
 #endif
diff --git a/firmware/fsm.h b/firmware/fsm.h
index 1a3fcf8f1e..5b6eef971e 100644
--- a/firmware/fsm.h
+++ b/firmware/fsm.h
@@ -63,6 +63,9 @@ void fsm_msgWordAck(WordAck *msg);
 //void fsm_msgDebugLinkDecision(DebugLinkDecision *msg);
 void fsm_msgDebugLinkGetState(DebugLinkGetState *msg);
 void fsm_msgDebugLinkStop(DebugLinkStop *msg);
+void fsm_msgDebugLinkMemoryWrite(DebugLinkMemoryWrite *msg);
+void fsm_msgDebugLinkMemoryRead(DebugLinkMemoryRead *msg);
+void fsm_msgDebugLinkFlashErase(DebugLinkFlashErase *msg);
 #endif
 
 #endif
diff --git a/firmware/messages.c b/firmware/messages.c
index 1994f61a78..57c311151d 100644
--- a/firmware/messages.c
+++ b/firmware/messages.c
@@ -97,9 +97,13 @@ static const struct MessagesMap_t MessagesMap[] = {
 //	{'d', 'i', MessageType_MessageType_DebugLinkDecision,	DebugLinkDecision_fields,	(void (*)(void *))fsm_msgDebugLinkDecision},
 	{'d', 'i', MessageType_MessageType_DebugLinkGetState,	DebugLinkGetState_fields,	(void (*)(void *))fsm_msgDebugLinkGetState},
 	{'d', 'i', MessageType_MessageType_DebugLinkStop,		DebugLinkStop_fields,		(void (*)(void *))fsm_msgDebugLinkStop},
+	{'d', 'i', MessageType_MessageType_DebugLinkMemoryRead,	DebugLinkMemoryRead_fields,	(void (*)(void *))fsm_msgDebugLinkMemoryRead},
+	{'d', 'i', MessageType_MessageType_DebugLinkMemoryWrite, DebugLinkMemoryWrite_fields, (void (*)(void *))fsm_msgDebugLinkMemoryWrite},
+	{'d', 'i', MessageType_MessageType_DebugLinkFlashErase,	DebugLinkFlashErase_fields,	(void (*)(void *))fsm_msgDebugLinkFlashErase},
 	// debug out messages
 	{'d', 'o', MessageType_MessageType_DebugLinkState,		DebugLinkState_fields,		0},
 	{'d', 'o', MessageType_MessageType_DebugLinkLog,		DebugLinkLog_fields,		0},
+	{'d', 'o', MessageType_MessageType_DebugLinkMemory,		DebugLinkMemory_fields,		0},
 #endif
 	// end
 	{0, 0, 0, 0, 0}