Support encrypted backup files

Also includes features merged from:

Update twrpTar by kokotas

Revised function entryExists().
Added function to get archive's uncompressed size.
Added option to exclude item(s) from the archive.
Revised forks()

http://review.teamw.in/#/c/590/

Change-Id: I01fa2c81643161984eff2625247af75990684bd9
diff --git a/Android.mk b/Android.mk
index 8806616..f393bae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -232,6 +232,11 @@
 ifeq ($(TARGET_BOARD_PLATFORM),rk30xx)
     LOCAL_CFLAGS += -DRK3066
 endif
+ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+    LOCAL_SHARED_LIBRARIES += libopenaes
+else
+    LOCAL_CFLAGS += -DTW_EXCLUDE_ENCRYPTED_BACKUPS
+endif
 
 include $(BUILD_EXECUTABLE)
 
@@ -304,7 +309,8 @@
     $(commands_recovery_local_path)/crypto/cryptfs/Android.mk \
     $(commands_recovery_local_path)/libcrecovery/Android.mk \
     $(commands_recovery_local_path)/libblkid/Android.mk \
-    $(commands_recovery_local_path)/minuitwrp/Android.mk
+    $(commands_recovery_local_path)/minuitwrp/Android.mk \
+    $(commands_recovery_local_path)/openaes/Android.mk
 
 ifeq ($(TW_INCLUDE_CRYPTO_SAMSUNG), true)
     include $(commands_recovery_local_path)/crypto/libcrypt_samsung/Android.mk
diff --git a/data.cpp b/data.cpp
index 867c289..c6c3d0a 100644
--- a/data.cpp
+++ b/data.cpp
@@ -908,6 +908,7 @@
 	mValues.insert(make_pair("tw_military_time", make_pair("0", 1)));
 	mValues.insert(make_pair("tw_screen_timeout_secs", make_pair("60", 1)));
 	mValues.insert(make_pair("tw_gui_done", make_pair("0", 0)));
+	mValues.insert(make_pair("tw_encrypt_backup", make_pair("0", 0)));
 #ifdef TW_BRIGHTNESS_PATH
 #ifndef TW_MAX_BRIGHTNESS
 #define TW_MAX_BRIGHTNESS 255
@@ -926,6 +927,12 @@
 	}
 #endif
 	mValues.insert(make_pair(TW_MILITARY_TIME, make_pair("0", 1)));
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	mValues.insert(make_pair("tw_include_encrypted_backup", make_pair("1", 0)));
+#else
+	LOGINFO("TW_EXCLUDE_ENCRYPTED_BACKUPS := true\n");
+	mValues.insert(make_pair("tw_include_encrypted_backup", make_pair("0", 0)));
+#endif
 }
 
 // Magic Values
diff --git a/gui/action.cpp b/gui/action.cpp
index 64049b2..9bd5ce5 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/wait.h>
+#include <dirent.h>
 
 #include <string>
 #include <sstream>
@@ -405,6 +406,7 @@
 			}
 		}
         operation_end(ret_val, simulate);
+		return 0;
 	}
 
     if (function == "readBackup")
@@ -494,6 +496,7 @@
 			PartitionManager.Mount_Current_Storage(true);
 		}
 		operation_end(0, simulate);
+		return 0;
 	}
 	
 	if (function == "copylog")
@@ -705,6 +708,7 @@
 				operation_end(0, simulate);
 			else
 				operation_end(1, simulate);
+			return 0;
 		}
 
 		if (function == "flash")
@@ -863,6 +867,7 @@
 			} else
 				PartitionManager.Update_System_Details();
 			operation_end(0, simulate);
+			return 0;
 		}
         if (function == "nandroid")
         {
@@ -893,12 +898,13 @@
 					return -1;
 				}
 			}
+			DataManager::SetValue("tw_encrypt_backup", 0);
 			if (ret == false)
 				ret = 1; // 1 for failure
 			else
 				ret = 0; // 0 for success
-            	operation_end(ret, simulate);
-		return 0;
+            operation_end(ret, simulate);
+			return 0;
         }
 		if (function == "fixpermissions")
 		{
@@ -1226,6 +1232,7 @@
 					DataManager::SetValue("tw_page_done", 1);
 				}
 			}
+			return 0;
 		}
 		if (function == "installsu")
 		{
@@ -1257,13 +1264,35 @@
 			operation_end(op_status, simulate);
 			return 0;
 		}
+		if (function == "decrypt_backup")
+		{
+			int op_status = 0;
+
+			operation_start("Try Restore Decrypt");
+			if (simulate) {
+				simulate_progress_bar();
+			} else {
+				string Restore_Path, Filename, Password;
+				DataManager::GetValue("tw_restore", Restore_Path);
+				Restore_Path += "/";
+				DataManager::GetValue("tw_restore_password", Password);
+				if (TWFunc::Try_Decrypting_Backup(Restore_Path, Password))
+					op_status = 0; // success
+				else
+					op_status = 1; // fail
+			}
+
+			operation_end(op_status, simulate);
+			return 0;
+		}
     }
     else
     {
-        pthread_t t;
-        pthread_create(&t, NULL, thread_start, this);
+		pthread_t t;
+		pthread_create(&t, NULL, thread_start, this);
         return 0;
     }
+	LOGERR("Unknown action '%s'\n", function.c_str());
     return -1;
 }
 
diff --git a/gui/devices/1024x600/res/ui.xml b/gui/devices/1024x600/res/ui.xml
index b24bda3..4835d82 100755
--- a/gui/devices/1024x600/res/ui.xml
+++ b/gui/devices/1024x600/res/ui.xml
@@ -183,7 +183,7 @@
 		<variable name="button_fill_full_width" value="512" />
 		<variable name="button_fill_main_width" value="486" />
 		<variable name="button_fill_main_height" value="150" />
-		<variable name="button_fill_half_height" value="75" />
+		<variable name="button_fill_half_height" value="50" />
 		<variable name="button_fill_quarter_height" value="30" />
 		<variable name="button_full_center_x" value="256" />
 		<variable name="backup_list_x" value="23" />
@@ -191,6 +191,7 @@
 		<variable name="backup_list_width" value="486" />
 		<variable name="backup_list_height" value="360" />
 		<variable name="backup_storage_y" value="250" />
+		<variable name="backup_encrypt_y" value="310" />
 		<variable name="restore_list_y" value="140" />
 		<variable name="restore_list_height" value="320" />
 		<variable name="mount_list_height" value="400" />
@@ -1667,6 +1668,36 @@
 				</actions>
 			</object>
 
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>No Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
 			<object type="checkbox">
 				<placement x="%col3_x%" y="%nandcheck_row6%" />
 				<font resource="font" color="%text_color%" />
@@ -1787,6 +1818,140 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please enter a password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1855,7 +2020,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1872,6 +2037,138 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Backup encrypted. Please enter your password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col3_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/1024x768/res/ui.xml b/gui/devices/1024x768/res/ui.xml
index 5b9c3fc..dd53da4 100644
--- a/gui/devices/1024x768/res/ui.xml
+++ b/gui/devices/1024x768/res/ui.xml
@@ -183,7 +183,7 @@
 		<variable name="button_fill_full_width" value="512" />
 		<variable name="button_fill_main_width" value="486" />
 		<variable name="button_fill_main_height" value="150" />
-		<variable name="button_fill_half_height" value="75" />
+		<variable name="button_fill_half_height" value="50" />
 		<variable name="button_fill_quarter_height" value="30" />
 		<variable name="button_full_center_x" value="256" />
 		<variable name="backup_list_x" value="23" />
@@ -191,6 +191,7 @@
 		<variable name="backup_list_width" value="486" />
 		<variable name="backup_list_height" value="450" />
 		<variable name="backup_storage_y" value="250" />
+		<variable name="backup_encrypt_y" value="310" />
 		<variable name="restore_list_y" value="140" />
 		<variable name="restore_list_height" value="400" />
 		<variable name="mount_list_height" value="500" />
@@ -1667,6 +1668,36 @@
 				</actions>
 			</object>
 
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>No Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
 			<object type="checkbox">
 				<placement x="%col3_x%" y="%nandcheck_row6%" />
 				<font resource="font" color="%text_color%" />
@@ -1787,6 +1818,140 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please enter a password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1855,7 +2020,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1872,6 +2037,138 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Backup encrypted. Please enter your password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col3_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/1080x1920/res/ui.xml b/gui/devices/1080x1920/res/ui.xml
index 625cad8..1c757fa 100644
--- a/gui/devices/1080x1920/res/ui.xml
+++ b/gui/devices/1080x1920/res/ui.xml
@@ -1338,15 +1338,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1359,14 +1365,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1508,6 +1533,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1574,7 +1745,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1591,6 +1762,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/1280x800/res/ui.xml b/gui/devices/1280x800/res/ui.xml
index 3ffa79d..8babda1 100644
--- a/gui/devices/1280x800/res/ui.xml
+++ b/gui/devices/1280x800/res/ui.xml
@@ -183,7 +183,7 @@
 		<variable name="button_fill_full_width" value="640" />
 		<variable name="button_fill_main_width" value="609" />
 		<variable name="button_fill_main_height" value="160" />
-		<variable name="button_fill_half_height" value="80" />
+		<variable name="button_fill_half_height" value="53" />
 		<variable name="button_fill_quarter_height" value="40" />
 		<variable name="button_full_center_x" value="320" />
 		<variable name="backup_list_x" value="28" />
@@ -191,6 +191,7 @@
 		<variable name="backup_list_width" value="609" />
 		<variable name="backup_list_height" value="440" />
 		<variable name="backup_storage_y" value="270" />
+		<variable name="backup_encrypt_y" value="330" />
 		<variable name="restore_list_y" value="140" />
 		<variable name="restore_list_height" value="400" />
 		<variable name="mount_list_height" value="600" />
@@ -1667,6 +1668,36 @@
 				</actions>
 			</object>
 
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>No Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
 			<object type="checkbox">
 				<placement x="%col3_x%" y="%nandcheck_row6%" />
 				<font resource="font" color="%text_color%" />
@@ -1787,6 +1818,140 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please enter a password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1855,7 +2020,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1872,6 +2037,138 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Backup encrypted. Please enter your password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col3_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/1920x1200/res/ui.xml b/gui/devices/1920x1200/res/ui.xml
index af9aba6..0cc4d7e 100644
--- a/gui/devices/1920x1200/res/ui.xml
+++ b/gui/devices/1920x1200/res/ui.xml
@@ -183,7 +183,7 @@
 		<variable name="button_fill_full_width" value="960" />
 		<variable name="button_fill_main_width" value="900" />
 		<variable name="button_fill_main_height" value="240" />
-		<variable name="button_fill_half_height" value="120" />
+		<variable name="button_fill_half_height" value="80" />
 		<variable name="button_fill_quarter_height" value="60" />
 		<variable name="button_full_center_x" value="480" />
 		<variable name="backup_list_x" value="50" />
@@ -191,6 +191,7 @@
 		<variable name="backup_list_width" value="900" />
 		<variable name="backup_list_height" value="660" />
 		<variable name="backup_storage_y" value="405" />
+		<variable name="backup_encrypt_y" value="495" />
 		<variable name="restore_list_y" value="190" />
 		<variable name="restore_list_height" value="600" />
 		<variable name="mount_list_height" value="900" />
@@ -1667,6 +1668,36 @@
 				</actions>
 			</object>
 
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>No Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
 			<object type="checkbox">
 				<placement x="%col3_x%" y="%nandcheck_row6%" />
 				<font resource="font" color="%text_color%" />
@@ -1787,6 +1818,140 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please enter a password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1855,7 +2020,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1872,6 +2037,138 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Backup encrypted. Please enter your password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col3_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/2560x1600/res/ui.xml b/gui/devices/2560x1600/res/ui.xml
index 12c032b..c9e6c69 100644
--- a/gui/devices/2560x1600/res/ui.xml
+++ b/gui/devices/2560x1600/res/ui.xml
@@ -183,7 +183,7 @@
 		<variable name="button_fill_full_width" value="1280" />
 		<variable name="button_fill_main_width" value="1200" />
 		<variable name="button_fill_main_height" value="320" />
-		<variable name="button_fill_half_height" value="160" />
+		<variable name="button_fill_half_height" value="107" />
 		<variable name="button_fill_quarter_height" value="80" />
 		<variable name="button_full_center_x" value="640" />
 		<variable name="backup_list_x" value="50" />
@@ -191,6 +191,7 @@
 		<variable name="backup_list_width" value="1200" />
 		<variable name="backup_list_height" value="880" />
 		<variable name="backup_storage_y" value="540" />
+		<variable name="backup_encrypt_y" value="650" />
 		<variable name="restore_list_y" value="280" />
 		<variable name="restore_list_height" value="800" />
 		<variable name="mount_list_height" value="1200" />
@@ -1667,6 +1668,36 @@
 				</actions>
 			</object>
 
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>No Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
 			<object type="checkbox">
 				<placement x="%col3_x%" y="%nandcheck_row6%" />
 				<font resource="font" color="%text_color%" />
@@ -1787,6 +1818,140 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please enter a password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1855,7 +2020,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1872,6 +2037,138 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Backup encrypted. Please enter your password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col3_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
@@ -2297,100 +2594,47 @@
 				<text>Screen Settings</text>
 			</object>
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
-				<text>Screen Timeout: %tw_screen_timeout_secs% seconds</text>
-			</object>
-
 			<object type="button">
-				<placement x="%col1_medium_x%" y="%row2_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>None</text>
-				<image resource="medium_button" />
-				<action function="set">tw_screen_timeout_secs=0</action>
-			</object>
-
-			<object type="button">
-				<placement x="%col2_medium_x%" y="%row2_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>60</text>
-				<image resource="medium_button" />
+				<placement x="%slidervalue_x%" y="%row3_text_y%" />
+				<font resource="font" color="%text_color%" />
+				<condition var1="tw_screen_timeout_secs" op="=" var2="0" />
+				<text>Enable screen timeout.</text>
+				<image resource="checkbox_false" />
 				<action function="set">tw_screen_timeout_secs=60</action>
 			</object>
 
 			<object type="button">
-				<placement x="%col3_medium_x%" y="%row2_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>120</text>
-				<image resource="medium_button" />
-				<action function="set">tw_screen_timeout_secs=120</action>
+				<placement x="%slidervalue_x%" y="%row3_text_y%" />
+				<font resource="font" color="%text_color%" />
+				<condition var1="tw_screen_timeout_secs" op="!=" var2="0" />
+				<text>Enable screen timeout.</text>
+				<image resource="checkbox_true" />
+				<action function="set">tw_screen_timeout_secs=0</action>
 			</object>
 
-			<object type="button">
-				<placement x="%col4_medium_x%" y="%row2_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>180</text>
-				<image resource="medium_button" />
-				<action function="set">tw_screen_timeout_secs=180</action>
+			<object type="slidervalue">
+				<condition var1="tw_screen_timeout_secs" op="!=" var2="0" />
+				<placement x="slidervalue_x" y="%row5_text_y%" w="%slidervalue_w%" />
+				<font resource="font" color="%text_color%" />
+				<colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" />
+				<dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%" />
+				<text>Screen timeout in seconds:</text>
+				<data variable="tw_screen_timeout_secs" min="15" max="300" />
 			</object>
 
-			<object type="text" color="%text_color%">
+			<object type="slidervalue">
 				<condition var1="tw_has_brightnesss_file" var2="1" />
-				<font resource="font" />
-				<placement x="%center_x%" y="%row12_text_y%" placement="5" />
-				<text>Brightness: %tw_brightness_display%</text>
-			</object>
-
-			<object type="button">
-				<condition var1="tw_has_brightnesss_file" var2="1" />
-				<placement x="%col1_medium_x%" y="%row4_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>25%</text>
-				<image resource="medium_button" />
+				<placement x="slidervalue_x" y="%row12_text_y%" w="%slidervalue_w%" />
+				<font resource="font" color="%text_color%" />
+				<colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" />
+				<dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%" />
+				<text>Brightness: %tw_brightness_pct%%</text>
+				<data variable="tw_brightness_pct" min="10" max="100" />
 				<actions>
-					<action function="cmd">echo %tw_brightness_25% > &quot;%tw_brightness_file%&quot;</action>
-					<action function="set">tw_brightness_display=25%</action>
-					<action function="set">tw_brightness=%tw_brightness_25%</action>
-				</actions>
-			</object>
-
-			<object type="button">
-				<condition var1="tw_has_brightnesss_file" var2="1" />
-				<placement x="%col2_medium_x%" y="%row4_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>50%</text>
-				<image resource="medium_button" />
-				<actions>
-					<action function="cmd">echo %tw_brightness_50% > &quot;%tw_brightness_file%&quot;</action>
-					<action function="set">tw_brightness_display=50%</action>
-					<action function="set">tw_brightness=%tw_brightness_50%</action>
-				</actions>
-			</object>
-
-			<object type="button">
-				<condition var1="tw_has_brightnesss_file" var2="1" />
-				<placement x="%col3_medium_x%" y="%row4_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>75%</text>
-				<image resource="medium_button" />
-				<actions>
-					<action function="cmd">echo %tw_brightness_75% > &quot;%tw_brightness_file%&quot;</action>
-					<action function="set">tw_brightness_display=75%</action>
-					<action function="set">tw_brightness=%tw_brightness_75%</action>
-				</actions>
-			</object>
-
-			<object type="button">
-				<condition var1="tw_has_brightnesss_file" var2="1" />
-				<placement x="%col4_medium_x%" y="%row4_medium_y%" />
-				<font resource="font" color="%button_text_color%" />
-				<text>100%</text>
-				<image resource="medium_button" />
-				<actions>
-					<action function="cmd">echo %tw_brightness_100% > &quot;%tw_brightness_file%&quot;</action>
-					<action function="set">tw_brightness_display=100%</action>
-					<action function="set">tw_brightness=%tw_brightness_100%</action>
+					<action function="set">tw_brightness=%tw_brightness_max%</action>
+					<action function="compute">tw_brightness*%tw_brightness_pct%</action>
+					<action function="compute">tw_brightness/100</action>
+					<action function="cmd">echo %tw_brightness% > &quot;%tw_brightness_file%&quot;</action>
 				</actions>
 			</object>
 
diff --git a/gui/devices/320x480/res/ui.xml b/gui/devices/320x480/res/ui.xml
index 66865a7..6d258b0 100644
--- a/gui/devices/320x480/res/ui.xml
+++ b/gui/devices/320x480/res/ui.xml
@@ -169,7 +169,7 @@
 		<variable name="button_fill_main_height" value="81" />
 		<variable name="button_fill_half_height" value="40" />
 		<variable name="button_fill_quarter_height" value="24" />
-		<variable name="backup_list_height" value="212" />
+		<variable name="backup_list_height" value="193" />
 		<variable name="backup_button_row1" value="300" />
 		<variable name="backup_button_row2" value="326" />
 		<variable name="mount_list_height" value="270" />
@@ -1325,15 +1325,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1346,14 +1352,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1495,6 +1520,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1561,7 +1732,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1578,6 +1749,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/480x800/res/ui.xml b/gui/devices/480x800/res/ui.xml
index e33e5b1..fdebf15 100644
--- a/gui/devices/480x800/res/ui.xml
+++ b/gui/devices/480x800/res/ui.xml
@@ -169,7 +169,7 @@
 		<variable name="button_fill_main_height" value="135" />
 		<variable name="button_fill_half_height" value="67" />
 		<variable name="button_fill_quarter_height" value="34" />
-		<variable name="backup_list_height" value="325" />
+		<variable name="backup_list_height" value="300" />
 		<variable name="backup_button_row1" value="480" />
 		<variable name="backup_button_row2" value="520" />
 		<variable name="mount_list_height" value="380" />
@@ -1325,15 +1325,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1346,14 +1352,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1495,6 +1520,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1561,7 +1732,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1578,6 +1749,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/480x854/res/ui.xml b/gui/devices/480x854/res/ui.xml
index e4487f6..b2a5f4c 100644
--- a/gui/devices/480x854/res/ui.xml
+++ b/gui/devices/480x854/res/ui.xml
@@ -168,7 +168,7 @@
 		<variable name="button_fill_main_height" value="135" />
 		<variable name="button_fill_half_height" value="67" />
 		<variable name="button_fill_quarter_height" value="34" />
-		<variable name="backup_list_height" value="325" />
+		<variable name="backup_list_height" value="300" />
 		<variable name="backup_button_row1" value="480" />
 		<variable name="backup_button_row2" value="520" />
 		<variable name="mount_list_height" value="380" />
@@ -1324,15 +1324,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1345,14 +1351,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1494,6 +1519,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1560,7 +1731,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1577,6 +1748,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/540x960/res/ui.xml b/gui/devices/540x960/res/ui.xml
index 6ea2e1c..c6b0c92 100644
--- a/gui/devices/540x960/res/ui.xml
+++ b/gui/devices/540x960/res/ui.xml
@@ -169,7 +169,7 @@
 		<variable name="button_fill_main_height" value="162" />
 		<variable name="button_fill_half_height" value="81" />
 		<variable name="button_fill_quarter_height" value="40" />
-		<variable name="backup_list_height" value="445" />
+		<variable name="backup_list_height" value="410" />
 		<variable name="backup_button_row1" value="600" />
 		<variable name="backup_button_row2" value="645" />
 		<variable name="mount_list_height" value="500" />
@@ -1325,15 +1325,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1346,14 +1352,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1495,6 +1520,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1561,7 +1732,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1578,6 +1749,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/720x1280/res/ui.xml b/gui/devices/720x1280/res/ui.xml
index d43aae9..5481114 100644
--- a/gui/devices/720x1280/res/ui.xml
+++ b/gui/devices/720x1280/res/ui.xml
@@ -174,7 +174,7 @@
 		<variable name="button_fill_main_height" value="216" />
 		<variable name="button_fill_half_height" value="108" />
 		<variable name="button_fill_quarter_height" value="54" />
-		<variable name="backup_list_height" value="570" />
+		<variable name="backup_list_height" value="520" />
 		<variable name="backup_button_row1" value="745" />
 		<variable name="backup_button_row2" value="810" />
 		<variable name="mount_list_height" value="690" />
@@ -1338,15 +1338,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1359,14 +1365,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1508,6 +1533,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1574,7 +1745,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1591,6 +1762,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/800x1280/res/ui.xml b/gui/devices/800x1280/res/ui.xml
index f7226f0..a6931b2 100755
--- a/gui/devices/800x1280/res/ui.xml
+++ b/gui/devices/800x1280/res/ui.xml
@@ -170,7 +170,7 @@
 		<variable name="button_fill_main_height" value="240" />
 		<variable name="button_fill_half_height" value="120" />
 		<variable name="button_fill_quarter_height" value="54" />
-		<variable name="backup_list_height" value="570" />
+		<variable name="backup_list_height" value="520" />
 		<variable name="backup_button_row1" value="745" />
 		<variable name="backup_button_row2" value="810" />
 		<variable name="mount_list_height" value="690" />
@@ -1326,15 +1326,21 @@
 		<page name="backup">
 			<object type="template" name="header" />
 
-			<object type="text" color="%text_color%">
-				<font resource="font" />
-				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
 				<text>Backup Name: %tw_backup_name%</text>
+				<actions>
+					<action function="set">tw_fileexists=0</action>
+					<action function="page">backupname1</action>
+				</actions>
 			</object>
 
 			<object type="partitionlist">
 				<highlight color="%fileselector_highlight_color%" />
-				<placement x="%listbox_x%" y="%row1_text_y%" w="%listbox_width%" h="%backup_list_height%" />
+				<placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" />
 				<header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" />
 				<fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" />
 				<text>Select Partitions to Back Up:</text>
@@ -1347,14 +1353,33 @@
 			</object>
 
 			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
 				<highlight color="%highlight_color%" />
 				<fill color="%button_fill_color%" />
 				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
 				<font resource="font" color="%button_text_color%" />
-				<text>Set Backup Name</text>
+				<text>No Encryption</text>
 				<actions>
-					<action function="set">tw_fileexists=0</action>
-					<action function="page">backupname1</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="set">tw_password_not_match=0</action>
+					<action function="page">backupencryption</action>
 				</actions>
 			</object>
 
@@ -1496,6 +1521,152 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter A Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Encrypt your backup?</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1562,7 +1733,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1579,6 +1750,144 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_header_y%" placement="5" />
+				<text>Backup Encrypted</text>
+			</object>
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row2_text_y%" placement="5" />
+				<text>Please Enter Your Password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col1_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%row2_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/gui/devices/800x480/res/ui.xml b/gui/devices/800x480/res/ui.xml
index bb324df..562cb16 100755
--- a/gui/devices/800x480/res/ui.xml
+++ b/gui/devices/800x480/res/ui.xml
@@ -183,7 +183,7 @@
 		<variable name="button_fill_full_width" value="400" />
 		<variable name="button_fill_main_width" value="367" />
 		<variable name="button_fill_main_height" value="120" />
-		<variable name="button_fill_half_height" value="60" />
+		<variable name="button_fill_half_height" value="40" />
 		<variable name="button_fill_quarter_height" value="30" />
 		<variable name="button_full_center_x" value="200" />
 		<variable name="backup_list_x" value="23" />
@@ -191,6 +191,7 @@
 		<variable name="backup_list_width" value="367" />
 		<variable name="backup_list_height" value="290" />
 		<variable name="backup_storage_y" value="190" />
+		<variable name="backup_encrypt_y" value="235" />
 		<variable name="restore_list_y" value="100" />
 		<variable name="restore_list_height" value="270" />
 		<variable name="mount_list_height" value="360" />
@@ -1675,6 +1676,36 @@
 				</actions>
 			</object>
 
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="0" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>No Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<conditions>
+					<condition var1="tw_include_encrypted_backup" var2="1" />
+					<condition var1="tw_encrypt_backup" var2="1" />
+				</conditions>
+				<highlight color="%highlight_color%" />
+				<fill color="%button_fill_color%" />
+				<placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Using Encryption</text>
+				<actions>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+
 			<object type="checkbox">
 				<placement x="%col3_x%" y="%nandcheck_row6%" />
 				<font resource="font" color="%text_color%" />
@@ -1795,6 +1826,140 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="backupencryption">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please enter a password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display%</text>
+				<data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<action function="page">backupencryption2</action>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_not_match" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Passwords Do Not Match</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="backupencryption2">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Encrypt your backup? Please Enter Password Again:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_backup_encrypt_display2%</text>
+				<data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">checkbackuppassword</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">backup</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="checkbackuppassword">
+			<object type="action">
+				<condition var1="tw_backup_password2" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=1</action>
+					<action function="page">backup</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" />
+				<actions>
+					<action function="set">tw_encrypt_backup=0</action>
+					<action function="set">tw_password_not_match=1</action>
+					<action function="set">tw_backup_password=</action>
+					<action function="set">tw_backup_password2=</action>
+					<action function="set">tw_backup_encrypt_display=</action>
+					<action function="set">tw_backup_encrypt_display2=</action>
+					<action function="page">backupencryption</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="backup_run">
 			<object type="template" name="header" />
 
@@ -1863,7 +2028,7 @@
 				<condition var1="tw_restore" op="modified" />
 				<actions>
 					<action function="readBackup"></action>
-					<action function="page">restore_select</action>
+					<action function="page">restore_read</action>
 				</actions>
 			</object>
 
@@ -1880,6 +2045,138 @@
 			<object type="template" name="footer" />
 		</page>
 
+		<page name="restore_read">
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="1" />
+				<actions>
+					<action function="set">tw_password_fail=0</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<condition var1="tw_restore_encrypted" var2="0" />
+				<actions>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
+		<page name="restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Backup encrypted. Please enter your password:</text>
+			</object>
+
+			<object type="input">
+				<placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" />
+				<background color="%input_background_color%" />
+				<cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" />
+				<font resource="font" color="%text_color%" />
+				<text>%tw_restore_display%</text>
+				<data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" />
+				<restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" />
+				<actions>
+					<action function="page">try_restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="text" color="%text_fail_color%">
+				<condition var1="tw_password_fail" var2="1" />
+				<font resource="font" />
+				<placement x="%center_x%" y="%row4_text_y%" placement="5" />
+				<text>Password Failed, Please Try Again</text>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col2_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore</action>
+				</actions>
+			</object>
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col3_x%" y="%cancel_button_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Delete</text>
+				<image resource="main_button" />
+				<actions>
+					<action function="set">tw_back=restore</action>
+					<action function="set">tw_action=cmd</action>
+					<action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf &quot;%tw_restore_name%&quot;</action>
+					<action function="set">tw_text1=Delete Backup? %tw_restore_name%</action>
+					<action function="set">tw_text2=This cannot be undone!</action>
+					<action function="set">tw_action_text1=Deleting Backup...</action>
+					<action function="set">tw_complete_text1=Backup Delete Complete</action>
+					<action function="set">tw_slider_text=Swipe to Delete</action>
+					<action function="page">confirm_action</action>
+				</actions>
+			</object>
+
+			<object type="template" name="keyboardtemplate" />
+
+			<object type="action">
+				<touch key="home" />
+				<action function="page">main</action>
+			</object>
+
+			<object type="action">
+				<touch key="back" />
+				<action function="page">restore</action>
+			</object>
+
+			<object type="template" name="footer" />
+		</page>
+
+		<page name="try_restore_decrypt">
+			<object type="template" name="header" />
+
+			<object type="text" color="%text_color%">
+				<font resource="font" />
+				<placement x="%center_x%" y="%row1_text_y%" placement="5" />
+				<text>Trying Decryption with Your Password</text>
+			</object>
+
+			<object type="template" name="action_page_console" />
+
+			<object type="template" name="progress_bar" />
+
+			<object type="action">
+				<action function="decrypt_backup"></action>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="!=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_password_fail=1</action>
+					<action function="page">restore_decrypt</action>
+				</actions>
+			</object>
+
+			<object type="action">
+				<conditions>
+					<condition var1="tw_operation_state" var2="1" />
+					<condition var1="tw_operation_status" op="=" var2="0" />
+				</conditions>
+				<actions>
+					<action function="set">tw_page_done=1</action>
+					<action function="page">restore_select</action>
+				</actions>
+			</object>
+		</page>
+
 		<page name="restore_select">
 			<object type="template" name="header" />
 
diff --git a/libtar/libtar.h b/libtar/libtar.h
index 1d6c1df..e7a355a 100644
--- a/libtar/libtar.h
+++ b/libtar/libtar.h
@@ -289,7 +289,7 @@
 int tar_extract_all(TAR *t, char *prefix);
 
 /* add a whole tree of files */
-int tar_append_tree(TAR *t, char *realdir, char *savedir);
+int tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude);
 
 /* find an entry */
 int tar_find(TAR *t, char *searchstr);
diff --git a/libtar/wrapper.c b/libtar/wrapper.c
index 7f65375..0673244 100644
--- a/libtar/wrapper.c
+++ b/libtar/wrapper.c
@@ -17,7 +17,7 @@
 #include <sys/param.h>
 #include <dirent.h>
 #include <errno.h>
-
+#include <stdlib.h>
 #ifdef STDC_HEADERS
 # include <string.h>
 #endif
@@ -94,62 +94,94 @@
 
 
 int
-tar_append_tree(TAR *t, char *realdir, char *savedir)
+tar_append_tree(TAR *t, char *realdir, char *savedir, char *exclude)
 {
+#ifdef DEBUG
+	printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
+	       (long unsigned int)t, realdir, (savedir ? savedir : "[NULL]"));
+#endif
+
+	char temp[1024];
+	int skip = 0, i, n_spaces = 0;
+	char ** excluded = NULL;
+	char * p = NULL;
+	if (exclude) {
+		strcpy(temp, exclude);
+		p = strtok(exclude, " ");
+		if (p == NULL) {
+			excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
+			excluded[0] = temp;
+		} else {
+			while (p) {
+				excluded = realloc(excluded, sizeof(char*) * (++n_spaces));
+				excluded[n_spaces-1] = p;
+				p = strtok(NULL, " ");
+			}
+		}
+		excluded = realloc(excluded, sizeof(char*) * (n_spaces+1));
+		excluded[n_spaces] = 0;
+		for (i = 0; i < (n_spaces+1); i++) {
+			if (realdir == excluded[i]) {
+				printf("    excluding '%s'\n", excluded[i]);
+				skip = 1;
+				break;
+			}
+		}
+	}
+	if (skip == 0) {
+		if (tar_append_file(t, realdir, savedir) != 0)
+			return -1;
+	}
+
 	char realpath[MAXPATHLEN];
 	char savepath[MAXPATHLEN];
 	struct dirent *dent;
 	DIR *dp;
 	struct stat s;
 
-#ifdef DEBUG
-	printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
-	       t, realdir, (savedir ? savedir : "[NULL]"));
-#endif
-
-	if (tar_append_file(t, realdir, savedir) != 0)
-		return -1;
-
-#ifdef DEBUG
-	puts("    tar_append_tree(): done with tar_append_file()...");
-#endif
-
 	dp = opendir(realdir);
-	if (dp == NULL)
-	{
+	if (dp == NULL) {
 		if (errno == ENOTDIR)
 			return 0;
 		return -1;
 	}
-	while ((dent = readdir(dp)) != NULL)
-	{
-		if (strcmp(dent->d_name, ".") == 0 ||
-		    strcmp(dent->d_name, "..") == 0)
+	while ((dent = readdir(dp)) != NULL) {
+		if(strcmp(dent->d_name, ".") == 0
+		|| strcmp(dent->d_name, "..") == 0)
 			continue;
 
-		snprintf(realpath, MAXPATHLEN, "%s/%s", realdir,
-			 dent->d_name);
+		if (exclude) {
+			int omit = 0;
+			for (i = 0; i < (n_spaces+1); i++) {
+				if (dent->d_name == excluded[i]) {
+					printf("    excluding '%s'\n", excluded[i]);
+					omit = 1;
+					break;
+				}
+			}
+			if (omit)
+				continue;
+		}
+
+		snprintf(realpath, MAXPATHLEN, "%s/%s", realdir, dent->d_name);
 		if (savedir)
-			snprintf(savepath, MAXPATHLEN, "%s/%s", savedir,
-				 dent->d_name);
+			snprintf(savepath, MAXPATHLEN, "%s/%s", savedir, dent->d_name);
 
 		if (lstat(realpath, &s) != 0)
 			return -1;
 
-		if (S_ISDIR(s.st_mode))
-		{
-			if (tar_append_tree(t, realpath,
-					    (savedir ? savepath : NULL)) != 0)
+		if (S_ISDIR(s.st_mode)) {
+			if (tar_append_tree(t, realpath, (savedir ? savepath : NULL), (exclude ? exclude : NULL)) != 0)
+				return -1;
+			continue;
+		} else {
+			if (tar_append_file(t, realpath, (savedir ? savepath : NULL)) != 0)
 				return -1;
 			continue;
 		}
-
-		if (tar_append_file(t, realpath,
-				    (savedir ? savepath : NULL)) != 0)
-			return -1;
-	}
-
+	}	
 	closedir(dp);
+	free(excluded);
 
 	return 0;
 }
diff --git a/openaes/Android.mk b/openaes/Android.mk
new file mode 100644
index 0000000..1beefda
--- /dev/null
+++ b/openaes/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+	LOCAL_SRC_FILES:= src/oaes.c \
+	LOCAL_C_INCLUDES := \
+		bootable/recovery/openaes/src/isaac \
+		bootable/recovery/openaes/inc
+	LOCAL_CFLAGS:= -g -c -W
+	LOCAL_MODULE:=openaes
+	LOCAL_MODULE_TAGS:= eng
+	LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
+	LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+	LOCAL_SHARED_LIBRARIES = libopenaes libc
+	include $(BUILD_EXECUTABLE)
+
+	include $(CLEAR_VARS)
+	LOCAL_MODULE := libopenaes
+	LOCAL_MODULE_TAGS := eng
+	LOCAL_C_INCLUDES := \
+		bootable/recovery/openaes/src/isaac \
+		bootable/recovery/openaes/inc
+	LOCAL_SRC_FILES = src/oaes_lib.c src/isaac/rand.c
+	LOCAL_SHARED_LIBRARIES = libc
+	include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/openaes/CHANGELOG b/openaes/CHANGELOG
new file mode 100644
index 0000000..8ea94cf
--- /dev/null
+++ b/openaes/CHANGELOG
@@ -0,0 +1,43 @@
+---------------------------------------------------------------------------
+OpenAES-0.7.0
+Nabil S. Al Ramli
+www.nalramli.com
+---------------------------------------------------------------------------
+
+OpenAES-0.7.0
+-------------
+* implement oaes command line utility
+* defect: oaes_decrypt() does not have a way to tell if pad pattern is accidental
+
+OpenAES-0.6.0
+-------------
+* add stepping pause to vt_aes
+
+OpenAES-0.5.0
+-------------
+* defect: algorithm errors with ExpandKey for 192 bit and 256 bit keys
+
+OpenAES-0.4.0
+-------------
+* add vt_aes test program
+* defect: algorithm errors with ShiftRows and MixColumns
+* OAES_DEBUG config to step through encryption and decryption
+* defect: test_performance crash when printing results
+* allow user to specify iv by passing it to oaes_set_option()
+* oaes_key_import_data() and oaes_key_export_data() to operate on key data directly
+* defect: Access violation in oaes_key_export()
+
+OpenAES-0.3.0
+-------------
+* Add CMake support
+* platform independence fixes
+
+OpenAES-0.2.0
+-------------
+* Add performance tests
+* Implement CBC mode in AES algorithm
+* Performance improvements in oaes_shift_rows() and oaes_inv_shift_rows()
+
+OpenAES-0.1.0
+-------------
+* Implement AES algorithm
diff --git a/openaes/CMakeLists.txt b/openaes/CMakeLists.txt
new file mode 100644
index 0000000..251d5a3
--- /dev/null
+++ b/openaes/CMakeLists.txt
@@ -0,0 +1,74 @@
+# ---------------------------------------------------------------------------
+# OpenAES License
+# ---------------------------------------------------------------------------
+# Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+#   - Redistributions of source code must retain the above copyright notice,
+#     this list of conditions and the following disclaimer.
+#   - Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ---------------------------------------------------------------------------
+
+cmake_minimum_required (VERSION 2.8.0)
+
+project ( "oaes" )
+
+include_directories (
+		${CMAKE_CURRENT_SOURCE_DIR}/inc
+		${CMAKE_CURRENT_SOURCE_DIR}/src/isaac
+	)
+
+set (SRC
+		${CMAKE_CURRENT_SOURCE_DIR}/src/oaes_lib.c
+		${CMAKE_CURRENT_SOURCE_DIR}/src/isaac/rand.c
+	)
+
+set (HDR
+		${CMAKE_CURRENT_SOURCE_DIR}/inc/oaes_config.h
+		${CMAKE_CURRENT_SOURCE_DIR}/inc/oaes_lib.h
+		${CMAKE_CURRENT_SOURCE_DIR}/src/isaac/rand.h
+		${CMAKE_CURRENT_SOURCE_DIR}/src/isaac/standard.h
+	)
+
+set (SRC_test_encrypt
+		${CMAKE_CURRENT_SOURCE_DIR}/test/test_encrypt.c
+	)
+
+set (SRC_test_keys
+		${CMAKE_CURRENT_SOURCE_DIR}/test/test_keys.c
+	)
+
+set (SRC_test_performance
+		${CMAKE_CURRENT_SOURCE_DIR}/test/test_performance.c
+	)
+
+set (SRC_vt_aes
+		${CMAKE_CURRENT_SOURCE_DIR}/test/vt_aes.c
+	)
+
+set (SRC_oaes
+		${CMAKE_CURRENT_SOURCE_DIR}/src/oaes.c
+	)
+
+add_executable (test_encrypt ${SRC_test_encrypt} ${SRC} ${HDR})
+add_executable (test_keys ${SRC_test_keys} ${SRC} ${HDR})
+add_executable (test_performance ${SRC_test_performance} ${SRC} ${HDR})
+add_executable (vt_aes ${SRC_vt_aes} ${SRC} ${HDR})
+add_executable (oaes ${SRC_oaes} ${SRC} ${HDR})
diff --git a/openaes/LICENSE b/openaes/LICENSE
new file mode 100644
index 0000000..d824e13
--- /dev/null
+++ b/openaes/LICENSE
@@ -0,0 +1,27 @@
+---------------------------------------------------------------------------
+OpenAES Licence
+---------------------------------------------------------------------------
+Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
diff --git a/openaes/README b/openaes/README
new file mode 100644
index 0000000..6fb957b
--- /dev/null
+++ b/openaes/README
@@ -0,0 +1,78 @@
+---------------------------------------------------------------------------
+OpenAES-0.7.0
+Nabil S. Al Ramli
+www.nalramli.com
+---------------------------------------------------------------------------
+
+License Terms
+-------------
+
+---------------------------------------------------------------------------
+OpenAES Licence
+---------------------------------------------------------------------------
+Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  - Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+  - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+
+Introduction
+------------
+
+OpenAES is an open source implementation of the Advanced Encryption
+Standard.  It is distributed as a portable, lightweight C library that can
+be easily integrated into applications.
+
+Compiling
+---------
+
+OpenAES has been tested with the GCC as well as VC compilers.  It is
+necessary to compile the source files located in ./src, and to add ./inc to
+the include paths.
+
+If you are building with OAES_HAVE_ISAAC defined (true by default), then
+you also need to link in the source files under ./src/isaac and also add
+./src/isaac to the include paths.
+
+You may edit ./inc/oaes_config.h to modify build options.
+
+CMake 2.8.0 can be used to build the test programs on different platforms.
+
+In a Linux command line terminal type:
+
+cmake .
+make
+
+In Windows, in a Visual Studio command line window type:
+
+cmake . -G "NMake Makefiles"
+nmake
+
+Usage
+-----
+
+Usage is described in the header file ./inc/oaes_lib.h.
+
+Samples
+-------
+
+Samples applications are provided in the /test folder.
diff --git a/openaes/VERSION b/openaes/VERSION
new file mode 100644
index 0000000..831dbdd
--- /dev/null
+++ b/openaes/VERSION
@@ -0,0 +1 @@
+OpenAES-0.7.0
\ No newline at end of file
diff --git a/openaes/inc/oaes_config.h b/openaes/inc/oaes_config.h
new file mode 100644
index 0000000..d887f03
--- /dev/null
+++ b/openaes/inc/oaes_config.h
@@ -0,0 +1,50 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _OAES_CONFIG_H
+#define _OAES_CONFIG_H
+
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+#ifndef OAES_HAVE_ISAAC
+#define OAES_HAVE_ISAAC 1
+#endif // OAES_HAVE_ISAAC
+
+#ifndef OAES_DEBUG
+#define OAES_DEBUG 0
+#endif // OAES_DEBUG
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif // _OAES_CONFIG_H
diff --git a/openaes/inc/oaes_lib.h b/openaes/inc/oaes_lib.h
new file mode 100644
index 0000000..fd89a70
--- /dev/null
+++ b/openaes/inc/oaes_lib.h
@@ -0,0 +1,172 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef _OAES_LIB_H
+#define _OAES_LIB_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+#define OAES_VERSION "0.7.0"
+#define OAES_BLOCK_SIZE 16
+
+typedef void OAES_CTX;
+
+typedef enum
+{
+	OAES_RET_FIRST = 0,
+	OAES_RET_SUCCESS = 0,
+	OAES_RET_UNKNOWN,
+	OAES_RET_ARG1,
+	OAES_RET_ARG2,
+	OAES_RET_ARG3,
+	OAES_RET_ARG4,
+	OAES_RET_ARG5,
+	OAES_RET_NOKEY,
+	OAES_RET_MEM,
+	OAES_RET_BUF,
+	OAES_RET_HEADER,
+	OAES_RET_COUNT
+} OAES_RET;
+
+/*
+ * oaes_set_option() takes one of these values for its [option] parameter
+ * some options accept either an optional or a required [value] parameter
+ */
+// no option
+#define OAES_OPTION_NONE 0
+// enable ECB mode, disable CBC mode
+#define OAES_OPTION_ECB 1
+// enable CBC mode, disable ECB mode
+// value is optional, may pass uint8_t iv[OAES_BLOCK_SIZE] to specify
+// the value of the initialization vector, iv
+#define OAES_OPTION_CBC 2
+
+#ifdef OAES_DEBUG
+typedef int ( * oaes_step_cb ) (
+		const uint8_t state[OAES_BLOCK_SIZE],
+		const char * step_name,
+		int step_count,
+		void * user_data );
+// enable state stepping mode
+// value is required, must pass oaes_step_cb to receive the state at each step
+#define OAES_OPTION_STEP_ON 4
+// disable state stepping mode
+#define OAES_OPTION_STEP_OFF 8
+#endif // OAES_DEBUG
+
+typedef uint16_t OAES_OPTION;
+
+/*
+ * // usage:
+ * 
+ * OAES_CTX * ctx = oaes_alloc();
+ * .
+ * .
+ * .
+ * {
+ *   oaes_gen_key_xxx( ctx );
+ *   {
+ *     oaes_key_export( ctx, _buf, &_buf_len );
+ *     // or
+ *     oaes_key_export_data( ctx, _buf, &_buf_len );\
+ *   }
+ * }
+ * // or
+ * {
+ *   oaes_key_import( ctx, _buf, _buf_len );
+ *   // or
+ *   oaes_key_import_data( ctx, _buf, _buf_len );
+ * }
+ * .
+ * .
+ * .
+ * oaes_encrypt( ctx, m, m_len, c, &c_len );
+ * .
+ * .
+ * .
+ * oaes_decrypt( ctx, c, c_len, m, &m_len );
+ * .
+ * .
+ * .
+ * oaes_free( &ctx );
+ */
+
+OAES_CTX * oaes_alloc();
+
+OAES_RET oaes_free( OAES_CTX ** ctx );
+
+OAES_RET oaes_set_option( OAES_CTX * ctx,
+		OAES_OPTION option, const void * value );
+
+OAES_RET oaes_key_gen_128( OAES_CTX * ctx );
+
+OAES_RET oaes_key_gen_192( OAES_CTX * ctx );
+
+OAES_RET oaes_key_gen_256( OAES_CTX * ctx );
+
+// export key with header information
+// set data == NULL to get the required data_len
+OAES_RET oaes_key_export( OAES_CTX * ctx,
+		uint8_t * data, size_t * data_len );
+
+// directly export the data from key
+// set data == NULL to get the required data_len
+OAES_RET oaes_key_export_data( OAES_CTX * ctx,
+		uint8_t * data, size_t * data_len );
+
+// import key with header information
+OAES_RET oaes_key_import( OAES_CTX * ctx,
+		const uint8_t * data, size_t data_len );
+
+// directly import data into key
+OAES_RET oaes_key_import_data( OAES_CTX * ctx,
+		const uint8_t * data, size_t data_len );
+
+// set c == NULL to get the required c_len
+OAES_RET oaes_encrypt( OAES_CTX * ctx,
+		const uint8_t * m, size_t m_len, uint8_t * c, size_t * c_len );
+
+// set m == NULL to get the required m_len
+OAES_RET oaes_decrypt( OAES_CTX * ctx,
+		const uint8_t * c, size_t c_len, uint8_t * m, size_t * m_len );
+
+// set buf == NULL to get the required buf_len
+OAES_RET oaes_sprintf(
+		char * buf, size_t * buf_len, const uint8_t * data, size_t data_len );
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif // _OAES_LIB_H
diff --git a/openaes/src/isaac/rand.c b/openaes/src/isaac/rand.c
new file mode 100644
index 0000000..63babc7
--- /dev/null
+++ b/openaes/src/isaac/rand.c
@@ -0,0 +1,137 @@
+/*
+------------------------------------------------------------------------------
+rand.c: By Bob Jenkins.  My random number generator, ISAAC.  Public Domain.
+MODIFIED:
+  960327: Creation (addition of randinit, really)
+  970719: use context, not global variables, for internal state
+  980324: added main (ifdef'ed out), also rearranged randinit()
+  010626: Note that this is public domain
+------------------------------------------------------------------------------
+*/
+#ifndef STANDARD
+#include "standard.h"
+#endif
+#ifndef RAND
+#include "rand.h"
+#endif
+
+
+#define ind(mm,x)  (*(ub4 *)((ub1 *)(mm) + ((x) & ((RANDSIZ-1)<<2))))
+#define rngstep(mix,a,b,mm,m,m2,r,x) \
+{ \
+  x = *m;  \
+  a = (a^(mix)) + *(m2++); \
+  *(m++) = y = ind(mm,x) + a + b; \
+  *(r++) = b = ind(mm,y>>RANDSIZL) + x; \
+}
+
+void     isaac(ctx)
+randctx *ctx;
+{
+   register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
+   mm=ctx->randmem; r=ctx->randrsl;
+   a = ctx->randa; b = ctx->randb + (++ctx->randc);
+   for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
+   {
+      rngstep( a<<13, a, b, mm, m, m2, r, x);
+      rngstep( a>>6 , a, b, mm, m, m2, r, x);
+      rngstep( a<<2 , a, b, mm, m, m2, r, x);
+      rngstep( a>>16, a, b, mm, m, m2, r, x);
+   }
+   for (m2 = mm; m2<mend; )
+   {
+      rngstep( a<<13, a, b, mm, m, m2, r, x);
+      rngstep( a>>6 , a, b, mm, m, m2, r, x);
+      rngstep( a<<2 , a, b, mm, m, m2, r, x);
+      rngstep( a>>16, a, b, mm, m, m2, r, x);
+   }
+   ctx->randb = b; ctx->randa = a;
+}
+
+
+#define mix(a,b,c,d,e,f,g,h) \
+{ \
+   a^=b<<11; d+=a; b+=c; \
+   b^=c>>2;  e+=b; c+=d; \
+   c^=d<<8;  f+=c; d+=e; \
+   d^=e>>16; g+=d; e+=f; \
+   e^=f<<10; h+=e; f+=g; \
+   f^=g>>4;  a+=f; g+=h; \
+   g^=h<<8;  b+=g; h+=a; \
+   h^=a>>9;  c+=h; a+=b; \
+}
+
+/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
+void randinit(ctx, flag)
+randctx *ctx;
+word     flag;
+{
+   word i;
+   ub4 a,b,c,d,e,f,g,h;
+   ub4 *m,*r;
+   ctx->randa = ctx->randb = ctx->randc = 0;
+   m=ctx->randmem;
+   r=ctx->randrsl;
+   a=b=c=d=e=f=g=h=0x9e3779b9;  /* the golden ratio */
+
+   for (i=0; i<4; ++i)          /* scramble it */
+   {
+     mix(a,b,c,d,e,f,g,h);
+   }
+
+   if (flag) 
+   {
+     /* initialize using the contents of r[] as the seed */
+     for (i=0; i<RANDSIZ; i+=8)
+     {
+       a+=r[i  ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
+       e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
+       mix(a,b,c,d,e,f,g,h);
+       m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
+       m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
+     }
+     /* do a second pass to make all of the seed affect all of m */
+     for (i=0; i<RANDSIZ; i+=8)
+     {
+       a+=m[i  ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
+       e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
+       mix(a,b,c,d,e,f,g,h);
+       m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
+       m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
+     }
+   }
+   else
+   {
+     /* fill in m[] with messy stuff */
+     for (i=0; i<RANDSIZ; i+=8)
+     {
+       mix(a,b,c,d,e,f,g,h);
+       m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
+       m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
+     }
+   }
+
+   isaac(ctx);            /* fill in the first set of results */
+   ctx->randcnt=RANDSIZ;  /* prepare to use the first set of results */
+}
+
+
+#ifdef NEVER
+int main()
+{
+  ub4 i,j;
+  randctx ctx;
+  ctx.randa=ctx.randb=ctx.randc=(ub4)0;
+  for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
+  randinit(&ctx, TRUE);
+  for (i=0; i<2; ++i)
+  {
+    isaac(&ctx);
+    for (j=0; j<256; ++j)
+    {
+      printf("%.8lx",ctx.randrsl[j]);
+      if ((j&7)==7) printf("\n");
+    }
+  }
+}
+#endif
diff --git a/openaes/src/isaac/rand.h b/openaes/src/isaac/rand.h
new file mode 100644
index 0000000..73f6e3e
--- /dev/null
+++ b/openaes/src/isaac/rand.h
@@ -0,0 +1,56 @@
+/*
+------------------------------------------------------------------------------
+rand.h: definitions for a random number generator
+By Bob Jenkins, 1996, Public Domain
+MODIFIED:
+  960327: Creation (addition of randinit, really)
+  970719: use context, not global variables, for internal state
+  980324: renamed seed to flag
+  980605: recommend RANDSIZL=4 for noncryptography.
+  010626: note this is public domain
+------------------------------------------------------------------------------
+*/
+#ifndef STANDARD
+#include "standard.h"
+#endif
+
+#ifndef RAND
+#define RAND
+#define RANDSIZL   (8)
+#define RANDSIZ    (1<<RANDSIZL)
+
+/* context of random number generator */
+struct randctx
+{
+  ub4 randcnt;
+  ub4 randrsl[RANDSIZ];
+  ub4 randmem[RANDSIZ];
+  ub4 randa;
+  ub4 randb;
+  ub4 randc;
+};
+typedef  struct randctx  randctx;
+
+/*
+------------------------------------------------------------------------------
+ If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
+------------------------------------------------------------------------------
+*/
+void randinit(/*_ randctx *r, word flag _*/);
+
+void isaac(/*_ randctx *r _*/);
+
+
+/*
+------------------------------------------------------------------------------
+ Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
+------------------------------------------------------------------------------
+*/
+#define rand(r) \
+   (!(r)->randcnt-- ? \
+     (isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
+     (r)->randrsl[(r)->randcnt])
+
+#endif  /* RAND */
+
+
diff --git a/openaes/src/isaac/standard.h b/openaes/src/isaac/standard.h
new file mode 100644
index 0000000..202a5d6
--- /dev/null
+++ b/openaes/src/isaac/standard.h
@@ -0,0 +1,57 @@
+/*
+------------------------------------------------------------------------------
+Standard definitions and types, Bob Jenkins
+------------------------------------------------------------------------------
+*/
+#ifndef STANDARD
+# define STANDARD
+# ifndef STDIO
+#  include <stdio.h>
+#  define STDIO
+# endif
+# ifndef STDDEF
+#  include <stddef.h>
+#  define STDDEF
+# endif
+typedef  unsigned long long  ub8;
+#define UB8MAXVAL 0xffffffffffffffffLL
+#define UB8BITS 64
+typedef    signed long long  sb8;
+#define SB8MAXVAL 0x7fffffffffffffffLL
+typedef  unsigned long  int  ub4;   /* unsigned 4-byte quantities */
+#define UB4MAXVAL 0xffffffff
+typedef    signed long  int  sb4;
+#define UB4BITS 32
+#define SB4MAXVAL 0x7fffffff
+typedef  unsigned short int  ub2;
+#define UB2MAXVAL 0xffff
+#define UB2BITS 16
+typedef    signed short int  sb2;
+#define SB2MAXVAL 0x7fff
+typedef  unsigned       char ub1;
+#define UB1MAXVAL 0xff
+#define UB1BITS 8
+typedef    signed       char sb1;   /* signed 1-byte quantities */
+#define SB1MAXVAL 0x7f
+typedef                 int  word;  /* fastest type available */
+
+#define bis(target,mask)  ((target) |=  (mask))
+#define bic(target,mask)  ((target) &= ~(mask))
+#define bit(target,mask)  ((target) &   (mask))
+#ifndef min
+# define min(a,b) (((a)<(b)) ? (a) : (b))
+#endif /* min */
+#ifndef max
+# define max(a,b) (((a)<(b)) ? (b) : (a))
+#endif /* max */
+#ifndef align
+# define align(a) (((ub4)a+(sizeof(void *)-1))&(~(sizeof(void *)-1)))
+#endif /* align */
+#ifndef abs
+# define abs(a)   (((a)>0) ? (a) : -(a))
+#endif
+#define TRUE  1
+#define FALSE 0
+#define SUCCESS 0  /* 1 on VAX */
+
+#endif /* STANDARD */
diff --git a/openaes/src/oaes.c b/openaes/src/oaes.c
new file mode 100644
index 0000000..9a5d268
--- /dev/null
+++ b/openaes/src/oaes.c
@@ -0,0 +1,317 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define OAES_DEBUG 1
+#include "../inc/oaes_lib.h"
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+#include <io.h>
+#else
+__inline static int setmode(int a, int b)
+{
+	return 0;
+}
+#endif
+
+#ifndef __max
+	#define __max(a,b)  (((a) > (b)) ? (a) : (b))
+#endif // __max
+
+#ifndef __min
+	#define __min(a,b)  (((a) < (b)) ? (a) : (b))
+#endif // __min
+
+#define OAES_BUF_LEN_ENC 4096 - 2 * OAES_BLOCK_SIZE
+#define OAES_BUF_LEN_DEC 4096
+
+static void usage( const char * exe_name )
+{
+	if( NULL == exe_name )
+		return;
+	
+	fprintf( stderr,
+			"Usage:\n"
+			"  %s <command> --key <key_data> [options]\n"
+			"\n"
+			"    command:\n"
+			"      enc: encrypt\n"
+			"      dec:  decrypt\n"
+			"\n"
+			"    options:\n"
+			"      --ecb: use ecb mode instead of cbc\n"
+			"      --in <path_in>\n"
+			"      --out <path_out>\n"
+			"\n",
+			exe_name
+	);
+}
+
+int main(int argc, char** argv)
+{
+	size_t _i = 0, _j = 0;
+	OAES_CTX * ctx = NULL;
+	uint8_t _buf_in[OAES_BUF_LEN_DEC];
+	uint8_t *_buf_out = NULL, _key_data[32] = "";
+	size_t _buf_in_len = 0, _buf_out_len = 0, _read_len = 0;
+	size_t _key_data_len = 0;
+	short _is_ecb = 0;
+	char *_file_in = NULL, *_file_out = NULL;
+	int _op = 0;
+	FILE *_f_in = stdin, *_f_out = stdout;
+	
+	fprintf( stderr, "\n"
+		"*******************************************************************************\n"
+		"* OpenAES %-10s                                                          *\n"
+		"* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com                     *\n"
+		"*******************************************************************************\n\n",
+		OAES_VERSION );
+
+	// pad the key
+	for( _j = 0; _j < 32; _j++ )
+		_key_data[_j] = _j + 1;
+
+	if( argc < 2 )
+	{
+		usage( argv[0] );
+		return EXIT_FAILURE;
+	}
+
+	if( 0 == strcmp( argv[1], "enc" ) )
+	{
+		_op = 0;
+		_read_len = OAES_BUF_LEN_ENC;
+	}
+	else if( 0 == strcmp( argv[1], "dec" ) )
+	{
+		_op = 1;
+		_read_len = OAES_BUF_LEN_DEC;
+	}
+	else
+	{
+		fprintf(stderr, "Error: Unknown command '%s'.", argv[1]);
+		usage( argv[0] );
+		return EXIT_FAILURE;
+	}
+
+	for( _i = 2; _i < argc; _i++ )
+	{
+		int _found = 0;
+
+		if( 0 == strcmp( argv[_i], "--ecb" ) )
+		{
+			_found = 1;
+			_is_ecb = 1;
+		}
+		
+		if( 0 == strcmp( argv[_i], "--key" ) )
+		{
+			_found = 1;
+			_i++; // key_data
+			if( _i >= argc )
+			{
+				fprintf(stderr, "Error: No value specified for '%s'.\n",
+						"--key");
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			_key_data_len = strlen(argv[_i]);
+			if( 16 >= _key_data_len )
+				_key_data_len = 16;
+			else if( 24 >= _key_data_len )
+				_key_data_len = 24;
+			else
+				_key_data_len = 32;
+			memcpy(_key_data, argv[_i], __min(32, strlen(argv[_i])));
+		}
+		
+		if( 0 == strcmp( argv[_i], "--in" ) )
+		{
+			_found = 1;
+			_i++; // path_in
+			if( _i >= argc )
+			{
+				fprintf(stderr, "Error: No value specified for '%s'.\n",
+						"--in");
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			_file_in = argv[_i];
+		}
+		
+		if( 0 == strcmp( argv[_i], "--out" ) )
+		{
+			_found = 1;
+			_i++; // path_out
+			if( _i >= argc )
+			{
+				fprintf(stderr, "Error: No value specified for '%s'.\n",
+						"--out");
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			_file_out = argv[_i];
+		}
+		
+		if( 0 == _found )
+		{
+			fprintf(stderr, "Error: Invalid option '%s'.\n", argv[_i]);
+			usage( argv[0] );
+			return EXIT_FAILURE;
+		}			
+	}
+
+	if( 0 == _key_data_len )
+	{
+		fprintf(stderr, "Error: --key must be specified.\n");
+		return EXIT_FAILURE;
+	}
+
+	if( _file_in )
+	{
+		_f_in = fopen(_file_in, "rb");
+		if( NULL == _f_in )
+		{
+			fprintf(stderr,
+				"Error: Failed to open '-%s' for reading.\n", _file_in);
+			return EXIT_FAILURE;
+		}
+	}
+	else
+	{
+		if( setmode(fileno(stdin), 0x8000) < 0 )
+			fprintf(stderr,"Error: Failed in setmode().\n");
+		_f_in = stdin;
+	}
+
+	if( _file_out )
+	{
+		_f_out = fopen(_file_out, "wb");
+		if( NULL == _f_out )
+		{
+			fprintf(stderr,
+				"Error: Failed to open '-%s' for writing.\n", _file_out);
+			if( _file_in )
+				fclose(_f_in);
+			return EXIT_FAILURE;
+		}
+	}
+	else
+	{
+		if( setmode(fileno(stdout), 0x8000) < 0 )
+			fprintf(stderr, "Error: Failed in setmode().\n");
+		_f_out = stdout;
+	}
+
+	ctx = oaes_alloc();
+	if( NULL == ctx )
+	{
+		fprintf(stderr, "Error: Failed to initialize OAES.\n");
+		if( _file_in )
+			fclose(_f_in);
+		if( _file_out )
+			fclose(_f_out);
+		return EXIT_FAILURE;
+	}
+	if( _is_ecb )
+		if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) )
+			fprintf(stderr, "Error: Failed to set OAES options.\n");
+
+	oaes_key_import_data( ctx, _key_data, _key_data_len );
+
+	while( _buf_in_len =
+		fread(_buf_in, sizeof(uint8_t), _read_len, _f_in) )
+	{
+		switch(_op)
+		{
+		case 0:
+			if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+					_buf_in, _buf_in_len, NULL, &_buf_out_len ) )
+				fprintf( stderr,
+					"Error: Failed to retrieve required buffer size for "
+					"encryption.\n" );
+			_buf_out = (uint8_t *) calloc( _buf_out_len, sizeof( char ) );
+			if( NULL == _buf_out )
+			{
+				fprintf(stderr,  "Error: Failed to allocate memory.\n" );
+				if( _file_in )
+					fclose(_f_in);
+				if( _file_out )
+					fclose(_f_out);
+				return EXIT_FAILURE;
+			}
+			if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+					_buf_in, _buf_in_len, _buf_out, &_buf_out_len ) )
+				fprintf(stderr, "Error: Encryption failed.\n");
+			fwrite(_buf_out, sizeof(uint8_t), _buf_out_len, _f_out);
+			free(_buf_out);
+			break;
+		case 1:
+			if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+					_buf_in, _buf_in_len, NULL, &_buf_out_len ) )
+				fprintf( stderr,
+					"Error: Failed to retrieve required buffer size for "
+					"encryption.\n" );
+			_buf_out = (uint8_t *) calloc( _buf_out_len, sizeof( char ) );
+			if( NULL == _buf_out )
+			{
+				fprintf(stderr,  "Error: Failed to allocate memory.\n" );
+				free( _buf_out );
+				if( _file_in )
+					fclose(_f_in);
+				if( _file_out )
+					fclose(_f_out);
+				return EXIT_FAILURE;
+			}
+			if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+					_buf_in, _buf_in_len, _buf_out, &_buf_out_len ) )
+				fprintf(stderr, "Error: Decryption failed.\n");
+			fwrite(_buf_out, sizeof(uint8_t), _buf_out_len, _f_out);
+			free(_buf_out);
+			break;
+		default:
+			break;
+		}
+	}
+
+
+	if( OAES_RET_SUCCESS !=  oaes_free( &ctx ) )
+		fprintf(stderr, "Error: Failed to uninitialize OAES.\n");
+	
+	if( _file_in )
+		fclose(_f_in);
+	if( _file_out )
+		fclose(_f_out);
+
+	return (EXIT_SUCCESS);
+}
diff --git a/openaes/src/oaes_lib.c b/openaes/src/oaes_lib.c
new file mode 100644
index 0000000..7cfdc1c
--- /dev/null
+++ b/openaes/src/oaes_lib.c
@@ -0,0 +1,1429 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+static const char _NR[] = {
+	0x4e,0x61,0x62,0x69,0x6c,0x20,0x53,0x2e,0x20,
+	0x41,0x6c,0x20,0x52,0x61,0x6d,0x6c,0x69,0x00 };
+
+#include <stddef.h>
+#include <time.h> 
+#include <sys/timeb.h>
+#include <malloc.h>
+#include <string.h>
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+#include "oaes_config.h"
+#include "oaes_lib.h"
+
+#ifdef OAES_HAVE_ISAAC
+#include "rand.h"
+#endif // OAES_HAVE_ISAAC
+
+#define OAES_RKEY_LEN 4
+#define OAES_COL_LEN 4
+#define OAES_ROUND_BASE 7
+
+// the block is padded
+#define OAES_FLAG_PAD 0x01
+
+#ifndef min
+# define min(a,b) (((a)<(b)) ? (a) : (b))
+#endif /* min */
+
+typedef struct _oaes_key
+{
+	size_t data_len;
+	uint8_t *data;
+	size_t exp_data_len;
+	uint8_t *exp_data;
+	size_t num_keys;
+	size_t key_base;
+} oaes_key;
+
+typedef struct _oaes_ctx
+{
+#ifdef OAES_HAVE_ISAAC
+  randctx * rctx;
+#endif // OAES_HAVE_ISAAC
+
+#ifdef OAES_DEBUG
+	oaes_step_cb step_cb;
+#endif // OAES_DEBUG
+
+	oaes_key * key;
+	OAES_OPTION options;
+	uint8_t iv[OAES_BLOCK_SIZE];
+} oaes_ctx;
+
+// "OAES<8-bit header version><8-bit type><16-bit options><8-bit flags><56-bit reserved>"
+static uint8_t oaes_header[OAES_BLOCK_SIZE] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x4f, 0x41, 0x45, 0x53, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static uint8_t oaes_gf_8[] = {
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
+
+static uint8_t oaes_sub_byte_value[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+	/*1*/	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+	/*2*/	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+	/*3*/	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+	/*4*/	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+	/*5*/	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+	/*6*/	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+	/*7*/	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+	/*8*/	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+	/*9*/	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+	/*a*/	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+	/*b*/	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+	/*c*/	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+	/*d*/	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+	/*e*/	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+	/*f*/	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
+};
+
+static uint8_t oaes_inv_sub_byte_value[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+	/*1*/	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+	/*2*/	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+	/*3*/	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+	/*4*/	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+	/*5*/	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+	/*6*/	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+	/*7*/	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+	/*8*/	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+	/*9*/	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+	/*a*/	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+	/*b*/	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+	/*c*/	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+	/*d*/	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+	/*e*/	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+	/*f*/	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
+};
+
+static uint8_t oaes_gf_mul_2[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+	/*1*/	0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
+	/*2*/	0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
+	/*3*/	0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
+	/*4*/	0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
+	/*5*/	0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+	/*6*/	0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
+	/*7*/	0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
+	/*8*/	0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
+	/*9*/	0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
+	/*a*/	0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
+	/*b*/	0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
+	/*c*/	0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
+	/*d*/	0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
+	/*e*/	0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
+	/*f*/	0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5,
+};
+
+static uint8_t oaes_gf_mul_3[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
+	/*1*/	0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
+	/*2*/	0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
+	/*3*/	0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
+	/*4*/	0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
+	/*5*/	0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
+	/*6*/	0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
+	/*7*/	0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
+	/*8*/	0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
+	/*9*/	0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
+	/*a*/	0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
+	/*b*/	0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
+	/*c*/	0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
+	/*d*/	0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
+	/*e*/	0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
+	/*f*/	0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a,
+};
+
+static uint8_t oaes_gf_mul_9[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+	/*1*/	0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
+	/*2*/	0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+	/*3*/	0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
+	/*4*/	0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
+	/*5*/	0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
+	/*6*/	0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
+	/*7*/	0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
+	/*8*/	0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
+	/*9*/	0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
+	/*a*/	0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
+	/*b*/	0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
+	/*c*/	0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
+	/*d*/	0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
+	/*e*/	0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
+	/*f*/	0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46,
+};
+
+static uint8_t oaes_gf_mul_b[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
+	/*1*/	0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
+	/*2*/	0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
+	/*3*/	0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
+	/*4*/	0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
+	/*5*/	0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
+	/*6*/	0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
+	/*7*/	0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
+	/*8*/	0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
+	/*9*/	0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
+	/*a*/	0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
+	/*b*/	0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
+	/*c*/	0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
+	/*d*/	0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
+	/*e*/	0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
+	/*f*/	0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3,
+};
+
+static uint8_t oaes_gf_mul_d[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
+	/*1*/	0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
+	/*2*/	0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
+	/*3*/	0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
+	/*4*/	0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
+	/*5*/	0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
+	/*6*/	0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
+	/*7*/	0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
+	/*8*/	0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
+	/*9*/	0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
+	/*a*/	0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
+	/*b*/	0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
+	/*c*/	0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
+	/*d*/	0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
+	/*e*/	0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
+	/*f*/	0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97,
+};
+
+static uint8_t oaes_gf_mul_e[16][16] = {
+	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
+	/*0*/	0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
+	/*1*/	0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
+	/*2*/	0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
+	/*3*/	0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
+	/*4*/	0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
+	/*5*/	0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
+	/*6*/	0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
+	/*7*/	0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
+	/*8*/	0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
+	/*9*/	0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
+	/*a*/	0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
+	/*b*/	0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
+	/*c*/	0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
+	/*d*/	0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
+	/*e*/	0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
+	/*f*/	0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d,
+};
+
+static OAES_RET oaes_sub_byte( uint8_t * byte )
+{
+	size_t _x, _y;
+	
+	if( NULL == byte )
+		return OAES_RET_ARG1;
+
+	_x = _y = *byte;
+	_x &= 0x0f;
+	_y &= 0xf0;
+	_y >>= 4;
+	*byte = oaes_sub_byte_value[_y][_x];
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_inv_sub_byte( uint8_t * byte )
+{
+	size_t _x, _y;
+	
+	if( NULL == byte )
+		return OAES_RET_ARG1;
+
+	_x = _y = *byte;
+	_x &= 0x0f;
+	_y &= 0xf0;
+	_y >>= 4;
+	*byte = oaes_inv_sub_byte_value[_y][_x];
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_word_rot_right( uint8_t word[OAES_COL_LEN] )
+{
+	uint8_t _temp[OAES_COL_LEN];
+	
+	if( NULL == word )
+		return OAES_RET_ARG1;
+
+	memcpy( _temp + 1, word, OAES_COL_LEN - 1 );
+	_temp[0] = word[OAES_COL_LEN - 1];
+	memcpy( word, _temp, OAES_COL_LEN );
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_word_rot_left( uint8_t word[OAES_COL_LEN] )
+{
+	uint8_t _temp[OAES_COL_LEN];
+	
+	if( NULL == word )
+		return OAES_RET_ARG1;
+
+	memcpy( _temp, word + 1, OAES_COL_LEN - 1 );
+	_temp[OAES_COL_LEN - 1] = word[0];
+	memcpy( word, _temp, OAES_COL_LEN );
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_shift_rows( uint8_t block[OAES_BLOCK_SIZE] )
+{
+	uint8_t _temp[OAES_BLOCK_SIZE];
+
+	if( NULL == block )
+		return OAES_RET_ARG1;
+
+	_temp[0x00] = block[0x00];
+	_temp[0x01] = block[0x05];
+	_temp[0x02] = block[0x0a];
+	_temp[0x03] = block[0x0f];
+	_temp[0x04] = block[0x04];
+	_temp[0x05] = block[0x09];
+	_temp[0x06] = block[0x0e];
+	_temp[0x07] = block[0x03];
+	_temp[0x08] = block[0x08];
+	_temp[0x09] = block[0x0d];
+	_temp[0x0a] = block[0x02];
+	_temp[0x0b] = block[0x07];
+	_temp[0x0c] = block[0x0c];
+	_temp[0x0d] = block[0x01];
+	_temp[0x0e] = block[0x06];
+	_temp[0x0f] = block[0x0b];
+	memcpy( block, _temp, OAES_BLOCK_SIZE );
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_inv_shift_rows( uint8_t block[OAES_BLOCK_SIZE] )
+{
+	uint8_t _temp[OAES_BLOCK_SIZE];
+
+	if( NULL == block )
+		return OAES_RET_ARG1;
+
+	_temp[0x00] = block[0x00];
+	_temp[0x01] = block[0x0d];
+	_temp[0x02] = block[0x0a];
+	_temp[0x03] = block[0x07];
+	_temp[0x04] = block[0x04];
+	_temp[0x05] = block[0x01];
+	_temp[0x06] = block[0x0e];
+	_temp[0x07] = block[0x0b];
+	_temp[0x08] = block[0x08];
+	_temp[0x09] = block[0x05];
+	_temp[0x0a] = block[0x02];
+	_temp[0x0b] = block[0x0f];
+	_temp[0x0c] = block[0x0c];
+	_temp[0x0d] = block[0x09];
+	_temp[0x0e] = block[0x06];
+	_temp[0x0f] = block[0x03];
+	memcpy( block, _temp, OAES_BLOCK_SIZE );
+	
+	return OAES_RET_SUCCESS;
+}
+
+static uint8_t oaes_gf_mul(uint8_t left, uint8_t right)
+{
+	size_t _x, _y;
+	
+	_x = _y = left;
+	_x &= 0x0f;
+	_y &= 0xf0;
+	_y >>= 4;
+	
+	switch( right )
+	{
+		case 0x02:
+			return oaes_gf_mul_2[_y][_x];
+			break;
+		case 0x03:
+			return oaes_gf_mul_3[_y][_x];
+			break;
+		case 0x09:
+			return oaes_gf_mul_9[_y][_x];
+			break;
+		case 0x0b:
+			return oaes_gf_mul_b[_y][_x];
+			break;
+		case 0x0d:
+			return oaes_gf_mul_d[_y][_x];
+			break;
+		case 0x0e:
+			return oaes_gf_mul_e[_y][_x];
+			break;
+		default:
+			return left;
+			break;
+	}
+}
+
+static OAES_RET oaes_mix_cols( uint8_t word[OAES_COL_LEN] )
+{
+	uint8_t _temp[OAES_COL_LEN];
+
+	if( NULL == word )
+		return OAES_RET_ARG1;
+	
+	_temp[0] = oaes_gf_mul(word[0], 0x02) ^ oaes_gf_mul( word[1], 0x03 ) ^
+			word[2] ^ word[3];
+	_temp[1] = word[0] ^ oaes_gf_mul( word[1], 0x02 ) ^
+			oaes_gf_mul( word[2], 0x03 ) ^ word[3];
+	_temp[2] = word[0] ^ word[1] ^
+			oaes_gf_mul( word[2], 0x02 ) ^ oaes_gf_mul( word[3], 0x03 );
+	_temp[3] = oaes_gf_mul( word[0], 0x03 ) ^ word[1] ^
+			word[2] ^ oaes_gf_mul( word[3], 0x02 );
+	memcpy( word, _temp, OAES_COL_LEN );
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_inv_mix_cols( uint8_t word[OAES_COL_LEN] )
+{
+	uint8_t _temp[OAES_COL_LEN];
+
+	if( NULL == word )
+		return OAES_RET_ARG1;
+	
+	_temp[0] = oaes_gf_mul( word[0], 0x0e ) ^ oaes_gf_mul( word[1], 0x0b ) ^
+			oaes_gf_mul( word[2], 0x0d ) ^ oaes_gf_mul( word[3], 0x09 );
+	_temp[1] = oaes_gf_mul( word[0], 0x09 ) ^ oaes_gf_mul( word[1], 0x0e ) ^
+			oaes_gf_mul( word[2], 0x0b ) ^ oaes_gf_mul( word[3], 0x0d );
+	_temp[2] = oaes_gf_mul( word[0], 0x0d ) ^ oaes_gf_mul( word[1], 0x09 ) ^
+			oaes_gf_mul( word[2], 0x0e ) ^ oaes_gf_mul( word[3], 0x0b );
+	_temp[3] = oaes_gf_mul( word[0], 0x0b ) ^ oaes_gf_mul( word[1], 0x0d ) ^
+			oaes_gf_mul( word[2], 0x09 ) ^ oaes_gf_mul( word[3], 0x0e );
+	memcpy( word, _temp, OAES_COL_LEN );
+	
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_sprintf(
+		char * buf, size_t * buf_len, const uint8_t * data, size_t data_len )
+{
+	size_t _i, _buf_len_in;
+	char _temp[4];
+	
+	if( NULL == buf_len )
+		return OAES_RET_ARG2;
+
+	_buf_len_in = *buf_len;
+	*buf_len = data_len * 3 + data_len / OAES_BLOCK_SIZE + 1;
+	
+	if( NULL == buf )
+		return OAES_RET_SUCCESS;
+
+	if( *buf_len > _buf_len_in )
+		return OAES_RET_BUF;
+
+	if( NULL == data )
+		return OAES_RET_ARG3;
+
+	strcpy( buf, "" );
+	
+	for( _i = 0; _i < data_len; _i++ )
+	{
+		sprintf( _temp, "%02x ", data[_i] );
+		strcat( buf, _temp );
+		if( _i && 0 == ( _i + 1 ) % OAES_BLOCK_SIZE )
+			strcat( buf, "\n" );
+	}
+	
+	return OAES_RET_SUCCESS;
+}
+
+#ifdef OAES_HAVE_ISAAC
+static void oaes_get_seed( char buf[RANDSIZ + 1] )
+{
+	struct timeb timer;
+	struct tm *gmTimer;
+	char * _test = NULL;
+	
+	ftime (&timer);
+	gmTimer = gmtime( &timer.time );
+	_test = (char *) calloc( sizeof( char ), timer.millitm );
+	sprintf( buf, "%04d%02d%02d%02d%02d%02d%03d%p%d",
+		gmTimer->tm_year + 1900, gmTimer->tm_mon + 1, gmTimer->tm_mday,
+		gmTimer->tm_hour, gmTimer->tm_min, gmTimer->tm_sec, timer.millitm,
+		_test + timer.millitm, getpid() );
+	
+	if( _test )
+		free( _test );
+}
+#else
+static uint32_t oaes_get_seed()
+{
+	struct timeb timer;
+	struct tm *gmTimer;
+	char * _test = NULL;
+	uint32_t _ret = 0;
+	
+	ftime (&timer);
+	gmTimer = gmtime( &timer.time );
+	_test = (char *) calloc( sizeof( char ), timer.millitm );
+	_ret = gmTimer->tm_year + 1900 + gmTimer->tm_mon + 1 + gmTimer->tm_mday +
+			gmTimer->tm_hour + gmTimer->tm_min + gmTimer->tm_sec + timer.millitm +
+			(uint32_t) ( _test + timer.millitm ) + getpid();
+
+	if( _test )
+		free( _test );
+	
+	return _ret;
+}
+#endif // OAES_HAVE_ISAAC
+
+static OAES_RET oaes_key_destroy( oaes_key ** key )
+{
+	if( NULL == *key )
+		return OAES_RET_SUCCESS;
+	
+	if( (*key)->data )
+	{
+		free( (*key)->data );
+		(*key)->data = NULL;
+	}
+	
+	if( (*key)->exp_data )
+	{
+		free( (*key)->exp_data );
+		(*key)->exp_data = NULL;
+	}
+	
+	(*key)->data_len = 0;
+	(*key)->exp_data_len = 0;
+	(*key)->num_keys = 0;
+	(*key)->key_base = 0;
+	free( *key );
+	*key = NULL;
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_key_expand( OAES_CTX * ctx )
+{
+	size_t _i, _j;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+	_ctx->key->key_base = _ctx->key->data_len / OAES_RKEY_LEN;
+	_ctx->key->num_keys =  _ctx->key->key_base + OAES_ROUND_BASE;
+					
+	_ctx->key->exp_data_len = _ctx->key->num_keys * OAES_RKEY_LEN * OAES_COL_LEN;
+	_ctx->key->exp_data = (uint8_t *)
+			calloc( _ctx->key->exp_data_len, sizeof( uint8_t ));
+	
+	if( NULL == _ctx->key->exp_data )
+		return OAES_RET_MEM;
+	
+	// the first _ctx->key->data_len are a direct copy
+	memcpy( _ctx->key->exp_data, _ctx->key->data, _ctx->key->data_len );
+
+	// apply ExpandKey algorithm for remainder
+	for( _i = _ctx->key->key_base; _i < _ctx->key->num_keys * OAES_RKEY_LEN; _i++ )
+	{
+		uint8_t _temp[OAES_COL_LEN];
+		
+		memcpy( _temp,
+				_ctx->key->exp_data + ( _i - 1 ) * OAES_RKEY_LEN, OAES_COL_LEN );
+		
+		// transform key column
+		if( 0 == _i % _ctx->key->key_base )
+		{
+			oaes_word_rot_left( _temp );
+
+			for( _j = 0; _j < OAES_COL_LEN; _j++ )
+				oaes_sub_byte( _temp + _j );
+
+			_temp[0] = _temp[0] ^ oaes_gf_8[ _i / _ctx->key->key_base - 1 ];
+		}
+		else if( _ctx->key->key_base > 6 && 4 == _i % _ctx->key->key_base )
+		{
+			for( _j = 0; _j < OAES_COL_LEN; _j++ )
+				oaes_sub_byte( _temp + _j );
+		}
+		
+		for( _j = 0; _j < OAES_COL_LEN; _j++ )
+		{
+			_ctx->key->exp_data[ _i * OAES_RKEY_LEN + _j ] =
+					_ctx->key->exp_data[ ( _i - _ctx->key->key_base ) *
+					OAES_RKEY_LEN + _j ] ^ _temp[_j];
+		}
+	}
+	
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_key_gen( OAES_CTX * ctx, size_t key_size )
+{
+	size_t _i;
+	oaes_key * _key = NULL;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	OAES_RET _rc = OAES_RET_SUCCESS;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	_key = (oaes_key *) calloc( sizeof( oaes_key ), 1 );
+	
+	if( NULL == _key )
+		return OAES_RET_MEM;
+	
+	if( _ctx->key )
+		oaes_key_destroy( &(_ctx->key) );
+	
+	_key->data_len = key_size;
+	_key->data = (uint8_t *) calloc( key_size, sizeof( uint8_t ));
+	
+	if( NULL == _key->data )
+		return OAES_RET_MEM;
+	
+	for( _i = 0; _i < key_size; _i++ )
+#ifdef OAES_HAVE_ISAAC
+		_key->data[_i] = (uint8_t) rand( _ctx->rctx );
+#else
+		_key->data[_i] = (uint8_t) rand();
+#endif // OAES_HAVE_ISAAC
+	
+	_ctx->key = _key;
+	_rc = _rc || oaes_key_expand( ctx );
+	
+	if( _rc != OAES_RET_SUCCESS )
+	{
+		oaes_key_destroy( &(_ctx->key) );
+		return _rc;
+	}
+	
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_key_gen_128( OAES_CTX * ctx )
+{
+	return oaes_key_gen( ctx, 16 );
+}
+
+OAES_RET oaes_key_gen_192( OAES_CTX * ctx )
+{
+	return oaes_key_gen( ctx, 24 );
+}
+
+OAES_RET oaes_key_gen_256( OAES_CTX * ctx )
+{
+	return oaes_key_gen( ctx, 32 );
+}
+
+OAES_RET oaes_key_export( OAES_CTX * ctx,
+		uint8_t * data, size_t * data_len )
+{
+	size_t _data_len_in;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+	if( NULL == data_len )
+		return OAES_RET_ARG3;
+
+	_data_len_in = *data_len;
+	// data + header
+	*data_len = _ctx->key->data_len + OAES_BLOCK_SIZE;
+
+	if( NULL == data )
+		return OAES_RET_SUCCESS;
+	
+	if( _data_len_in < *data_len )
+		return OAES_RET_BUF;
+	
+	// header
+	memcpy( data, oaes_header, OAES_BLOCK_SIZE );
+	data[5] = 0x01;
+	data[7] = _ctx->key->data_len;
+	memcpy( data + OAES_BLOCK_SIZE, _ctx->key->data, _ctx->key->data_len );
+	
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_key_export_data( OAES_CTX * ctx,
+		uint8_t * data, size_t * data_len )
+{
+	size_t _data_len_in;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+	if( NULL == data_len )
+		return OAES_RET_ARG3;
+
+	_data_len_in = *data_len;
+	*data_len = _ctx->key->data_len;
+
+	if( NULL == data )
+		return OAES_RET_SUCCESS;
+	
+	if( _data_len_in < *data_len )
+		return OAES_RET_BUF;
+	
+	memcpy( data, _ctx->key->data, *data_len );
+	
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_key_import( OAES_CTX * ctx,
+		const uint8_t * data, size_t data_len )
+{
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	OAES_RET _rc = OAES_RET_SUCCESS;
+	int _key_length;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == data )
+		return OAES_RET_ARG2;
+	
+	switch( data_len )
+	{
+		case 16 + OAES_BLOCK_SIZE:
+		case 24 + OAES_BLOCK_SIZE:
+		case 32 + OAES_BLOCK_SIZE:
+			break;
+		default:
+			return OAES_RET_ARG3;
+	}
+	
+	// header
+	if( 0 != memcmp( data, oaes_header, 4 ) )
+		return OAES_RET_HEADER;
+
+	// header version
+	switch( data[4] )
+	{
+		case 0x01:
+			break;
+		default:
+			return OAES_RET_HEADER;
+	}
+	
+	// header type
+	switch( data[5] )
+	{
+		case 0x01:
+			break;
+		default:
+			return OAES_RET_HEADER;
+	}
+	
+	// options
+	_key_length = data[7];
+	switch( _key_length )
+	{
+		case 16:
+		case 24:
+		case 32:
+			break;
+		default:
+			return OAES_RET_HEADER;
+	}
+	
+	if( data_len != _key_length + OAES_BLOCK_SIZE )
+			return OAES_RET_ARG3;
+	
+	if( _ctx->key )
+		oaes_key_destroy( &(_ctx->key) );
+	
+	_ctx->key = (oaes_key *) calloc( sizeof( oaes_key ), 1 );
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_MEM;
+	
+	_ctx->key->data_len = _key_length;
+	_ctx->key->data = (uint8_t *)
+			calloc( _key_length, sizeof( uint8_t ));
+	
+	if( NULL == _ctx->key->data )
+	{
+		oaes_key_destroy( &(_ctx->key) );
+		return OAES_RET_MEM;
+	}
+
+	memcpy( _ctx->key->data, data + OAES_BLOCK_SIZE, _key_length );
+	_rc = _rc || oaes_key_expand( ctx );
+	
+	if( _rc != OAES_RET_SUCCESS )
+	{
+		oaes_key_destroy( &(_ctx->key) );
+		return _rc;
+	}
+	
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_key_import_data( OAES_CTX * ctx,
+		const uint8_t * data, size_t data_len )
+{
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	OAES_RET _rc = OAES_RET_SUCCESS;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == data )
+		return OAES_RET_ARG2;
+	
+	switch( data_len )
+	{
+		case 16:
+		case 24:
+		case 32:
+			break;
+		default:
+			return OAES_RET_ARG3;
+	}
+	
+	if( _ctx->key )
+		oaes_key_destroy( &(_ctx->key) );
+	
+	_ctx->key = (oaes_key *) calloc( sizeof( oaes_key ), 1 );
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_MEM;
+	
+	_ctx->key->data_len = data_len;
+	_ctx->key->data = (uint8_t *)
+			calloc( data_len, sizeof( uint8_t ));
+	
+	if( NULL == _ctx->key->data )
+	{
+		oaes_key_destroy( &(_ctx->key) );
+		return OAES_RET_MEM;
+	}
+
+	memcpy( _ctx->key->data, data, data_len );
+	_rc = _rc || oaes_key_expand( ctx );
+	
+	if( _rc != OAES_RET_SUCCESS )
+	{
+		oaes_key_destroy( &(_ctx->key) );
+		return _rc;
+	}
+	
+	return OAES_RET_SUCCESS;
+}
+
+OAES_CTX * oaes_alloc()
+{
+	oaes_ctx * _ctx = (oaes_ctx *) calloc( sizeof( oaes_ctx ), 1 );
+	
+	if( NULL == _ctx )
+		return NULL;
+
+#ifdef OAES_HAVE_ISAAC
+	{
+	  ub4 _i = 0;
+		char _seed[RANDSIZ + 1];
+		
+		_ctx->rctx = (randctx *) calloc( sizeof( randctx ), 1 );
+
+		if( NULL == _ctx->rctx )
+		{
+			free( _ctx );
+			return NULL;
+		}
+
+		oaes_get_seed( _seed );
+		memset( _ctx->rctx->randrsl, 0, RANDSIZ );
+		memcpy( _ctx->rctx->randrsl, _seed, RANDSIZ );
+		randinit( _ctx->rctx, TRUE);
+	}
+#else
+		srand( oaes_get_seed() );
+#endif // OAES_HAVE_ISAAC
+
+	_ctx->key = NULL;
+	oaes_set_option( _ctx, OAES_OPTION_CBC, NULL );
+
+#ifdef OAES_DEBUG
+	_ctx->step_cb = NULL;
+	oaes_set_option( _ctx, OAES_OPTION_STEP_OFF, NULL );
+#endif // OAES_DEBUG
+
+	return (OAES_CTX *) _ctx;
+}
+
+OAES_RET oaes_free( OAES_CTX ** ctx )
+{
+	oaes_ctx ** _ctx = (oaes_ctx **) ctx;
+
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == *_ctx )
+		return OAES_RET_SUCCESS;
+	
+	if( (*_ctx)->key )
+		oaes_key_destroy( &((*_ctx)->key) );
+
+#ifdef OAES_HAVE_ISAAC
+	if( (*_ctx)->rctx )
+	{
+		free( (*_ctx)->rctx );
+		(*_ctx)->rctx = NULL;
+	}
+#endif // OAES_HAVE_ISAAC
+	
+	free( *_ctx );
+	*_ctx = NULL;
+
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_set_option( OAES_CTX * ctx,
+		OAES_OPTION option, const void * value )
+{
+	size_t _i;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+
+	switch( option )
+	{
+		case OAES_OPTION_ECB:
+			_ctx->options &= ~OAES_OPTION_CBC;
+			memset( _ctx->iv, 0, OAES_BLOCK_SIZE );
+			break;
+
+		case OAES_OPTION_CBC:
+			_ctx->options &= ~OAES_OPTION_ECB;
+			if( value )
+				memcpy( _ctx->iv, value, OAES_BLOCK_SIZE );
+			else
+			{
+				for( _i = 0; _i < OAES_BLOCK_SIZE; _i++ )
+#ifdef OAES_HAVE_ISAAC
+					_ctx->iv[_i] = (uint8_t) rand( _ctx->rctx );
+#else
+					_ctx->iv[_i] = (uint8_t) rand();
+#endif // OAES_HAVE_ISAAC
+			}
+			break;
+
+#ifdef OAES_DEBUG
+
+		case OAES_OPTION_STEP_ON:
+			if( value )
+			{
+				_ctx->options &= ~OAES_OPTION_STEP_OFF;
+				_ctx->step_cb = value;
+			}
+			else
+			{
+				_ctx->options &= ~OAES_OPTION_STEP_ON;
+				_ctx->options |= OAES_OPTION_STEP_OFF;
+				_ctx->step_cb = NULL;
+				return OAES_RET_ARG3;
+			}
+			break;
+
+		case OAES_OPTION_STEP_OFF:
+			_ctx->options &= ~OAES_OPTION_STEP_ON;
+			_ctx->step_cb = NULL;
+			break;
+
+#endif // OAES_DEBUG
+
+		default:
+			return OAES_RET_ARG2;
+	}
+
+	_ctx->options |= option;
+
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_encrypt_block(
+		OAES_CTX * ctx, uint8_t * c, size_t c_len )
+{
+	size_t _i, _j;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == c )
+		return OAES_RET_ARG2;
+	
+	if( c_len != OAES_BLOCK_SIZE )
+		return OAES_RET_ARG3;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "input", 1, NULL );
+#endif // OAES_DEBUG
+
+	// AddRoundKey(State, K0)
+	for( _i = 0; _i < c_len; _i++ )
+		c[_i] = c[_i] ^ _ctx->key->exp_data[_i];
+	
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+	{
+		_ctx->step_cb( _ctx->key->exp_data, "k_sch", 1, NULL );
+		_ctx->step_cb( c, "k_add", 1, NULL );
+	}
+#endif // OAES_DEBUG
+
+	// for round = 1 step 1 to Nr–1
+	for( _i = 1; _i < _ctx->key->num_keys - 1; _i++ )
+	{
+		// SubBytes(state)
+		for( _j = 0; _j < c_len; _j++ )
+			oaes_sub_byte( c + _j );
+
+#ifdef OAES_DEBUG
+		if( _ctx->step_cb )
+			_ctx->step_cb( c, "s_box", _i, NULL );
+#endif // OAES_DEBUG
+
+		// ShiftRows(state)
+		oaes_shift_rows( c );
+		
+#ifdef OAES_DEBUG
+		if( _ctx->step_cb )
+			_ctx->step_cb( c, "s_row", _i, NULL );
+#endif // OAES_DEBUG
+
+		// MixColumns(state)
+		oaes_mix_cols( c );
+		oaes_mix_cols( c + 4 );
+		oaes_mix_cols( c + 8 );
+		oaes_mix_cols( c + 12 );
+		
+#ifdef OAES_DEBUG
+		if( _ctx->step_cb )
+			_ctx->step_cb( c, "m_col", _i, NULL );
+#endif // OAES_DEBUG
+
+		// AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
+		for( _j = 0; _j < c_len; _j++ )
+			c[_j] = c[_j] ^
+					_ctx->key->exp_data[_i * OAES_RKEY_LEN * OAES_COL_LEN + _j];
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+	{
+		_ctx->step_cb( _ctx->key->exp_data + _i * OAES_RKEY_LEN * OAES_COL_LEN,
+				"k_sch", _i, NULL );
+		_ctx->step_cb( c, "k_add", _i, NULL );
+	}
+#endif // OAES_DEBUG
+
+	}
+	
+	// SubBytes(state)
+	for( _i = 0; _i < c_len; _i++ )
+		oaes_sub_byte( c + _i );
+	
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "s_box", _ctx->key->num_keys - 1, NULL );
+#endif // OAES_DEBUG
+
+	// ShiftRows(state)
+	oaes_shift_rows( c );
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "s_row", _ctx->key->num_keys - 1, NULL );
+#endif // OAES_DEBUG
+
+	// AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
+	for( _i = 0; _i < c_len; _i++ )
+		c[_i] = c[_i] ^ _ctx->key->exp_data[
+				( _ctx->key->num_keys - 1 ) * OAES_RKEY_LEN * OAES_COL_LEN + _i ];
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+	{
+		_ctx->step_cb( _ctx->key->exp_data +
+				( _ctx->key->num_keys - 1 ) * OAES_RKEY_LEN * OAES_COL_LEN,
+				"k_sch", _ctx->key->num_keys - 1, NULL );
+		_ctx->step_cb( c, "output", _ctx->key->num_keys - 1, NULL );
+	}
+#endif // OAES_DEBUG
+
+	return OAES_RET_SUCCESS;
+}
+
+static OAES_RET oaes_decrypt_block(
+		OAES_CTX * ctx, uint8_t * c, size_t c_len )
+{
+	size_t _i, _j;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == c )
+		return OAES_RET_ARG2;
+	
+	if( c_len != OAES_BLOCK_SIZE )
+		return OAES_RET_ARG3;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "iinput", _ctx->key->num_keys - 1, NULL );
+#endif // OAES_DEBUG
+
+	// AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
+	for( _i = 0; _i < c_len; _i++ )
+		c[_i] = c[_i] ^ _ctx->key->exp_data[
+				( _ctx->key->num_keys - 1 ) * OAES_RKEY_LEN * OAES_COL_LEN + _i ];
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+	{
+		_ctx->step_cb( _ctx->key->exp_data +
+				( _ctx->key->num_keys - 1 ) * OAES_RKEY_LEN * OAES_COL_LEN,
+				"ik_sch", _ctx->key->num_keys - 1, NULL );
+		_ctx->step_cb( c, "ik_add", _ctx->key->num_keys - 1, NULL );
+	}
+#endif // OAES_DEBUG
+
+	for( _i = _ctx->key->num_keys - 2; _i > 0; _i-- )
+	{
+		// InvShiftRows(state)
+		oaes_inv_shift_rows( c );
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "is_row", _i, NULL );
+#endif // OAES_DEBUG
+
+		// InvSubBytes(state)
+		for( _j = 0; _j < c_len; _j++ )
+			oaes_inv_sub_byte( c + _j );
+	
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "is_box", _i, NULL );
+#endif // OAES_DEBUG
+
+		// AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
+		for( _j = 0; _j < c_len; _j++ )
+			c[_j] = c[_j] ^
+					_ctx->key->exp_data[_i * OAES_RKEY_LEN * OAES_COL_LEN + _j];
+		
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+	{
+		_ctx->step_cb( _ctx->key->exp_data + _i * OAES_RKEY_LEN * OAES_COL_LEN,
+				"ik_sch", _i, NULL );
+		_ctx->step_cb( c, "ik_add", _i, NULL );
+	}
+#endif // OAES_DEBUG
+
+		// InvMixColums(state)
+		oaes_inv_mix_cols( c );
+		oaes_inv_mix_cols( c + 4 );
+		oaes_inv_mix_cols( c + 8 );
+		oaes_inv_mix_cols( c + 12 );
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "im_col", _i, NULL );
+#endif // OAES_DEBUG
+
+	}
+
+	// InvShiftRows(state)
+	oaes_inv_shift_rows( c );
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "is_row", 1, NULL );
+#endif // OAES_DEBUG
+
+	// InvSubBytes(state)
+	for( _i = 0; _i < c_len; _i++ )
+		oaes_inv_sub_byte( c + _i );
+
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+		_ctx->step_cb( c, "is_box", 1, NULL );
+#endif // OAES_DEBUG
+
+	// AddRoundKey(state, w[0, Nb-1])
+	for( _i = 0; _i < c_len; _i++ )
+		c[_i] = c[_i] ^ _ctx->key->exp_data[_i];
+	
+#ifdef OAES_DEBUG
+	if( _ctx->step_cb )
+	{
+		_ctx->step_cb( _ctx->key->exp_data, "ik_sch", 1, NULL );
+		_ctx->step_cb( c, "ioutput", 1, NULL );
+	}
+#endif // OAES_DEBUG
+
+	return OAES_RET_SUCCESS;
+}
+
+OAES_RET oaes_encrypt( OAES_CTX * ctx,
+		const uint8_t * m, size_t m_len, uint8_t * c, size_t * c_len )
+{
+	size_t _i, _j, _c_len_in, _c_data_len;
+	size_t _pad_len = m_len % OAES_BLOCK_SIZE == 0 ?
+			0 : OAES_BLOCK_SIZE - m_len % OAES_BLOCK_SIZE;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	OAES_RET _rc = OAES_RET_SUCCESS;
+	uint8_t _flags = _pad_len ? OAES_FLAG_PAD : 0;
+	
+	if( NULL == _ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == m )
+		return OAES_RET_ARG2;
+	
+	if( NULL == c_len )
+		return OAES_RET_ARG5;
+	
+	_c_len_in = *c_len;
+	// data + pad
+	_c_data_len = m_len + _pad_len;
+	// header + iv + data + pad
+	*c_len = 2 * OAES_BLOCK_SIZE + m_len + _pad_len;
+
+	if( NULL == c )
+		return OAES_RET_SUCCESS;
+	
+	if( _c_len_in < *c_len )
+		return OAES_RET_BUF;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+	// header
+	memcpy(c, oaes_header, OAES_BLOCK_SIZE );
+	memcpy(c + 6, &_ctx->options, sizeof(_ctx->options));
+	memcpy(c + 8, &_flags, sizeof(_flags));
+	// iv
+	memcpy(c + OAES_BLOCK_SIZE, _ctx->iv, OAES_BLOCK_SIZE );
+	// data
+	memcpy(c + 2 * OAES_BLOCK_SIZE, m, m_len );
+	
+	for( _i = 0; _i < _c_data_len; _i += OAES_BLOCK_SIZE )
+	{
+		uint8_t _block[OAES_BLOCK_SIZE];
+		size_t _block_size = min( m_len - _i, OAES_BLOCK_SIZE );
+
+		memcpy( _block, c + 2 * OAES_BLOCK_SIZE + _i, _block_size );
+		
+		// insert pad
+		for( _j = 0; _j < OAES_BLOCK_SIZE - _block_size; _j++ )
+			_block[ _block_size + _j ] = _j + 1;
+	
+		// CBC
+		if( _ctx->options & OAES_OPTION_CBC )
+		{
+			for( _j = 0; _j < OAES_BLOCK_SIZE; _j++ )
+				_block[_j] = _block[_j] ^ _ctx->iv[_j];
+		}
+
+		_rc = _rc ||
+				oaes_encrypt_block( ctx, _block, OAES_BLOCK_SIZE );
+		memcpy( c + 2 * OAES_BLOCK_SIZE + _i, _block, OAES_BLOCK_SIZE );
+		
+		if( _ctx->options & OAES_OPTION_CBC )
+			memcpy( _ctx->iv, _block, OAES_BLOCK_SIZE );
+	}
+	
+	return _rc;
+}
+
+OAES_RET oaes_decrypt( OAES_CTX * ctx,
+		const uint8_t * c, size_t c_len, uint8_t * m, size_t * m_len )
+{
+	size_t _i, _j, _m_len_in;
+	oaes_ctx * _ctx = (oaes_ctx *) ctx;
+	OAES_RET _rc = OAES_RET_SUCCESS;
+	uint8_t _iv[OAES_BLOCK_SIZE];
+	uint8_t _flags;
+	OAES_OPTION _options;
+	
+	if( NULL == ctx )
+		return OAES_RET_ARG1;
+	
+	if( NULL == c )
+		return OAES_RET_ARG2;
+	
+	if( c_len % OAES_BLOCK_SIZE )
+		return OAES_RET_ARG3;
+	
+	if( NULL == m_len )
+		return OAES_RET_ARG5;
+	
+	_m_len_in = *m_len;
+	*m_len = c_len - 2 * OAES_BLOCK_SIZE;
+	
+	if( NULL == m )
+		return OAES_RET_SUCCESS;
+	
+	if( _m_len_in < *m_len )
+		return OAES_RET_BUF;
+	
+	if( NULL == _ctx->key )
+		return OAES_RET_NOKEY;
+	
+	// header
+	if( 0 != memcmp( c, oaes_header, 4 ) )
+		return OAES_RET_HEADER;
+
+	// header version
+	switch( c[4] )
+	{
+		case 0x01:
+			break;
+		default:
+			return OAES_RET_HEADER;
+	}
+	
+	// header type
+	switch( c[5] )
+	{
+		case 0x02:
+			break;
+		default:
+			return OAES_RET_HEADER;
+	}
+	
+	// options
+	memcpy(&_options, c + 6, sizeof(_options));
+	// validate that all options are valid
+	if( _options & ~(
+			  OAES_OPTION_ECB
+			| OAES_OPTION_CBC
+#ifdef OAES_DEBUG
+			| OAES_OPTION_STEP_ON
+			| OAES_OPTION_STEP_OFF
+#endif // OAES_DEBUG
+			) )
+		return OAES_RET_HEADER;
+	if( ( _options & OAES_OPTION_ECB ) &&
+			( _options & OAES_OPTION_CBC ) )
+		return OAES_RET_HEADER;
+	if( _options == OAES_OPTION_NONE )
+		return OAES_RET_HEADER;
+	
+	// flags
+	memcpy(&_flags, c + 8, sizeof(_flags));
+	// validate that all flags are valid
+	if( _flags & ~(
+			  OAES_FLAG_PAD
+			) )
+		return OAES_RET_HEADER;
+
+	// iv
+	memcpy( _iv, c + OAES_BLOCK_SIZE, OAES_BLOCK_SIZE);
+	// data + pad
+	memcpy( m, c + 2 * OAES_BLOCK_SIZE, *m_len );
+	
+	for( _i = 0; _i < *m_len; _i += OAES_BLOCK_SIZE )
+	{
+		if( ( _options & OAES_OPTION_CBC ) && _i > 0 )
+			memcpy( _iv, c + OAES_BLOCK_SIZE + _i, OAES_BLOCK_SIZE );
+		
+		_rc = _rc ||
+				oaes_decrypt_block( ctx, m + _i, min( *m_len - _i, OAES_BLOCK_SIZE ) );
+		
+		// CBC
+		if( _options & OAES_OPTION_CBC )
+		{
+			for( _j = 0; _j < OAES_BLOCK_SIZE; _j++ )
+				m[ _i + _j ] = m[ _i + _j ] ^ _iv[_j];
+		}
+	}
+	
+	// remove pad
+	if( _flags & OAES_FLAG_PAD )
+	{
+		int _is_pad = 1;
+		size_t _temp = (size_t) m[*m_len - 1];
+
+		if( _temp  <= 0x00 || _temp > 0x0f )
+			return OAES_RET_HEADER;
+		for( _i = 0; _i < _temp; _i++ )
+			if( m[*m_len - 1 - _i] != _temp - _i )
+				_is_pad = 0;
+		if( _is_pad )
+		{
+			memset( m + *m_len - _temp, 0, _temp );
+			*m_len -= _temp;
+		}
+		else
+			return OAES_RET_HEADER;
+	}
+	
+	return OAES_RET_SUCCESS;
+}
diff --git a/openaes/test/test_encrypt.c b/openaes/test/test_encrypt.c
new file mode 100644
index 0000000..b229f2d
--- /dev/null
+++ b/openaes/test/test_encrypt.c
@@ -0,0 +1,229 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "oaes_lib.h"
+
+void usage(const char * exe_name)
+{
+	if( NULL == exe_name )
+		return;
+	
+	printf(
+			"Usage:\n"
+			"\t%s [-ecb] [-key < 128 | 192 | 256 >] <text>\n",
+			exe_name
+	);
+}
+
+int main(int argc, char** argv)
+{
+	size_t _i;
+	OAES_CTX * ctx = NULL;
+	uint8_t *_encbuf, *_decbuf;
+	size_t _encbuf_len, _decbuf_len, _buf_len;
+	char *_buf;
+	short _is_ecb = 0;
+	char * _text = NULL;
+	int _key_len = 128;
+	
+	if( argc < 2 )
+	{
+		usage( argv[0] );
+		return EXIT_FAILURE;
+	}
+
+	for( _i = 1; _i < argc; _i++ )
+	{
+		int _found = 0;
+		
+		if( 0 == strcmp( argv[_i], "-ecb" ) )
+		{
+			_found = 1;
+			_is_ecb = 1;
+		}
+		
+		if( 0 == strcmp( argv[_i], "-key" ) )
+		{
+			_found = 1;
+			_i++; // len
+			if( _i >= argc )
+			{
+				printf("Error: No value specified for '-%s'.\n",
+						"key");
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			_key_len = atoi( argv[_i] );
+			switch( _key_len )
+			{
+				case 128:
+				case 192:
+				case 256:
+					break;
+				default:
+					printf("Error: Invalid value [%d] specified for '-%s'.\n",
+							_key_len, "key");
+					usage( argv[0] );
+					return EXIT_FAILURE;
+			}
+		}
+		
+		if( 0 == _found )
+		{
+			if( _text )
+			{
+				printf("Error: Invalid option '%s'.\n", argv[_i]);
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			else
+			{
+				_text = (char *) calloc(strlen( argv[_i] ) + 1, sizeof(char));
+				if( NULL == _text )
+				{
+					printf("Error: Failed to allocate memory.\n", argv[_i]);
+					return EXIT_FAILURE;
+				}
+				strcpy( _text, argv[_i] );
+			}
+		}			
+	}
+
+	if( NULL == _text )
+	{
+		usage( argv[0] );
+		return EXIT_FAILURE;
+	}
+
+	oaes_sprintf( NULL, &_buf_len,
+			(const uint8_t *)_text, strlen( _text ) );
+	_buf = (char *) calloc(_buf_len, sizeof(char));
+	printf( "\n***** plaintext  *****\n" );
+	if( _buf )
+	{
+		oaes_sprintf( _buf, &_buf_len,
+				(const uint8_t *)_text, strlen( _text ) );
+		printf( "%s", _buf );
+	}
+	printf( "\n**********************\n" );
+	free( _buf );
+	
+	ctx = oaes_alloc();
+	if( NULL == ctx )
+	{
+		printf("Error: Failed to initialize OAES.\n");
+		free( _text );
+		return EXIT_FAILURE;
+	}
+	if( _is_ecb )
+		if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) )
+			printf("Error: Failed to set OAES options.\n");
+	switch( _key_len )
+	{
+		case 128:
+			if( OAES_RET_SUCCESS != oaes_key_gen_128(ctx) )
+				printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+			break;
+		case 192:
+			if( OAES_RET_SUCCESS != oaes_key_gen_192(ctx) )
+				printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+			break;
+		case 256:
+			if( OAES_RET_SUCCESS != oaes_key_gen_256(ctx) )
+				printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+			break;
+		default:
+			break;
+	}
+
+	if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+			(const uint8_t *)_text, strlen( _text ), NULL, &_encbuf_len ) )
+		printf("Error: Failed to retrieve required buffer size for encryption.\n");
+	_encbuf = (uint8_t *) calloc( _encbuf_len, sizeof(uint8_t) );
+	if( NULL == _encbuf )
+	{
+		printf( "Error: Failed to allocate memory.\n" );
+		free( _text );
+		return EXIT_FAILURE;
+	}
+	if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+			(const uint8_t *)_text, strlen( _text ), _encbuf, &_encbuf_len ) )
+		printf("Error: Encryption failed.\n");
+
+	if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+			_encbuf, _encbuf_len, NULL, &_decbuf_len ) )
+		printf("Error: Failed to retrieve required buffer size for encryption.\n");
+	_decbuf = (uint8_t *) calloc( _decbuf_len, sizeof(uint8_t) );
+	if( NULL == _decbuf )
+	{
+		printf( "Error: Failed to allocate memory.\n" );
+		free( _text );
+		free( _encbuf );
+		return EXIT_FAILURE;
+	}
+	if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+			_encbuf, _encbuf_len, _decbuf, &_decbuf_len ) )
+		printf("Error: Decryption failed.\n");
+
+	if( OAES_RET_SUCCESS !=  oaes_free( &ctx ) )
+		printf("Error: Failed to uninitialize OAES.\n");
+	
+	oaes_sprintf( NULL, &_buf_len, _encbuf, _encbuf_len );
+	_buf = (char *) calloc(_buf_len, sizeof(char));
+	printf( "\n***** cyphertext *****\n" );
+	if( _buf )
+	{
+		oaes_sprintf( _buf, &_buf_len, _encbuf, _encbuf_len );
+		printf( "%s", _buf );
+	}
+	printf( "\n**********************\n" );
+	free( _buf );
+	
+	oaes_sprintf( NULL, &_buf_len, _decbuf, _decbuf_len );
+	_buf = (char *) calloc(_buf_len, sizeof( char));
+	printf( "\n***** plaintext  *****\n" );
+	if( _buf )
+	{
+		oaes_sprintf( _buf, &_buf_len, _decbuf, _decbuf_len );
+		printf( "%s", _buf );
+	}
+	printf( "\n**********************\n\n" );
+	free( _buf );
+	
+	free( _encbuf );
+	free( _decbuf );
+	free( _text );
+
+	return (EXIT_SUCCESS);
+}
diff --git a/openaes/test/test_keys.c b/openaes/test/test_keys.c
new file mode 100644
index 0000000..6a8d625
--- /dev/null
+++ b/openaes/test/test_keys.c
@@ -0,0 +1,248 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "oaes_lib.h"
+
+/*
+ * 
+ */
+int main(int argc, char** argv) {
+
+	OAES_CTX * ctx = NULL;
+	uint8_t * _buf;
+	size_t _data_len;
+	FILE * f = NULL;
+	OAES_RET _rc;
+	
+	if( NULL == ( ctx = oaes_alloc() ) )
+	{
+		printf( "Error: Initialization failed.\n" );
+		return 1;
+	}
+	
+	/* ************** Generate 128-bit key and export it **************
+	 * ****************************************************************/
+	if( OAES_RET_SUCCESS != ( _rc = oaes_key_gen_128(ctx) ) )
+	{
+		printf( "Error: Failed to generate 128-bit key [%d].\n", _rc );
+		oaes_free(&ctx);
+		return 1;
+	}
+	
+	if( OAES_RET_SUCCESS != ( _rc = oaes_key_export(ctx, NULL, &_data_len) ) )
+	{
+		printf( "Error: Failed to retrieve key length [%d].\n", _rc );
+		oaes_free(&ctx);
+		return 1;
+	}
+	
+	_buf = (uint8_t *) calloc(_data_len, sizeof(uint8_t));
+	if( _buf )
+	{
+		if( OAES_RET_SUCCESS != ( _rc = oaes_key_export(ctx, _buf, &_data_len) ) )
+		{
+			printf("Error: Failed to export key [%d].\n", _rc);
+			free(_buf);
+			oaes_free(&ctx);
+			return 1;
+		}
+		
+		f = fopen( "key_128", "wb" );
+		if( f )
+		{
+			fwrite(_buf, _data_len, sizeof(uint8_t), f);
+			fclose(f);
+		}
+		free(_buf);
+	}
+	
+	/* ************** Generate 192-bit key and export it **************
+	 * ****************************************************************/
+	if( OAES_RET_SUCCESS != ( _rc = oaes_key_gen_192(ctx) ) )
+	{
+		printf( "Error: Failed to generate 192-bit key [%d].\n", _rc );
+		oaes_free(&ctx);
+		return 1;
+	}
+	
+	if( OAES_RET_SUCCESS != ( _rc = oaes_key_export(ctx, NULL, &_data_len) ) )
+	{
+		printf( "Error: Failed to retrieve key length [%d].\n", _rc );
+		oaes_free(&ctx);
+		return 1;
+	}
+	
+	_buf = (uint8_t *) calloc(_data_len, sizeof(uint8_t));
+	if( _buf )
+	{
+		if( OAES_RET_SUCCESS != ( _rc = oaes_key_export(ctx, _buf, &_data_len) ) )
+		{
+			printf("Error: Failed to export key [%d].\n", _rc);
+			free(_buf);
+			oaes_free(&ctx);
+			return 1;
+		}
+		
+		f = fopen("key_192", "wb");
+		if( f )
+		{
+			fwrite(_buf, _data_len, sizeof(uint8_t), f);
+			fclose(f);
+		}
+		free(_buf);
+	}
+	
+	/* ************** Generate 256-bit key and export it **************
+	 * ****************************************************************/
+	if( OAES_RET_SUCCESS != ( _rc = oaes_key_gen_256(ctx) ) )
+	{
+		printf("Error: Failed to generate 256-bit key [%d].\n", _rc);
+		oaes_free(&ctx);
+		return 1;
+	}
+	
+	if( OAES_RET_SUCCESS != ( _rc = oaes_key_export(ctx, NULL, &_data_len) ) )
+	{
+		printf("Error: Failed to retrieve key length [%d].\n", _rc);
+		oaes_free(&ctx);
+		return 1;
+	}
+	
+	_buf = (uint8_t *) calloc(_data_len, sizeof(uint8_t));
+	if( _buf )
+	{
+		if( OAES_RET_SUCCESS != ( _rc = oaes_key_export(ctx, _buf, &_data_len) ) )
+		{
+			printf("Error: Failed to export key [%d].\n", _rc);
+			free(_buf);
+			oaes_free(&ctx);
+			return 1;
+		}
+		
+		f = fopen("key_256", "wb");
+		if( f )
+		{
+			fwrite(_buf, _data_len, sizeof(uint8_t), f);
+			fclose(f);
+		}
+		free(_buf);
+	}
+	
+	/* ********************** Import 128-bit key **********************
+	 * ****************************************************************/
+	f = fopen("key_128", "rb");
+	if( f )
+	{
+		fseek(f, 0L, SEEK_END);
+		_data_len = ftell(f);
+		fseek(f, 0L, SEEK_SET);
+		_buf = (uint8_t *) calloc(_data_len, sizeof(uint8_t));
+		if( _buf )
+		{
+			fread(_buf, _data_len, sizeof(uint8_t), f);
+			
+			if( OAES_RET_SUCCESS !=
+					( _rc = oaes_key_import(ctx, _buf, _data_len) ) )
+			{
+				printf( "Error: Failed to import key [%d].\n", _rc );
+				free(_buf);
+				fclose(f);
+				oaes_free(&ctx);
+				return 1;
+			}
+			
+			free(_buf);
+		}
+		fclose(f);
+	}
+	
+	/* ********************** Import 192-bit key **********************
+	 * ****************************************************************/
+	f = fopen("key_192", "rb");
+	if( f )
+	{
+		fseek(f, 0L, SEEK_END);
+		_data_len = ftell(f);
+		fseek(f, 0L, SEEK_SET);
+		_buf = (uint8_t *) calloc(_data_len, sizeof(uint8_t));
+		if( _buf )
+		{
+			fread(_buf, _data_len, sizeof(uint8_t), f);
+			
+			if( OAES_RET_SUCCESS !=
+					( _rc = oaes_key_import(ctx, _buf, _data_len) ) )
+			{
+				printf("Error: Failed to import key [%d].\n", _rc);
+				free(_buf);
+				fclose(f);
+				oaes_free(&ctx);
+				return 1;
+			}
+			
+			free(_buf);
+		}
+		fclose(f);
+	}
+	
+	/* ********************** Import 256-bit key **********************
+	 * ****************************************************************/
+	f = fopen("key_256", "rb");
+	if( f )
+	{
+		fseek(f, 0L, SEEK_END);
+		_data_len = ftell(f);
+		fseek(f, 0L, SEEK_SET);
+		_buf = (uint8_t *) calloc(_data_len, sizeof(uint8_t));
+		if( _buf )
+		{
+			fread(_buf, _data_len, sizeof(uint8_t), f);
+			
+			if( OAES_RET_SUCCESS !=
+					( _rc = oaes_key_import(ctx, _buf, _data_len) ) )
+			{
+				printf("Error: Failed to import key [%d].\n", _rc);
+				free(_buf);
+				fclose(f);
+				oaes_free(&ctx);
+				return 1;
+			}
+			
+			free(_buf);
+		}
+		fclose(f);
+	}
+	
+	oaes_free(&ctx);
+
+	return (EXIT_SUCCESS);
+}
diff --git a/openaes/test/test_performance.c b/openaes/test/test_performance.c
new file mode 100644
index 0000000..a005c58
--- /dev/null
+++ b/openaes/test/test_performance.c
@@ -0,0 +1,200 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "oaes_lib.h"
+
+void usage(const char * exe_name)
+{
+	if( NULL == exe_name )
+		return;
+	
+	printf(
+			"Usage:\n"
+			"\t%s [-ecb] [-key < 128 | 192 | 256 >] [-data <data_len>]\n",
+			exe_name
+	);
+}
+
+/*
+ * 
+ */
+int main(int argc, char** argv) {
+
+	size_t _i, _j;
+	time_t _time_start, _time_end;
+	OAES_CTX * ctx = NULL;
+	uint8_t *_encbuf, *_decbuf;
+	size_t _encbuf_len, _decbuf_len;
+	uint8_t _buf[1024 * 1024];
+	short _is_ecb = 0;
+	int _key_len = 128;
+	size_t _data_len = 64;
+	
+	for( _i = 1; _i < argc; _i++ )
+	{
+		int _found = 0;
+		
+		if( 0 == strcmp( argv[_i], "-ecb" ) )
+		{
+			_found = 1;
+			_is_ecb = 1;
+		}
+		
+		if( 0 == strcmp( argv[_i], "-key" ) )
+		{
+			_found = 1;
+			_i++; // key_len
+			if( _i >= argc )
+			{
+				printf("Error: No value specified for '-%s'.\n",
+						"key");
+				usage( argv[0] );
+				return 1;
+			}
+			_key_len = atoi( argv[_i] );
+			switch( _key_len )
+			{
+				case 128:
+				case 192:
+				case 256:
+					break;
+				default:
+					printf("Error: Invalid value [%d] specified for '-%s'.\n",
+							_key_len, "key");
+					usage( argv[0] );
+					return 1;
+			}
+		}
+		
+		if( 0 == strcmp( argv[_i], "-data" ) )
+		{
+			_found = 1;
+			_i++; // data_len
+			if( _i >= argc )
+			{
+				printf("Error: No value specified for '-%s'.\n",
+						"data");
+				usage( argv[0] );
+				return 1;
+			}
+			_data_len = atoi( argv[_i] );
+		}
+		
+		if( 0 == _found )
+		{
+			printf("Error: Invalid option '%s'.\n", argv[_i]);
+			usage( argv[0] );
+			return 1;
+		}			
+	}
+
+	// generate random test data
+	time( &_time_start );
+	srand( _time_start );
+	for( _i = 0; _i < 1024 * 1024; _i++ )
+		_buf[_i] = rand();
+	
+	ctx = oaes_alloc();
+	if( NULL == ctx )
+	{
+		printf("Error: Failed to initialize OAES.\n");
+		return EXIT_FAILURE;
+	}
+	if( _is_ecb )
+		if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) )
+			printf("Error: Failed to set OAES options.\n");
+	switch( _key_len )
+	{
+		case 128:
+			if( OAES_RET_SUCCESS != oaes_key_gen_128(ctx) )
+				printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+			break;
+		case 192:
+			if( OAES_RET_SUCCESS != oaes_key_gen_192(ctx) )
+				printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+			break;
+		case 256:
+			if( OAES_RET_SUCCESS != oaes_key_gen_256(ctx) )
+				printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+			break;
+		default:
+			break;
+	}
+
+	if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+			(const uint8_t *)_buf, 1024 * 1024, NULL, &_encbuf_len ) )
+		printf("Error: Failed to retrieve required buffer size for encryption.\n");
+	_encbuf = (uint8_t *) calloc( _encbuf_len, sizeof( char ) );
+	if( NULL == _encbuf )
+	{
+		printf( "Error: Failed to allocate memory.\n" );
+		return EXIT_FAILURE;
+	}
+
+	if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+			_encbuf, _encbuf_len, NULL, &_decbuf_len ) )
+		printf("Error: Failed to retrieve required buffer size for encryption.\n");
+	_decbuf = (uint8_t *) calloc( _decbuf_len, sizeof( char ) );
+	if( NULL == _decbuf )
+	{
+		free( _encbuf );
+		printf( "Error: Failed to allocate memory.\n" );
+		return EXIT_FAILURE;
+	}
+
+	time( &_time_start );
+	
+	for( _i = 0; _i < _data_len; _i++ )
+	{
+		if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+				(const uint8_t *)_buf, 1024 * 1024, _encbuf, &_encbuf_len ) )
+			printf("Error: Encryption failed.\n");
+		if( OAES_RET_SUCCESS !=  oaes_decrypt( ctx,
+				_encbuf, _encbuf_len, _decbuf, &_decbuf_len ) )
+			printf("Error: Decryption failed.\n");
+	}
+	
+	time( &_time_end );
+	printf( "Test encrypt and decrypt:\n\ttime: %lld seconds\n\tdata: %ld MB"
+			"\n\tkey: %d bits\n\tmode: %s\n",
+			_time_end - _time_start, _data_len,
+			_key_len, _is_ecb? "EBC" : "CBC" );
+	free( _encbuf );
+	free( _decbuf );
+	if( OAES_RET_SUCCESS !=  oaes_free( &ctx ) )
+		printf("Error: Failed to uninitialize OAES.\n");
+
+	return (EXIT_SUCCESS);
+}
diff --git a/openaes/test/vt_aes.c b/openaes/test/vt_aes.c
new file mode 100644
index 0000000..1ba755e
--- /dev/null
+++ b/openaes/test/vt_aes.c
@@ -0,0 +1,405 @@
+/* 
+ * ---------------------------------------------------------------------------
+ * OpenAES License
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * ---------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define OAES_DEBUG 1
+#include "oaes_lib.h"
+
+static int _is_step = 1;
+
+static int step_cb(
+		const uint8_t state[OAES_BLOCK_SIZE],
+		const char * step_name,
+		int step_count,
+		void * user_data )
+{
+	size_t _buf_len;
+	char * _buf;
+
+
+	if( NULL == state )
+		return 1;
+
+	oaes_sprintf( NULL, &_buf_len, state, OAES_BLOCK_SIZE );
+	_buf = (char *) calloc( _buf_len, sizeof( char ) );
+
+	if( _buf )
+	{
+		oaes_sprintf( _buf, &_buf_len, state, OAES_BLOCK_SIZE );
+		printf( "round[%2d].%-7s --> %s", step_count, step_name, _buf );
+		free( _buf );
+	}
+	
+	if( 1 == _is_step && '\n' != getchar( ) )
+		_is_step = 0;
+
+	return 0;
+}
+
+static int to_binary(uint8_t * buf, size_t * buf_len, const char * data)
+{
+	size_t _i, _buf_len_in;
+	
+	if( NULL == buf_len )
+		return 1;
+
+	if( NULL == data )
+		return 1;
+
+	_buf_len_in = *buf_len;
+	*buf_len = strlen( data ) / 2;
+	
+	if( NULL == buf )
+		return 0;
+
+	if( *buf_len > _buf_len_in )
+		return 1;
+
+	memset( buf, 0, strlen( data ) / 2 );
+	
+	// lookup ascii table
+	for( _i = 0; _i < strlen( data ); _i++ )
+	{
+		// 0-9
+		if( data[_i] >= 0x30 && data[_i] <= 0x39 )
+			buf[_i / 2] += ( data[_i] - 0x30 ) << ( 4 * ( ( _i + 1 ) % 2 ) ) ;
+		// a-f
+		else if( data[_i] >= 0x41 && data[_i] <= 0x46 )
+			buf[_i / 2] += ( data[_i] - 0x37 ) << ( 4 * ( ( _i + 1 ) % 2 ) );
+		// A-F
+		else if( data[_i] >= 0x61 && data[_i] <= 0x66 )
+			buf[_i / 2] += ( data[_i] - 0x57 ) << ( 4 * ( ( _i + 1 ) % 2 ) );
+		// invalid character
+		else
+			return 1;
+	}
+	
+	return 0;
+}
+
+static void usage(const char * exe_name)
+{
+	if( NULL == exe_name )
+		return;
+	
+	printf(
+			"Usage:\n"
+			"  %s [-step] [-ecb] [[-key < 128 | 192 | 256 | key_data >] [-bin] <text>\n",
+			exe_name
+	);
+}
+
+int main(int argc, char** argv)
+{
+	size_t _i;
+	OAES_CTX * ctx = NULL;
+	uint8_t *_encbuf, *_decbuf, *_key_data = NULL, *_bin_data = NULL;
+	size_t _encbuf_len, _decbuf_len, _buf_len;
+	size_t _key_data_len = 0, _bin_data_len = 0;
+	char *_buf;
+	short _is_ecb = 0, _is_bin = 0;
+	char * _text = NULL, * _key_text = NULL;
+	int _key_len = 128;
+	
+	if( argc < 2 )
+	{
+		usage( argv[0] );
+		return EXIT_FAILURE;
+	}
+
+	for( _i = 1; _i < argc; _i++ )
+	{
+		int _found = 0;
+
+		if( 0 == strcmp( argv[_i], "-nostep" ) )
+		{
+			_found = 1;
+			_is_step = 0;
+		}
+
+		if( 0 == strcmp( argv[_i], "-ecb" ) )
+		{
+			_found = 1;
+			_is_ecb = 1;
+		}
+		
+		if( 0 == strcmp( argv[_i], "-bin" ) )
+		{
+			_found = 1;
+			_is_bin = 1;
+		}
+		
+		if( 0 == strcmp( argv[_i], "-key" ) )
+		{
+			_found = 1;
+			_i++; // len
+			if( _i >= argc )
+			{
+				printf("Error: No value specified for '-%s'.\n",
+						"key");
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			_key_len = atoi( argv[_i] );
+			switch( _key_len )
+			{
+				case 128:
+				case 192:
+				case 256:
+					break;
+				default:
+					_key_text = argv[_i];
+					if( to_binary( NULL, &_key_data_len, _key_text ) )
+					{
+						printf( "Error: Invalid value [%s] specified for '-%s'.\n",
+								argv[_i], "key" );
+						return EXIT_FAILURE;
+					}
+					switch( _key_data_len )
+					{
+						case 16:
+						case 24:
+						case 32:
+							break;
+						default:
+							printf("Error: key_data [%s] specified for '-%s' has an invalid "
+									"size.\n", argv[_i], "key");
+							usage( argv[0] );
+							return EXIT_FAILURE;
+					}
+			}
+		}
+		
+		if( 0 == _found )
+		{
+			if( _text )
+			{
+				printf("Error: Invalid option '%s'.\n", argv[_i]);
+				usage( argv[0] );
+				return EXIT_FAILURE;
+			}
+			else
+			{
+				_text = argv[_i];
+				if( _is_bin && to_binary( NULL, &_bin_data_len, _text ) )
+				{
+					printf( "Error: Invalid value [%s] specified for '-%s'.\n",
+							argv[_i], "bin" );
+					return EXIT_FAILURE;
+				}
+			}
+		}			
+	}
+
+	if( NULL == _text )
+	{
+		usage( argv[0] );
+		return EXIT_FAILURE;
+	}
+
+	if( _is_step )
+		printf( "\nEnabling step mode, press Return to step.\n\n" );
+
+	if( _is_bin )
+	{
+		_bin_data = (uint8_t *) calloc(_bin_data_len, sizeof(uint8_t));
+		if( NULL == _bin_data )
+		{
+			printf( "Error: Failed to allocate memory.\n" );
+			return EXIT_FAILURE;
+		}
+		if( to_binary( _bin_data, &_bin_data_len, _text ) )
+		{
+			printf( "Error: Could not load data [%s].\n", _text);
+			free( _bin_data );
+			return EXIT_FAILURE;
+		}
+	}
+	else
+	{
+		oaes_sprintf( NULL, &_buf_len, (const uint8_t *)_text, strlen(_text));
+		_buf = (char *) calloc(_buf_len, sizeof(char));
+		printf( "\n***** plaintext  *****\n" );
+		if( _buf )
+		{
+			oaes_sprintf( _buf, &_buf_len,
+					(const uint8_t *)_text, strlen( _text ) );
+			printf( "%s", _buf );
+		}
+		printf( "\n**********************\n" );
+		free( _buf );
+	}
+	
+	ctx = oaes_alloc();
+	if( NULL == ctx )
+	{
+		printf("Error: Failed to initialize OAES.\n");
+		if( _bin_data )
+			free( _bin_data );
+		return EXIT_FAILURE;
+	}
+	if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_STEP_ON, step_cb ) )
+		printf("Error: Failed to set OAES options.\n");
+	if( _is_ecb )
+		if( OAES_RET_SUCCESS != oaes_set_option( ctx, OAES_OPTION_ECB, NULL ) )
+			printf("Error: Failed to set OAES options.\n");
+
+	if( _key_text )
+	{
+		_key_data = (uint8_t *) calloc(_key_data_len, sizeof(uint8_t));
+		if( NULL == _key_data )
+		{
+			printf( "Error: Failed to allocate memory.\n" );
+			if( _bin_data )
+				free( _bin_data );
+			return EXIT_FAILURE;
+		}
+		if( to_binary( _key_data, &_key_data_len, _key_text ) )
+		{
+			printf( "Error: Could not load key [%s].\n", _key_text);
+			free( _key_data );
+			return EXIT_FAILURE;
+		}
+		oaes_key_import_data( ctx, _key_data, _key_data_len );
+	}
+	else
+		switch( _key_len )
+		{
+			case 128:
+				if( OAES_RET_SUCCESS != oaes_key_gen_128(ctx) )
+					printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+				break;
+			case 192:
+				if( OAES_RET_SUCCESS != oaes_key_gen_192(ctx) )
+					printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+				break;
+			case 256:
+				if( OAES_RET_SUCCESS != oaes_key_gen_256(ctx) )
+					printf("Error: Failed to generate OAES %d bit key.\n", _key_len);
+				break;
+			default:
+				break;
+		}
+
+	if( _bin_data )
+	{
+		if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+				_bin_data, _bin_data_len, NULL, &_encbuf_len ) )
+			printf("Error: Failed to retrieve required buffer size for encryption.\n");
+		_encbuf = (uint8_t *) calloc(_encbuf_len, sizeof(uint8_t));
+		if( NULL == _encbuf )
+		{
+			printf( "Error: Failed to allocate memory.\n" );
+			if( _key_data )
+				free( _key_data );
+			free( _bin_data );
+			return EXIT_FAILURE;
+		}
+		printf( "\n" );
+		if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+				_bin_data, _bin_data_len, _encbuf, &_encbuf_len ) )
+			printf("Error: Encryption failed.\n");
+		printf( "\n**********************\n\n" );
+	}
+	else
+	{
+		if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+				(const uint8_t *)_text, strlen( _text ), NULL, &_encbuf_len ) )
+			printf("Error: Failed to retrieve required buffer size for encryption.\n");
+		_encbuf = (uint8_t *) calloc(_encbuf_len, sizeof(uint8_t));
+		if( NULL == _encbuf )
+		{
+			printf( "Error: Failed to allocate memory.\n" );
+			if( _key_data )
+				free( _key_data );
+			return EXIT_FAILURE;
+		}
+		printf( "\n" );
+		if( OAES_RET_SUCCESS != oaes_encrypt( ctx,
+				(const uint8_t *)_text, strlen( _text ), _encbuf, &_encbuf_len ) )
+			printf("Error: Encryption failed.\n");
+		printf( "\n**********************\n\n" );
+	}
+
+	if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+			_encbuf, _encbuf_len, NULL, &_decbuf_len ) )
+		printf("Error: Failed to retrieve required buffer size for encryption.\n");
+	_decbuf = (uint8_t *) calloc(_decbuf_len, sizeof(uint8_t));
+	if( NULL == _decbuf )
+	{
+		printf( "Error: Failed to allocate memory.\n" );
+		if( _key_data )
+			free( _key_data );
+		if( _bin_data )
+			free( _bin_data );
+		free( _encbuf );
+		return EXIT_FAILURE;
+	}
+	if( OAES_RET_SUCCESS != oaes_decrypt( ctx,
+			_encbuf, _encbuf_len, _decbuf, &_decbuf_len ) )
+		printf("Error: Decryption failed.\n");
+
+	if( OAES_RET_SUCCESS !=  oaes_free( &ctx ) )
+		printf("Error: Failed to uninitialize OAES.\n");
+	
+	oaes_sprintf( NULL, &_buf_len, _encbuf, _encbuf_len );
+	_buf = (char *) calloc(_buf_len, sizeof(char));
+	printf( "\n***** cyphertext *****\n" );
+	if( _buf )
+	{
+		oaes_sprintf( _buf, &_buf_len, _encbuf, _encbuf_len );
+		printf( "%s", _buf );
+	}
+	printf( "\n**********************\n" );
+	free( _buf );
+	
+	oaes_sprintf( NULL, &_buf_len, _decbuf, _decbuf_len );
+	_buf = (char *) calloc(_buf_len, sizeof(char));
+	printf( "\n***** plaintext  *****\n" );
+	if( _buf )
+	{
+		oaes_sprintf( _buf, &_buf_len, _decbuf, _decbuf_len );
+		printf( "%s", _buf );
+	}
+	printf( "\n**********************\n\n" );
+	free( _buf );
+	
+	free( _encbuf );
+	free( _decbuf );
+	if( _key_data )
+		free( _key_data );
+	if( _bin_data )
+		free( _bin_data );
+
+	return (EXIT_SUCCESS);
+}
diff --git a/openrecoveryscript.cpp b/openrecoveryscript.cpp
index a842d33..f6f63dc 100644
--- a/openrecoveryscript.cpp
+++ b/openrecoveryscript.cpp
@@ -215,6 +215,8 @@
 
 				PartitionManager.Set_Restore_Files(folder_path);
 				string Partition_List;
+				int is_encrypted = 0;
+				DataManager::GetValue("tw_restore_encrypted", is_encrypted);
 				DataManager::GetValue("tw_restore_list", Partition_List);
 				if (strlen(partitions) != 0) {
 					string Restore_List;
@@ -260,7 +262,10 @@
 				} else {
 					DataManager::SetValue("tw_restore_selected", Partition_List);
 				}
-				if (!PartitionManager.Run_Restore(folder_path))
+				if (is_encrypted) {
+					LOGERR("Unable to use OpenRecoveryScript to restore an encrypted backup.\n");
+					ret_val = 1;
+				} else if (!PartitionManager.Run_Restore(folder_path))
 					ret_val = 1;
 				else
 					gui_print("Restore complete!\n");
diff --git a/partition.cpp b/partition.cpp
index 4405536..7b687e7 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -87,6 +87,8 @@
 	Backup_FileName = "";
 	MTD_Name = "";
 	Backup_Method = NONE;
+	Can_Encrypt_Backup = false;
+	Use_Userdata_Encryption = false;
 	Has_Data_Media = false;
 	Has_Android_Secure = false;
 	Is_Storage = false;
@@ -210,6 +212,8 @@
 			Wipe_Available_in_GUI = true;
 			Wipe_During_Factory_Reset = true;
 			Can_Be_Backed_Up = true;
+			Can_Encrypt_Backup = true;
+			Use_Userdata_Encryption = true;
 #ifdef RECOVERY_SDCARD_ON_DATA
 			Storage_Name = "Internal Storage";
 			Has_Data_Media = true;
@@ -287,6 +291,8 @@
 			SubPartition_Of = "/data";
 			DataManager::SetValue(TW_HAS_DATADATA, 1);
 			Can_Be_Backed_Up = true;
+			Can_Encrypt_Backup = true;
+			Use_Userdata_Encryption = false; // This whole partition should be encrypted
 		} else if (Mount_Point == "/sd-ext") {
 			Wipe_During_Factory_Reset = true;
 			Display_Name = "SD-Ext";
@@ -295,6 +301,8 @@
 			Wipe_Available_in_GUI = true;
 			Removable = true;
 			Can_Be_Backed_Up = true;
+			Can_Encrypt_Backup = true;
+			Use_Userdata_Encryption = true;
 		} else if (Mount_Point == "/boot") {
 			Display_Name = "Boot";
 			Backup_Display_Name = Display_Name;
@@ -445,6 +453,20 @@
 		} else if (ptr_len > 7 && strncmp(ptr, "length=", 7) == 0) {
 			ptr += 7;
 			Length = atoi(ptr);
+		} else if (ptr_len > 17 && strncmp(ptr, "canencryptbackup=", 17) == 0) {
+			ptr += 17;
+			if (*ptr == '1' || *ptr == 'y' || *ptr == 'Y')
+				Can_Encrypt_Backup = true;
+			else
+				Can_Encrypt_Backup = false;
+		} else if (ptr_len > 21 && strncmp(ptr, "userdataencryptbackup=", 21) == 0) {
+			ptr += 21;
+			if (*ptr == '1' || *ptr == 'y' || *ptr == 'Y') {
+				Can_Encrypt_Backup = true;
+				Use_Userdata_Encryption = true;
+			} else {
+				Use_Userdata_Encryption = false;
+			}
 		} else {
 			if (Display_Error)
 				LOGERR("Unhandled flag: '%s'\n", ptr);
@@ -1046,8 +1068,8 @@
 			return false;
 		}
 		md5sum.setfn(split_filename);
-		while (index < 1000 && TWFunc::Path_Exists(split_filename)) {
-			if (md5sum.verify_md5digest() != 0) {
+		while (index < 1000) {
+			if (TWFunc::Path_Exists(split_filename) && md5sum.verify_md5digest() != 0) {
 				LOGERR("MD5 failed to match on '%s'.\n", split_filename);
 				return false;
 			}
@@ -1370,7 +1392,7 @@
 bool TWPartition::Backup_Tar(string backup_folder) {
 	char back_name[255], split_index[5];
 	string Full_FileName, Split_FileName, Tar_Args, Command;
-	int use_compression, index, backup_count;
+	int use_compression, use_encryption = 0, index, backup_count;
 	struct stat st;
 	unsigned long long total_bsize = 0, file_size;
 	twrpTar tar;
@@ -1383,11 +1405,23 @@
 	gui_print("Backing up %s...\n", Backup_Display_Name.c_str());
 
 	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
+	tar.use_compression = use_compression;
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	DataManager::GetValue("tw_encrypt_backup", use_encryption);
+	if (use_encryption && Can_Encrypt_Backup) {
+		tar.use_encryption = use_encryption;
+		if (Use_Userdata_Encryption)
+			tar.userdata_encryption = use_encryption;
+	} else {
+		use_encryption = false;
+	}
+#endif
 
 	sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str());
 	Backup_FileName = back_name;
 	Full_FileName = backup_folder + "/" + Backup_FileName;
-	 if (Backup_Size > MAX_ARCHIVE_SIZE) {
+	tar.has_data_media = Has_Data_Media;
+	if (!use_encryption && Backup_Size > MAX_ARCHIVE_SIZE) {
 		// This backup needs to be split into multiple archives
 		gui_print("Breaking backup file into multiple archives...\n");
 		sprintf(back_name, "%s", Backup_Path.c_str());
@@ -1401,20 +1435,16 @@
 		return true;
 	} else {
 		Full_FileName = backup_folder + "/" + Backup_FileName;
-		if (use_compression) {
-			tar.setdir(Backup_Path);
-			tar.setfn(Full_FileName);
-			if (tar.createTarGZFork() != 0)
-				return -1;
+		tar.setdir(Backup_Path);
+		tar.setfn(Full_FileName);
+		if (tar.createTarFork() != 0)
+			return false;
+		if (use_compression && !use_encryption) {
 			string gzname = Full_FileName + ".gz";
 			rename(gzname.c_str(), Full_FileName.c_str());
 		}
-		else {
-			tar.setdir(Backup_Path);
-			tar.setfn(Full_FileName);
-			if (tar.createTarFork() != 0)
-				return -1;
-		}
+		if (use_encryption)
+			Full_FileName += "000";
 		if (TWFunc::Get_File_Size(Full_FileName) == 0) {
 			LOGERR("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
 			return false;
@@ -1493,7 +1523,7 @@
 		return false;
 
 	Full_FileName = restore_folder + "/" + Backup_FileName;
-	if (!TWFunc::Path_Exists(Full_FileName)) {
+	/*if (!TWFunc::Path_Exists(Full_FileName)) {
 		if (!TWFunc::Path_Exists(Full_FileName)) {
 			// Backup is multiple archives
 			LOGINFO("Backup is multiple archives.\n");
@@ -1516,13 +1546,14 @@
 				return false;
 			}
 		}
-	} else {
+	} else {*/
 		twrpTar tar;
 		tar.setdir(Backup_Path);
 		tar.setfn(Full_FileName);
+		tar.backup_name = Backup_Name;
 		if (tar.extractTarFork() != 0)
 			return false;
-	}
+	//}
 	return true;
 }
 
diff --git a/partitionmanager.cpp b/partitionmanager.cpp
index 0bed258..a78705b 100644
--- a/partitionmanager.cpp
+++ b/partitionmanager.cpp
@@ -184,6 +184,10 @@
 		printf("Is_Decrypted ");
 	if (Part->Has_Data_Media)
 		printf("Has_Data_Media ");
+	if (Part->Can_Encrypt_Backup)
+		printf("Can_Encrypt_Backup ");
+	if (Part->Use_Userdata_Encryption)
+		printf("Use_Userdata_Encryption ");
 	if (Part->Has_Android_Secure)
 		printf("Has_Android_Secure ");
 	if (Part->Is_Storage)
@@ -532,18 +536,20 @@
 		string strfn;
 		sprintf(filename, "%s%03i", Full_File.c_str(), index);
 		strfn = filename;
-		while (TWFunc::Path_Exists(filename) == true) {
+		while (index < 1000) {
 			md5sum.setfn(filename);
-			if (md5sum.computeMD5() == 0) {
-				if (md5sum.write_md5digest() != 0)
-				{
-					gui_print(" * MD5 Error.\n");
+			if (TWFunc::Path_Exists(filename)) {
+				if (md5sum.computeMD5() == 0) {
+					if (md5sum.write_md5digest() != 0)
+					{
+						gui_print(" * MD5 Error.\n");
+						return false;
+					}
+				} else {
+					gui_print(" * Error computing MD5.\n");
 					return false;
 				}
 			}
-			else {
-				return -1;
-			}
 			index++;
 			sprintf(filename, "%s%03i", Full_File.c_str(), index);
 			strfn = filename;
@@ -902,7 +908,9 @@
 void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
 	// Start with the default values
 	string Restore_List;
-	bool get_date = true;
+	bool get_date = true, check_encryption = true;
+
+	DataManager::SetValue("tw_restore_encrypted", 0);
 
 	DIR* d;
 	d = opendir(Restore_Name.c_str());
@@ -956,10 +964,20 @@
 			extn = ptr;
 		}
 
-		if (strcmp(fstype, "log") == 0) continue;
+		if (fstype == NULL || extn == NULL || strcmp(fstype, "log") == 0) continue;
 		int extnlength = strlen(extn);
-		if (extn == NULL || (extnlength != 3 && extnlength != 6)) continue;
-		if (extnlength == 3 && strncmp(extn, "win", 3) != 0) continue;
+		if (extnlength != 3 && extnlength != 6) continue;
+		if (extnlength >= 3 && strncmp(extn, "win", 3) != 0) continue;
+		//if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
+
+		if (check_encryption) {
+			string filename = Restore_Name + "/";
+			filename += de->d_name;
+			if (TWFunc::Get_File_Type(filename) == 2) {
+				LOGINFO("'%s' is encrypted\n", filename.c_str());
+				DataManager::SetValue("tw_restore_encrypted", 1);
+			}
+		}
 		if (extnlength == 6 && strncmp(extn, "win000", 6) != 0) continue;
 
 		TWPartition* Part = Find_Partition_By_Path(label);
diff --git a/partitions.hpp b/partitions.hpp
index 704ba68..3ed4da6 100644
--- a/partitions.hpp
+++ b/partitions.hpp
@@ -110,6 +110,8 @@
 	string Storage_Name;                                                      // Name displayed in the partition list for storage selection
 	string Backup_FileName;                                                   // Actual backup filename
 	Backup_Method_enum Backup_Method;                                         // Method used for backup
+	bool Can_Encrypt_Backup;                                                  // Indicates if this item can be encrypted during backup
+	bool Use_Userdata_Encryption;                                             // Indicates if we will use userdata encryption splitting on an encrypted backup
 	bool Has_Data_Media;                                                      // Indicates presence of /data/media, may affect wiping and backup methods
 	bool Has_Android_Secure;                                                  // Indicates the presence of .android_secure on this partition
 	bool Is_Storage;                                                          // Indicates if this partition is used for storage for backup, restore, and installing zips
diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk
index 00a8663..1470951 100644
--- a/prebuilt/Android.mk
+++ b/prebuilt/Android.mk
@@ -79,6 +79,10 @@
 ifneq ($(wildcard system/core/libsparse/Android.mk),)
     RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libsparse.so
 endif
+ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+    RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/openaes
+    RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libopenaes.so
+endif
 
 TWRP_AUTOGEN := $(intermediates)/teamwin
 
@@ -121,6 +125,17 @@
 	include $(BUILD_PREBUILT)
 endif
 
+# copy license file for OpenAES
+ifneq ($(TW_EXCLUDE_ENCRYPTED_BACKUPS), true)
+	include $(CLEAR_VARS)
+	LOCAL_MODULE := ../openaes/LICENSE
+	LOCAL_MODULE_TAGS := eng
+	LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
+	LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/license/openaes
+	LOCAL_SRC_FILES := $(LOCAL_MODULE)
+	include $(BUILD_PREBUILT)
+endif
+
 ifeq ($(TW_INCLUDE_DUMLOCK), true)
 	#htcdumlock for /system for dumlock
 	include $(CLEAR_VARS)
diff --git a/tarWrite.c b/tarWrite.c
index f5af449..7d46014 100644
--- a/tarWrite.c
+++ b/tarWrite.c
@@ -29,11 +29,13 @@
 unsigned char *write_buffer;
 unsigned buffer_size = 4096;
 unsigned buffer_loc = 0;
+int buffer_status = 0;
 
 void reinit_libtar_buffer(void) {
 	flush = 0;
 	eot_count = -1;
 	buffer_loc = 0;
+	buffer_status = 1;
 }
 
 void init_libtar_buffer(unsigned new_buff_size) {
@@ -45,7 +47,9 @@
 }
 
 void free_libtar_buffer(void) {
-	free(write_buffer);
+	if (buffer_status > 0)
+		free(write_buffer);
+	buffer_status = 0;
 }
 
 ssize_t write_libtar_buffer(int fd, const void *buffer, size_t size) {
@@ -89,4 +93,5 @@
 
 void flush_libtar_buffer(int fd) {
 	eot_count = 0;
+	buffer_status = 2;
 }
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index a0194b3..d9014b3 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -12,17 +12,23 @@
 #include <sys/sendfile.h>
 #include <sys/stat.h>
 #include <sys/vfs.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #ifdef ANDROID_RB_POWEROFF
 	#include "cutils/android_reboot.h"
 #endif
 #include <iostream>
 #include <fstream>
+#include <sstream>
 #include "twrp-functions.hpp"
 #include "partitions.hpp"
 #include "twcommon.h"
 #include "data.hpp"
 #include "variables.h"
 #include "bootloader.h"
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	#include "openaes/inc/oaes_lib.h"
+#endif
 
 extern "C" {
 	#include "libcrecovery/common.h"
@@ -455,6 +461,30 @@
 	return -1;
 }
 
+vector<string> TWFunc::split_string(const string &in, char del, bool skip_empty) {
+	vector<string> res;
+
+	if (in.empty() || del == '\0')
+		return res;
+
+	string field;
+	istringstream f(in);
+	if (del == '\n') {
+		while(getline(f, field)) {
+			if (field.empty() && skip_empty)
+				continue;
+			res.push_back(field);
+		}
+	} else {
+		while(getline(f, field, del)) {
+			if (field.empty() && skip_empty)
+				continue;
+			res.push_back(field);
+		}
+	}
+	return res;
+}
+
 timespec TWFunc::timespec_diff(timespec& start, timespec& end)
 {
 	timespec temp;
@@ -678,3 +708,172 @@
 		return false;
 	return true;
 }
+
+int TWFunc::Get_File_Type(string fn) {
+	string::size_type i = 0;
+	int firstbyte = 0, secondbyte = 0;
+	char header[3];
+        
+	ifstream f;
+	f.open(fn.c_str(), ios::in | ios::binary);
+	f.get(header, 3);
+	f.close();
+	firstbyte = header[i] & 0xff;
+	secondbyte = header[++i] & 0xff;
+
+	if (firstbyte == 0x1f && secondbyte == 0x8b) {
+		return 1; // Compressed
+	} else if (firstbyte == 0x4f && secondbyte == 0x41) {
+		return 2; // Encrypted
+	} else {
+		return 0; // Unknown
+	}
+
+	return 0;
+}
+
+int TWFunc::Try_Decrypting_File(string fn, string password) {
+#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
+	OAES_CTX * ctx = NULL;
+	uint8_t _key_data[32] = "";
+	FILE *f;
+	uint8_t buffer[4096];
+	uint8_t *buffer_out = NULL;
+	uint8_t *ptr = NULL;
+	size_t read_len = 0, out_len = 0;
+	int firstbyte = 0, secondbyte = 0, key_len;
+	size_t _j = 0;
+	size_t _key_data_len = 0;
+
+	// mostly kanged from OpenAES oaes.c
+	for( _j = 0; _j < 32; _j++ )
+		_key_data[_j] = _j + 1;
+	_key_data_len = password.size();
+	if( 16 >= _key_data_len )
+		_key_data_len = 16;
+	else if( 24 >= _key_data_len )
+		_key_data_len = 24;
+	else
+	_key_data_len = 32;
+	memcpy(_key_data, password.c_str(), password.size());
+
+	ctx = oaes_alloc();
+	if (ctx == NULL) {
+		LOGERR("Failed to allocate OAES\n");
+		return -1;
+	}
+
+	oaes_key_import_data(ctx, _key_data, _key_data_len);
+
+	f = fopen(fn.c_str(), "rb");
+	if (f == NULL) {
+		LOGERR("Failed to open '%s' to try decrypt\n", fn.c_str());
+		return -1;
+	}
+	read_len = fread(buffer, sizeof(uint8_t), 4096, f);
+	if (read_len <= 0) {
+		LOGERR("Read size during try decrypt failed\n");
+		fclose(f);
+		return -1;
+	}
+	if (oaes_decrypt(ctx, buffer, read_len, NULL, &out_len) != OAES_RET_SUCCESS) {
+		LOGERR("Error: Failed to retrieve required buffer size for trying decryption.\n");
+		fclose(f);
+		return -1;
+	}
+	buffer_out = (uint8_t *) calloc(out_len, sizeof(char));
+	if (buffer_out == NULL) {
+		LOGERR("Failed to allocate output buffer for try decrypt.\n");
+		fclose(f);
+		return -1;
+	}
+	if (oaes_decrypt(ctx, buffer, read_len, buffer_out, &out_len) != OAES_RET_SUCCESS) {
+		LOGERR("Failed to decrypt file '%s'\n", fn.c_str());
+		fclose(f);
+		free(buffer_out);
+		return 0;
+	}
+	fclose(f);
+	if (out_len < 2) {
+		LOGINFO("Successfully decrypted '%s' but read length %i too small.\n", fn.c_str(), out_len);
+		free(buffer_out);
+		return 1; // Decrypted successfully
+	}
+	ptr = buffer_out;
+	firstbyte = *ptr & 0xff;
+	ptr++;
+	secondbyte = *ptr & 0xff;
+	if (firstbyte == 0x1f && secondbyte == 0x8b) {
+		LOGINFO("Successfully decrypted '%s' and file is compressed.\n", fn.c_str());
+		free(buffer_out);
+		return 3; // Compressed
+	}
+	if (out_len >= 262) {
+		ptr = buffer_out + 257;
+		if (strncmp((char*)ptr, "ustar", 5) == 0) {
+			LOGINFO("Successfully decrypted '%s' and file is tar format.\n", fn.c_str());
+			free(buffer_out);
+			return 2; // Tar
+		}
+	}
+	free(buffer_out);
+	LOGINFO("No errors decrypting '%s' but no known file format.\n", fn.c_str());
+	return 1; // Decrypted successfully
+#else
+	LOGERR("Encrypted backup support not included.\n");
+	return -1;
+#endif
+}
+
+bool TWFunc::Try_Decrypting_Backup(string Restore_Path, string Password) {
+	DIR* d;
+
+	string Filename;
+	Restore_Path += "/";
+	d = opendir(Restore_Path.c_str());
+	if (d == NULL) {
+		LOGERR("Error opening '%s'\n", Restore_Path.c_str());
+		return false;
+	}
+
+	struct dirent* de;
+	while ((de = readdir(d)) != NULL) {
+		Filename = Restore_Path;
+		Filename += de->d_name;
+		if (TWFunc::Get_File_Type(Filename) == 2) {
+			if (TWFunc::Try_Decrypting_File(Filename, Password) < 2) {
+				DataManager::SetValue("tw_restore_password", ""); // Clear the bad password
+				DataManager::SetValue("tw_restore_display", "");  // Also clear the display mask
+				closedir(d);
+				return false;
+			}
+		}
+	}
+	closedir(d);
+	return true;
+}
+
+int TWFunc::Wait_For_Child(pid_t pid, int *status, string Child_Name) {
+	pid_t rc_pid;
+
+	rc_pid = waitpid(pid, status, 0);
+	if (rc_pid > 0) {
+		if (WEXITSTATUS(*status) == 0)
+			LOGINFO("%s process ended with RC=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Success
+		else if (WIFSIGNALED(*status)) {
+			LOGINFO("%s process ended with signal: %d\n", Child_Name.c_str(), WTERMSIG(*status)); // Seg fault or some other non-graceful termination
+			return -1;
+		} else if (WEXITSTATUS(*status) != 0) {
+			LOGINFO("%s process ended with ERROR=%d\n", Child_Name.c_str(), WEXITSTATUS(*status)); // Graceful exit, but there was an error
+			return -1;
+		}
+	} else { // no PID returned
+		if (errno == ECHILD)
+			LOGINFO("%s no child process exist\n", Child_Name.c_str());
+		else {
+			LOGINFO("%s Unexpected error\n", Child_Name.c_str());
+			return -1;
+		}
+	}
+	return 0;
+}
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index 8e31e42..9f66621 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -50,6 +50,11 @@
 	static bool Fix_su_Perms(void); // sets proper permissions for su binaries and superuser apk
 	static int tw_chmod(string fn, string mode); // chmod function that converts a 4 char string into st_mode automatically
 	static bool Install_SuperSU(void); // Installs su binary and apk and sets proper permissions
+	static vector<string> split_string(const string &in, char del, bool skip_empty);
+	static int Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted
+	static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format
+	static bool Try_Decrypting_Backup(string Restore_Path, string Password); // true for success, false for failed to decrypt
+	static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status
 
 private:
 	static void Copy_Log(string Source, string Destination);
diff --git a/twrpTar.cpp b/twrpTar.cpp
index 2dbfd15..bc7f370 100644
--- a/twrpTar.cpp
+++ b/twrpTar.cpp
@@ -32,6 +32,7 @@
 #include <iostream>
 #include <string>
 #include <sstream>
+#include <vector>
 #include <dirent.h>
 #include <sys/mman.h>
 #include "twrpTar.hpp"
@@ -42,6 +43,20 @@
 
 using namespace std;
 
+twrpTar::twrpTar(void) {
+	use_encryption = 0;
+	userdata_encryption = 0;
+	use_compression = 0;
+	split_archives = 0;
+	has_data_media = 0;
+	pigz_pid = 0;
+	oaes_pid = 0;
+}
+
+twrpTar::~twrpTar(void) {
+	// Do nothing
+}
+
 void twrpTar::setfn(string fn) {
 	tarfn = fn;
 }
@@ -50,139 +65,428 @@
 	tardir = dir;
 }
 
-int twrpTar::createTarGZFork() {
-	int status;
-	pid_t pid;
-	if ((pid = fork()) == -1) {
-		LOGINFO("create tar failed to fork.\n");
-		return -1;
-	}
-	if (pid == 0) {
-		if (createTGZ() != 0)
-			exit(-1);
-		else
-			exit(0);
-	}
-	else {
-		if ((pid = wait(&status)) == -1) {
-			LOGINFO("Tar creation failed\n");
-			return -1;
-		}
-		else {
-			if (WIFSIGNALED(status) != 0) {
-				LOGINFO("Child process ended with signal: %d\n", WTERMSIG(status));
-				return -1;
-			}
-			else if (WIFEXITED(status) != 0)
-				LOGINFO("Tar creation successful\n");
-			else {
-				LOGINFO("Tar creation failed\n");
-				return -1;
-			}
-		}
-	}
-	return 0;
+void twrpTar::setexcl(string exclude) {
+	tarexclude = exclude;
 }
 
 int twrpTar::createTarFork() {
-	int status;
-	pid_t pid;
+	int status = 0;
+	pid_t pid, rc_pid;
 	if ((pid = fork()) == -1) {
 		LOGINFO("create tar failed to fork.\n");
 		return -1;
 	}
 	if (pid == 0) {
-		if (create() != 0)
-			exit(-1);
-		else
-			exit(0);
-	}
-	else {
-		if ((pid = wait(&status)) == -1) {
-			LOGINFO("Tar creation failed\n");
+		// Child process
+		if (use_encryption || userdata_encryption) {
+			LOGINFO("Using encryption\n");
+			DIR* d;
+			struct dirent* de;
+			unsigned long long regular_size = 0, encrypt_size = 0, target_size = 0, core_count = 1;
+			unsigned enc_thread_id = 1, regular_thread_id = 0, i, start_thread_id = 1;
+			int item_len, ret, thread_error = 0;
+			std::vector<TarListStruct> RegularList;
+			std::vector<TarListStruct> EncryptList;
+			string FileName;
+			struct TarListStruct TarItem;
+			twrpTar reg, enc[9];
+			struct stat st;
+			pthread_t enc_thread[9];
+			pthread_attr_t tattr;
+			void *thread_return;
+
+			core_count = sysconf(_SC_NPROCESSORS_CONF);
+			if (core_count > 8)
+				core_count = 8;
+			LOGINFO("   Core Count      : %llu\n", core_count);
+			Archive_Current_Size = 0;
+
+			d = opendir(tardir.c_str());
+			if (d == NULL) {
+				LOGERR("error opening '%s'\n", tardir.c_str());
+				_exit(-1);
+			}
+			// Figure out the size of all data to be encrypted and create a list of unencrypted files
+			while ((de = readdir(d)) != NULL) {
+				FileName = tardir + "/";
+				FileName += de->d_name;
+				if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
+					continue; // Skip /data/media
+				if (de->d_type == DT_BLK || de->d_type == DT_CHR)
+					continue;
+				if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) {
+					item_len = strlen(de->d_name);
+					if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) {
+						if (Generate_TarList(FileName, &RegularList, &target_size, &regular_thread_id) < 0) {
+							LOGERR("Error in Generate_TarList with regular list!\n");
+							closedir(d);
+							_exit(-1);
+						}
+						regular_size += TWFunc::Get_Folder_Size(FileName, false);
+					} else {
+						encrypt_size += TWFunc::Get_Folder_Size(FileName, false);
+					}
+				} else if (de->d_type == DT_REG) {
+					stat(FileName.c_str(), &st);
+					encrypt_size += (unsigned long long)(st.st_size);
+				}
+			}
+			closedir(d);
+
+			target_size = encrypt_size / core_count;
+			target_size++;
+			LOGINFO("   Unencrypted size: %llu\n", regular_size);
+			LOGINFO("   Encrypted size  : %llu\n", encrypt_size);
+			LOGINFO("   Target size     : %llu\n", target_size);
+			if (!userdata_encryption) {
+				enc_thread_id = 0;
+				start_thread_id = 0;
+				core_count--;
+			}
+			Archive_Current_Size = 0;
+
+			d = opendir(tardir.c_str());
+			if (d == NULL) {
+				LOGERR("error opening '%s'\n", tardir.c_str());
+				_exit(-1);
+			}
+			// Divide up the encrypted file list for threading
+			while ((de = readdir(d)) != NULL) {
+				FileName = tardir + "/";
+				FileName += de->d_name;
+				if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
+					continue; // Skip /data/media
+				if (de->d_type == DT_BLK || de->d_type == DT_CHR)
+					continue;
+				if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) {
+					item_len = strlen(de->d_name);
+					if (userdata_encryption && ((item_len >= 3 && strncmp(de->d_name, "app", 3) == 0) || (item_len >= 6 && strncmp(de->d_name, "dalvik", 6) == 0))) {
+						// Do nothing, we added these to RegularList earlier
+					} else {
+						FileName = tardir + "/";
+						FileName += de->d_name;
+						if (Generate_TarList(FileName, &EncryptList, &target_size, &enc_thread_id) < 0) {
+							LOGERR("Error in Generate_TarList with encrypted list!\n");
+							closedir(d);
+							_exit(-1);
+						}
+					}
+				} else if (de->d_type == DT_REG || de->d_type == DT_LNK) {
+					stat(FileName.c_str(), &st);
+					if (de->d_type == DT_REG)
+						Archive_Current_Size += (unsigned long long)(st.st_size);
+					TarItem.fn = FileName;
+					TarItem.thread_id = enc_thread_id;
+					EncryptList.push_back(TarItem);
+				}
+			}
+			closedir(d);
+			if (enc_thread_id != core_count) {
+				LOGERR("Error dividing up threads for encryption, %i threads for %i cores!\n", enc_thread_id, core_count);
+				if (enc_thread_id > core_count)
+					_exit(-1);
+				else
+					LOGERR("Continuining anyway.");
+			}
+
+			if (userdata_encryption) {
+				// Create a backup of unencrypted data
+				reg.setfn(tarfn);
+				reg.ItemList = &RegularList;
+				reg.thread_id = 0;
+				reg.use_encryption = 0;
+				reg.use_compression = use_compression;
+				LOGINFO("Creating unencrypted backup...\n");
+				if (createList((void*)&reg) != 0) {
+					LOGERR("Error creating unencrypted backup.\n");
+					_exit(-1);
+				}
+			}
+
+			if (pthread_attr_init(&tattr)) {
+				LOGERR("Unable to pthread_attr_init\n");
+				_exit(-1);
+			}
+			if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) {
+				LOGERR("Error setting pthread_attr_setdetachstate\n");
+				_exit(-1);
+			}
+			if (pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM)) {
+				LOGERR("Error setting pthread_attr_setscope\n");
+				_exit(-1);
+			}
+			/*if (pthread_attr_setstacksize(&tattr, 524288)) {
+				LOGERR("Error setting pthread_attr_setstacksize\n");
+				_exit(-1);
+			}*/
+
+			// Create threads for the divided up encryption lists
+			for (i = start_thread_id; i <= core_count; i++) {
+				enc[i].setdir(tardir);
+				enc[i].setfn(tarfn);
+				enc[i].ItemList = &EncryptList;
+				enc[i].thread_id = i;
+				enc[i].use_encryption = use_encryption;
+				enc[i].use_compression = use_compression;
+				LOGINFO("Start encryption thread %i\n", i);
+				ret = pthread_create(&enc_thread[i], &tattr, createList, (void*)&enc[i]);
+				if (ret) {
+					LOGINFO("Unable to create %i thread for encryption! %i\nContinuing in same thread (backup will be slower).", i, ret);
+					if (createList((void*)&enc[i]) != 0) {
+						LOGERR("Error creating encrypted backup %i.\n", i);
+						_exit(-1);
+					} else {
+						enc[i].thread_id = i + 1;
+					}
+				}
+				usleep(100000); // Need a short delay before starting the next thread or the threads will never finish for some reason.
+			}
+			if (pthread_attr_destroy(&tattr)) {
+				LOGERR("Failed to pthread_attr_destroy\n");
+			}
+			for (i = start_thread_id; i <= core_count; i++) {
+				if (enc[i].thread_id == i) {
+					if (pthread_join(enc_thread[i], &thread_return)) {
+						LOGERR("Error joining thread %i\n", i);
+						_exit(-1);
+					} else {
+						LOGINFO("Joined thread %i.\n", i);
+						ret = (int)thread_return;
+						if (ret != 0) {
+							thread_error = 1;
+							LOGERR("Thread %i returned an error %i.\n", i, ret);
+							_exit(-1);
+						}
+					}
+				} else {
+					LOGINFO("Skipping joining thread %i because of pthread failure.\n", i);
+				}
+			}
+			if (thread_error) {
+				LOGERR("Error returned by one or more threads.\n");
+				_exit(-1);
+			}
+			LOGINFO("Finished encrypted backup.\n");
+			_exit(0);
+		} else {
+			if (create() != 0)
+				_exit(-1);
+			else
+				_exit(0);
+		}
+	} else {
+		if (TWFunc::Wait_For_Child(pid, &status, "createTarFork()") != 0)
 			return -1;
-		}
-		else {
-			if (WIFSIGNALED(status) != 0) {
-				LOGINFO("Child process ended with signal: %d\n", WTERMSIG(status));
-				return -1;
-			}
-			else if (WEXITSTATUS(status) == 0)
-				LOGINFO("Tar creation successful\n");
-			else {
-				LOGINFO("Tar creation failed\n");
-				return -1;
-			}
-		}
 	}
 	return 0;
 }
 
 int twrpTar::extractTarFork() {
-	int status;
-	pid_t pid;
-	if ((pid = fork()) == -1) {
+	int status = 0;
+	pid_t pid, rc_pid;
+
+	pid = fork();
+	if (pid >= 0) // fork was successful
+	{
+		if (pid == 0) // child process
+		{
+			if (TWFunc::Path_Exists(tarfn)) {
+				LOGINFO("Single archive\n");
+				if (extract() != 0)
+					_exit(-1);
+				else
+					_exit(0);
+			} else {
+				LOGINFO("Multiple archives\n");
+				string temp;
+				char actual_filename[255];
+				twrpTar tars[9];
+				pthread_t tar_thread[9];
+				pthread_attr_t tattr;
+				int thread_count = 0, i, start_thread_id = 1, ret, thread_error = 0;
+				void *thread_return;
+
+				basefn = tarfn;
+				temp = basefn + "%i%02i";
+				tarfn += "000";
+				if (!TWFunc::Path_Exists(tarfn)) {
+					LOGERR("Unable to locate '%s' or '%s'\n", basefn.c_str(), tarfn.c_str());
+					_exit(-1);
+				}
+				if (TWFunc::Get_File_Type(tarfn) != 2) {
+					LOGINFO("First tar file '%s' not encrypted\n", tarfn.c_str());
+					tars[0].basefn = basefn;
+					tars[0].thread_id = 0;
+					if (extractMulti((void*)&tars[0]) != 0) {
+						LOGERR("Error extracting split archive.\n");
+						_exit(-1);
+					}
+				} else {
+					start_thread_id = 0;
+				}
+				// Start threading encrypted restores
+				if (pthread_attr_init(&tattr)) {
+					LOGERR("Unable to pthread_attr_init\n");
+					_exit(-1);
+				}
+				if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) {
+					LOGERR("Error setting pthread_attr_setdetachstate\n");
+					_exit(-1);
+				}
+				if (pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM)) {
+					LOGERR("Error setting pthread_attr_setscope\n");
+					_exit(-1);
+				}
+				/*if (pthread_attr_setstacksize(&tattr, 524288)) {
+					LOGERR("Error setting pthread_attr_setstacksize\n");
+					_exit(-1);
+				}*/
+				for (i = start_thread_id; i < 9; i++) {
+					sprintf(actual_filename, temp.c_str(), i, 0);
+					if (TWFunc::Path_Exists(actual_filename)) {
+						thread_count++;
+						tars[i].basefn = basefn;
+						tars[i].thread_id = i;
+						LOGINFO("Creating extract thread ID %i\n", i);
+						ret = pthread_create(&tar_thread[i], &tattr, extractMulti, (void*)&tars[i]);
+						if (ret) {
+							LOGINFO("Unable to create %i thread for extraction! %i\nContinuing in same thread (restore will be slower).", i, ret);
+							if (extractMulti((void*)&tars[i]) != 0) {
+								LOGERR("Error extracting backup in thread %i.\n", i);
+								_exit(-1);
+							} else {
+								tars[i].thread_id = i + 1;
+							}
+						}
+						usleep(100000); // Need a short delay before starting the next thread or the threads will never finish for some reason.
+					} else {
+						break;
+					}
+				}
+				for (i = start_thread_id; i < thread_count + start_thread_id; i++) {
+					if (tars[i].thread_id == i) {
+						if (pthread_join(tar_thread[i], &thread_return)) {
+							LOGERR("Error joining thread %i\n", i);
+							_exit(-1);
+						} else {
+							LOGINFO("Joined thread %i.\n", i);
+							ret = (int)thread_return;
+							if (ret != 0) {
+								thread_error = 1;
+								LOGERR("Thread %i returned an error %i.\n", i, ret);
+								_exit(-1);
+							}
+						}
+					} else {
+						LOGINFO("Skipping joining thread %i because of pthread failure.\n", i);
+					}
+				}
+				if (thread_error) {
+					LOGERR("Error returned by one or more threads.\n");
+					_exit(-1);
+				}
+				LOGINFO("Finished encrypted backup.\n");
+				_exit(0);
+			}
+		}
+		else // parent process
+		{
+			if (TWFunc::Wait_For_Child(pid, &status, "extractTarFork()") != 0)
+				return -1;
+		}
+	}
+	else // fork has failed
+	{
 		LOGINFO("extract tar failed to fork.\n");
 		return -1;
 	}
-	if (pid == 0) {
-		if (extract() != 0)
-			exit(-1);
-		else
-			exit(0);
-	}
-	else {
-		if ((pid = wait(&status)) == -1) {
-			LOGINFO("Tar extraction failed\n");
-			return -1;
-		}
-		else {
-			if (WIFSIGNALED(status) != 0) {
-				LOGINFO("Child process ended with signal: %d\n", WTERMSIG(status));
-				return -1;
-			}
-			else if (WEXITSTATUS(status) == 0)
-				LOGINFO("Tar extraction successful\n");
-			else {
-				LOGINFO("Tar extraction failed\n");
-				return -1;
-			}
-		}
-	}
 	return 0;
 }
 
 int twrpTar::splitArchiveFork() {
-	int status;
-	pid_t pid;
-	if ((pid = fork()) == -1) {
-		LOGINFO("create tar failed to fork.\n");
+	int status = 0;
+	pid_t pid, rc_pid;
+
+	pid = fork();
+	if (pid >= 0) // fork was successful
+	{
+		if (pid == 0) // child process
+		{
+			if (Split_Archive() <= 0)
+				_exit(-1);
+			else
+				_exit(0);
+		}
+		else // parent process
+		{
+			if (TWFunc::Wait_For_Child(pid, &status, "splitArchiveFork()") != 0)
+				return -1;
+		}
+	}
+	else // fork has failed
+	{
+		LOGINFO("split archive failed to fork.\n");
 		return -1;
 	}
-	if (pid == 0) {
-		if (Split_Archive() != 0)
-			exit(-1);
-		else
-			exit(0);
+	return 0;
+}
+
+int twrpTar::Generate_TarList(string Path, std::vector<TarListStruct> *TarList, unsigned long long *Target_Size, unsigned *thread_id) {
+	DIR* d;
+	struct dirent* de;
+	struct stat st;
+	string FileName;
+	struct TarListStruct TarItem;
+	string::size_type i;
+	bool skip;
+
+	if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
+		return 0; // Skip /data/media
+
+	d = opendir(Path.c_str());
+	if (d == NULL) {
+		LOGERR("error opening '%s' -- error: %s\n", Path.c_str(), strerror(errno));
+		closedir(d);
+		return -1;
 	}
-	else {
-		if ((pid = wait(&status)) == -1) {
-			LOGINFO("Tar creation failed\n");
-			return -1;
-		}
-		else {
-			if (WIFSIGNALED(status) != 0) {
-				LOGINFO("Child process ended with signal: %d\n", WTERMSIG(status));
-				return -1;
+	while ((de = readdir(d)) != NULL) {
+		// Skip excluded stuff
+		if (split.size() > 0) {
+			skip = false;
+			for (i = 0; i < split.size(); i++) {
+				if (strcmp(de->d_name, split[i].c_str()) == 0) {
+					LOGINFO("excluding %s\n", de->d_name);
+					skip = true;
+					break;
+				}
 			}
-			else if (WIFEXITED(status) != 0)
-				LOGINFO("Tar creation successful\n");
-			else {
-				LOGINFO("Tar creation failed\n");
+			if (skip)
+				continue;
+		}
+		FileName = Path + "/";
+		FileName += de->d_name;
+		if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
+			continue; // Skip /data/media
+		if (de->d_type == DT_BLK || de->d_type == DT_CHR)
+			continue;
+		TarItem.fn = FileName;
+		TarItem.thread_id = *thread_id;
+		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) {
+			TarList->push_back(TarItem);
+			if (Generate_TarList(FileName, TarList, Target_Size, thread_id) < 0)
 				return -1;
+		} else if (de->d_type == DT_REG || de->d_type == DT_LNK) {
+			stat(FileName.c_str(), &st);
+			TarList->push_back(TarItem);
+			if (de->d_type == DT_REG)
+				Archive_Current_Size += st.st_size;
+			if (Archive_Current_Size != 0 && *Target_Size != 0 && Archive_Current_Size > *Target_Size) {
+				*thread_id = *thread_id + 1;
+				Archive_Current_Size = 0;
 			}
 		}
 	}
+	closedir(d);
 	return 0;
 }
 
@@ -193,6 +497,9 @@
 	string FileName;
 	char actual_filename[255];
 
+	string::size_type i;
+	bool skip;
+
 	if (has_data_media == 1 && Path.size() >= 11 && strncmp(Path.c_str(), "/data/media", 11) == 0)
 		return 0; // Skip /data/media
 	LOGINFO("Path: '%s', archive filename: '%s'\n", Path.c_str(), tarfn.c_str());
@@ -204,8 +511,20 @@
 		closedir(d);
 		return -1;
 	}
-	while ((de = readdir(d)) != NULL)
-	{
+	while ((de = readdir(d)) != NULL) {
+		// Skip excluded stuff
+		if (split.size() > 0) {
+			skip = false;
+			for (i = 0; i < split.size(); i++) {
+				if (strcmp(de->d_name, split[i].c_str()) == 0) {
+					LOGINFO("excluding %s\n", de->d_name);
+					skip = true;
+					break;
+				}
+			}
+			if (skip)
+				continue;
+		}
 		FileName = Path + "/";
 		FileName += de->d_name;
 		if (has_data_media == 1 && FileName.size() >= 11 && strncmp(FileName.c_str(), "/data/media", 11) == 0)
@@ -234,8 +553,7 @@
 
 			if (Archive_Current_Size != 0 && Archive_Current_Size + st.st_size > MAX_ARCHIVE_SIZE) {
 				LOGINFO("Closing tar '%s', ", tarfn.c_str());
-				closeTar(false);
-				reinit_libtar_buffer();
+				closeTar();
 				if (TWFunc::Get_File_Size(tarfn) == 0) {
 					LOGERR("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str());
 					return -1;
@@ -277,25 +595,23 @@
 	Archive_Current_Size = 0;
 	sprintf(actual_filename, temp.c_str(), Archive_File_Count);
 	tarfn = actual_filename;
-	init_libtar_buffer(0);
+	if (!tarexclude.empty())
+		split = TWFunc::split_string(tarexclude, ' ', true);
 	createTar();
 	DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
 	gui_print("Creating archive 1...\n");
 	if (Generate_Multiple_Archives(tardir) < 0) {
 		LOGERR("Error generating multiple archives\n");
-		free_libtar_buffer();
 		return -1;
 	}
-	closeTar(false);
-	free_libtar_buffer();
-	LOGINFO("Done, created %i archives.\n", (Archive_File_Count++));
+	closeTar();
+	LOGINFO("Done, created %i archives.\n", (++Archive_File_Count));
 	return (Archive_File_Count);
 }
 
 int twrpTar::extractTar() {
 	char* charRootDir = (char*) tardir.c_str();
-	bool gzip = false;
-	if (openTar(gzip) == -1)
+	if (openTar() == -1)
 		return -1;
 	if (tar_extract_all(t, charRootDir) != 0) {
 		LOGERR("Unable to extract tar archive '%s'\n", tarfn.c_str());
@@ -308,37 +624,33 @@
 	return 0;
 }
 
-int twrpTar::getArchiveType() {
-        int type = 0;
-        string::size_type i = 0;
-        int firstbyte = 0, secondbyte = 0;
-	char header[3];
-        
-        ifstream f;
-        f.open(tarfn.c_str(), ios::in | ios::binary);
-        f.get(header, 3);
-        f.close();
-        firstbyte = header[i] & 0xff;
-        secondbyte = header[++i] & 0xff;
-
-        if (firstbyte == 0x1f && secondbyte == 0x8b)
-		type = 1; // Compressed
-	else
-		type = 0; // Uncompressed
-
-	return type;
-}
-
 int twrpTar::extract() {
-	int Archive_Current_Type = getArchiveType();
+	Archive_Current_Type = TWFunc::Get_File_Type(tarfn);
 
 	if (Archive_Current_Type == 1) {
 		//if you return the extractTGZ function directly, stack crashes happen
 		LOGINFO("Extracting gzipped tar\n");
-		int ret = extractTGZ();
+		int ret = extractTar();
 		return ret;
-	}
-	else {
+	} else if (Archive_Current_Type == 2) {
+		string Password;
+		DataManager::GetValue("tw_restore_password", Password);
+		int ret = TWFunc::Try_Decrypting_File(tarfn, Password);
+		if (ret < 1) {
+			LOGERR("Failed to decrypt tar file '%s'\n", tarfn.c_str());
+			return -1;
+		}
+		if (ret == 1) {
+			LOGERR("Decrypted file is not in tar format.\n");
+			return -1;
+		}
+		if (ret == 3) {
+			LOGINFO("Extracting encrypted and compressed tar.\n");
+			Archive_Current_Type = 3;
+		} else
+			LOGINFO("Extracting encrypted tar.\n");
+		return extractTar();
+	} else {
 		LOGINFO("Extracting uncompressed tar\n");
 		return extractTar();
 	}
@@ -348,8 +660,17 @@
 	DIR* d;
 	string mainfolder = tardir + "/", subfolder;
 	char buf[PATH_MAX];
+
+	char excl[1024];
+	string::size_type i;
+	bool skip;
+
 	d = opendir(tardir.c_str());
-	if (d != NULL) {
+	if (d != NULL) {		
+		if (!tarexclude.empty()) {
+			strcpy(excl, tarexclude.c_str());
+			split = TWFunc::split_string(tarexclude, ' ', true);
+		}
 		struct dirent* de;
 		while ((de = readdir(d)) != NULL) {
 #ifdef RECOVERY_SDCARD_ON_DATA
@@ -357,6 +678,21 @@
 #endif
 			if (de->d_type == DT_BLK || de->d_type == DT_CHR || strcmp(de->d_name, "..") == 0)
 				continue;
+
+			// Skip excluded stuff
+			if (split.size() > 0) {
+				skip = false;
+				for (i = 0; i < split.size(); i++) {
+					if (strcmp(de->d_name, split[i].c_str()) == 0) {
+						LOGINFO("excluding %s\n", de->d_name);
+						skip = true;
+						break;
+					}
+				}
+				if (skip)
+					continue;
+			}
+
 			subfolder = mainfolder;
 			if (strcmp(de->d_name, ".") != 0) {
 				subfolder += de->d_name;
@@ -376,7 +712,7 @@
 					string temp = Strip_Root_Dir(buf);
 					charTarPath = (char*) temp.c_str();
 				}
-				if (tar_append_tree(t, buf, charTarPath) != 0) {
+				if (tar_append_tree(t, buf, charTarPath, excl) != 0) {
 					LOGERR("Error appending '%s' to tar archive '%s'\n", buf, tarfn.c_str());
 					return -1;
 				}
@@ -391,103 +727,476 @@
 	return 0;
 }
 
-int twrpTar::createTGZ() {
-	bool gzip = true;
+int twrpTar::tarList(bool include_root, std::vector<TarListStruct> *TarList, unsigned thread_id) {
+	struct stat st;
+	char buf[PATH_MAX];
+	int list_size = TarList->size(), i = 0, archive_count = 0;
+	string temp;
+	char actual_filename[PATH_MAX];
 
-	init_libtar_buffer(0);
-	if (createTar() == -1)
-		return -1;
-	if (tarDirs(false) == -1)
-		return -1;
-	if (closeTar(gzip) == -1)
-		return -1;
-	free_libtar_buffer();
+	basefn = tarfn;
+	temp = basefn + "%i%02i";
+	sprintf(actual_filename, temp.c_str(), thread_id, archive_count);
+	tarfn = actual_filename;
+	if (createTar() != 0) {
+		LOGERR("Error creating tar '%s' for thread %i\n", tarfn.c_str(), thread_id);
+		return -2;
+	}
+	Archive_Current_Size = 0;
+
+	while (i < list_size) {
+		if (TarList->at(i).thread_id == thread_id) {
+			strcpy(buf, TarList->at(i).fn.c_str());
+			stat(buf, &st);
+			if (st.st_mode & S_IFREG) { // item is a regular file
+				if (Archive_Current_Size + (unsigned long long)(st.st_size) > MAX_ARCHIVE_SIZE) {
+					if (closeTar() != 0) {
+						LOGERR("Error closing '%s' on thread %i\n", tarfn.c_str(), thread_id);
+						return -3;
+					}
+					archive_count++;
+					LOGINFO("Splitting thread ID %i into archive %i\n", thread_id, archive_count);
+					if (archive_count > 99) {
+						LOGINFO("BLAH!\n");
+						LOGERR("Too many archives for thread %i\n", thread_id);
+						return -4;
+					}
+					sprintf(actual_filename, temp.c_str(), thread_id, archive_count);
+					tarfn = actual_filename;
+					if (createTar() != 0) {
+						LOGERR("Error creating tar '%s' for thread %i\n", tarfn.c_str(), thread_id);
+						return -2;
+					}
+					Archive_Current_Size = 0;
+				}
+				Archive_Current_Size += (unsigned long long)(st.st_size);
+			}
+			if (addFile(buf, include_root) != 0) {
+				LOGERR("Error adding file '%s' to '%s'\n", buf, tarfn.c_str());
+				return -1;
+			}
+		}
+		i++;
+	}
+	if (closeTar() != 0) {
+		LOGERR("Error closing '%s' on thread %i\n", tarfn.c_str(), thread_id);
+		return -3;
+	}
+	LOGINFO("Thread id %i tarList done, %i archives.\n", thread_id, archive_count, i, list_size);
 	return 0;
 }
 
 int twrpTar::create() {
-	bool gzip = false;
 
 	init_libtar_buffer(0);
 	if (createTar() == -1)
 		return -1;
 	if (tarDirs(false) == -1)
 		return -1;
-	if (closeTar(gzip) == -1)
+	if (closeTar() == -1)
 		return -1;
 	free_libtar_buffer();
 	return 0;
 }
 
+void* twrpTar::createList(void *cookie) {
+
+	twrpTar* threadTar = (twrpTar*) cookie;
+	if (threadTar->tarList(true, threadTar->ItemList, threadTar->thread_id) == -1) {
+		LOGINFO("ERROR tarList for thread ID %i\n", threadTar->thread_id);
+		return (void*)-2;
+	}
+	LOGINFO("Thread ID %i finished successfully.\n", threadTar->thread_id);
+	return (void*)0;
+}
+
+void* twrpTar::extractMulti(void *cookie) {
+
+	twrpTar* threadTar = (twrpTar*) cookie;
+	int archive_count = 0;
+	string temp = threadTar->basefn + "%i%02i";
+	char actual_filename[255];
+	sprintf(actual_filename, temp.c_str(), threadTar->thread_id, archive_count);
+	while (TWFunc::Path_Exists(actual_filename)) {
+		threadTar->tarfn = actual_filename;
+		if (threadTar->extract() != 0) {
+			LOGINFO("Error extracting '%s' in thread ID %i\n", actual_filename, threadTar->thread_id);
+			return (void*)-2;
+		}
+		archive_count++;
+		if (archive_count > 99)
+			break;
+		sprintf(actual_filename, temp.c_str(), threadTar->thread_id, archive_count);
+	}
+	LOGINFO("Thread ID %i finished successfully.\n", threadTar->thread_id);
+	return (void*)0;
+}
+
 int twrpTar::addFilesToExistingTar(vector <string> files, string fn) {
 	char* charTarFile = (char*) fn.c_str();
-	static tartype_t type = { open, close, read, write_tar };
 
-	init_libtar_buffer(0);
-	if (tar_open(&t, charTarFile, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) == -1)
+	if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) == -1)
 		return -1;
 	removeEOT(charTarFile);
-	if (tar_open(&t, charTarFile, &type, O_WRONLY | O_APPEND | O_LARGEFILE, 0644, TAR_GNU) == -1)
+	if (tar_open(&t, charTarFile, NULL, O_WRONLY | O_APPEND | O_LARGEFILE, 0644, TAR_GNU) == -1)
 		return -1;
 	for (unsigned int i = 0; i < files.size(); ++i) {
 		char* file = (char*) files.at(i).c_str();
 		if (tar_append_file(t, file, file) == -1)
 			return -1;
 	}
-	flush_libtar_buffer(t->fd);
 	if (tar_append_eof(t) == -1)
 		return -1;
 	if (tar_close(t) == -1)
 		return -1;
-	free_libtar_buffer();
 	return 0;
 }
 
 int twrpTar::createTar() {
 	char* charTarFile = (char*) tarfn.c_str();
 	char* charRootDir = (char*) tardir.c_str();
-	int use_compression = 0;
 	static tartype_t type = { open, close, read, write_tar };
+	string Password;
 
-	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
-	if (use_compression) {
-		string cmd = "pigz - > '" + tarfn + "'";
-		p = popen(cmd.c_str(), "w");
-		fd = fileno(p);
-		if (!p) return -1;
-		if(tar_fdopen(&t, fd, charRootDir, &type, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
-			pclose(p);
+	if (use_encryption && use_compression) {
+		// Compressed and encrypted
+		Archive_Current_Type = 3;
+		LOGINFO("Using encryption and compression...\n");
+		DataManager::GetValue("tw_backup_password", Password);
+		int i, pipes[4];
+
+		if (pipe(pipes) < 0) {
+			LOGERR("Error creating first pipe\n");
 			return -1;
 		}
-	}
-	else {
-		if (tar_open(&t, charTarFile, &type, O_WRONLY | O_CREAT | O_LARGEFILE, 0644, TAR_GNU) == -1)
+		if (pipe(pipes + 2) < 0) {
+			LOGERR("Error creating second pipe\n");
 			return -1;
+		}
+		pigz_pid = fork();
+		
+		if (pigz_pid < 0) {
+			LOGERR("pigz fork() failed\n");
+			for (i = 0; i < 4; i++)
+				close(pipes[i]); // close all
+			return -1;
+		} else if (pigz_pid == 0) {
+			// pigz Child
+			close(pipes[1]);
+			close(pipes[2]);
+			close(0);
+			dup2(pipes[0], 0);
+			close(1);
+			dup2(pipes[3], 1);
+			if (execlp("pigz", "pigz", "-", NULL) < 0) {
+				LOGERR("execlp pigz ERROR!\n");
+				close(pipes[0]);
+				close(pipes[3]);
+				_exit(-1);
+			}
+		} else {
+			// Parent
+			oaes_pid = fork();
+		
+			if (oaes_pid < 0) {
+				LOGERR("openaes fork() failed\n");
+				for (i = 0; i < 4; i++)
+					close(pipes[i]); // close all
+				return -1;
+			} else if (oaes_pid == 0) {
+				// openaes Child
+				int output_fd = open(tarfn.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+				if (output_fd < 0) {
+					LOGERR("Failed to open '%s'\n", tarfn.c_str());
+					for (i = 0; i < 4; i++)
+						close(pipes[i]); // close all
+					return -1;
+				}
+				close(pipes[0]);
+				close(pipes[1]);
+				close(pipes[3]);
+				close(0);
+				dup2(pipes[2], 0);
+				close(1);
+				dup2(output_fd, 1);
+				if (execlp("openaes", "openaes", "enc", "--key", Password.c_str(), NULL) < 0) {
+					LOGERR("execlp openaes ERROR!\n");
+					close(pipes[2]);
+					close(output_fd);
+					_exit(-1);
+				}
+			} else {
+				// Parent
+				close(pipes[0]);
+				close(pipes[2]);
+				close(pipes[3]);
+				fd = pipes[1];
+				if(tar_fdopen(&t, fd, charRootDir, NULL, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+					close(fd);
+					LOGERR("tar_fdopen failed\n");
+					return -1;
+				}
+				return 0;
+			}
+		}
+	} else if (use_compression) {
+		// Compressed
+		Archive_Current_Type = 1;
+		LOGINFO("Using compression...\n");
+		int pigzfd[2];
+
+		if (pipe(pigzfd) < 0) {
+			LOGERR("Error creating pipe\n");
+			return -1;
+		}
+		pigz_pid = fork();
+		
+		if (pigz_pid < 0) {
+			LOGERR("fork() failed\n");
+			close(pigzfd[0]);
+			close(pigzfd[1]);
+			return -1;
+		} else if (pigz_pid == 0) {
+			// Child
+			close(pigzfd[1]);   // close unused output pipe
+			int output_fd = open(tarfn.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+			if (output_fd < 0) {
+				LOGERR("Failed to open '%s'\n", tarfn.c_str());
+				close(pigzfd[0]);
+				_exit(-1);
+			}
+			dup2(pigzfd[0], 0); // remap stdin
+			dup2(output_fd, 1); // remap stdout to output file
+			if (execlp("pigz", "pigz", "-", NULL) < 0) {
+				LOGERR("execlp pigz ERROR!\n");
+				close(output_fd);
+				close(pigzfd[0]);
+				_exit(-1);
+			}
+		} else {
+			// Parent
+			close(pigzfd[0]); // close parent input
+			fd = pigzfd[1];   // copy parent output
+			if(tar_fdopen(&t, fd, charRootDir, NULL, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+				close(fd);
+				LOGERR("tar_fdopen failed\n");
+				return -1;
+			}
+		}
+	} else if (use_encryption) {
+		// Encrypted
+		Archive_Current_Type = 2;
+		LOGINFO("Using encryption...\n");
+		DataManager::GetValue("tw_backup_password", Password);
+		int oaesfd[2];
+		pipe(oaesfd);
+		oaes_pid = fork();
+		
+		if (oaes_pid < 0) {
+			LOGERR("fork() failed\n");
+			close(oaesfd[0]);
+			close(oaesfd[1]);
+			return -1;
+		} else if (oaes_pid == 0) {
+			// Child
+			close(oaesfd[1]);   // close unused
+			int output_fd = open(tarfn.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+			if (output_fd < 0) {
+				LOGERR("Failed to open '%s'\n", tarfn.c_str());
+				_exit(-1);
+			}
+			dup2(oaesfd[0], 0); // remap stdin
+			dup2(output_fd, 1); // remap stdout to output file
+			if (execlp("openaes", "openaes", "enc", "--key", Password.c_str(), NULL) < 0) {
+				LOGERR("execlp openaes ERROR!\n");
+				close(output_fd);
+				close(oaesfd[0]);
+				_exit(-1);
+			}
+		} else {
+			// Parent
+			close(oaesfd[0]); // close parent input
+			fd = oaesfd[1];   // copy parent output
+			if(tar_fdopen(&t, fd, charRootDir, NULL, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+				close(fd);
+				LOGERR("tar_fdopen failed\n");
+				return -1;
+			}
+			return 0;
+		}
+	} else {
+		// Not compressed or encrypted
+		init_libtar_buffer(0);
+		if (tar_open(&t, charTarFile, &type, O_WRONLY | O_CREAT | O_LARGEFILE, 0644, TAR_GNU) == -1) {
+			LOGERR("tar_open error opening '%s'\n", tarfn.c_str());
+			return -1;
+		}
 	}
 	return 0;
 }
 
-int twrpTar::openTar(bool gzip) {
+int twrpTar::openTar() {
 	char* charRootDir = (char*) tardir.c_str();
 	char* charTarFile = (char*) tarfn.c_str();
+	string Password;
 
-	if (gzip) {
-		LOGINFO("Opening as a gzip\n");
-		string cmd = "pigz -d -c '" + tarfn + "'";
-		FILE* pipe = popen(cmd.c_str(), "r");
-		int fd = fileno(pipe);
-		if (!pipe) return -1;
-		if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
-			LOGINFO("tar_fdopen returned error\n");
-			__pclose(pipe);
+	if (Archive_Current_Type == 3) {
+		LOGINFO("Opening encrypted and compressed backup...\n");
+		DataManager::GetValue("tw_restore_password", Password);
+		int i, pipes[4];
+
+		if (pipe(pipes) < 0) {
+			LOGERR("Error creating first pipe\n");
 			return -1;
 		}
-	}
-	else {
-		if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
-			LOGERR("Unable to open tar archive '%s'\n", charTarFile);
+		if (pipe(pipes + 2) < 0) {
+			LOGERR("Error creating second pipe\n");
 			return -1;
 		}
+		oaes_pid = fork();
+		
+		if (oaes_pid < 0) {
+			LOGERR("pigz fork() failed\n");
+			for (i = 0; i < 4; i++)
+				close(pipes[i]); // close all
+			return -1;
+		} else if (oaes_pid == 0) {
+			// openaes Child
+			close(pipes[0]); // Close pipes that are not used by this child
+			close(pipes[2]);
+			close(pipes[3]);
+			int input_fd = open(tarfn.c_str(), O_RDONLY | O_LARGEFILE);
+			if (input_fd < 0) {
+				LOGERR("Failed to open '%s'\n", tarfn.c_str());
+				close(pipes[1]);
+				_exit(-1);
+			}
+			close(0);
+			dup2(input_fd, 0);
+			close(1);
+			dup2(pipes[1], 1);
+			if (execlp("openaes", "openaes", "dec", "--key", Password.c_str(), NULL) < 0) {
+				LOGERR("execlp openaes ERROR!\n");
+				close(input_fd);
+				close(pipes[1]);
+				_exit(-1);
+			}
+		} else {
+			// Parent
+			pigz_pid = fork();
+		
+			if (pigz_pid < 0) {
+				LOGERR("openaes fork() failed\n");
+				for (i = 0; i < 4; i++)
+					close(pipes[i]); // close all
+				return -1;
+			} else if (pigz_pid == 0) {
+				// pigz Child
+				close(pipes[1]); // Close pipes not used by this child
+				close(pipes[2]);
+				close(0);
+				dup2(pipes[0], 0);
+				close(1);
+				dup2(pipes[3], 1);
+				if (execlp("pigz", "pigz", "-d", "-c", NULL) < 0) {
+					LOGERR("execlp pigz ERROR!\n");
+					close(pipes[0]);
+					close(pipes[3]);
+					_exit(-1);
+				}
+			} else {
+				// Parent
+				close(pipes[0]); // Close pipes not used by parent
+				close(pipes[1]);
+				close(pipes[3]);
+				fd = pipes[2];
+				if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+					close(fd);
+					LOGERR("tar_fdopen failed\n");
+					return -1;
+				}
+			}
+		}
+	} else if (Archive_Current_Type == 2) {
+		LOGINFO("Opening encrypted backup...\n");
+		DataManager::GetValue("tw_restore_password", Password);
+		int oaesfd[2];
+
+		pipe(oaesfd);
+		oaes_pid = fork();
+		if (oaes_pid < 0) {
+			LOGERR("fork() failed\n");
+			close(oaesfd[0]);
+			close(oaesfd[1]);
+			return -1;
+		} else if (oaes_pid == 0) {
+			// Child
+			close(oaesfd[0]); // Close unused pipe
+			int input_fd = open(tarfn.c_str(), O_RDONLY | O_LARGEFILE);
+			if (input_fd < 0) {
+				LOGERR("Failed to open '%s'\n", tarfn.c_str());
+				close(oaesfd[1]);
+				_exit(-1);
+			}
+			close(0);   // close stdin
+			dup2(oaesfd[1], 1); // remap stdout
+			dup2(input_fd, 0); // remap input fd to stdin
+			if (execlp("openaes", "openaes", "dec", "--key", Password.c_str(), NULL) < 0) {
+				LOGERR("execlp openaes ERROR!\n");
+				close(input_fd);
+				close(oaesfd[1]);
+				_exit(-1);
+			}
+		} else {
+			// Parent
+			close(oaesfd[1]); // close parent output
+			fd = oaesfd[0];   // copy parent input
+			if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+				close(fd);
+				LOGERR("tar_fdopen failed\n");
+				return -1;
+			}
+		}
+	} else if (Archive_Current_Type == 1) {
+		LOGINFO("Opening as a gzip...\n");
+		int pigzfd[2];
+		pipe(pigzfd);
+
+		pigz_pid = fork();
+		if (pigz_pid < 0) {
+			LOGERR("fork() failed\n");
+			close(pigzfd[0]);
+			close(pigzfd[1]);
+			return -1;
+		} else if (pigz_pid == 0) {
+			// Child
+			close(pigzfd[0]);
+			int input_fd = open(tarfn.c_str(), O_RDONLY | O_LARGEFILE);
+			if (input_fd < 0) {
+				LOGERR("Failed to open '%s'\n", tarfn.c_str());
+				_exit(-1);
+			}
+			dup2(input_fd, 0); // remap input fd to stdin
+			dup2(pigzfd[1], 1); // remap stdout
+			if (execlp("pigz", "pigz", "-d", "-c", NULL) < 0) {
+				close(pigzfd[1]);
+				close(input_fd);
+				LOGERR("execlp openaes ERROR!\n");
+				_exit(-1);
+			}
+		} else {
+			// Parent
+			close(pigzfd[1]); // close parent output
+			fd = pigzfd[0];   // copy parent input
+			if(tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+				close(fd);
+				LOGERR("tar_fdopen failed\n");
+				return -1;
+			}
+		}
+	} else if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, 0644, TAR_GNU) != 0) {
+		LOGERR("Unable to open tar archive '%s'\n", charTarFile);
+		return -1;
 	}
 	return 0;
 }
@@ -526,10 +1235,7 @@
 	return 0;
 }
 
-int twrpTar::closeTar(bool gzip) {
-	int use_compression;
-	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
-
+int twrpTar::closeTar() {
 	flush_libtar_buffer(t->fd);
 	if (tar_append_eof(t) != 0) {
 		LOGERR("tar_append_eof(): %s\n", strerror(errno));
@@ -540,11 +1246,16 @@
 		LOGERR("Unable to close tar archive: '%s'\n", tarfn.c_str());
 		return -1;
 	}
-	if (use_compression || gzip) {
-		LOGINFO("Closing popen and fd\n");
-		pclose(p);
+	if (Archive_Current_Type > 1) {
 		close(fd);
+		int status;
+		if (pigz_pid > 0 && TWFunc::Wait_For_Child(pigz_pid, &status, "pigz") != 0)
+			return -1;
+		if (oaes_pid > 0 && TWFunc::Wait_For_Child(oaes_pid, &status, "openaes") != 0)
+			return -1;
 	}
+	free_libtar_buffer();
+	TWFunc::tw_chmod(tarfn, "644");
 	return 0;
 }
 
@@ -563,51 +1274,55 @@
 	return 0;
 }
 
-int twrpTar::compress(string fn) {
-	string cmd = "pigz " + fn;
-	p = popen(cmd.c_str(), "r");
-	if (!p) return -1;
-	char buffer[128];
-	string result = "";
-	while(!feof(p)) {
-		if(fgets(buffer, 128, p) != NULL)
-			result += buffer;
-	}
-	__pclose(p);
-	return 0;
-}
-
-int twrpTar::extractTGZ() {
-	string splatrootdir(tardir);
-	bool gzip = true;
-	char* splatCharRootDir = (char*) splatrootdir.c_str();
-	if (openTar(gzip) == -1)
-		return -1;
-	int ret = tar_extract_all(t, splatCharRootDir);
-	if (tar_close(t) != 0) {
-		LOGERR("Unable to close tar file\n");
-		return -1;
-	}
-	return 0;
-}
-
 int twrpTar::entryExists(string entry) {
 	char* searchstr = (char*)entry.c_str();
 	int ret;
 
-	int Archive_Current_Type = getArchiveType();
+	Archive_Current_Type = TWFunc::Get_File_Type(tarfn);
 
-	if (openTar(Archive_Current_Type) == -1)
+	if (openTar() == -1)
 		ret = 0;
 	else
 		ret = tar_find(t, searchstr);
 
-	if (tar_close(t) != 0)
-		LOGINFO("Unable to close tar file after searching for entry '%s'.\n", entry.c_str());
+	if (closeTar() != 0)
+		LOGINFO("Unable to close tar after searching for entry.\n");
 
 	return ret;
 }
 
+unsigned long long twrpTar::uncompressedSize() {
+	int type = 0;
+        unsigned long long total_size = 0;
+	string Tar, Command, result;
+	vector<string> split;
+
+	Tar = TWFunc::Get_Filename(tarfn);
+	type = TWFunc::Get_File_Type(tarfn);
+	if (type == 0)
+		total_size = TWFunc::Get_File_Size(tarfn);
+	else {
+		Command = "pigz -l " + tarfn;
+		/* if we set Command = "pigz -l " + tarfn + " | sed '1d' | cut -f5 -d' '";
+		   we get the uncompressed size at once. */
+		TWFunc::Exec_Cmd(Command, result);
+		if (!result.empty()) {
+			/* Expected output:
+				compressed   original reduced  name
+				  95855838  179403776   -1.3%  data.yaffs2.win
+						^
+					     split[5]
+			*/
+			split = TWFunc::split_string(result, ' ', true);
+			if (split.size() > 4)
+				total_size = atoi(split[5].c_str());
+		}
+	}
+	LOGINFO("%s's uncompressed size: %llu bytes\n", Tar.c_str(), total_size);
+
+	return total_size;
+}
+
 extern "C" ssize_t write_tar(int fd, const void *buffer, size_t size) {
 	return (ssize_t) write_libtar_buffer(fd, buffer, size);
 }
diff --git a/twrpTar.hpp b/twrpTar.hpp
index 3ee6028..e270d90 100644
--- a/twrpTar.hpp
+++ b/twrpTar.hpp
@@ -30,24 +30,43 @@
 
 using namespace std;
 
+struct TarListStruct {
+	std::string fn;
+	unsigned thread_id;
+};
+
+struct thread_data_struct {
+	std::vector<TarListStruct> *TarList;
+	unsigned thread_id;
+};
+
 class twrpTar {
 	public:
-		int extract();
-		int compress(string fn);
-		int uncompress(string fn);
-                int addFilesToExistingTar(vector <string> files, string tarFile);
-		int createTar();
-		int addFile(string fn, bool include_root);
-		int entryExists(string entry);
-		int closeTar(bool gzip);
-		int createTarGZFork();
+		twrpTar();
+		virtual ~twrpTar();
 		int createTarFork();
 		int extractTarFork();
 		int splitArchiveFork();
-                void setfn(string fn);
-                void setdir(string dir);
+		void setexcl(string exclude);
+		void setfn(string fn);
+		void setdir(string dir);
+		unsigned long long uncompressedSize();
+		
+	public:
+		int use_encryption;
+		int userdata_encryption;
+		int use_compression;
+		int split_archives;
+		int has_data_media;
+		string backup_name;
+
 	private:
-		int createTGZ();
+		int extract();
+		int addFilesToExistingTar(vector <string> files, string tarFile);
+		int createTar();
+		int addFile(string fn, bool include_root);
+		int entryExists(string entry);
+		int closeTar();
 		int create();
 		int Split_Archive();
 		int removeEOT(string tarFile);
@@ -55,16 +74,26 @@
 		int tarDirs(bool include_root);
 		int Generate_Multiple_Archives(string Path);
 		string Strip_Root_Dir(string Path);
-		int extractTGZ();
-		int openTar(bool gzip);
-		int has_data_media;
+		int openTar();
 		int Archive_File_Count;
+		int Archive_Current_Type;
 		unsigned long long Archive_Current_Size;
-		int getArchiveType(); // 1 for compressed - 0 for uncompressed
 		TAR *t;
-		FILE* p;
 		int fd;
+		pid_t pigz_pid;
+		pid_t oaes_pid;
+
 		string tardir;
 		string tarfn;
 		string basefn;
+		string tarexclude;
+
+		vector<string> split;
+
+		int Generate_TarList(string Path, std::vector<TarListStruct> *TarList, unsigned long long *Target_Size, unsigned *thread_id);
+		static void* createList(void *cookie);
+		static void* extractMulti(void *cookie);
+		int tarList(bool include_root, std::vector<TarListStruct> *TarList, unsigned thread_id);
+		std::vector<TarListStruct> *ItemList;
+		int thread_id;
 }; 
diff --git a/variables.h b/variables.h
index 4654703..ddae2af 100644
--- a/variables.h
+++ b/variables.h
@@ -166,6 +166,7 @@
 
 // Max archive size for tar backups before we split (1.5GB)
 #define MAX_ARCHIVE_SIZE 1610612736LLU
+//#define MAX_ARCHIVE_SIZE 52428800LLU // 50MB split for testing
 
 #ifndef CUSTOM_LUN_FILE
 #define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"