diff --git a/Control/cardreader_interface.c b/Control/cardreader_interface.c
index ce7310947f508a1929b8e6a3967b560aad57456b..eb09d687a3877cb875c23df79c1f246b13b98ef0 100644
--- a/Control/cardreader_interface.c
+++ b/Control/cardreader_interface.c
@@ -13,7 +13,7 @@
 #define CARD_AUTH_APPLET_NAME "\x23\x23\x00\x42\x42"
 #define CARD_STATUS_SUCCESS    0x9000
 
-
+//#define CARDREADER_DEBUG
 
 /** Card auth protcol
  * 1. Host -> Card:   CARD_CMD_SELECT_APPLET
@@ -239,7 +239,9 @@ void cardreader_auth_request(){
 	cardreader_card_message_t msg = {CARDREADER_MSG_TYPE_CARD};
 	memcpy(&msg.header, CARD_CMD_AUTH, sizeof(ISO7816_APDU_Header));
 	memcpy(&msg.body, keystore_get_salt(), sizeof(SALT));
+#ifdef CARDREADER_DEBUG
 	MGMT_transmit_buffer_hex((uint8_t*)&msg, 1+sizeof(ISO7816_APDU_Header)+sizeof(SALT)); 
+#endif
 	transport_send_message((uint8_t*)&msg, 1+sizeof(ISO7816_APDU_Header)+sizeof(SALT));
 }
 
@@ -248,14 +250,19 @@ uint8_t cardreader_auth_request_result(uint8_t* msg_buffer, uint8_t length){
 	uint8_t ret = check_card_status(msg_buffer, length, sizeof(HASH)+sizeof(SALT));
 	if (!ret) {cardreader_display_show_result(0); return 0;}
 	
+#ifdef CARDREADER_DEBUG
 	printf_P(PSTR("Msg Response: "));
 	MGMT_transmit_buffer_hex(msg_buffer, length);
 	printf_P(PSTR("\n"));
+#endif
 	
 	uint8_t* keyhash = CARD_RESULT_BODY(msg_buffer);
 	memcpy(card_challenge, (CARD_RESULT_BODY(msg_buffer) + sizeof(HASH)), sizeof(SALT));
 	
-	printf_P(PSTR("Card Response: ")); MGMT_transmit_buffer_hex(keyhash, sizeof(HASH));
+	printf_P(PSTR("Card Response: "));
+#ifdef CARDREADER_DEBUG
+	MGMT_transmit_buffer_hex(keyhash, sizeof(HASH));
+#endif
 	
 	keyslot_index = keystore_find_key(keyhash);
 	if (keyslot_index == -1){
@@ -266,8 +273,10 @@ uint8_t cardreader_auth_request_result(uint8_t* msg_buffer, uint8_t length){
 	}
 	printf_P(PSTR(" Valid! (Slot: %i) :)\n"), keyslot_index);
 	
+#ifdef CARDREADER_DEBUG
 	printf_P(PSTR("Card Challange: ")); MGMT_transmit_buffer_hex(card_challenge, sizeof(SALT));
 	printf_P(PSTR("\n"));
+#endif
 	
 	cardreader_display_show_result(1);
 	return 1;
@@ -284,21 +293,27 @@ void cardreader_update_key(){
 	cardreader_display_write_sz_P(PSTR("Updating Key..."));
 	
 	keystore_gen_keydelta(new_key_delta);
+#ifdef CARDREADER_DEBUG
 	printf_P(PSTR("KeyDelta: "));
 	MGMT_transmit_buffer_hex(new_key_delta, sizeof(KEY));
+#endif
 	memcpy(&msg.body, new_key_delta, sizeof(KEY));
 	
 	uint8_t ret = keystore_calc_keyhash(keyslot_index, card_challenge, card_challenge_response);
 	if (ret){
+#ifdef CARDREADER_DEBUG
 		printf_P(PSTR("\nChallange Response: "));
 		MGMT_transmit_buffer_hex(card_challenge_response, sizeof(HASH));
+#endif
 		memcpy(((uint8_t*)(&msg.body)) + sizeof(KEY), card_challenge_response, sizeof(HASH));
+#ifdef CARDREADER_DEBUG
 		printf_P(PSTR(" "));
 		
 		MGMT_transmit_buffer_hex((uint8_t*)&msg, 1+sizeof(ISO7816_APDU_Header)+ sizeof(KEY)+sizeof(HASH));
+#endif
 		transport_send_message((uint8_t*)&msg, 1+sizeof(ISO7816_APDU_Header)+ sizeof(KEY)+sizeof(HASH));
 	} else {
-		
+		printf_P(PSTR("Failed to calculate key hash.\n"));
 	}
 }
 
@@ -333,6 +348,36 @@ uint8_t cardreader_update_key_result(uint8_t* msg_buffer, uint8_t length){
 	return 1;
 }
 
+uint8_t cardreader_init_card_key(KEY key){
+	cardreader_card_message_t msg = {CARDREADER_MSG_TYPE_CARD};
+	memcpy(&msg.header, CARD_CMD_INIT_KEY, sizeof(ISO7816_APDU_Header));
+	memcpy(&msg.body, key, sizeof(KEY));
+	transport_send_message((uint8_t*)&msg, 1+sizeof(ISO7816_APDU_Header)+ sizeof(KEY));
+	
+	uint8_t card_status[4];
+	uint16_t length = transport_receive_message(&card_status, 4, 3000);
+	if (TRANSPORT_IS_ERROR(length)){
+		printf_P(PSTR("Transport Error %04x\n"), length);
+		return 0;
+	} else {
+		return check_card_status(card_status, length, 0);
+	}
+}
+
+uint8_t cardreader_clear_card_key(void){
+	cardreader_card_message_t msg = {CARDREADER_MSG_TYPE_CARD};
+	memcpy(&msg.header, CARD_CMD_CLEAR_KEY, sizeof(ISO7816_APDU_Header));
+	transport_send_message((uint8_t*)&msg, 1+sizeof(ISO7816_APDU_Header));
+	
+	uint8_t card_status[4];
+	uint16_t length = transport_receive_message(&card_status, 4, 3000);
+	if (TRANSPORT_IS_ERROR(length)){
+		printf_P(PSTR("Transport Error %04x\n"), length);
+		return 0;
+	} else {
+		return check_card_status(card_status, length, 0);
+	}
+}
 
 void cardreader_timeout(void){
 	printf_P(PSTR(" Timeout\n"));
diff --git a/Control/cardreader_interface.h b/Control/cardreader_interface.h
index 0ab374d866708f4756da3468f5a2991ca9ea8f65..8843bdf5d341f2531639f2ee408d220099178243 100644
--- a/Control/cardreader_interface.h
+++ b/Control/cardreader_interface.h
@@ -21,3 +21,6 @@ void card_power_request_pin_changed(uint8_t power_request);
 
 void cardreader_process(void);
 void cardreader_tick(void);
+
+uint8_t cardreader_init_card_key(KEY key);
+uint8_t cardreader_clear_card_key(void);
\ No newline at end of file
diff --git a/Control/keystore.c b/Control/keystore.c
index 126dc2e861175d40280298181bd2b35667c95f35..0f26e4314e1f0860e988c1a0115bf7f5a2269d1c 100644
--- a/Control/keystore.c
+++ b/Control/keystore.c
@@ -4,6 +4,11 @@
 void keystore_update_hashes(SALT salt);
 uint8_t keystore_read_key(uint16_t index, KEY key);
 uint8_t keystore_write_key(uint16_t index, KEY key);
+uint8_t keystore_read_backup_key(uint16_t index, KEY key);
+uint8_t keystore_write_backup_key(uint16_t index, KEY key);
+uint8_t keystore_eeprom_read(uint8_t eeprom, uint16_t offset, uint8_t* buffer, uint8_t length);
+uint8_t keystore_eeprom_write(uint8_t eeprom, uint16_t offset, uint8_t* buffer, uint8_t length);
+
 void xor(uint8_t* src1dest, uint8_t* src2, uint8_t length);
 
 static SALT salt;
@@ -34,7 +39,7 @@ int16_t keystore_find_key(HASH keyhash){
 	for (uint16_t index = 0; index < KEY_COUNT; index++){
 		
 		//TODO: No need to compare for empty keyslots.
-		if (memcmp(hashes[index], keyhash, sizeof(HASH_HEAD)) == 0){
+		if (memcmp(&(hashes[index]), keyhash, sizeof(HASH_HEAD)) == 0){
 			if (keystore_read_slot_status(index) == KEYSLOT_USED){
 				if (keystore_calc_keyhash(index, salt, refhash)){
 					if (memcmp(refhash, keyhash, sizeof(HASH)) == 0){
@@ -60,6 +65,7 @@ void keystore_gen_keydelta(KEY keydelta){
 uint8_t keystore_update_slot(uint16_t index, KEY keydelta){
 	KEY key;
 	if (!keystore_read_key(index, key)) return 0;
+	keystore_write_backup_key(index, key); //Backup old key.
 	xor(key, keydelta, sizeof(KEY));
 	if (!keystore_write_key(index, key)) return 0;
 	return 1;
@@ -74,19 +80,57 @@ void keystore_update_hashes(SALT salt){
 	for (uint16_t index = 0; index < KEY_COUNT; index++){
 		wdt_reset(); //this may take a while, keep the Watchdog happy.
 		
+#ifdef KEYSTORE_DEBUG
 		printf_P(PSTR("Debug: Slot %03i: "), index);
+#endif
 		uint8_t slot_status = keystore_read_slot_status(index);
 		if (slot_status == KEYSLOT_USED || slot_status == KEYSLOT_DISABLED){
 			keystore_read_key(index, buffer);
 			
+#ifdef KEYSTORE_DEBUG
 			printf_P(PSTR("K:"));
-			MGMT_transmit_buffer_hex(buffer, 20);
+			MGMT_transmit_buffer_hex(buffer, 8);
+#endif
 			
-			sha1(&fullhash, buffer, (sizeof(KEY) + sizeof(SALT))*8);
-			memcpy(hashes[index], fullhash, sizeof(HASH_HEAD));
+			sha1(fullhash, buffer, (sizeof(KEY) + sizeof(SALT))*8);
+			memcpy(&(hashes[index]), fullhash, sizeof(HASH_HEAD));
 			
+#ifdef KEYSTORE_DEBUG
 			printf_P(PSTR(" H:"));
-			MGMT_transmit_buffer_hex(fullhash, sizeof(HASH_HEAD));
+			MGMT_transmit_buffer_hex(&hashes[index], sizeof(HASH_HEAD));
+			
+			if (slot_status == KEYSLOT_DISABLED){
+				printf_P(PSTR(" (Disabled)"));
+			}
+			
+			printf_P(PSTR("\n"));
+			
+		} else if (slot_status == KEYSLOT_EMPTY){
+			printf_P(PSTR("Empty\n"));
+		} else if (slot_status == KEYSLOT_ERROR){
+			printf_P(PSTR("Read Error\n"));
+		} else {
+			printf_P(PSTR("Unknown (%02x)\n"), slot_status);
+#endif
+		}
+	}
+}
+
+void keystore_list(void){
+	KEY key;
+	for (uint16_t index = 0; index < KEY_COUNT; index++){
+		wdt_reset(); //this may take a while, keep the Watchdog happy.
+		
+		printf_P(PSTR("Slot %03i: "), index);
+		uint8_t slot_status = keystore_read_slot_status(index);
+		if (slot_status == KEYSLOT_USED || slot_status == KEYSLOT_DISABLED){
+			keystore_read_key(index, key);
+			
+			printf_P(PSTR("K:"));
+			MGMT_transmit_buffer_hex(key, 8);
+			
+			printf_P(PSTR(" H:"));
+			MGMT_transmit_buffer_hex(&(hashes[index]), sizeof(HASH_HEAD));
 			
 			if (slot_status == KEYSLOT_DISABLED){
 				printf_P(PSTR(" (Disabled)"));
@@ -109,13 +153,31 @@ uint8_t keystore_calc_keyhash(uint16_t index, SALT salt, HASH keyhash){
 	uint8_t ret = keystore_read_key(index, buffer);
 	if (ret == 0) return 0;
 	memcpy(buffer+sizeof(KEY), salt, sizeof(SALT));
+#ifdef KEYSTORE_DEBUG
 	printf_P(PSTR("sha1("));
 	MGMT_transmit_buffer_hex(buffer, sizeof(SALT)+sizeof(KEY));
 	printf_P(PSTR(")\n"));
+#endif
 	sha1(keyhash, buffer, (sizeof(SALT)+sizeof(KEY))*8);
 	return 1;
 }
 
+uint8_t keystore_restore_slot(uint16_t index){
+	KEY key;
+	if (!keystore_read_backup_key(index, key)) return 0;
+	if (!keystore_write_key(index, key))       return 0;
+	
+	uint8_t status;
+	if (!keystore_eeprom_read(KEY_BACKUP_EEPROM, EEPROM_TABLE_OFFSET + index, &status, sizeof(uint8_t))) return 0;
+	if (!keystore_eeprom_write(KEY_MAIN_EEPROM,  EEPROM_TABLE_OFFSET + index, &status, sizeof(uint8_t))) return 0;
+	
+	if (status == KEYSLOT_USED || status == KEYSLOT_DISABLED){
+		keystore_calc_keyhash(index, salt, &hashes[index]);
+	}
+	
+	return 1;
+}
+
 void xor(uint8_t* src1dest, uint8_t* src2, uint8_t length){
 	for (uint8_t i = 0; i < length; i++){
 		src1dest[i] ^= src2[i];
@@ -151,7 +213,7 @@ uint8_t keystore_init_slot(uint16_t index, KEY keyout){
 	
 	HASH fullhash;
 	sha1(&fullhash, keyout, (sizeof(KEY) + sizeof(SALT))*8);
-	memcpy(hashes[index], fullhash, sizeof(HASH_HEAD));
+	memcpy(&hashes[index], fullhash, sizeof(HASH_HEAD));
 	
 	return 1;
 }
@@ -173,7 +235,7 @@ uint8_t keystore_init_slot_empty(uint16_t index, KEY keyout){
 	
 	HASH fullhash;
 	sha1(&fullhash, keyout, (sizeof(KEY) + sizeof(SALT))*8);
-	memcpy(hashes[index], fullhash, sizeof(HASH_HEAD));
+	memcpy(&hashes[index], fullhash, sizeof(HASH_HEAD));
 	
 	return 1;
 }
@@ -200,59 +262,62 @@ uint8_t keystore_enable_slot(uint16_t index){
 
 uint8_t keystore_read_slot_status(uint16_t index){
 	uint8_t key_status = KEYSLOT_ERROR;
-	uint8_t ret;
-	i2c_master_set_speed(I2C_BITRATE_REG_1M);
-	ret = i2c_master_read(KEY_MAIN_EEPROM, EEPROM_TABLE_OFFSET + index, sizeof(uint16_t), &key_status, sizeof(uint8_t));
-	if (ret != I2C_SUCCESS) {
-		printf_P(PSTR("Key status read error %02x, retry...\n"), ret);
-		ret = i2c_master_read(KEY_MAIN_EEPROM, EEPROM_TABLE_OFFSET + index, sizeof(uint16_t), &key_status, sizeof(uint8_t));
-		if (ret != I2C_SUCCESS) printf_P(PSTR("Key status read error %02x (fatal)\n"), ret);
-	}
-	return (ret == I2C_SUCCESS) ? key_status : KEYSLOT_ERROR;
+	uint8_t ret = keystore_eeprom_read(KEY_MAIN_EEPROM, EEPROM_TABLE_OFFSET + index, &key_status, sizeof(uint8_t));
+	return (ret == 1) ? key_status : KEYSLOT_ERROR;
 }
 
 uint8_t keystore_write_slot_status(uint16_t index, uint8_t key_status){
-	uint8_t ret;
-	EEPROM_WRITE_PROTECT_PORT &= ~EEPROM_WRITE_PROTECT_MAIN;
-	
-	i2c_master_set_speed(I2C_BITRATE_REG_1M);
-	ret = i2c_master_write(KEY_MAIN_EEPROM, EEPROM_TABLE_OFFSET + index, sizeof(uint16_t), &key_status, sizeof(uint8_t));
-	if (ret != 0) {
-		printf_P(PSTR("Key status write error %02x, retry...\n"), ret);
-		ret = i2c_master_write(KEY_MAIN_EEPROM, EEPROM_TABLE_OFFSET + index, sizeof(uint16_t), &key_status, 1);
-		if (ret != I2C_SUCCESS) printf_P(PSTR("Key status write error %02x (fatal)\n"), ret);
-	}
-	
-	EEPROM_WRITE_PROTECT_PORT |= EEPROM_WRITE_PROTECT_MAIN;
-	
-	return (ret == I2C_SUCCESS) ? key_status : KEYSLOT_ERROR;
+	uint8_t ret = keystore_eeprom_write(KEY_MAIN_EEPROM,  EEPROM_TABLE_OFFSET + index, &key_status, sizeof(uint8_t));
+	keystore_eeprom_write(KEY_BACKUP_EEPROM,  EEPROM_TABLE_OFFSET + index, &key_status, sizeof(uint8_t));
+	return (ret == 1) ? key_status : KEYSLOT_ERROR;
 }
 
 uint8_t keystore_read_key(uint16_t index, KEY key){
+	return keystore_eeprom_read(KEY_MAIN_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), key, sizeof(KEY));
+}
+uint8_t keystore_read_backup_key(uint16_t index, KEY key){
+	return keystore_eeprom_read(KEY_BACKUP_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), key, sizeof(KEY));
+}
+
+uint8_t keystore_write_key(uint16_t index, KEY key){
+	return keystore_eeprom_write(KEY_MAIN_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), key, sizeof(KEY));
+}
+uint8_t keystore_write_backup_key(uint16_t index, KEY key){
+	return keystore_eeprom_write(KEY_BACKUP_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), key, sizeof(KEY));
+}
+
+uint8_t keystore_eeprom_read(uint8_t eeprom, uint16_t offset, uint8_t* buffer, uint8_t length){
 	uint8_t ret;
 	i2c_master_set_speed(I2C_BITRATE_REG_1M);
-	ret = i2c_master_read(KEY_MAIN_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), sizeof(uint16_t), key, sizeof(KEY));
+	ret = i2c_master_read(eeprom, offset, sizeof(uint16_t), buffer, length);
 	if (ret != I2C_SUCCESS) {
-		printf_P(PSTR("Key read error %02x, retry...\n"), ret);
-		ret = i2c_master_read(KEY_MAIN_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), sizeof(uint16_t), key, sizeof(KEY));
-		if (ret != I2C_SUCCESS) printf_P(PSTR("Key read error %02x (fatal)\n"), ret);
+		printf_P(PSTR("EEPROM %02x read error %02x, retry...\n"), eeprom, ret);
+		ret = i2c_master_read(eeprom, offset, sizeof(uint16_t), buffer, length);
+		if (ret != I2C_SUCCESS) printf_P(PSTR("EEPROM %02x read error %02x (fatal)\n"), eeprom, ret);
 	}
 	return (ret == I2C_SUCCESS);
 }
 
-uint8_t keystore_write_key(uint16_t index, KEY key){
+uint8_t keystore_eeprom_write(uint8_t eeprom, uint16_t offset, uint8_t* buffer, uint8_t length){
 	uint8_t ret;
-	EEPROM_WRITE_PROTECT_PORT &= ~EEPROM_WRITE_PROTECT_MAIN;
+	uint8_t write_protect_flag;
+	if (eeprom == KEY_MAIN_EEPROM){
+		write_protect_flag = EEPROM_WRITE_PROTECT_MAIN;
+	} else {
+		write_protect_flag = EEPROM_WRITE_PROTECT_BACKUP;
+	}
+	
+	EEPROM_WRITE_PROTECT_PORT &= ~write_protect_flag;
 	
 	i2c_master_set_speed(I2C_BITRATE_REG_1M);
-	ret = i2c_master_write(KEY_MAIN_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), sizeof(uint16_t), key, sizeof(KEY));
+	ret = i2c_master_write(eeprom, offset, sizeof(uint16_t), buffer, length);
 	if (ret != I2C_SUCCESS) {
-		printf_P(PSTR("Key write error %02x, retry...\n"), ret);
-		ret = i2c_master_write(KEY_MAIN_EEPROM, EEPROM_KEY_OFFSET + (index * sizeof(KEY)), sizeof(uint16_t), key, sizeof(KEY));
-		if (ret != I2C_SUCCESS) printf_P(PSTR("Key write error %02x (fatal)\n"), ret);
+		printf_P(PSTR("EEPROM %02x Write error %02x, retry...\n"), eeprom, ret);
+		ret = i2c_master_write(eeprom, offset, sizeof(uint16_t), buffer, length);
+		if (ret != I2C_SUCCESS) printf_P(PSTR("EEPROM %02x write error %02x (fatal)\n"), eeprom, ret);
 	}
 	
-	EEPROM_WRITE_PROTECT_PORT |= EEPROM_WRITE_PROTECT_MAIN;
+	EEPROM_WRITE_PROTECT_PORT |= write_protect_flag;
 	
 	return (ret == I2C_SUCCESS);
-}
+}
\ No newline at end of file
diff --git a/Control/keystore.h b/Control/keystore.h
index 0cf8e3ddd7b1ac7c4fa6c317472690ff5a6c6f3c..3ef2ec3f948df31f516f8cd6c240c2a4c5645e75 100644
--- a/Control/keystore.h
+++ b/Control/keystore.h
@@ -14,6 +14,8 @@
 
 #define KEY_COUNT 32 //eeprom has space for 1008 keys, but RAM for hash precalc is limited.
 
+// #define KEYSTORE_DEBUG
+
 #define EEPROM_TABLE_OFFSET 0  //table listing used and unused keyslots
 #define EEPROM_KEY_OFFSET 1024 //keys start here
 
@@ -54,6 +56,11 @@ int16_t keystore_find_key(HASH keyhash);
  */
 void keystore_update_salt(void);
 
+/**
+ * List keystore content (stubs)
+ */
+void keystore_list(void);
+
 /**
  * Generates a byte string of sizeof(KEY) length which is used to update
  * the card key. new_key = current_key XOR keydelta
@@ -119,3 +126,17 @@ uint8_t keystore_write_slot_status(uint16_t index, uint8_t key_status);
  * @return KEYSLOT_USED, KEYSLOT_EMPTY or KEYSLOT_ERROR
  */
 uint8_t keystore_read_slot_status(uint16_t index);
+
+/**
+ * Reads the key of a keyslot
+ * @param index number of the keyslot to read
+ * @param key   buffer for the key
+ * @return 1 if read successful, 0 otherwise.
+ */
+uint8_t keystore_read_key(uint16_t index, KEY key);
+
+/**
+ * Restores the key slot content to the last successful auth key
+ * @param index number of the keyslot to restore
+ */
+uint8_t keystore_restore_slot(uint16_t index);
\ No newline at end of file
diff --git a/Control/shell/shell.c b/Control/shell/shell.c
index ca78d02debc4a9643d190bc25ad251d319324542..cedda17b1a2a8a688c6d4ee1b5b196afbc86485f 100644
--- a/Control/shell/shell.c
+++ b/Control/shell/shell.c
@@ -2,6 +2,7 @@
 #include "../ds1307.h"
 #include "../log.h"
 #include "../door.h"
+#include "../cardreader_interface.h"
 
 #define SHELL_LOGIN_PROMPT "\nMezu Login: "
 
@@ -18,6 +19,7 @@ void cmd_keyslot_clear(readline_parsed_cmd_t* cmd);
 void cmd_keyslot_list(readline_parsed_cmd_t* cmd);
 void cmd_keyslot_disable(readline_parsed_cmd_t* cmd);
 void cmd_keyslot_enable(readline_parsed_cmd_t* cmd);
+void cmd_keyslot_restore(readline_parsed_cmd_t* cmd);
 void cmd_lock(readline_parsed_cmd_t* cmd);
 void cmd_unlock(readline_parsed_cmd_t* cmd);
 void cmd_logout(readline_parsed_cmd_t* cmd);
@@ -26,23 +28,28 @@ void cmd_keyslot_alarm_stop(readline_parsed_cmd_t* cmd);
 void cmd_reset(readline_parsed_cmd_t* cmd);
 void cmd_date(readline_parsed_cmd_t* cmd);
 void cmd_show_log(readline_parsed_cmd_t* cmd);
-
-readline_supported_cmd_t readline_commands[] = {{"help"     , 0, 0, cmd_help},
-                                                {"logout"   , 0, 0, cmd_logout},
-                                                {"exit"     , 0, 0, cmd_logout},
-                                                {"passwd"   , 0, 1, cmd_passwd},
-                                                {"unlock"   , 0, 0, cmd_unlock},
-                                                {"lock"     , 0, 1, cmd_lock},
-                                                {"status"   , 0, 0, cmd_status},
-                                                {"reset"    , 0, 0, cmd_reset},
-                                                {"initks"   , 0, 2, cmd_keyslot_init},
-                                                {"clearks"  , 1, 1, cmd_keyslot_clear},
-                                                {"disableks", 1, 1, cmd_keyslot_disable},
-                                                {"enableks" , 1, 1, cmd_keyslot_enable},
-                                                {"urusai"   , 0, 0, cmd_keyslot_alarm_stop},
-                                                {"ls"       , 0, 0, cmd_keyslot_list},
-                                                {"date"     , 0, 2, cmd_date},
-                                                {"log"      , 0, 0, cmd_show_log},
+void cmd_card_init_key(readline_parsed_cmd_t* cmd);
+void cmd_card_clear_key(readline_parsed_cmd_t* cmd);
+
+readline_supported_cmd_t readline_commands[] = {{"help"        , 0, 0, cmd_help},
+                                                {"logout"      , 0, 0, cmd_logout},
+                                                {"exit"        , 0, 0, cmd_logout},
+                                                {"passwd"      , 0, 1, cmd_passwd},
+                                                {"unlock"      , 0, 0, cmd_unlock},
+                                                {"lock"        , 0, 1, cmd_lock},
+                                                {"status"      , 0, 0, cmd_status},
+                                                {"reset"       , 0, 0, cmd_reset},
+                                                {"initks"      , 0, 2, cmd_keyslot_init},
+                                                {"clearks"     , 1, 1, cmd_keyslot_clear},
+                                                {"disableks"   , 1, 1, cmd_keyslot_disable},
+                                                {"enableks"    , 1, 1, cmd_keyslot_enable},
+                                                {"restoreks"   , 1, 1, cmd_keyslot_restore},
+                                                {"urusai"      , 0, 0, cmd_keyslot_alarm_stop},
+                                                {"ls"          , 0, 0, cmd_keyslot_list},
+                                                {"date"        , 0, 2, cmd_date},
+                                                {"log"         , 0, 0, cmd_show_log},
+                                                {"initcardkey" , 1, 1, cmd_card_init_key},
+                                                {"clearcardkey", 0, 0, cmd_card_clear_key},
                                                 {0,0,0,0}};
 
 #define SHELL_STATE_READ_USER 0
@@ -143,11 +150,19 @@ unlock        - Unlock door\n\
 status        - Display system status\n\
 reset         - Reset controller\n\
 passwd [user] - Change user password\n\
-initks  x     - Initialize keyslot x with a new random key\n\
-clearks x     - Clear keyslot x (delete key)\n\
+initks    x   - Initialize keyslot x with a new random key\n\
+clearks   x   - Clear keyslot x (delete key)\n\
+disableks x   - Disable keyslot x (but keep key)\n\
+enableks  x   - Enable a disabled keyslot\n\
+restoreks x   - Restore keyslot content from last valid key\n\
 ls            - List keyslots (only key stubs)\n\
+initcardkey x - Program the key of keyslot x on the card in the cardreader\n\
+clearcardkey  - Clear the key of the card currently in the cardreader\n\
+date [dd-mm-yy] hh:mm:ss - Set system date and time\n\
+log           - Show systemlog\n\
 urusai        - Turn Alarm off\n\
-logout        - Exit shell\n"));
+logout        - Exit shell\n\
+quit          - Exit shell\n"));
 }
 
 void cmd_keyslot_init(readline_parsed_cmd_t* cmd){
@@ -200,7 +215,7 @@ void cmd_keyslot_init(readline_parsed_cmd_t* cmd){
 	
 	KEY new_key;
 	if (keystore_init_slot(keyslot_index, new_key)){
-		printf_P(PSTR("Success\nNew key: "));
+		printf_P(PSTR("Slot %i initialized\nNew key: "), keyslot_index);
 		MGMT_transmit_buffer_hex(new_key, sizeof(KEY));
 		printf_P(PSTR("\n"));
 	} else {
@@ -212,9 +227,9 @@ void cmd_keyslot_disable(readline_parsed_cmd_t* cmd){
 	uint16_t keyslot_index;
 	char* endptr;
 	keyslot_index = strtol(cmd->args[0], &endptr, 10);
-	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
+// 	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
 	if (*endptr != 0){//number parsing didn't reach the end of the string
-		printf_P(PSTR("Usage: clearks index\n"));
+		printf_P(PSTR("Usage: disableks index\n"));
 	}
 	
 	if (keystore_disable_slot(keyslot_index)){
@@ -227,9 +242,9 @@ void cmd_keyslot_enable(readline_parsed_cmd_t* cmd){
 	uint16_t keyslot_index;
 	char* endptr;
 	keyslot_index = strtol(cmd->args[0], &endptr, 10);
-	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
+// 	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
 	if (*endptr != 0){//number parsing didn't reach the end of the string
-		printf_P(PSTR("Usage: clearks index\n"));
+		printf_P(PSTR("Usage: enableks index\n"));
 	}
 	
 	if (keystore_enable_slot(keyslot_index)){
@@ -243,7 +258,7 @@ void cmd_keyslot_clear(readline_parsed_cmd_t* cmd){
 	uint16_t keyslot_index;
 	char* endptr;
 	keyslot_index = strtol(cmd->args[0], &endptr, 10);
-	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
+// 	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
 	if (*endptr != 0){//number parsing didn't reach the end of the string
 		printf_P(PSTR("Usage: clearks index\n"));
 	}
@@ -255,38 +270,25 @@ void cmd_keyslot_clear(readline_parsed_cmd_t* cmd){
 	}
 }
 
+void cmd_keyslot_restore(readline_parsed_cmd_t* cmd){
+	uint16_t keyslot_index;
+	char* endptr;
+	keyslot_index = strtol(cmd->args[0], &endptr, 10);
+// 	printf_P(PSTR("Keyslot '%s' %i\n"), cmd->args[0], keyslot_index);
+	if (*endptr != 0){//number parsing didn't reach the end of the string
+		printf_P(PSTR("Usage: restoreks index\n"));
+	}
+	
+	if (keystore_restore_slot(keyslot_index)){
+		printf_P(PSTR("OK\n"));
+	} else {
+		printf_P(PSTR("Failed\n"));
+	}
+	
+}
 
-extern HASH hashes[KEY_COUNT];
 void cmd_keyslot_list(readline_parsed_cmd_t* cmd){
-	KEY key;
-	for (uint16_t index = 0; index < KEY_COUNT; index++){
-		wdt_reset(); //this may take a while, keep the Watchdog happy.
-		
-		printf_P(PSTR("Slot %03i: "), index);
-		uint8_t slot_status = keystore_read_slot_status(index);
-		if (slot_status == KEYSLOT_USED || slot_status == KEYSLOT_DISABLED){
-			keystore_read_key(index, key);
-			
-			printf_P(PSTR("K:"));
-			MGMT_transmit_buffer_hex(key, 20);
-			
-			printf_P(PSTR(" H:"));
-			MGMT_transmit_buffer_hex(hashes[index], sizeof(HASH_HEAD));
-			
-			if (slot_status == KEYSLOT_DISABLED){
-				printf_P(PSTR(" (Disabled)"));
-			}
-			
-			printf_P(PSTR("\n"));
-			
-		} else if (slot_status == KEYSLOT_EMPTY){
-			printf_P(PSTR("Empty\n"));
-		} else if (slot_status == KEYSLOT_ERROR){
-			printf_P(PSTR("Read Error\n"));
-		} else {
-			printf_P(PSTR("Unknown (%02x)\n"), slot_status);
-		}
-	}
+	keystore_list();
 }
 
 void cmd_lock(readline_parsed_cmd_t* cmd){
@@ -391,6 +393,34 @@ void cmd_date(readline_parsed_cmd_t* cmd){
 	printf_P(PSTR("\n"));
 }
 
+void cmd_card_init_key(readline_parsed_cmd_t* cmd){
+	uint16_t keyslot_index;
+	char* endptr;
+	keyslot_index = strtol(cmd->args[0], &endptr, 10);
+	if (*endptr != 0){//number parsing didn't reach the end of the string
+		printf_P(PSTR("Usage: initcardkey index\n"));
+	}
+	
+	uint8_t slot_status = keystore_read_slot_status(keyslot_index);
+	if (slot_status == KEYSLOT_USED || slot_status == KEYSLOT_DISABLED){
+		printf_P(PSTR("Programming Keyslot %i -> Card:"),keyslot_index);
+		
+		KEY key;
+		if (keystore_read_key(keyslot_index, key)){
+			cardreader_init_card_key(key);
+		} else {
+			printf_P(PSTR("Key read error\n"));
+		}
+	} else {
+		printf_P(PSTR("Invalid keyslot %i\n"), keyslot_index);
+	}
+}
+void cmd_card_clear_key(readline_parsed_cmd_t* cmd){
+	printf_P(PSTR("Clearing card key:"));
+	cardreader_clear_card_key();
+}
+
+
 uint8_t shell_find_user(char* username){
 	uint8_t i = 0;
 	while (users[i]){