Merge "ext4crypt: keymaster: fix missing include" into android-8.1
diff --git a/crypto/ext4crypt/Android.mk b/crypto/ext4crypt/Android.mk
index af5ab3a..693b675 100644
--- a/crypto/ext4crypt/Android.mk
+++ b/crypto/ext4crypt/Android.mk
@@ -28,6 +28,7 @@
         LOCAL_CFLAGS += -DHAVE_LIBKEYUTILS
         LOCAL_SHARED_LIBRARIES += libkeyutils
     endif
+    LOCAL_ADDITIONAL_DEPENDENCIES := keystore_auth
 else
     LOCAL_SRC_FILES += Keymaster.cpp KeyStorage.cpp
 endif
@@ -58,4 +59,15 @@
 
 include $(BUILD_EXECUTABLE)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := keystore_auth
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+LOCAL_SRC_FILES := keystore_auth.cpp
+LOCAL_SHARED_LIBRARIES := libc libkeystore_binder libutils libbinder liblog
+LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker64
+
+include $(BUILD_EXECUTABLE)
+
 endif
diff --git a/crypto/ext4crypt/Decrypt.cpp b/crypto/ext4crypt/Decrypt.cpp
index 2dab166..c062f8a 100644
--- a/crypto/ext4crypt/Decrypt.cpp
+++ b/crypto/ext4crypt/Decrypt.cpp
@@ -287,10 +287,27 @@
 			return false;
 		}
 		memcpy(pwd->salt, intptr + 1, pwd->salt_len);
+		intptr++;
+		byteptr = (const unsigned char*)intptr;
+		byteptr += pwd->salt_len;
 	} else {
 		printf("Get_Password_Data salt_len is 0\n");
 		return false;
 	}
+	intptr = (const int*)byteptr;
+	pwd->handle_len = *intptr;
+	endianswap(&pwd->handle_len);
+	if (pwd->handle_len != 0) {
+		pwd->password_handle = malloc(pwd->handle_len);
+		if (!pwd->password_handle) {
+			printf("Get_Password_Data malloc password_handle\n");
+			return false;
+		}
+		memcpy(pwd->password_handle, intptr + 1, pwd->handle_len);
+	} else {
+		printf("Get_Password_Data handle_len is 0\n");
+		// Not an error if using weaver
+	}
 	return true;
 }
 
@@ -416,7 +433,8 @@
 
 namespace keystore {
 
-#define SYNTHETIC_PASSWORD_VERSION 1
+#define SYNTHETIC_PASSWORD_VERSION_V1 1
+#define SYNTHETIC_PASSWORD_VERSION 2
 #define SYNTHETIC_PASSWORD_PASSWORD_BASED 0
 #define SYNTHETIC_PASSWORD_KEY_PREFIX "USRSKEY_synthetic_password_"
 
@@ -496,7 +514,7 @@
 /* C++ replacement for function of the same name
  * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#867
  * returning an empty string indicates an error */
-std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const std::string& handle_str, const userid_t user_id, const void* application_id, const size_t application_id_size) {
+std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const std::string& handle_str, const userid_t user_id, const void* application_id, const size_t application_id_size, uint32_t auth_token_len) {
 	std::string disk_decryption_secret_key = "";
 
 	std::string keystore_alias_subid;
@@ -513,6 +531,11 @@
 		return disk_decryption_secret_key;
 	}
 
+	if (auth_token_len > 0) {
+		printf("Starting keystore_auth service...\n");
+		property_set("ctl.start", "keystore_auth");
+	}
+
 	// Read the data from the .spblob file per: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#869
 	std::string spblob_file = spblob_path + handle_str + ".spblob";
 	std::string spblob_data;
@@ -520,156 +543,339 @@
 		printf("Failed to read '%s'\n", spblob_file.c_str());
 		return disk_decryption_secret_key;
 	}
-	const unsigned char* byteptr = (const unsigned char*)spblob_data.data();
-	if (*byteptr != SYNTHETIC_PASSWORD_VERSION) {
-		printf("SYNTHETIC_PASSWORD_VERSION does not match\n");
+	unsigned char* byteptr = (unsigned char*)spblob_data.data();
+	if (*byteptr != SYNTHETIC_PASSWORD_VERSION && *byteptr != SYNTHETIC_PASSWORD_VERSION_V1) {
+		printf("Unsupported synthetic password version %i\n", *byteptr);
 		return disk_decryption_secret_key;
 	}
+	const unsigned char* synthetic_password_version = byteptr;
 	byteptr++;
 	if (*byteptr != SYNTHETIC_PASSWORD_PASSWORD_BASED) {
 		printf("spblob data is not SYNTHETIC_PASSWORD_PASSWORD_BASED\n");
 		return disk_decryption_secret_key;
 	}
 	byteptr++; // Now we're pointing to the blob data itself
-	/* We're now going to handle decryptSPBlob: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#115
-	 * Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#879
-	 * This small function ends up being quite a headache. The call to get data from the keystore basically is not needed in TWRP at this time.
-	 * The keystore data seems to be the serialized data from an entire class in Java. Specifically I think it represents:
-	 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
-	 * or perhaps
-	 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
-	 * but the only things we "need" from this keystore are a user ID and the keyAlias which ends up being USRSKEY_synthetic_password_{handle_str}
-	 * the latter of which we already have. We may need to figure out how to get the user ID if we ever support decrypting mulitple users.
-	 * There are 2 calls to a Java decrypt funcion that is overloaded. These 2 calls go in completely different directions despite the seemingly
-	 * similar use of decrypt() and decrypt parameters. To figure out where things were going, I added logging to:
-	 * https://android.googlesource.com/platform/libcore/+/android-8.0.0_r23/ojluni/src/main/java/javax/crypto/Cipher.java#2575
-	 * Logger.global.severe("Cipher tryCombinations " + prov.getName() + " - " + prov.getInfo());
-	 * To make logging work in libcore, import java.util.logging.Logger; and either set a better logging level or modify the framework to log everything
-	 * regardless of logging level. This will give you some strings that you can grep for and find the actual crypto provider in use. In our case there were
-	 * 2 different providers in use. The first stage to get the intermediate key used:
-	 * https://android.googlesource.com/platform/external/conscrypt/+/android-8.0.0_r23/common/src/main/java/org/conscrypt/OpenSSLProvider.java
-	 * which is a pretty straight-forward OpenSSL implementation of AES/GCM/NoPadding. */
-	// First we personalize as seen https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#102
-	void* personalized_application_id = PersonalizedHashBinary(PERSONALISATION_APPLICATION_ID, (const char*)application_id, application_id_size);
-	if (!personalized_application_id) {
-		printf("malloc personalized_application_id\n");
+	if (*synthetic_password_version == SYNTHETIC_PASSWORD_VERSION_V1) {
+		printf("spblob v1\n");
+		/* We're now going to handle decryptSPBlob: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#115
+		 * Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#879
+		 * This small function ends up being quite a headache. The call to get data from the keystore basically is not needed in TWRP at this time.
+		 * The keystore data seems to be the serialized data from an entire class in Java. Specifically I think it represents:
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
+		 * or perhaps
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+		 * but the only things we "need" from this keystore are a user ID and the keyAlias which ends up being USRSKEY_synthetic_password_{handle_str}
+		 * the latter of which we already have. We may need to figure out how to get the user ID if we ever support decrypting mulitple users.
+		 * There are 2 calls to a Java decrypt funcion that is overloaded. These 2 calls go in completely different directions despite the seemingly
+		 * similar use of decrypt() and decrypt parameters. To figure out where things were going, I added logging to:
+		 * https://android.googlesource.com/platform/libcore/+/android-8.0.0_r23/ojluni/src/main/java/javax/crypto/Cipher.java#2575
+		 * Logger.global.severe("Cipher tryCombinations " + prov.getName() + " - " + prov.getInfo());
+		 * To make logging work in libcore, import java.util.logging.Logger; and either set a better logging level or modify the framework to log everything
+		 * regardless of logging level. This will give you some strings that you can grep for and find the actual crypto provider in use. In our case there were
+		 * 2 different providers in use. The first stage to get the intermediate key used:
+		 * https://android.googlesource.com/platform/external/conscrypt/+/android-8.0.0_r23/common/src/main/java/org/conscrypt/OpenSSLProvider.java
+		 * which is a pretty straight-forward OpenSSL implementation of AES/GCM/NoPadding. */
+		// First we personalize as seen https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#102
+		void* personalized_application_id = PersonalizedHashBinary(PERSONALISATION_APPLICATION_ID, (const char*)application_id, application_id_size);
+		if (!personalized_application_id) {
+			printf("malloc personalized_application_id\n");
+			return disk_decryption_secret_key;
+		}
+		//printf("personalized application id: "); output_hex((unsigned char*)personalized_application_id, SHA512_DIGEST_LENGTH); printf("\n");
+		// Now we'll decrypt using openssl AES/GCM/NoPadding
+		OpenSSL_add_all_ciphers();
+		int actual_size=0, final_size=0;
+		EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new();
+		const unsigned char* iv = (const unsigned char*)byteptr; // The IV is the first 12 bytes of the spblob
+		//printf("iv: "); output_hex((const unsigned char*)iv, 12); printf("\n");
+		const unsigned char* cipher_text = (const unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
+		//printf("cipher_text: "); output_hex((const unsigned char*)cipher_text, spblob_data.size() - 2 - 12); printf("\n");
+		const unsigned char* key = (const unsigned char*)personalized_application_id; // The key is the now personalized copy of the application ID
+		//printf("key: "); output_hex((const unsigned char*)key, 32); printf("\n");
+		EVP_DecryptInit(d_ctx, EVP_aes_256_gcm(), key, iv);
+		std::vector<unsigned char> intermediate_key;
+		intermediate_key.resize(spblob_data.size() - 2 - 12, '\0');
+		EVP_DecryptUpdate(d_ctx, &intermediate_key[0], &actual_size, cipher_text, spblob_data.size() - 2 - 12);
+		unsigned char tag[AES_BLOCK_SIZE];
+		EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
+		EVP_DecryptFinal_ex(d_ctx, &intermediate_key[actual_size], &final_size);
+		EVP_CIPHER_CTX_free(d_ctx);
+		free(personalized_application_id);
+		//printf("spblob_data size: %lu actual_size %i, final_size: %i\n", spblob_data.size(), actual_size, final_size);
+		intermediate_key.resize(actual_size + final_size - 16, '\0');// not sure why we have to trim the size by 16 as I don't see where this is done in Java side
+		//printf("intermediate key: "); output_hex((const unsigned char*)intermediate_key.data(), intermediate_key.size()); printf("\n");
+
+		// When using secdis (aka not weaver) you must supply an auth token to the keystore prior to the begin operation
+		if (auth_token_len > 0) {
+			/*::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, auth_token_len);
+			if (!auth_result.isOk()) {
+				// The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0
+				printf("keystore error adding auth token\n");
+				return disk_decryption_secret_key;
+			}*/
+			// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file earlier and
+			// run a separate service that runs user the system user to add the auth token. We wait for the auth token file to be
+			// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after after a while if
+			// the /auth_token file never gets deleted.
+			int auth_wait_count = 20;
+			while (access("/auth_token", F_OK) == 0 && auth_wait_count-- > 0)
+				usleep(5000);
+			if (auth_wait_count == 0 || access("/auth_error", F_OK) == 0) {
+				printf("error during keymaster_auth service\n");
+				/* If you are getting this error, make sure that you have the keymaster_auth service defined in your init scripts, preferrably in init.recovery.{ro.hardware}.rc
+				 * service keystore_auth /sbin/keystore_auth
+				 *     disabled
+				 *     oneshot
+				 *     user system
+				 *     group root
+				 *     seclabel u:r:recovery:s0
+				 *
+				 * And check dmesg for error codes regarding this service if needed. */
+				return disk_decryption_secret_key;
+			}
+		}
+
+		int32_t ret;
+
+		/* We only need a keyAlias which is USRSKEY_synthetic_password_b6f71045af7bd042 which we find and a uid which is -1 or 1000, I forget which
+		 * as the key data will be read again by the begin function later via the keystore.
+		 * The data is in a hidl_vec format which consists of a type and a value. */
+		/*::keystore::hidl_vec<uint8_t> data;
+		std::string keystoreid = SYNTHETIC_PASSWORD_KEY_PREFIX;
+		keystoreid += handle_str;
+
+		ret = service->get(String16(keystoreid.c_str()), user_id, &data);
+		if (ret < 0) {
+			printf("Could not connect to keystore service %i\n", ret);
+			return disk_decryption_secret_key;
+		} else if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*//*) {
+			printf("keystore error: (%d)\n", /*responses[ret],*//* ret);
+			return disk_decryption_secret_key;
+		} else {
+			printf("keystore returned: "); output_hex(&data[0], data.size()); printf("\n");
+		}*/
+
+		// Now we'll break up the intermediate key into the IV (first 12 bytes) and the cipher text (the rest of it).
+		std::vector<unsigned char> nonce = intermediate_key;
+		nonce.resize(12);
+		intermediate_key.erase (intermediate_key.begin(),intermediate_key.begin()+12);
+		//printf("nonce: "); output_hex((const unsigned char*)nonce.data(), nonce.size()); printf("\n");
+		//printf("cipher text: "); output_hex((const unsigned char*)intermediate_key.data(), intermediate_key.size()); printf("\n");
+
+		/* Now we will begin the second decrypt call found in
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#122
+		 * This time we will use https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
+		 * and https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+		 * First we set some algorithm parameters as seen in two places:
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#297
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#216 */
+		size_t maclen = 128;
+		::keystore::AuthorizationSetBuilder begin_params;
+		begin_params.Authorization(::keystore::TAG_ALGORITHM, ::keystore::Algorithm::AES);
+		begin_params.Authorization(::keystore::TAG_BLOCK_MODE, ::keystore::BlockMode::GCM);
+		begin_params.Padding(::keystore::PaddingMode::NONE);
+		begin_params.Authorization(::keystore::TAG_NONCE, nonce);
+		begin_params.Authorization(::keystore::TAG_MAC_LENGTH, maclen);
+		//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+		//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
+		//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+		//keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
+		::keystore::hidl_vec<uint8_t> entropy; // No entropy is needed for decrypt
+		entropy.resize(0);
+		std::string keystore_alias = SYNTHETIC_PASSWORD_KEY_PREFIX;
+		keystore_alias += keystore_alias_subid;
+		String16 keystore_alias16(keystore_alias.c_str());
+		::keystore::KeyPurpose purpose = ::keystore::KeyPurpose::DECRYPT;
+		OperationResult begin_result;
+		// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
+		service->begin(binder, keystore_alias16, purpose, true, begin_params.hidl_data(), entropy, -1, &begin_result);
+		ret = begin_result.resultCode;
+		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
+			printf("keystore begin error: (%d)\n", /*responses[ret],*/ ret);
+			return disk_decryption_secret_key;
+		} else {
+			//printf("keystore begin operation successful\n");
+		}
+		::keystore::hidl_vec<::keystore::KeyParameter> empty_params;
+		empty_params.resize(0);
+		OperationResult update_result;
+		// The cipher.doFinal call triggers an update to the keystore followed by a finish https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#64
+		// See also https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java#208
+		service->update(begin_result.token, empty_params, intermediate_key, &update_result);
+		ret = update_result.resultCode;
+		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
+			printf("keystore update error: (%d)\n", /*responses[ret],*/ ret);
+			return disk_decryption_secret_key;
+		} else {
+			//printf("keystore update operation successful\n");
+			//printf("keystore update returned: "); output_hex(&update_result.data[0], update_result.data.size()); printf("\n"); // this ends up being the synthetic password
+		}
+		// We must use the data in update_data.data before we call finish below or the data will be gone
+		// The payload data from the keystore update is further personalized at https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
+		// We now have the disk decryption key!
+		disk_decryption_secret_key = PersonalizedHash(PERSONALIZATION_FBE_KEY, (const char*)&update_result.data[0], update_result.data.size());
+		//printf("disk_decryption_secret_key: '%s'\n", disk_decryption_secret_key.c_str());
+		::keystore::hidl_vec<uint8_t> signature;
+		OperationResult finish_result;
+		service->finish(begin_result.token, empty_params, signature, entropy, &finish_result);
+		ret = finish_result.resultCode;
+		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
+			printf("keystore finish error: (%d)\n", /*responses[ret],*/ ret);
+			return disk_decryption_secret_key;
+		} else {
+			//printf("keystore finish operation successful\n");
+		}
+		stop_keystore();
+		return disk_decryption_secret_key;
+	} else if (*synthetic_password_version == SYNTHETIC_PASSWORD_VERSION) {
+		printf("spblob v2\n");
+		/* Version 2 of the spblob is basically the same as version 1, but the order of getting the intermediate key and disk decryption key have been flip-flopped
+		 * as seen in https://android.googlesource.com/platform/frameworks/base/+/5025791ac6d1538224e19189397de8d71dcb1a12
+		 */
+		/* First decrypt call found in
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r18/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#135
+		 * We will use https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
+		 * and https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+		 * First we set some algorithm parameters as seen in two places:
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#297
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#216 */
+		// When using secdis (aka not weaver) you must supply an auth token to the keystore prior to the begin operation
+		if (auth_token_len > 0) {
+			/*::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, auth_token_len);
+			if (!auth_result.isOk()) {
+				// The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0
+				printf("keystore error adding auth token\n");
+				return disk_decryption_secret_key;
+			}*/
+			// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file earlier and
+			// run a separate service that runs user the system user to add the auth token. We wait for the auth token file to be
+			// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after after a while if
+			// the /auth_token file never gets deleted.
+			int auth_wait_count = 20;
+			while (access("/auth_token", F_OK) == 0 && auth_wait_count-- > 0)
+				usleep(5000);
+			if (auth_wait_count == 0 || access("/auth_error", F_OK) == 0) {
+				printf("error during keymaster_auth service\n");
+				/* If you are getting this error, make sure that you have the keymaster_auth service defined in your init scripts, preferrably in init.recovery.{ro.hardware}.rc
+				 * service keystore_auth /sbin/keystore_auth
+				 *     disabled
+				 *     oneshot
+				 *     user system
+				 *     group root
+				 *     seclabel u:r:recovery:s0
+				 *
+				 * And check dmesg for error codes regarding this service if needed. */
+				return disk_decryption_secret_key;
+			}
+		}
+		int32_t ret;
+		size_t maclen = 128;
+		unsigned char* iv = (unsigned char*)byteptr; // The IV is the first 12 bytes of the spblob
+		::keystore::hidl_vec<uint8_t> iv_hidlvec;
+		iv_hidlvec.setToExternal((unsigned char*)byteptr, 12);
+		//printf("iv: "); output_hex((const unsigned char*)iv, 12); printf("\n");
+		unsigned char* cipher_text = (unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
+		::keystore::hidl_vec<uint8_t> cipher_text_hidlvec;
+		cipher_text_hidlvec.setToExternal(cipher_text, spblob_data.size() - 14 /* 1 each for version and SYNTHETIC_PASSWORD_PASSWORD_BASED and 12 for the iv */);
+		::keystore::AuthorizationSetBuilder begin_params;
+		begin_params.Authorization(::keystore::TAG_ALGORITHM, ::keystore::Algorithm::AES);
+		begin_params.Authorization(::keystore::TAG_BLOCK_MODE, ::keystore::BlockMode::GCM);
+		begin_params.Padding(::keystore::PaddingMode::NONE);
+		begin_params.Authorization(::keystore::TAG_NONCE, iv_hidlvec);
+		begin_params.Authorization(::keystore::TAG_MAC_LENGTH, maclen);
+		::keystore::hidl_vec<uint8_t> entropy; // No entropy is needed for decrypt
+		entropy.resize(0);
+		std::string keystore_alias = SYNTHETIC_PASSWORD_KEY_PREFIX;
+		keystore_alias += keystore_alias_subid;
+		String16 keystore_alias16(keystore_alias.c_str());
+		::keystore::KeyPurpose purpose = ::keystore::KeyPurpose::DECRYPT;
+		OperationResult begin_result;
+		// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
+		service->begin(binder, keystore_alias16, purpose, true, begin_params.hidl_data(), entropy, -1, &begin_result);
+		ret = begin_result.resultCode;
+		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
+			printf("keystore begin error: (%d)\n", /*responses[ret],*/ ret);
+			return disk_decryption_secret_key;
+		} /*else {
+			printf("keystore begin operation successful\n");
+		}*/
+		::keystore::hidl_vec<::keystore::KeyParameter> empty_params;
+		empty_params.resize(0);
+		OperationResult update_result;
+		// The cipher.doFinal call triggers an update to the keystore followed by a finish https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#64
+		// See also https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java#208
+		service->update(begin_result.token, empty_params, cipher_text_hidlvec, &update_result);
+		ret = update_result.resultCode;
+		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
+			printf("keystore update error: (%d)\n", /*responses[ret],*/ ret);
+			return disk_decryption_secret_key;
+		} /*else {
+			printf("keystore update operation successful\n");
+			printf("keystore update returned: "); output_hex(&update_result.data[0], update_result.data.size()); printf("\n"); // this ends up being the synthetic password
+		}*/
+		//printf("keystore resulting data: "); output_hex((unsigned char*)&update_result.data[0], update_result.data.size()); printf("\n");
+		// We must copy the data in update_data.data before we call finish below or the data will be gone
+		size_t keystore_result_size = update_result.data.size();
+		unsigned char* keystore_result = (unsigned char*)malloc(keystore_result_size);
+		if (!keystore_result) {
+			printf("malloc on keystore_result\n");
+			return disk_decryption_secret_key;
+		}
+		memcpy(keystore_result, &update_result.data[0], update_result.data.size());
+		//printf("keystore_result data: "); output_hex(keystore_result, keystore_result_size); printf("\n");
+		::keystore::hidl_vec<uint8_t> signature;
+		OperationResult finish_result;
+		service->finish(begin_result.token, empty_params, signature, entropy, &finish_result);
+		ret = finish_result.resultCode;
+		if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
+			printf("keystore finish error: (%d)\n", /*responses[ret],*/ ret);
+			free(keystore_result);
+			return disk_decryption_secret_key;
+		} /*else {
+			printf("keystore finish operation successful\n");
+		}*/
+		stop_keystore();
+
+		/* Now we do the second decrypt call as seen in:
+		 * https://android.googlesource.com/platform/frameworks/base/+/android-8.1.0_r18/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#136
+		 */
+		const unsigned char* intermediate_iv = keystore_result;
+		//printf("intermediate_iv: "); output_hex((const unsigned char*)intermediate_iv, 12); printf("\n");
+		const unsigned char* intermediate_cipher_text = (const unsigned char*)keystore_result + 12; // The cipher text comes immediately after the IV
+		int cipher_size = keystore_result_size - 12;
+		//printf("intermediate_cipher_text: "); output_hex((const unsigned char*)intermediate_cipher_text, cipher_size); printf("\n");
+		// First we personalize as seen https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#102
+		void* personalized_application_id = PersonalizedHashBinary(PERSONALISATION_APPLICATION_ID, (const char*)application_id, application_id_size);
+		if (!personalized_application_id) {
+			printf("malloc personalized_application_id\n");
+			free(keystore_result);
+			return disk_decryption_secret_key;
+		}
+		//printf("personalized application id: "); output_hex((unsigned char*)personalized_application_id, SHA512_DIGEST_LENGTH); printf("\n");
+		// Now we'll decrypt using openssl AES/GCM/NoPadding
+		OpenSSL_add_all_ciphers();
+		int actual_size=0, final_size=0;
+		EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new();
+		const unsigned char* key = (const unsigned char*)personalized_application_id; // The key is the now personalized copy of the application ID
+		//printf("key: "); output_hex((const unsigned char*)key, 32); printf("\n");
+		EVP_DecryptInit(d_ctx, EVP_aes_256_gcm(), key, intermediate_iv);
+		unsigned char* secret_key = (unsigned char*)malloc(cipher_size);
+		EVP_DecryptUpdate(d_ctx, secret_key, &actual_size, intermediate_cipher_text, cipher_size);
+		unsigned char tag[AES_BLOCK_SIZE];
+		EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
+		EVP_DecryptFinal_ex(d_ctx, secret_key + actual_size, &final_size);
+		EVP_CIPHER_CTX_free(d_ctx);
+		free(personalized_application_id);
+		free(keystore_result);
+		int secret_key_real_size = actual_size - 16;
+		//printf("secret key:  "); output_hex((const unsigned char*)secret_key, secret_key_real_size); printf("\n");
+		// The payload data from the keystore update is further personalized at https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
+		// We now have the disk decryption key!
+		disk_decryption_secret_key = PersonalizedHash(PERSONALIZATION_FBE_KEY, (const char*)secret_key, secret_key_real_size);
+		//printf("disk_decryption_secret_key: '%s'\n", disk_decryption_secret_key.c_str());
+		free(secret_key);
 		return disk_decryption_secret_key;
 	}
-	//printf("personalized application id: "); output_hex((unsigned char*)personalized_application_id, SHA512_DIGEST_LENGTH); printf("\n");
-	// Now we'll decrypt using openssl AES/GCM/NoPadding
-	OpenSSL_add_all_ciphers();
-	int actual_size=0, final_size=0;
-    EVP_CIPHER_CTX *d_ctx = EVP_CIPHER_CTX_new();
-    const unsigned char* iv = (const unsigned char*)byteptr; // The IV is the first 12 bytes of the spblob
-    //printf("iv: "); output_hex((const unsigned char*)iv, 12); printf("\n");
-    const unsigned char* cipher_text = (const unsigned char*)byteptr + 12; // The cipher text comes immediately after the IV
-    //printf("cipher_text: "); output_hex((const unsigned char*)cipher_text, spblob_data.size() - 2 - 12); printf("\n");
-    const unsigned char* key = (const unsigned char*)personalized_application_id; // The key is the now personalized copy of the application ID
-    //printf("key: "); output_hex((const unsigned char*)key, 32); printf("\n");
-    EVP_DecryptInit(d_ctx, EVP_aes_256_gcm(), key, iv);
-    std::vector<unsigned char> intermediate_key;
-    intermediate_key.resize(spblob_data.size() - 2 - 12, '\0');
-    EVP_DecryptUpdate(d_ctx, &intermediate_key[0], &actual_size, cipher_text, spblob_data.size() - 2 - 12);
-    unsigned char tag[AES_BLOCK_SIZE];
-    EVP_CIPHER_CTX_ctrl(d_ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
-    EVP_DecryptFinal_ex(d_ctx, &intermediate_key[actual_size], &final_size);
-    EVP_CIPHER_CTX_free(d_ctx);
-    free(personalized_application_id);
-    //printf("spblob_data size: %lu actual_size %i, final_size: %i\n", spblob_data.size(), actual_size, final_size);
-    intermediate_key.resize(actual_size + final_size - 16, '\0');// not sure why we have to trim the size by 16 as I don't see where this is done in Java side
-    //printf("intermediate key: "); output_hex((const unsigned char*)intermediate_key.data(), intermediate_key.size()); printf("\n");
-
-	int32_t ret;
-
-	/* We only need a keyAlias which is USRSKEY_synthetic_password_b6f71045af7bd042 which we find and a uid which is -1 or 1000, I forget which
-	 * as the key data will be read again by the begin function later via the keystore.
-	 * The data is in a hidl_vec format which consists of a type and a value. */
-	/*::keystore::hidl_vec<uint8_t> data;
-	std::string keystoreid = SYNTHETIC_PASSWORD_KEY_PREFIX;
-	keystoreid += handle_str;
-
-	ret = service->get(String16(keystoreid.c_str()), user_id, &data);
-	if (ret < 0) {
-		printf("Could not connect to keystore service %i\n", ret);
-		return disk_decryption_secret_key;
-	} else if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*//*) {
-		printf("keystore error: (%d)\n", /*responses[ret],*//* ret);
-		return disk_decryption_secret_key;
-	} else {
-		printf("keystore returned: "); output_hex(&data[0], data.size()); printf("\n");
-	}*/
-
-	// Now we'll break up the intermediate key into the IV (first 12 bytes) and the cipher text (the rest of it).
-	std::vector<unsigned char> nonce = intermediate_key;
-	nonce.resize(12);
-	intermediate_key.erase (intermediate_key.begin(),intermediate_key.begin()+12);
-	//printf("nonce: "); output_hex((const unsigned char*)nonce.data(), nonce.size()); printf("\n");
-	//printf("cipher text: "); output_hex((const unsigned char*)intermediate_key.data(), intermediate_key.size()); printf("\n");
-
-	/* Now we will begin the second decrypt call found in
-	 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#122
-	 * This time we will use https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java
-	 * and https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
-	 * First we set some algorithm parameters as seen in two places:
-	 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#297
-	 * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java#216 */
-	size_t maclen = 128;
-	::keystore::AuthorizationSetBuilder begin_params;
-	begin_params.Authorization(::keystore::TAG_ALGORITHM, ::keystore::Algorithm::AES);
-	begin_params.Authorization(::keystore::TAG_BLOCK_MODE, ::keystore::BlockMode::GCM);
-    begin_params.Padding(::keystore::PaddingMode::NONE);
-    begin_params.Authorization(::keystore::TAG_NONCE, nonce);
-    begin_params.Authorization(::keystore::TAG_MAC_LENGTH, maclen);
-	//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-	//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
-	//keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
-	//keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
-	::keystore::hidl_vec<uint8_t> entropy; // No entropy is needed for decrypt
-	entropy.resize(0);
-	std::string keystore_alias = SYNTHETIC_PASSWORD_KEY_PREFIX;
-	keystore_alias += keystore_alias_subid;
-	String16 keystore_alias16(keystore_alias.c_str());
-	::keystore::KeyPurpose purpose = ::keystore::KeyPurpose::DECRYPT;
-	OperationResult begin_result;
-	// These parameters are mostly driven by the cipher.init call https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#63
-	service->begin(binder, keystore_alias16, purpose, true, begin_params.hidl_data(), entropy, -1, &begin_result);
-	ret = begin_result.resultCode;
-	if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-		printf("keystore begin error: (%d)\n", /*responses[ret],*/ ret);
-		return disk_decryption_secret_key;
-	} else {
-		//printf("keystore begin operation successful\n");
-	}
-	::keystore::hidl_vec<::keystore::KeyParameter> empty_params;
-	empty_params.resize(0);
-	OperationResult update_result;
-	// The cipher.doFinal call triggers an update to the keystore followed by a finish https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java#64
-	// See also https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java#208
-	service->update(begin_result.token, empty_params, intermediate_key, &update_result);
-	ret = update_result.resultCode;
-	if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-		printf("keystore update error: (%d)\n", /*responses[ret],*/ ret);
-		return disk_decryption_secret_key;
-	} else {
-		//printf("keystore update operation successful\n");
-		//printf("keystore update returned: "); output_hex(&update_result.data[0], update_result.data.size()); printf("\n"); // this ends up being the synthetic password
-	}
-	// We must use the data in update_data.data before we call finish below or the data will be gone
-	// The payload data from the keystore update is further personalized at https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
-	// We now have the disk decryption key!
-	disk_decryption_secret_key = PersonalizedHash(PERSONALIZATION_FBE_KEY, (const char*)&update_result.data[0], update_result.data.size());
-	//printf("disk_decryption_secret_key: '%s'\n", disk_decryption_secret_key.c_str());
-	::keystore::hidl_vec<uint8_t> signature;
-	OperationResult finish_result;
-	service->finish(begin_result.token, empty_params, signature, entropy, &finish_result);
-	ret = finish_result.resultCode;
-	if (ret != 1 /*android::keystore::ResponseCode::NO_ERROR*/) {
-		printf("keystore finish error: (%d)\n", /*responses[ret],*/ ret);
-		return disk_decryption_secret_key;
-	} else {
-		//printf("keystore finish operation successful\n");
-	}
-	stop_keystore();
 	return disk_decryption_secret_key;
 }
 
@@ -677,11 +883,40 @@
 
 #define PASSWORD_TOKEN_SIZE 32
 
-bool Free_Return(bool retval, void* weaver_key, void* pwd_salt) {
+/* C++ replacement for
+ * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#992
+ * called here
+ * https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#813 */
+bool Get_Secdis(const std::string& spblob_path, const std::string& handle_str, std::string& secdis_data) {
+	std::string secdis_file = spblob_path + handle_str + ".secdis";
+	if (!android::base::ReadFileToString(secdis_file, &secdis_data)) {
+		printf("Failed to read '%s'\n", secdis_file.c_str());
+		return false;
+	}
+	//output_hex(secdis_data.data(), secdis_data.size());printf("\n");
+	return true;
+}
+
+// C++ replacement for https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1033
+userid_t fakeUid(const userid_t uid) {
+    return 100000 + uid;
+}
+
+bool Is_Weaver(const std::string& spblob_path, const std::string& handle_str) {
+	std::string weaver_file = spblob_path + handle_str + ".weaver";
+	struct stat st;
+	if (stat(weaver_file.c_str(), &st) == 0)
+		return true;
+	return false;
+}
+
+bool Free_Return(bool retval, void* weaver_key, password_data_struct* pwd) {
 	if (weaver_key)
 		free(weaver_key);
-	if (pwd_salt)
-		free(pwd_salt);
+	if (pwd->salt)
+		free(pwd->salt);
+	if (pwd->password_handle)
+		free(pwd->password_handle);
 	return retval;
 }
 
@@ -692,6 +927,12 @@
 	void* weaver_key = NULL;
 	password_data_struct pwd;
 	pwd.salt = NULL;
+	pwd.salt_len = 0;
+	pwd.password_handle = NULL;
+	pwd.handle_len = 0;
+	char application_id[PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH];
+
+    uint32_t auth_token_len = 0;
 
 	std::string secret; // this will be the disk decryption key that is sent to vold
 	std::string token = "!"; // there is no token used for this kind of decrypt, key escrow is handled by weaver
@@ -708,14 +949,14 @@
 	// Get the handle: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/LockSettingsService.java#2017
 	if (!Find_Handle(spblob_path, handle_str)) {
 		printf("Error getting handle\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+		return Free_Return(retval, weaver_key, &pwd);
 	}
 	printf("Handle is '%s'\n", handle_str.c_str());
 	// Now we begin driving unwrapPasswordBasedSyntheticPassword from: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#758
 	// First we read the password data which contains scrypt parameters
 	if (!Get_Password_Data(spblob_path, handle_str, &pwd)) {
 		printf("Failed to Get_Password_Data\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+		return Free_Return(retval, weaver_key, &pwd);
 	}
 	//printf("pwd N %i R %i P %i salt ", pwd.scryptN, pwd.scryptR, pwd.scryptP); output_hex((char*)pwd.salt, pwd.salt_len); printf("\n");
 	unsigned char password_token[PASSWORD_TOKEN_SIZE];
@@ -723,81 +964,152 @@
 	// The password token is the password scrypted with the parameters from the password data file
 	if (!Get_Password_Token(&pwd, Password, &password_token[0])) {
 		printf("Failed to Get_Password_Token\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+		return Free_Return(retval, weaver_key, &pwd);
 	}
 	//output_hex(&password_token[0], PASSWORD_TOKEN_SIZE);printf("\n");
-	// BEGIN PIXEL 2 WEAVER
-	// Get the weaver data from the .weaver file which tells us which slot to use when we ask weaver for the escrowed key
-	// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#768
-	weaver_data_struct wd;
-	if (!Get_Weaver_Data(spblob_path, handle_str, &wd)) {
-		printf("Failed to get weaver data\n");
-		// Fail over to gatekeeper path for Pixel 1???
-		return Free_Return(retval, weaver_key, pwd.salt);
-	}
-	// The weaver key is the the password token prefixed with "weaver-key" padded to 128 with nulls with the password token appended then SHA512
-	// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1059
-	weaver_key = PersonalizedHashBinary(PERSONALISATION_WEAVER_KEY, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
-	if (!weaver_key) {
-		printf("malloc error getting weaver_key\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
-	}
-	// Now we start driving weaverVerify: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#343
-	// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#776
-	android::vold::Weaver weaver;
-    if (!weaver) {
-		printf("Failed to get weaver service\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
-	}
-	// Get the key size from weaver service
-	uint32_t weaver_key_size = 0;
-	if (!weaver.GetKeySize(&weaver_key_size)) {
-		printf("Failed to get weaver key size\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+	if (Is_Weaver(spblob_path, handle_str)) {
+		printf("using weaver\n");
+		// BEGIN PIXEL 2 WEAVER
+		// Get the weaver data from the .weaver file which tells us which slot to use when we ask weaver for the escrowed key
+		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#768
+		weaver_data_struct wd;
+		if (!Get_Weaver_Data(spblob_path, handle_str, &wd)) {
+			printf("Failed to get weaver data\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		// The weaver key is the the password token prefixed with "weaver-key" padded to 128 with nulls with the password token appended then SHA512
+		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#1059
+		weaver_key = PersonalizedHashBinary(PERSONALISATION_WEAVER_KEY, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
+		if (!weaver_key) {
+			printf("malloc error getting weaver_key\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		// Now we start driving weaverVerify: https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#343
+		// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#776
+		android::vold::Weaver weaver;
+		if (!weaver) {
+			printf("Failed to get weaver service\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		// Get the key size from weaver service
+		uint32_t weaver_key_size = 0;
+		if (!weaver.GetKeySize(&weaver_key_size)) {
+			printf("Failed to get weaver key size\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		} else {
+			//printf("weaver key size is %u\n", weaver_key_size);
+		}
+		//printf("weaver key: "); output_hex((unsigned char*)weaver_key, weaver_key_size); printf("\n");
+		// Send the slot from the .weaver file, the computed weaver key, and get the escrowed key data
+		std::vector<uint8_t> weaver_payload;
+		// TODO: we should return more information about the status including time delays before the next retry
+		if (!weaver.WeaverVerify(wd.slot, weaver_key, &weaver_payload)) {
+			printf("failed to weaver verify\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		//printf("weaver payload: "); output_hex(&weaver_payload); printf("\n");
+		// Done with weaverVerify
+		// Now we will compute the application ID
+		// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#964
+		// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#780
+		// The escrowed weaver key data is prefixed with "weaver-pwd" padded to 128 with nulls with the weaver payload appended then SHA512
+		void* weaver_secret = PersonalizedHashBinary(PERSONALISATION_WEAVER_PASSWORD, (const char*)weaver_payload.data(), weaver_payload.size());
+		//printf("weaver secret: "); output_hex((unsigned char*)weaver_secret, SHA512_DIGEST_LENGTH); printf("\n");
+		// The application ID is the password token and weaver secret appended to each other
+		memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
+		memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], weaver_secret, SHA512_DIGEST_LENGTH);
+		//printf("application ID: "); output_hex((unsigned char*)application_id, PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH); printf("\n");
+		// END PIXEL 2 WEAVER
 	} else {
-		//printf("weaver key size is %u\n", weaver_key_size);
+		printf("using secdis\n");
+		std::string secdis_data;
+		if (!Get_Secdis(spblob_path, handle_str, secdis_data)) {
+			printf("Failed to get secdis data\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		void* secdiscardable = PersonalizedHashBinary(PERSONALISATION_SECDISCARDABLE, (char*)secdis_data.data(), secdis_data.size());
+		if (!secdiscardable) {
+			printf("malloc error getting secdiscardable\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
+		memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], secdiscardable, SHA512_DIGEST_LENGTH);
+
+		int ret = -1;
+		bool request_reenroll = false;
+		android::sp<android::hardware::gatekeeper::V1_0::IGatekeeper> gk_device;
+		gk_device = ::android::hardware::gatekeeper::V1_0::IGatekeeper::getService();
+		if (gk_device == nullptr) {
+			printf("failed to get gatekeeper service\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		if (pwd.handle_len <= 0) {
+			printf("no password handle supplied\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		android::hardware::hidl_vec<uint8_t> pwd_handle_hidl;
+		pwd_handle_hidl.setToExternal(const_cast<uint8_t *>((const uint8_t *)pwd.password_handle), pwd.handle_len);
+		void* gk_pwd_token = PersonalizedHashBinary(PERSONALIZATION_USER_GK_AUTH, (char*)&password_token[0], PASSWORD_TOKEN_SIZE);
+		if (!gk_pwd_token) {
+			printf("malloc error getting gatekeeper_key\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
+		android::hardware::hidl_vec<uint8_t> gk_pwd_token_hidl;
+		gk_pwd_token_hidl.setToExternal(const_cast<uint8_t *>((const uint8_t *)gk_pwd_token), SHA512_DIGEST_LENGTH);
+		android::hardware::Return<void> hwRet =
+			gk_device->verify(fakeUid(user_id), 0 /* challange */,
+							  pwd_handle_hidl,
+							  gk_pwd_token_hidl,
+							  [&ret, &request_reenroll, &auth_token_len]
+								(const android::hardware::gatekeeper::V1_0::GatekeeperResponse &rsp) {
+									ret = static_cast<int>(rsp.code); // propagate errors
+									if (rsp.code >= android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_OK) {
+										auth_token_len = rsp.data.size();
+										request_reenroll = (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::STATUS_REENROLL);
+										ret = 0; // all success states are reported as 0
+										// The keystore refuses to allow the root user to supply auth tokens, so we write the auth token to a file here and later
+										// run a separate service that runs as the system user to add the auth token. We wait for the auth token file to be
+										// deleted by the keymaster_auth service and check for a /auth_error file in case of errors. We quit after a while seconds if
+										// the /auth_token file never gets deleted.
+										unlink("/auth_token");
+										FILE* auth_file = fopen("/auth_token","wb");
+										if (auth_file != NULL) {
+											fwrite(rsp.data.data(), sizeof(uint8_t), rsp.data.size(), auth_file);
+											fclose(auth_file);
+										} else {
+											printf("failed to open /auth_token for writing\n");
+											ret = -2;
+										}
+									} else if (rsp.code == android::hardware::gatekeeper::V1_0::GatekeeperStatusCode::ERROR_RETRY_TIMEOUT && rsp.timeout > 0) {
+										ret = rsp.timeout;
+									}
+								}
+							 );
+		free(gk_pwd_token);
+		if (!hwRet.isOk() || ret != 0) {
+			printf("gatekeeper verification failed\n");
+			return Free_Return(retval, weaver_key, &pwd);
+		}
 	}
-	//printf("weaver key: "); output_hex((unsigned char*)weaver_key, weaver_key_size); printf("\n");
-	// Send the slot from the .weaver file, the computed weaver key, and get the escrowed key data
-	std::vector<uint8_t> weaver_payload;
-	// TODO: we should return more information about the status including time delays before the next retry
-	if (!weaver.WeaverVerify(wd.slot, weaver_key, &weaver_payload)) {
-		printf("failed to weaver verify\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
-	}
-	//printf("weaver payload: "); output_hex(&weaver_payload); printf("\n");
-	// Done with weaverVerify
-	// Now we will compute the application ID
-	// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#964
-	// Called from https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#780
-	// The escrowed weaver key data is prefixed with "weaver-pwd" padded to 128 with nulls with the weaver payload appended then SHA512
-	void* weaver_secret = PersonalizedHashBinary(PERSONALISATION_WEAVER_PASSWORD, (const char*)weaver_payload.data(), weaver_payload.size());
-	//printf("weaver secret: "); output_hex((unsigned char*)weaver_secret, SHA512_DIGEST_LENGTH); printf("\n");
-	// The application ID is the password token and weaver secret appended to each other
-	char application_id[PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH];
-	memcpy((void*)&application_id[0], (void*)&password_token[0], PASSWORD_TOKEN_SIZE);
-	memcpy((void*)&application_id[PASSWORD_TOKEN_SIZE], weaver_secret, SHA512_DIGEST_LENGTH);
-	//printf("application ID: "); output_hex((unsigned char*)application_id, PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH); printf("\n");
-	// END PIXEL 2 WEAVER
 	// Now we will handle https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#816
 	// Plus we will include the last bit that computes the disk decrypt key found in:
 	// https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r23/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java#153
-	secret = android::keystore::unwrapSyntheticPasswordBlob(spblob_path, handle_str, user_id, (const void*)&application_id[0], PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH);
+	secret = android::keystore::unwrapSyntheticPasswordBlob(spblob_path, handle_str, user_id, (const void*)&application_id[0], PASSWORD_TOKEN_SIZE + SHA512_DIGEST_LENGTH, auth_token_len);
 	if (!secret.size()) {
 		printf("failed to unwrapSyntheticPasswordBlob\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+		return Free_Return(retval, weaver_key, &pwd);
 	}
 	if (!e4crypt_unlock_user_key(user_id, 0, token.c_str(), secret.c_str())) {
 		printf("e4crypt_unlock_user_key returned fail\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+		return Free_Return(retval, weaver_key, &pwd);
 	}
 	if (!e4crypt_prepare_user_storage(nullptr, user_id, 0, flags)) {
 		printf("failed to e4crypt_prepare_user_storage\n");
-		return Free_Return(retval, weaver_key, pwd.salt);
+		return Free_Return(retval, weaver_key, &pwd);
 	}
 	printf("Decrypted Successfully!\n");
 	retval = true;
-	return Free_Return(retval, weaver_key, pwd.salt);
+	return Free_Return(retval, weaver_key, &pwd);
 }
 #endif //HAVE_SYNTH_PWD_SUPPORT
 
diff --git a/crypto/ext4crypt/HashPassword.h b/crypto/ext4crypt/HashPassword.h
index 8abd0de..4be107b 100644
--- a/crypto/ext4crypt/HashPassword.h
+++ b/crypto/ext4crypt/HashPassword.h
@@ -24,6 +24,8 @@
 #define PERSONALISATION_WEAVER_PASSWORD "weaver-pwd"
 #define PERSONALISATION_APPLICATION_ID "application-id"
 #define PERSONALIZATION_FBE_KEY "fbe-key"
+#define PERSONALIZATION_USER_GK_AUTH "user-gk-authentication"
+#define PERSONALISATION_SECDISCARDABLE "secdiscardable-transform"
 
 void* PersonalizedHashBinary(const char* prefix, const char* key, const size_t key_size);
 
diff --git a/crypto/ext4crypt/keystore_auth.cpp b/crypto/ext4crypt/keystore_auth.cpp
new file mode 100644
index 0000000..7d6eb24
--- /dev/null
+++ b/crypto/ext4crypt/keystore_auth.cpp
@@ -0,0 +1,90 @@
+/*
+	Copyright 2018 bigbiff/Dees_Troy TeamWin
+	This file is part of TWRP/TeamWin Recovery Project.
+
+	TWRP is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	TWRP is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The keystore refuses to allow the root user to supply auth tokens, so
+ * we write the auth token to a file in TWRP and run a separate service
+ * (this) that runs as the system user to add the auth token. TWRP waits
+ * for /auth_token to be deleted and also looks for /auth_error to check
+ * for errors. TWRP will error out after a while if /auth_token does not
+ * get deleted. */
+
+#include <stdio.h>
+#include <string>
+
+#include <keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <keystore/keystore.h>
+#include <keystore/authorization_set.h>
+
+#define LOG_TAG "keystore_auth"
+
+using namespace android;
+
+void create_error_file() {
+	FILE* error_file = fopen("/auth_error", "wb");
+	if (error_file == NULL) {
+		printf("Failed to open /auth_error\n");
+		ALOGE("Failed to open /auth_error\n");
+		return;
+	}
+	fwrite("1", 1, 1, error_file);
+	fclose(error_file);
+	unlink("/auth_token");
+}
+
+int main(int argc, char *argv[]) {
+	unlink("/auth_error");
+	FILE* auth_file = fopen("/auth_token", "rb");
+	if (auth_file == NULL) {
+		printf("Failed to open /auth_token\n");
+		ALOGE("Failed to open /auth_token\n");
+		create_error_file();
+		return -1;
+	}
+	// Get the file size
+	fseek(auth_file, 0, SEEK_END);
+	int size = ftell(auth_file);
+	fseek(auth_file, 0, SEEK_SET);
+	uint8_t auth_token[size];
+	fread(auth_token , sizeof(uint8_t), size, auth_file);
+	fclose(auth_file);
+	// First get the keystore service
+	sp<IServiceManager> sm = defaultServiceManager();
+	sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+	sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+	if (service == NULL) {
+		printf("error: could not connect to keystore service\n");
+		ALOGE("error: could not connect to keystore service\n");
+		create_error_file();
+		return -2;
+	}
+	::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, size);
+	if (!auth_result.isOk()) {
+		// The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0
+		printf("keystore error adding auth token\n");
+		ALOGE("keystore error adding auth token\n");
+		create_error_file();
+		return -3;
+	}
+	printf("successfully added auth token to keystore\n");
+	ALOGD("successfully added auth token to keystore\n");
+	unlink("/auth_token");
+	return 0;
+}
diff --git a/data.cpp b/data.cpp
index 599b5c0..4dfbde2 100644
--- a/data.cpp
+++ b/data.cpp
@@ -230,7 +230,7 @@
 
 int DataManager::LoadValues(const string& filename)
 {
-	string str, dev_id;
+	string dev_id;
 
 	if (!mInitialized)
 		SetDefaultValues();
@@ -263,6 +263,44 @@
 	return 0;
 }
 
+int DataManager::LoadPersistValues(void)
+{
+	static bool loaded = false;
+	string dev_id;
+
+	// Only run this function once, and make sure normal settings file has not yet been read
+	if (loaded || !mBackingFile.empty() || !TWFunc::Path_Exists(PERSIST_SETTINGS_FILE))
+		return -1;
+
+	LOGINFO("Attempt to load settings from /persist settings file...\n");
+
+	if (!mInitialized)
+		SetDefaultValues();
+
+	GetValue("device_id", dev_id);
+	mPersist.SetFile(PERSIST_SETTINGS_FILE);
+	mPersist.SetFileVersion(FILE_VERSION);
+
+	// Read in the file, if possible
+	pthread_mutex_lock(&m_valuesLock);
+	mPersist.LoadValues();
+
+#ifndef TW_NO_SCREEN_TIMEOUT
+	blankTimer.setTime(mPersist.GetIntValue("tw_screen_timeout_secs"));
+#endif
+
+	update_tz_environment_variables();
+	TWFunc::Set_Brightness(GetStrValue("tw_brightness"));
+
+	pthread_mutex_unlock(&m_valuesLock);
+
+	/* Don't set storage nor backup paths this early */
+
+	loaded = true;
+
+	return 0;
+}
+
 int DataManager::Flush()
 {
 	return SaveValues();
@@ -271,6 +309,15 @@
 int DataManager::SaveValues()
 {
 #ifndef TW_OEM_BUILD
+	if (PartitionManager.Mount_By_Path("/persist", false)) {
+		mPersist.SetFile(PERSIST_SETTINGS_FILE);
+		mPersist.SetFileVersion(FILE_VERSION);
+		pthread_mutex_lock(&m_valuesLock);
+		mPersist.SaveValues();
+		pthread_mutex_unlock(&m_valuesLock);
+		LOGINFO("Saved settings file values to %s\n", PERSIST_SETTINGS_FILE);
+	}
+
 	if (mBackingFile.empty())
 		return -1;
 
@@ -284,7 +331,7 @@
 	pthread_mutex_unlock(&m_valuesLock);
 
 	tw_set_default_metadata(mBackingFile.c_str());
-	LOGINFO("Saved settings file values\n");
+	LOGINFO("Saved settings file values to '%s'\n", mBackingFile.c_str());
 #endif // ifdef TW_OEM_BUILD
 	return 0;
 }
@@ -353,7 +400,7 @@
 	return 0;
 }
 
-unsigned long long DataManager::GetValue(const string& varName, unsigned long long& value)
+int DataManager::GetValue(const string& varName, unsigned long long& value)
 {
 	string data;
 
diff --git a/data.hpp b/data.hpp
index 790efc9..d61fe8e 100644
--- a/data.hpp
+++ b/data.hpp
@@ -23,6 +23,8 @@
 #include <pthread.h>
 #include "infomanager.hpp"
 
+#define PERSIST_SETTINGS_FILE  "/persist/.twrps"
+
 using namespace std;
 
 class DataManager
@@ -30,13 +32,14 @@
 public:
 	static int ResetDefaults();
 	static int LoadValues(const string& filename);
+	static int LoadPersistValues(void);
 	static int Flush();
 
 	// Core get routines
 	static int GetValue(const string& varName, string& value);
 	static int GetValue(const string& varName, int& value);
 	static int GetValue(const string& varName, float& value);
-	static unsigned long long GetValue(const string& varName, unsigned long long& value);
+	static int GetValue(const string& varName, unsigned long long& value);
 
 	// Helper functions
 	static string GetStrValue(const string& varName);
diff --git a/gui/theme/common/languages/cz.xml b/gui/theme/common/languages/cz.xml
index bb9fff9..4795622 100644
--- a/gui/theme/common/languages/cz.xml
+++ b/gui/theme/common/languages/cz.xml
@@ -511,7 +511,7 @@
 		<string name="done">Hotovo.</string>
 		<string name="start_partition_sd">Dělení SD karty...</string>
 		<string name="partition_sd_locate">Nelze najít zařízení na rozdělení.</string>
-		<string name="ext_swap_size">Velikost EXT + Swap je větší jako velikost SD-karty.</string>
+		<string name="ext_swap_size">Velikost EXT + Swap je větší jako velikost SD karty.</string>
 		<string name="remove_part_table">Vymazávání tabulky rozdělení...</string>
 		<string name="unable_rm_part">Nelze vymazat tabulku rozdělení.</string>
 		<string name="create_part">Vytváření oddílu {1}...</string>
diff --git a/gui/theme/common/languages/de.xml b/gui/theme/common/languages/de.xml
index 9d953a7..e629ec3 100644
--- a/gui/theme/common/languages/de.xml
+++ b/gui/theme/common/languages/de.xml
@@ -464,7 +464,7 @@
 		<string name="swipe_to_sideload">ADB Sideload starten</string>
 		<string name="swipe_sideload">Start</string>
 		<string name="sideload_confirm">ADB Sideload</string>
-		<string name="sideload_usage">Syntax: adb sideload Dateiname.zip</string>
+		<string name="sideload_usage">Syntax: adb sideload dateiname.zip</string>
 		<string name="sideload_complete">ADB Sideload abgeschlossen</string>
 		<string name="fix_contexts_hdr">SELinux Kontexte</string>
 		<string name="fix_contexts_note1">Das Korrigieren der Kontexte wird selten benötigt!</string>
diff --git a/gui/theme/common/languages/el.xml b/gui/theme/common/languages/el.xml
index 2af1a8f..271b087 100644
--- a/gui/theme/common/languages/el.xml
+++ b/gui/theme/common/languages/el.xml
@@ -17,7 +17,7 @@
         <string name="data_backup">Data (εκτός αποθ. χώρου)</string>
         <string name="sdcard">Κάρτα SD</string>
         <string name="internal">Εσωτερικός χώρος αποθήκευσης</string>
-        <string name="microsd">Micro SDCard</string>
+        <string name="microsd">Κάρτα Micro SD</string>
         <string name="usbotg">USB OTG</string>
         <string name="android_secure">Android secure</string>
         <string name="dalvik">Dalvik / ART Cache</string>
diff --git a/gui/theme/common/languages/fr.xml b/gui/theme/common/languages/fr.xml
index 9768a6a..80e781a 100644
--- a/gui/theme/common/languages/fr.xml
+++ b/gui/theme/common/languages/fr.xml
@@ -16,7 +16,7 @@
         <string name="data">Données</string>
         <string name="sdcard">Carte SD</string>
         <string name="internal">Mémoire interne</string>
-        <string name="microsd">Carte microSD</string>
+        <string name="microsd">Carte micro SD</string>
         <string name="usbotg">USB OTG</string>
         <string name="android_secure">Android Sécurisé</string>
         <string name="dalvik">Cache Dalvik / ART</string>
@@ -61,7 +61,7 @@
         <string name="adb_sideload_btn">Transfert via ADB</string>
         <string name="install_hdr">Installer</string>
         <string name="select_storage_hdr">Sélectionner l'emplacement</string>
-        <string name="select_storage_btn">Sélectionner l'emplacement</string>
+        <string name="select_storage_btn">Sélect. l'emplacement</string>
         <string name="queue_hdr">Mettre en file d'attente</string>
         <string name="zip_queue_count">%tw_zip_queue_count% de max de 10 fichiers en file d'attente</string>
         <string name="zip_queue_count_s">Fichier %tw_zip_queue_count% sur 10 :</string>
@@ -228,7 +228,7 @@
         <string name="restore_try_decrypt_s">Tentative de décryptage</string>
         <string name="restore_backup_date">Sauvegarde effectuée sur %tw_restore_file_date%</string>
         <string name="restore_sel_part">Sélectionner les Partitions à restaurer :</string>
-        <string name="restore_enable_digest_chk" version="2">Activer la vérification Digest des fichiers de sauvegarde</string>
+        <string name="restore_enable_digest_chk" version="2">Activer la vérif. Digest des fichiers de sauvegarde</string>
         <string name="restore_completed">Restauration terminée</string>
         <string name="swipe_restore">Glisser pour Restaurer</string>
         <string name="swipe_restore_s">Restaurer</string>
@@ -290,7 +290,7 @@
         <string name="ctr_navbar_rdo">Centrer les Boutons de la barre de navigation</string>
         <string name="lft_navbar_rdo">Aligner les boutons de la barre de navigation à gauche</string>
         <string name="rht_navbar_rdo">Aligner les boutons de barre de navigation à droite</string>
-        <string name="restore_defaults_btn">Rétablir les paramètres par défaut</string>
+        <string name="restore_defaults_btn">Rétablir les param. par défaut</string>
         <string name="settings_tz_btn">Fuseau horaire</string>
         <string name="settings_screen_btn">Écran</string>
         <string name="settings_screen_bright_btn">Luminosité</string>
diff --git a/gui/theme/common/languages/it.xml b/gui/theme/common/languages/it.xml
index 57cbe9a..71f7636 100644
--- a/gui/theme/common/languages/it.xml
+++ b/gui/theme/common/languages/it.xml
@@ -20,9 +20,9 @@
 		<string name="cache">Cache</string>
 		<string name="data">Data</string>
 		<string name="data_backup">Data (escl. archivio)</string>
-		<string name="sdcard">SDCard</string>
+		<string name="sdcard">Scheda SD</string>
 		<string name="internal">Archivio interno</string>
-		<string name="microsd">Micro SD</string>
+		<string name="microsd">Scheda Micro SD</string>
 		<string name="usbotg">USB OTG</string>
 		<string name="android_secure">Android Secure</string>
 		<string name="dalvik">Dalvik / ART Cache</string>
diff --git a/gui/theme/common/languages/nl.xml b/gui/theme/common/languages/nl.xml
index d4dd7bf..e716a91 100644
--- a/gui/theme/common/languages/nl.xml
+++ b/gui/theme/common/languages/nl.xml
@@ -19,9 +19,9 @@
 		<string name="recovery">Recovery</string>
 		<string name="cache">Cache</string>
 		<string name="data">Data</string>
-		<string name="sdcard">SD Kaart</string>
+		<string name="sdcard">SD kaart</string>
 		<string name="internal">Interne opslag</string>
-		<string name="microsd">Micro SDCard</string>
+		<string name="microsd">Micro SD kaart</string>
 		<string name="usbotg">USB OTG</string>
 		<string name="android_secure">Android Secure</string>
 		<string name="dalvik">Dalvik / ART Cache</string>
@@ -300,7 +300,7 @@
 		<string name="ctr_navbar_rdo">Navbar knoppen centreren</string>
 		<string name="lft_navbar_rdo">Navbar knoppen links uitlijnen</string>
 		<string name="rht_navbar_rdo">Navbar knoppen rechts uitlijnen</string>
-		<string name="restore_defaults_btn">Standaardwaarden herstellen</string>
+		<string name="restore_defaults_btn">Standaardwaarden herst.</string>
 		<string name="settings_tz_btn">Tijdzone</string>
 		<string name="settings_screen_btn">Scherm</string>
 		<string name="settings_screen_bright_btn">Scherm helderheid</string>
@@ -363,12 +363,12 @@
 		<string name="sel_lang_btn">Taal selecteren</string>
 		<string name="set_language_btn">Taal instellen</string>
 		<string name="advanced_hdr">Geavanceerd</string>
-		<string name="copy_log_confirm">Log naar SD-kaart kopiëren?</string>
-		<string name="copying_log">Log naar SD-kaart kopiëren...</string>
+		<string name="copy_log_confirm">Log naar SD kaart kopiëren?</string>
+		<string name="copying_log">Log naar SD kaart kopiëren...</string>
 		<string name="copy_log_complete">Log kopie voltooid</string>
 		<string name="fix_context_btn">Context repareren</string>
-		<string name="part_sd_btn">SD-kaart Partitioneren</string>
-		<string name="part_sd_s_btn">SD-kaart</string>
+		<string name="part_sd_btn">SD kaart Partitioneren</string>
+		<string name="part_sd_s_btn">SD kaart</string>
 		<string name="file_manager_btn">Bestandsbeheer</string>
 		<string name="language_hdr">Taal</string>
 		<string name="terminal_btn">Terminal</string>
@@ -379,9 +379,9 @@
 		<string name="injecting_twrp">TWRP Opnieuw injecteren...</string>
 		<string name="inject_twrp_complete">TWRP injectie voltooid</string>
 		<string name="swipe_to_confirm">Veeg om te bevestigen</string>
-		<string name="part_sd_hdr">SD-kaart Partitioneren</string>
+		<string name="part_sd_hdr">SD kaart Partitioneren</string>
 		<string name="invalid_partsd_sel">U moet een verwisselbaar apparaat selecteren</string>
-		<string name="part_sd_lose">U verliest alle bestanden op uw SD-kaart!</string>
+		<string name="part_sd_lose">U verliest alle bestanden op uw SD kaart!</string>
 		<string name="part_sd_undo">Deze actie kan niet ongedaan gemaakt worden!</string>
 		<string name="part_sd_ext_sz">EXT-grootte:</string>
 		<string name="part_sd_swap_sz">Swap grootte:</string>
@@ -390,7 +390,7 @@
 		<string name="file_system">Bestandsysteem:</string>
 		<string name="swipe_part_sd">Veeg om te partitioneren</string>
 		<string name="swipe_part_sd_s">Partitie</string>
-		<string name="partitioning_sd">SD-kaart partitioneren...</string>
+		<string name="partitioning_sd">SD kaart partitioneren...</string>
 		<string name="partitioning_sd2">Dit duurt een paar minuten.</string>
 		<string name="part_sd_complete">Partitionering voltooid</string>
 		<string name="dumlock_hdr">HTC Dumlock</string>
@@ -471,7 +471,7 @@
 		<string name="swipe_su_install">   Installeren</string>
 		<string name="su_installing">Installeren van SuperSU</string>
 		<string name="sel_storage_list">Selecteer opslag</string>
-		<string name="ok_btn">Oké</string>
+		<string name="ok_btn">OK</string>
 
 		<!-- Various console messages - these consist of user displayed messages, oftentimes errors -->
 		<string name="no_kernel_selinux">Kernel heeft geen ondersteuning voor het lezen van SELinux contexten.</string>
@@ -536,9 +536,9 @@
 		<string name="no_crypto_support">Er is geen crypto ondersteuning gecompileerd in deze build.</string>
 		<string name="decrypt_success_dev">Data succesvol gedecodeerd, nieuw block device: \'{1}\'</string>
 		<string name="done">Gereed.</string>
-		<string name="start_partition_sd">SD-kaart partitioneren...</string>
+		<string name="start_partition_sd">SD kaart partitioneren...</string>
 		<string name="partition_sd_locate">Kan apparaat om te partitioneren niet vinden.</string>
-		<string name="ext_swap_size">EXT + Swap grootte zijn groter dan de sd-kaart.</string>
+		<string name="ext_swap_size">EXT + Swap grootte zijn groter dan de sd kaart.</string>
 		<string name="remove_part_table">Partitie-tabel word verwijderd...</string>
 		<string name="unable_rm_part">Kan partitie-tabel niet verwijderen.</string>
 		<string name="create_part">Partitie {1} aanmaken...</string>
diff --git a/gui/theme/common/languages/pl.xml b/gui/theme/common/languages/pl.xml
index 46fe43d..77a6aa8 100644
--- a/gui/theme/common/languages/pl.xml
+++ b/gui/theme/common/languages/pl.xml
@@ -21,7 +21,7 @@
 		<string name="data">Data</string>
 		<string name="sdcard">Karta SD</string>
 		<string name="internal">Pamięć Wewnętrzna</string>
-		<string name="microsd">Karta MicroSD</string>
+		<string name="microsd">Karta Micro SD</string>
 		<string name="usbotg">USB OTG</string>
 		<string name="android_secure">Android Secure</string>
 		<string name="dalvik">Dalvik / ART Cache</string>
diff --git a/gui/theme/common/languages/pt_BR.xml b/gui/theme/common/languages/pt_BR.xml
index 7e301f1..fa7fa09 100644
--- a/gui/theme/common/languages/pt_BR.xml
+++ b/gui/theme/common/languages/pt_BR.xml
@@ -17,9 +17,9 @@
 		<string name="recovery">Recuperação</string>
 		<string name="cache">Cache</string>
 		<string name="data">Dados</string>
-		<string name="sdcard">SDCard</string>
+		<string name="sdcard">Cartão SD</string>
 		<string name="internal">Armazenamento interno</string>
-		<string name="microsd">Micro SDCard</string>
+		<string name="microsd">Cartão Micro SD</string>
 		<string name="usbotg">USB OTG</string>
 		<string name="android_secure">Android Seguro</string>
 		<string name="dalvik">Dalvik / Cache de arte</string>
diff --git a/gui/theme/common/languages/pt_PT.xml b/gui/theme/common/languages/pt_PT.xml
new file mode 100644
index 0000000..1244f9b
--- /dev/null
+++ b/gui/theme/common/languages/pt_PT.xml
@@ -0,0 +1,698 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<language>
+	<display>Português</display>
+
+	<resources>
+		<!-- Font overrides - only change these if your language requires special characters -->
+		<resource name="font_l" type="fontoverride" filename="RobotoCondensed-Regular.ttf" scale="100" />
+		<resource name="font_m" type="fontoverride" filename="RobotoCondensed-Regular.ttf" scale="100" />
+		<resource name="font_s" type="fontoverride" filename="RobotoCondensed-Regular.ttf" scale="100" />
+		<resource name="fixed" type="fontoverride" filename="DroidSansMono.ttf" scale="100" />
+
+		<!-- Partition display names -->
+		<string name="system">Sistema</string>
+		<string name="system_image">Imagem do sistema</string>
+		<string name="vendor">Fornecedor</string>
+		<string name="vendor_image">Imagem do fornecedor</string>
+		<string name="boot">Boot</string>
+		<string name="recovery">Recovery</string>
+		<string name="cache">Cache</string>
+		<string name="data">Dados</string>
+		<string name="data_backup">Dados (excl. armazenamento)</string>
+		<string name="sdcard">Cartão SD</string>
+		<string name="internal">Armazenamento interno</string>
+		<string name="microsd">Cartão SD</string>
+		<string name="usbotg">USB OTG</string>
+		<string name="android_secure">Android seguro</string>
+		<string name="dalvik">Cache Dalvik / ART</string>
+		<!-- This is a rarely used partition on a Micro SD card for a very old app2sd system -->
+		<string name="sdext">SD-EXT</string>
+		<string name="adopted_data">Dados adoptados</string>
+		<string name="adopted_storage">Armazenamento adoptado</string>
+		<string name="autostorage">Armazenamento</string>
+
+		<!-- GUI XML strings -->
+		<string name="twrp_header">Team Win Recovery Project</string>
+		<string name="twrp_watch_header">TWRP %tw_version%</string>
+		<string name="cpu_temp">CPU: %tw_cpu_temp% &#xB0;C</string>
+		<string name="battery_pct">Bateria: %tw_battery%</string>
+		<string name="sort_by_name">Ordenar por nome</string>
+		<string name="sort_by_date">Ordenar por data</string>
+		<string name="sort_by_size">Ordenar por tamanho</string>
+		<string name="sort_by_name_only">Nome</string>
+		<string name="sort_by_date_only">Data</string>
+		<string name="sort_by_size_only">Tamanho</string>
+		<string name="tab_general">GERAL</string>
+		<string name="tab_options">OPÇÕES</string>
+		<string name="tab_backup">BACKUP</string>
+		<string name="tab_time_zone">FUSO HORÁRIO</string>
+		<string name="tab_screen">ECRÃ</string>
+		<string name="tab_vibration">VIBRAÇÃO</string>
+		<string name="tab_language">IDIOMA</string>
+
+		<string name="install_btn">Instalar</string>
+		<string name="wipe_btn">Apagar</string>
+		<string name="backup_btn">Backup</string>
+		<string name="restore_btn">Restaurar</string>
+		<string name="mount_btn">Montar</string>
+		<string name="settings_btn">Definições</string>
+		<string name="advanced_btn">Avançadas</string>
+		<string name="reboot_btn">Reiniciar</string>
+		<string name="files_btn">Ficheiros</string>
+		<string name="copy_log_btn">Copiar registo</string>
+		<string name="select_type_hdr">Selecione o tipo</string>
+		<string name="install_zip_hdr">Instalar Zip</string>
+		<string name="install_zip_btn">Instalar Zip</string>
+		<string name="install_image_hdr">Instalar Imagem</string>
+		<string name="install_image_btn">Instalar Imagem</string>
+		<string name="install_select_file_hdr">Selecione o ficheiro</string>
+		<string name="file_selector_folders_hdr">Pastas</string>
+		<string name="select_file_from_storage">Selecione o ficheiro do %tw_storage_display_name% (%tw_storage_free_size% MB)</string>
+		<string name="adb_sideload_btn">ADB Sideload</string>
+		<string name="install_hdr">Instalar</string>
+		<string name="select_storage_hdr">Escolher armazenamento</string>
+		<string name="select_storage_btn">Armazenamento</string>
+		<string name="queue_hdr">Lista</string>
+		<string name="zip_queue_count">%tw_zip_queue_count% do máximo de 10 ficheiros na fila</string>
+		<string name="zip_queue_count_s">ficheiro %tw_zip_queue_count% de 10:</string>
+		<string name="zip_warn1">Esta operação poderá instalar software</string>
+		<string name="zip_warn2">incompatível e tornar o seu aparelho inutilizável.</string>
+		<string name="zip_back_cancel">Pressione o botão voltar para cancelar a instalação.</string>
+		<string name="zip_back_clear">Pressione o botão voltar para limpar a fila.</string>
+		<string name="folder">Origem:</string>
+		<string name="file">Ficheiro:</string>
+		<string name="zip_sig_chk">Verificação de assinatura do ficheiro zip</string>
+		<string name="inject_twrp_chk">Injetar a TWRP após a instalação</string>
+		<string name="install_reboot_chk">Reiniciar após concluir a instalação</string>
+		<string name="options_hdr">Opções</string>
+		<string name="confirm_flash_hdr">Confirmar a instalação</string>
+		<string name="zip_queue">Lista:</string>
+		<string name="options">Opcões:</string>
+		<string name="swipe_confirm">   Confirmar</string>
+		<string name="zip_add_btn">Adicionar Zips</string>
+		<string name="zip_clear_btn">Limpar fila</string>
+		<string name="install_zip_count_hdr">A instalar o Zip %tw_zip_index% de %tw_zip_queue_count%</string>
+		<string name="installing_zip_xml">A instalar o Zip: %tw_file%</string>
+		<string name="failed">Falhou</string>
+		<string name="successful">Sucesso</string>
+		<string name="install_failed">A instalação falhou</string>
+		<string name="install_successful">A instalação foi bem sucedida</string>
+		<string name="wipe_cache_dalvik_btn">Limpar cache/dalvik</string>
+		<string name="reboot_system_btn">Reiniciar</string>
+		<string name="install_sel_target">Selecione a partição de destino</string>
+		<string name="flash_image_select">Selecione a partição para onde instalar a imagem:</string>
+		<string name="target_partition">Partição de destino:</string>
+		<string name="flashing_image">A instalar a imagem...</string>
+		<string name="image_flashed">Imagem instalada</string>
+		<string name="wipe_cache_dalvik_confirm">Apagar a Cache &amp; Dalvik?</string>
+		<string name="wiping_cache_dalvik">A apagar a Cache &amp; Dalvik...</string>
+		<string name="wipe_cache_dalvik_complete">A cache de &amp; Dalvik foi apagada</string>
+		<string name="swipe_wipe">        Deslize para apagar</string>
+		<string name="swipe_wipe_s">   Apagar</string>
+		<string name="no_os1">Nenhum SO instalado! Tem a</string>
+		<string name="no_osrb">certeza que pretende reiniciar?</string>
+		<string name="no_ospo">certeza que pretende desligar?</string>
+		<string name="rebooting">A reiniciar...</string>
+		<string name="swipe_reboot">     Deslize para reiniciar</string>
+		<string name="swipe_reboot_s">   Reiniciar</string>
+		<string name="reboot_install_app_hdr">Instalar a App TWRP?</string>
+		<string name="reboot_install_app1">Pretende instalar a App TWRP Oficial?</string>
+		<string name="reboot_install_app2">A mesma pesquisa por novas versões da TWRP.</string>
+		<string name="reboot_install_app_prompt_install">Perguntar se pretende instalar a App TWRP caso não esteja</string>
+		<string name="reboot_install_app_system">Instalar como App de Sistema</string>
+		<string name="reboot_installing_app">A instalar a App...</string>
+		<string name="swipe_to_install_app">      Deslize para instalar</string>
+		<string name="swipe_flash">      Deslize para instalar</string>
+		<string name="confirm_action">Confirmar a ação</string>
+		<string name="back_cancel">Pressione o botão voltar para cancelar.</string>
+		<string name="cancel_btn">Cancelar</string>
+		<string name="wipe_hdr">Apagar a memória</string>
+		<string name="factory_reset_hdr">Reset de fábrica</string>
+		<string name="factory_reset_btn">Reset</string>
+		<string name="factory_reset1">Apaga os dados, a cache e a cache Dalvik/ART</string>
+		<string name="factory_reset2">(não apaga o armazenamento interno)</string>
+		<string name="factory_reset3">Por norma, esta é a limpeza</string>
+		<string name="factory_reset4">que se costuma querer fazer.</string>
+		<string name="factory_resetting">Reset de fábrica...</string>
+		<string name="advanced_wipe_hdr">Limpeza personalizada</string>
+		<string name="advanced_wipe_btn">Personalizar</string>
+		<string name="wipe_enc_confirm">Apagar a encriptação dos dados?</string>
+		<string name="formatting_data">A formatar os dados...</string>
+		<string name="swipe_format_data">Deslize para formatar os dados</string>
+		<string name="swipe_format_data_s">   Formatar os dados</string>
+		<string name="factory_reset_complete">Reset de fábrica completo</string>
+		<string name="sel_part_hdr">Selecione as partições</string>
+		<string name="wipe_sel_confirm">Limpar a(s) partição(s) selecionada(s)?</string>
+		<string name="wiping_part">A limpar partição(s)...</string>
+		<string name="wipe_complete">Limpeza completa</string>
+		<string name="sel_part_wipe">Selecione as partições a limpar:</string>
+		<string name="invalid_part_sel">Seleção de partição inválida</string>
+		<string name="format_data_hdr">Formatar dados</string>
+		<string name="format_data_btn">Formatar</string>
+		<string name="format_data_ptr1">O formatar dos dados eliminará todos os seus</string>
+		<string name="format_data_ptr2">aplicativos, backups, mídia, fotos, vídeos e</string>
+		<string name="format_data_ptr3">remove a encriptação do armazenamento interno.</string>
+		<string name="format_data_adopted">Incluindo o armazenamento adoptado</string>
+		<string name="format_data_lcp1">O formatar dos dados eliminará todos as suas apps, os backups, as fotos, os vídeos, a mídia, e</string>
+		<string name="format_data_lcp2">remove a encriptação do armazenamento interno.</string>
+		<string name="format_data_wtc1">O formatar dos dados eliminará todos os seus aplicativos,</string>
+		<string name="format_data_wtc2">backups e mídia. Isto não pode ser desfeito.</string>
+		<string name="format_data_undo">Isto não pode ser desfeito.</string>
+		<string name="format_data_complete">Concluída a formatação dos dados</string>
+		<!-- Translator note: the word "yes" must remain English! -->
+		<string name="yes_continue">Escreva yes para continuar.  Cancele com o botão voltar.</string>
+		<string name="part_opt_hdr">Opções de partição para: %tw_partition_name%</string>
+		<string name="sel_act_hdr">Escolher ação</string>
+		<string name="file_sys_opt">Opções de sistema de ficheiros</string>
+		<string name="partition">Partição: %tw_partition_name%</string>
+		<string name="part_mount_point">Ponto de montagem: %tw_partition_mount_point%</string>
+		<string name="part_curr_fs">Sistema de ficheiros: %tw_partition_file_system%</string>
+		<string name="part_present_yes">Presente: Sim</string>
+		<string name="part_present_no">Presente: Não</string>
+		<string name="part_removable_yes">Removível: Sim</string>
+		<string name="part_removable_no">Removível: Não</string>
+		<string name="part_size">Tamanho: % tw_partition_size % MB</string>
+		<string name="part_used">Ocupado: % tw_partition_used % MB</string>
+		<string name="part_free">Livre: % tw_partition_free % MB</string>
+		<string name="part_backup_size">Tamanho do backup: % tw_partition_backup_size % MB</string>
+		<string name="resize_btn">Redimensionar sistema de ficheiros</string>
+		<string name="resize_btn_s">Redimensionar</string>
+		<string name="resize_confirm">Redimensionar %tw_partition_name%?</string>
+		<string name="resizing">A redimensionar...</string>
+		<string name="resize_complete">Redimensionamento completo</string>
+		<string name="swipe_resize">Deslize para redimensionar</string>
+		<string name="swipe_resize_s">   Redimensionar</string>
+		<string name="repair_btn">Reparar sistema de ficheiros</string>
+		<string name="repair_btn_s">Reparar</string>
+		<string name="repair_confirm">%tw_partition_name% de reparação?</string>
+		<string name="repairing">A reparar...</string>
+		<string name="repair_complete">Reparação concluída</string>
+		<string name="swipe_repair">       Deslize para reparar</string>
+		<string name="swipe_repair_s">   Reparar</string>
+		<string name="change_fs_btn">Alterar sistema de ficheiros</string>
+		<string name="change_fs_btn_s">Alterar</string>
+		<string name="change_fs_for_hdr">Alterar o sistema de ficheiros para: %tw_partition_name%</string>
+		<string name="change_fs_for_hdr_s">Partição: %tw_partition_name% &gt; Selecione o sistema de ficheiros</string>
+		<string name="change_fs_warn1">Algumas ROMs, ou kernels, podem não suportar</string>
+		<string name="change_fs_warn2">certos sistemas de ficheiros. Proceda com cautela!</string>
+		<string name="change_fs_confirm">Alterar %tw_partition_name%?</string>
+		<string name="formatting">A formatar...</string>
+		<string name="format_complete">Formatação concluída</string>
+		<string name="swipe_change_fs">       Deslize para alterar</string>
+		<string name="swipe_change_s">   Alterar</string>
+		<string name="back_btn">Voltar</string>
+		<string name="wipe_enc_btn">Apagar encriptação</string>
+		<string name="swipe_factory_reset">   Deslize para fazer reset</string>
+		<string name="repair_change_btn">Reparar ou alterar sistema de ficheiros</string>
+		<string name="storage_hdr">Armazenamento: %tw_storage_display_name% (%tw_storage_free_size% MB)</string>
+		<string name="backup_hdr">Backup</string>
+		<string name="backup_confirm_hdr">Confirmar o Backup</string>
+		<string name="encryption_tab">ENCRIPTAÇÃO</string>
+		<string name="encryption">Encriptação:</string>
+		<string name="name">Nome:</string>
+		<string name="sel_part_backup">Selecione as partições para o Backup:</string>
+		<string name="storage">Armazenamento:</string>
+		<string name="enc_disabled">desativado - definir uma palavra-passe para ativar</string>
+		<string name="enc_enabled">ativado</string>
+		<string name="enable_backup_comp_chk">Ativar a compactação</string>
+		<string name="skip_digest_backup_chk" version="2">Não gerar MD5 durante o Backup</string>
+		<string name="disable_backup_space_chk" version="2">Desativar a verificação do espaço livre</string>
+		<string name="current_boot_slot">Slot atual: %tw_active_slot%</string>
+		<string name="boot_slot_a">Slot A</string>
+		<string name="boot_slot_b">Slot B</string>
+		<string name="changing_boot_slot">A alterar o Slot de Arranque</string>
+		<string name="changing_boot_slot_complete">Alteração efetuada com sucesso</string>
+		<string name="refresh_sizes_btn">Atualizar ocupação</string>
+		<string name="swipe_backup"> Deslize para fazer Backup</string>
+		<string name="append_date_btn">Acrescentar data</string>
+		<string name="backup_name_exists">Já existe um Backup com esse nome!</string>
+		<string name="encrypt_backup">Encriptar o Backup?</string>
+		<string name="enter_pass">Defina uma palavra-passe:</string>
+		<string name="enter_pass2">Digite a palavra-passe novamente:</string>
+		<string name="pass_not_match">As palavra-passes não coincidem!</string>
+		<string name="partitions">Partições:</string>
+		<string name="disabled">Desativado</string>
+		<string name="enabled">Ativado</string>
+		<string name="backup_name_hdr">Definir um nome para o Backup</string>
+		<string name="progress">Progresso:</string>
+		<string name="backup_complete">Backup concluído</string>
+		<string name="restore_hdr">Restaurar</string>
+		<string name="sel_backup_hdr">Selecione o Backup</string>
+		<string name="restore_sel_store_hdr">Selecione o Backup do %tw_storage_display_name% (%tw_storage_free_size% MB)</string>
+		<string name="restore_sel_pack_fs">Selecione o Backup a restaurar:</string>
+		<string name="restore_enc_backup_hdr">Backup encriptado</string>
+		<string name="restore_dec_fail">Palavra-passe incorrecta, por favor tente novamente!</string>
+		<string name="del_backup_btn">Apagar Backup</string>
+		<string name="del_backup_confirm">Apagar o Backup?</string>
+		<string name="del_backup_confirm2">Não será possível reverter!</string>
+		<string name="deleting_backup">A apagar o Backup...</string>
+		<string name="backup_deleted">Backup apagado</string>
+		<string name="swipe_delete">        Deslize para apagar</string>
+		<string name="swipe_delete_s">   Apagar</string>
+		<string name="restore_try_decrypt">Backup encriptado - a tentar desencriptar</string>
+		<string name="restore_try_decrypt_s">A tentar desencriptar</string>
+		<string name="restore_backup_date">Backup executado a %tw_restore_file_date%</string>
+		<string name="restore_sel_part">Selecione as partições a restaurar:</string>
+		<string name="restore_enable_digest_chk" version="2">Ativar a verificação de MD5 dos ficheiros de Backup</string>
+		<string name="restore_complete">Restauro completo</string>
+		<string name="swipe_restore">     Deslize para restaurar</string>
+		<string name="swipe_restore_s">   Restaurar</string>
+		<string name="rename_backup_hdr">Renomear o Backup</string>
+		<string name="rename_backup_confirm">Renomear o Backup?</string>
+		<string name="rename_backup_confirm2">Não será possível reverter!</string>
+		<string name="renaming_backup">A renomear o Backup...</string>
+		<string name="rename_backup_complete">Backup renomeado</string>
+		<string name="swipe_to_rename">      Deslize para renomear</string>
+		<string name="swipe_rename">   Renomear</string>
+		<string name="confirm_hdr">Confirme</string>
+		<string name="mount_hdr">Montar</string>
+		<string name="mount_sel_part">Selecione as partições a montar:</string>
+		<string name="mount_sys_ro_chk">Montar a partição de sistema apenas para leitura</string>
+		<string name="mount_sys_ro_s_chk">Sistema de montagem RO</string>
+		<string name="decrypt_data_btn">Desencriptar dados</string>
+		<string name="disable_mtp_btn">Desativar MTP</string>
+		<string name="enable_mtp_btn">Ativar MTP</string>
+		<string name="mount_usb_storage_btn">Montar Cartão SD</string>
+		<string name="usb_storage_hdr">Cartão SD</string>
+		<string name="usb_stor_mnt1">O Cartão SD está montado</string>
+		<string name="usb_stor_mnt2">Não se esqueça de remover o seu dispositivo com</string>
+		<string name="usb_stor_mnt3">segurança do computador antes de o desmontar!</string>
+		<string name="unmount_btn">Desmontar</string>
+		<string name="rb_system_btn">Sistema</string>
+		<string name="rb_poweroff_btn">Desligar</string>
+		<string name="rb_recovery_btn">Recovery</string>
+		<string name="rb_bootloader_btn">Bootloader</string>
+		<string name="rb_download_btn">Descarregar</string>
+		<string name="turning_off">A desligar...</string>
+		<string name="swipe_power_off">      Deslize para desligar</string>
+		<string name="swipe_power_off_s">Desligar</string>
+		<string name="sys_ro_hdr">Partição de sistema não modificada</string>
+		<string name="sys_ro_keep">Pretende manter o sistema apenas para leitura?</string>
+		<string name="sys_rop1">A TWRP pode manter a partição de sistema como não modificada</string>
+		<string name="sys_rop2">contudo, se assim for, a TWRP será incapaz de impedir</string>
+		<string name="sys_rop3">que a ROM oficial substitua a Recovery novamente e</string>
+		<string name="sys_rop4">não irá disponibilizar a opção de dar root ao seu dispositivo.</string>
+		<string name="sys_rop5">Ainda assim, a instalação de Zips, ou a execução de</string>
+		<string name="sys_rop6">operações adb, pode modificar a partição de sistema.</string>
+		<string name="sys_rol1">A TWRP pode manter a partição de sistema como não modificada contudo, se assim for, a TWRP será incapaz de impedir</string>
+		<string name="sys_rol2">que a ROM oficial substitua a Recovery novamente e não irá disponibilizar a opção de dar root ao seu dispositivo.</string>
+		<string name="sys_rol3">Ainda assim, a instalação de Zips, ou a execução de operações adb, pode modificar a partição de sistema.</string>
+		<string name="sys_ro_never_show_chk">Não voltar a mostrar este aviso</string>
+		<string name="sys_ro_keep_ro_btn">Apenas para leitura</string>
+		<string name="swipe_allow_mod">      Deslize para permitir</string>
+		<string name="swipe_allow_mod_s">Permitir modificações</string>
+		<string name="settings_hdr">Definições</string>
+		<string name="settings_gen_hdr">Geral</string>
+		<string name="settings_gen_s_hdr">Geral</string>
+		<string name="settings_gen_btn">Geral</string>
+		<string name="use_rmrf_chk">Utilizar rm -rf ao invés de formatar</string>
+		<string name="use24clock_chk">Relógio de 24 horas</string>
+		<string name="rev_navbar_chk">Barra de navegação invertida</string>
+		<string name="simact_chk">Simular ações para teste de temas</string>
+		<string name="simfail_chk">Simular falhas para ações</string>
+		<string name="ctr_navbar_rdo">Botões de navegação centrados</string>
+		<string name="lft_navbar_rdo">Botões de navegação alinhados à esquerda</string>
+		<string name="rht_navbar_rdo">Botões de navegação alinhados à direita</string>
+		<string name="restore_defaults_btn">Restaurar predefinições</string>
+		<string name="settings_tz_btn">Fuso Horário</string>
+		<string name="settings_screen_btn">Ecrã</string>
+		<string name="settings_screen_bright_btn">Brilho do ecrã</string>
+		<string name="settings_vibration_btn">Vibração</string>
+		<string name="settings_language_btn">Idioma</string>
+		<string name="time_zone_hdr">Fuso Horário</string>
+		<string name="sel_tz_list">Selecione o Fuso Horário:</string>
+		<!-- Translator note: if it does not make sense to translate the locations or if it makes more sense,
+				feel free to change the location listed or drop the location entirely and just call it UTC -6 -->
+		<string name="utcm11">(UTC -11) Samoa, Midway Island</string>
+		<string name="utcm10">(UTC -10) Hawaii</string>
+		<string name="utcm9">(UTC -9) Alaska</string>
+		<string name="utcm8">(UTC -8) Pacific Time</string>
+		<string name="utcm7">(UTC -7) Mountain Time</string>
+		<string name="utcm6">(UTC -6) Central Time</string>
+		<string name="utcm5">(UTC -5) Eastern Time</string>
+		<string name="utcm4">(UTC -4) Atlantic Time</string>
+		<string name="utcm3">(UTC -3) Brazil, Buenos Aires</string>
+		<string name="utcm2">(UTC -2) Mid-Atlantic</string>
+		<string name="utcm1">(UTC -1) Azores, Cape Verde</string>
+		<string name="utc0">(UTC  0) London, Dublin, Lisbon</string>
+		<string name="utcp1">(UTC +1) Berlin, Brussels, Paris</string>
+		<string name="utcp2">(UTC +2) Athens, Istanbul, South Africa</string>
+		<string name="utcp3">(UTC +3) Moscow, Baghdad</string>
+		<string name="utcp4">(UTC +4) Abu Dhabi, Tbilisi, Muscat</string>
+		<string name="utcp5">(UTC +5) Yekaterinburg, Islamabad</string>
+		<string name="utcp6">(UTC +6) Almaty, Dhaka, Colombo</string>
+		<string name="utcp7">(UTC +7) Bangkok, Hanoi, Jakarta</string>
+		<string name="utcp8">(UTC +8) Beijing, Singapore, Hong Kong</string>
+		<string name="utcp9">(UTC +9) Tokyo, Seoul, Yakutsk</string>
+		<string name="utcp10">(UTC +10) Eastern Australia, Guam</string>
+		<string name="utcp11">(UTC +11) Vladivostok, Solomon Islands</string>
+		<string name="utcp12">(UTC +12) Auckland, Wellington, Fiji</string>
+		<string name="sel_tz_offset">Selecione o deslocamento (geralmente 0): %tw_time_zone_guioffset%</string>
+		<string name="tz_offset_none">Nenhum</string>
+		<string name="tz_offset_0">0</string>
+		<string name="tz_offset_15">15</string>
+		<string name="tz_offset_30">30</string>
+		<string name="tz_offset_45">45</string>
+		<string name="use_dst_chk">Utilizar horário de Verão (DST)</string>
+		<string name="curr_tz">Fuso horário atual: %tw_time_zone%</string>
+		<string name="curr_tz_s">Fuso horário atual:</string>
+		<string name="set_tz_btn">Definir fuso horário</string>
+		<string name="settings_screen_hdr">Ecrã</string>
+		<string name="settings_screen_timeout_hdr">Tempo limite do ecrã</string>
+		<string name="enable_timeout_chk">Ativar tempo do ecrã</string>
+		<string name="screen_to_slider">Tempo limite do ecrã em segundos:</string>
+		<string name="screen_to_slider_s">Tempo limite do ecrã em segundos (0 = desativado): %tw_screen_timeout_secs%</string>
+		<string name="screen_to_na">Configuração de tempo limite do ecrã indisponível</string>
+		<string name="screen_bright_slider">Brilho: %tw_brightness_pct%%</string>
+		<string name="screen_bright_na">Configuração de brilho indisponível</string>
+		<string name="vibration_hdr">Vibração</string>
+		<string name="button_vibration_hdr">Vibração dos botões</string>
+		<string name="kb_vibration_hdr">Vibração do teclado</string>
+		<string name="act_vibration_hdr">Vibração de ações</string>
+		<string name="button_vibration">Vibração dos botões:</string>
+		<string name="kb_vibration">Vibração do teclado:</string>
+		<string name="act_vibration">Vibração de ações:</string>
+		<string name="select_language">Selecionar idioma:</string>
+		<string name="sel_lang_btn">Selecionar idioma</string>
+		<string name="set_language_btn">Definir idioma</string>
+		<string name="advanced_hdr">Avançadas</string>
+		<string name="copy_log_confirm">Copiar o registo para o cartão SD?</string>
+		<string name="copying_log" version="2">A copiar o registo para o cartão SD...</string>
+		<string name="copy_log_complete" version="2">Cópia do registo efetuada</string>
+		<string name="fix_context_btn">Corrigir SELinux</string>
+		<string name="part_sd_btn">Particionar SD</string>
+		<string name="part_sd_s_btn">Cartão SD</string>
+		<string name="file_manager_btn">Gestor de ficheiros</string>
+		<string name="language_hdr">Idioma</string>
+		<string name="terminal_btn">Terminal</string>
+		<string name="reload_theme_btn">Recarregar Tema</string>
+		<string name="dumlock_btn">HTC Dumlock</string>
+		<string name="inject_twrp_btn">Injetar TWRP</string>
+		<string name="inject_twrp_confirm">Pretende injetar a TWRP?</string>
+		<string name="injecting_twrp">A injetar a TWRP...</string>
+		<string name="inject_twrp_complete">Injeção da TWRP concluída</string>
+		<string name="swipe_to_confirm">     Deslize para confirmar</string>
+		<string name="part_sd_hdr">Particionar o Cartão SD</string>
+		<string name="invalid_partsd_sel">Tem de selecionar um dispositivo removível</string>
+		<string name="part_sd_lose">Irá perder todos os dados do cartão SD!</string>
+		<string name="part_sd_undo">Esta ação não pode ser desfeita!</string>
+		<string name="part_sd_ext_sz">Tamanho EXT:</string>
+		<string name="part_sd_swap_sz">Tamanho de swap:</string>
+		<string name="part_sd_m">-</string>
+		<string name="part_sd_p">+</string>
+		<string name="file_system">Sistema de ficheiros:</string>
+		<string name="swipe_part_sd">    Deslize para particionar</string>
+		<string name="swipe_part_sd_s">Particionar</string>
+		<string name="partitioning_sd">A particionar o cartão SD...</string>
+		<string name="partitioning_sd2">Esta operação demorará algum tempo.</string>
+		<string name="part_sd_complete">Particionamento concluído</string>
+		<string name="dumlock_hdr">HTC Dumlock</string>
+		<string name="dumlock_restore_btn">Restaurar a imagem de Boot Original</string>
+		<string name="dumlock_restore_confirm">Pretende restaurar a imagem de Boot original?</string>
+		<string name="dumlock_restoring">A restaurar a imagem de Boot Original...</string>
+		<string name="dumlock_restore_complete">Imagem de Boot restaurada</string>
+		<string name="dumlock_reflash_btn">Instalar Recovery</string>
+		<string name="dumlock_reflash_confirm">Pretende instalar a Recovery para a partição Boot?</string>
+		<string name="dumlock_reflashing">A instalar a Recovery para a partição Boot...</string>
+		<string name="dumlock_reflash_complete">Instalação da Recovery para a partição Boot concluída</string>
+		<string name="dumlock_install_btn">Instalar o HTC Dumlock</string>
+		<string name="dumlock_install_confirm">Pretende instalar os ficheiros HTC dumlock para a ROM?</string>
+		<string name="dumlock_installing">A instalar o HTC Dumlock...</string>
+		<string name="dumlock_install_complete">Instalção do HTC Dumlock concluída</string>
+		<string name="swipe_to_unlock">    Deslize para desbloquear</string>
+		<string name="swipe_unlock">   Desbloquear</string>
+		<string name="fm_hdr">Gestor de ficheiros</string>
+		<string name="fm_sel_file">Selecione um ficheiro ou pasta</string>
+		<string name="fm_type_folder">Pasta</string>
+		<string name="fm_type_file">Ficheiro</string>
+		<string name="fm_choose_act">Escolha uma Ação</string>
+		<string name="fm_selected">%tw_fm_type% selecionado:</string>
+		<string name="fm_copy_btn">Cópia</string>
+		<string name="fm_copy_file_btn">Copiar ficheiro</string>
+		<string name="fm_copy_folder_btn">Copiar pasta</string>
+		<string name="fm_copying">A copiar</string>
+		<string name="fm_move_btn">Mover</string>
+		<string name="fm_moving">A mover</string>
+		<string name="fm_chmod755_btn">chmod 755</string>
+		<string name="fm_chmod755ing">chmod 755</string>
+		<string name="fm_chmod_btn">chmod</string>
+		<string name="fm_delete_btn">Eliminar</string>
+		<string name="fm_deleting">A eliminar</string>
+		<string name="fm_rename_btn">Renomear</string>
+		<string name="fm_rename_file_btn">Renomear ficheiro</string>
+		<string name="fm_rename_folder_btn">Renomear Pasta</string>
+		<string name="fm_renaming">A renomear</string>
+		<string name="fm_sel_dest">Selecione a pasta de destino</string>
+		<string name="fm_sel_curr_folder">Selecione a pasta atual</string>
+		<string name="fm_rename_hdr">Renomear</string>
+		<string name="fm_set_perms_hdr">Definir permissões</string>
+		<string name="fm_perms">Permissões:</string>
+		<string name="fm_complete">Operação concluída</string>
+		<string name="decrypt_data_hdr">Desencriptar dados</string>
+		<string name="decrypt_data_enter_pass">Insira a sua palavra-passe.</string>
+		<string name="decrypt_data_failed">Palavra-passe incorrecta, tente novamente por favor!</string>
+		<string name="decrypt_data_failed_pattern">Padrão incorrecto, tente novamente por favor!</string>
+		<string name="decrypt_data_enter_pattern">Desenhe o seu padrão.</string>
+		<string name="decrypt_data_trying">A tentar a desencriptação</string>
+		<string name="decrypt_data_vold_os_missing">Ficheiros em falta necessários para a desencriptação vold: {1}</string>
+		<string name="term_hdr">Linha de comandos do Terminal</string>
+		<string name="term_s_hdr">Terminal</string>
+		<string name="term_kill_btn">KILL</string>
+		<string name="term_sel_folder_hdr">Voltar à pasta inicial</string>
+		<string name="adb_sideload_hdr">ADB Sideload</string>
+		<string name="sideload_wipe_dalvik_chk">Limpar a cache Dalvik</string>
+		<string name="sideload_wipe_cache_chk">Limpar a cache</string>
+		<string name="swipe_to_sideload">Deslize para iniciar Sideload</string>
+		<string name="swipe_sideload">   Início</string>
+		<string name="sideload_confirm">ADB Sideload</string>
+		<string name="sideload_usage">Modo de usar: adb sideload filename.zip</string>
+		<string name="sideload_complete">ADB Sideload concluído</string>
+		<string name="fix_contexts_hdr">Corrigir SELinux</string>
+		<string name="fix_contexts_note1">Nota: Corrigir contextos SELinux raramente é necessário.</string>
+		<string name="fix_contexts_note2">A correção de contextos SELinux poderá causar</string>
+		<string name="fix_contexts_note3">falhas que impeçam o arranque do seu dispositivo.</string>
+		<string name="swipe_to_fix_contexts">      Deslize para corrigir</string>
+		<string name="swipe_fix_contexts">   Corrigir</string>
+		<string name="fixing_contexts">A corrigir contextos...</string>
+		<string name="fix_contexts_complete">Correção de contextos concluída</string>
+		<string name="reboot_hdr">Reiniciar</string>
+		<string name="su_hdr">Permissão ROOT</string>
+		<string name="su_note1">O seu dispositivo parece não ter ROOT</string>
+		<string name="su_note2">Pretende instalar o binário su?</string>
+		<string name="su_note3">O mesmo permitirá dar ROOT ao dispositivo.</string>
+		<string name="su_cancel">Não instalar</string>
+		<string name="swipe_su_to_install">      Deslize para dar ROOT</string>
+		<string name="swipe_su_install">   Dar ROOT</string>
+		<string name="su_installing">A instalar SuperSU</string>
+		<string name="sel_storage_list">Selecionar armazenamento</string>
+		<string name="ok_btn">OK</string>
+
+		<!-- Various console messages - these consist of user displayed messages, oftentimes errors -->
+		<string name="no_kernel_selinux">O Kernel não tem suporte para leitura de contextos do SELinux.</string>
+		<string name="full_selinux">Suporte completo ao SELinux.</string>
+		<string name="no_selinux">Não há suporte ao SELinux (não existe libselinux).</string>
+		<string name="mtp_enabled">MTP ativado</string>
+		<string name="mtp_crash">MTP falhou, o mesmo não será iniciado no arranque.</string>
+		<string name="decrypt_success">Desencriptação realizada com êxito recorrendo à palavra-passe padrão.</string>
+		<string name="unable_to_decrypt">Não é possível desencriptar com a palavra-passe padrão. É possível que seja necessário executar uma formatação dos dados.</string>
+		<string name="generating_digest1" version="2">A gerar o MD5</string>
+		<!-- Message displayed during a backup if we are generating an MD5, ideally, leave the leading " * " to help align and separate this text from other console text -->
+		<string name="generating_digest2" version="2"> * A gerar o md5...</string>
+		<string name="digest_created" version="2"> * MD5 criado.</string>
+		<string name="digest_error" version="2"> * Erro MD5!</string>
+		<string name="digest_compute_error" version="2"> * Erro ao computar o MD5.</string>
+		<string name="current_date">(Data atual)</string>
+		<string name="auto_generate">(Criar automaticamente)</string>
+		<string name="unable_to_locate_partition">Não é possível localizar a partição '{1}' para os cálculos do Backup.</string>
+		<string name="no_partition_selected">Não estão selecionadas partições para Backup.</string>
+		<string name="total_partitions_backup"> * Número total de partições de Backup: {1}</string>
+		<string name="total_backup_size"> * Tamanho total dos dados: {1}MB</string>
+		<string name="available_space"> * Espaço disponível: {1}MB</string>
+		<string name="unable_locate_storage">Não é possível localizar o dispositivo de armazenamento.</string>
+		<string name="no_space">Não existe espaço suficiente no armazenamento.</string>
+		<string name="backup_started">[BACKUP INICIADO]</string>
+		<string name="backup_folder"> * Pasta de Backup: {1}</string>
+		<string name="fail_backup_folder">Não foi possível criar a pasta de Backup.</string>
+		<string name="avg_backup_fs">Taxa média de Backup para sistemas de ficheiro: {1} MB/seg</string>
+		<string name="avg_backup_img">Taxa média de Backup para drives de imagens: {1} MB/seg</string>
+		<string name="total_backed_size">[BACKUP CONCLUÍDO COM UM TOTAL DE {1} MB]</string>
+		<string name="backup_completed">[BACKUP REALIZADO EM {1} SEGUNDOS]</string>
+		<string name="restore_started">[RESTAURO INICIADO]</string>
+		<string name="restore_folder">Restaurar a pasta: '{1}'</string>
+		<!-- {1} is the partition display name and {2} is the number of seconds -->
+		<string name="restore_part_done">[{1} concluído(a) ({2} seconds)]</string>
+		<string name="verifying_digest" version="2">A verificar o MD5</string>
+		<string name="skip_digest" version="2">A ignorar a verificação MD5 por escolha do utilizador.</string>
+		<string name="calc_restore">A calcular detalhes da restauração...</string>
+		<string name="restore_read_only">Impossível restaurar a partição {1} -- está montada apenas para leitura.</string>
+		<string name="restore_unable_locate">Impossível localizar a partição '{1}' para restaurar.</string>
+		<string name="no_part_restore">Não estão selecionadas partições para restaurar.</string>
+		<string name="restore_part_count">A restaurar {1} partições...</string>
+		<string name="total_restore_size">{1}MB de tamanho total de restauro</string>
+		<string name="updating_system_details">A atualizar detalhes do sistema</string>
+		<string name="restore_completed">[RESTAURO CONCLUÍDO EM {1} SEGUNDOS]</string>
+		<!-- {1} is the path we could not open, {2} is strerror output -->
+		<string name="error_opening_strerr">Erro ao abrir: '{1}' ({2})</string>
+		<string name="unable_locate_part_backup_name">Não é possível localizar a partição pelo nome do Backup: '{1}'</string>
+		<string name="unable_find_part_path">Não é possível localizar a partição para o caminho '{1}'</string>
+		<string name="update_part_details">A atualizar detalhes da partição...</string>
+		<string name="update_part_details_done">... concluído</string>
+		<string name="wiping_dalvik">A limpar os diretórios da cache Dalvik...</string>
+		<string name="cleaned">Limpos: {1}...</string>
+		<string name="dalvik_done">-- Diretórios da cache Dalvik limpos!</string>
+		<string name="no_andsec">Não foram encontradas partições android secure.</string>
+		<string name="unable_to_locate">Não é possível localizar {1}.</string>
+		<string name="wiping_datamedia">A limpar o armazenamento interno  -- /data/media...</string>
+		<string name="unable_to_mount">Foi impossível montar {1}</string>
+		<string name="unable_to_mount_internal">Foi impossível montar a memória interna</string>
+		<string name="unable_to_mount_storage">Foi impossível montar o armazenamento</string>
+		<string name="fail_decrypt">Falha ao desencriptar os dados.</string>
+		<string name="no_crypto_support">Não existe crypto support nesta compilação.</string>
+		<string name="decrypt_success_dev">Dados desencriptados com sucesso, novo dispositivo de bloco: '{1}'</string>
+		<string name="decrypt_success_nodev">Dados desencriptados com sucesso</string>
+		<string name="done">Concluído.</string>
+		<string name="start_partition_sd">A particionar o cartão SD...</string>
+		<string name="partition_sd_locate">Não foi possível localizar o dispositivo a particionar.</string>
+		<string name="ext_swap_size">O tamanho EXT + Swap excede a capacidade do cartão SD.</string>
+		<string name="remove_part_table">A remover a tabela de partição...</string>
+		<string name="unable_rm_part">Não foi possível remover a tabela de partição.</string>
+		<string name="create_part">A criar a partição {1}...</string>
+		<string name="unable_to_create_part">Não foi possível criar a partição {1}.</string>
+		<string name="format_sdext_as">A formatar sd-ext como {1}...</string>
+		<string name="part_complete">Particionamento concluído.</string>
+		<string name="unable_to_open">Não é possível abrir '{1}'.</string>
+		<string name="mtp_already_enabled">O MTP já está ativado</string>
+		<string name="mtp_fail">Falha ao ativar o MTP</string>
+		<string name="no_mtp">Não existe suporte ao MTP</string>
+		<string name="image_flash_start">[INSTALAÇÃO DA IMAGEM INICIADA]</string>
+		<string name="img_to_flash">Imagem a instalar: '{1}'</string>
+		<string name="flash_unable_locate">Não é possível localizar a partição '{1}' para instalar.</string>
+		<string name="no_part_flash">Não foi selecionada nenhuma partição para onde instalar.</string>
+		<string name="too_many_flash">Demasiadas partições selecionadas para onde instalar.</string>
+		<string name="invalid_flash">Selecionou uma partição inválida para onde instalar.</string>
+		<string name="flash_done">[INSTALAÇÃO DA IMAGEM CONCLUÍDA]</string>
+		<string name="wiping">A limpar {1}</string>
+		<string name="repair_not_exist">{1} não existe! Não é possível reparar!</string>
+		<string name="repairing_using">Reparação de {1} utilizando {2}...</string>
+		<string name="unable_repair">Não é possível reparar {1}.</string>
+		<string name="mount_data_footer">Não foi possível montar a /data nem localizar o crypto footer.</string>
+		<!-- {1} is the folder name that we could not create, {2} is strerror output -->
+		<string name="create_folder_strerr">Não foi possível criar a pasta '{1}' ({2}).</string>
+		<!-- {1} is the folder name that we could not unmount, {2} is strerror output -->
+		<string name="fail_mount">Falha ao montar '{1}' ({2})</string>
+		<!-- {1} is the folder name that we could not unmount, {2} is strerror output -->
+		<string name="fail_unmount">Falha ao montar '{1}' ({2})</string>
+		<string name="cannot_resize">Não é possível redimensionar {1}.</string>
+		<string name="repair_resize">Reparação de {1} antes de redimensionamento.</string>
+		<string name="unable_resize">Não é possível redimensionar {1}.</string>
+		<string name="no_digest_found" version="2">'{1}' não dsipõe de md5. Por favor, desative a opção de verificação de MD5.</string>
+		<string name="digest_fail_match" version="2">MD5 de '{1}' não coincide.</string>
+		<string name="digest_matched" version="2">MD5 de '{1}' ok.</string>
+		<string name="fail_decrypt_tar">Falha ao desencriptar o ficheiro tar '{1}'</string>
+		<string name="format_data_msg">É necessário reiniciar a Recovery para a /data seja novamente capaz de ser utilizada.</string>
+		<string name="format_data_err">Não é possível formatar para remover a encriptação.</string>
+		<string name="formatting_using">A formatar {1} utilizando {2}...</string>
+		<string name="unable_to_wipe">Não foi possível limpar {1}.</string>
+		<string name="cannot_wipe">A partição {1} não pode ser apagada.</string>
+		<string name="remove_all">Remover todos os ficheiros em '{1}'</string>
+		<string name="wiping_data">A limpar os dados sem limpar /data/media...</string>
+		<string name="backing_up">A fazer backup de {1}...</string>
+		<string name="backup_storage_warning">O backup de {1} não inclui quaisquer ficheiros do armazenamento interno tais como imagens ou downloads.</string>
+		<string name="backing">A fazer backup</string>
+		<string name="backup_size">O tamanho do ficheiro de Backup para '{1}' é de 0 bytes.</string>
+		<string name="datamedia_fs_restore">AVISO: Este Backup de /data foi feito com o sistema de ficheiros de {1}! Ao restaurar, o dispositivo poderá não arrancar a não ser que mude para {1}.</string>
+		<string name="restoring">A restaurar {1}...</string>
+		<string name="restoring_hdr">A restaurar</string>
+		<string name="recreate_folder_err">Não é possível recriar a pasta {1}.</string>
+		<string name="img_size_err">O tamanho da imagem excede a capacidade do dispositivo de destino</string>
+		<string name="flashing">A instalar {1}...</string>
+		<string name="backup_folder_set">Pasta de Backup definida para '{1}'</string>
+		<string name="locate_backup_err">Não é possível localizar o Backup '{1}'</string>
+		<string name="set_restore_opt">A definir opções de restauro: '{1}':</string>
+		<string name="digest_check_skip" version="2">O ignorar da verificação MD5 está ativo</string>
+		<string name="ors_encrypt_restore_err">Não foi possível utilizar o OpenRecoveryScript para restaurar um Backup encriptado.</string>
+		<string name="mounting">A montar</string>
+		<string name="unmounting">A desmontar</string>
+		<string name="mounted">'{1}' Montado</string>
+		<string name="unmounted">'{1}' Desmontado</string>
+		<string name="setting">A definir '{1}' para '{2}'</string>
+		<string name="setting_empty">A definir '{1}' como vazio</string>
+		<string name="making_dir1">A criar o diretório</string>
+		<string name="making_dir2">A criar o diretório: '{1}'</string>
+		<string name="running_command">A executar o comando</string>
+		<string name="sideload">ADB Sideload</string>
+		<string name="start_sideload">A iniciar a funcionalidade ADB sideload...</string>
+		<string name="need_new_adb">É necessário o adb 1.0.32, ou mais recente, para fazer sideload a este dispositivo.</string>
+		<string name="no_pwd">Não foi fornecida uma palavra-passe.</string>
+		<string name="done_ors">O ficheiro de script foi processado</string>
+		<string name="injecttwrp">A injetar a TWRP na imagem de Boot...</string>
+		<string name="zip_err">Erro ao instalar o ficheiro zip '{1}'</string>
+		<string name="installing_zip">A instalar o ficheiro zip '{1}'</string>
+		<string name="select_backup_opt">A definir opções para o Backup:</string>
+		<string name="compression_on">A compactação está ativa</string>
+		<string name="digest_off" version="2">A geração do MD5 está desativada</string>
+		<string name="backup_fail">O backup falhou</string>
+		<string name="backup_clean">O backup falhou. A limpar a pasta de Backup.</string>
+		<string name="running_recovery_commands">A executar os comandos de Recovery</string>
+		<string name="recovery_commands_complete">Comandos de Recovery concluídos</string>
+		<string name="running_ors">OpenRecoveryScript em execução</string>
+		<string name="ors_complete">OpenRecoveryScript concluído</string>
+		<string name="check_for_digest" version="2">A pesquisar pelo ficheiro MD5...</string>
+		<string name="invalid_zip_format">Formato de zip inválido!</string>
+		<string name="fail_sysmap">Falha ao mapear o ficheiro '{1}'</string>
+		<string name="verify_zip_sig">A verificar a assinatura do zip...</string>
+		<string name="verify_zip_fail">A verificação da assinatura do ficheiro zip falhou!</string>
+		<string name="verify_zip_done">Assinatura do ficheiro zip verificada com sucesso.</string>
+		<string name="zip_corrupt">O ficheiro zip está corrompido!</string>
+		<string name="no_digest" version="2">A ignorar a verificação MD5: não foi encontrado nenhum ficheiro MD5</string>
+		<string name="digest_fail" version="2">O MD5 não coincide</string>
+		<string name="digest_match" version="2">O MD5 coincide</string>
+		<string name="pid_signal">O processo {1} terminou com o sinal: {2}</string>
+		<string name="pid_error">O processo {1} terminou com o erro: {2}</string>
+		<string name="install_dumlock">A instalar o HTC Dumlock para o sistema...</string>
+		<string name="dumlock_restore">A restaurar a imagem de Boot original...</string>
+		<string name="dumlock_reflash">A instalar a Recovery para o Boot...</string>
+		<string name="run_script">A executar o script {1}...</string>
+		<string name="rename_stock">O ficheiro da Recovery em /system foi renomeado de modo a impedir que a stock ROM substitua a TWRP.</string>
+		<string name="split_backup">A dividir o ficheiro de Backup em vários arquivos...</string>
+		<string name="backup_error">Erro ao criar o Backup.</string>
+		<string name="restore_error">Erro durante o processo de restauro.</string>
+		<string name="split_thread">A dividir o segmento com o ID {1} para o arquivo {2}</string>
+		<!-- These 2 items are saved in the data manager instead of resource manager, so %llu, etc is correct instead of {1} -->
+		<string name="file_progress">%llu de %llu ficheiros, %i%%</string>
+		<string name="size_progress">%lluMB de %lluMB, %i%%</string>
+		<string name="decrypt_cmd">A tentar desencriptar a partição de dados via linha de comandos.</string>
+		<string name="base_pkg_err">Falha ao carregar os pacotes base.</string>
+		<string name="simulating">A simular ações...</string>
+		<string name="backup_cancel">O backup foi cancelado</string>
+		<string name="config_twrp">A confiurar a TWRP...</string>
+		<string name="config_twrp_err">Não é possível configurar a TWRP com este kernel.</string>
+		<string name="copy_log">O registo da Recovery foi copiado para {1}.</string>
+		<string name="max_queue">A fila de ficheiros zip atingiu o seu máximo!</string>
+		<string name="min_queue">A fila de ficheiros zip atingiu o seu mínimo!</string>
+		<string name="screenshot_saved">A captura de ecrã foi guardada em {1}</string>
+		<string name="screenshot_err">Não foi possível capturar o ecrã!</string>
+		<string name="zip_wipe_cache">Pelo menos, um dos zip solicitou uma limpeza da cache -- a limpar a cache.</string>
+		<string name="and_sec_wipe_err">Não foi possível limpar o android secure</string>
+		<string name="dalvik_wipe_err">Falha ao limpar a cache dalvik</string>
+		<string name="auto_gen">(Criar automaticamente)</string>
+		<string name="curr_date">(Data atual)</string>
+		<string name="backup_name_len">O nome do Backup é muito extenso.</string>
+		<string name="backup_name_invalid">O nome '{1}' para o Backup contém um caráter inválido: '{1}'</string>
+		<string name="no_real_sdcard">Este dispositivo não tem um cartão SD externo! A abortar!</string>
+		<string name="cancel_sideload">A cancelar o ADB sideload...</string>
+		<string name="change_fs_err">Erro ao alterar o sistema de ficheiros.</string>
+		<string name="theme_ver_err">A versão do tema personalizado não é compatível com a versão da TWRP. A o usar o tema padrão.</string>
+		<string name="up_a_level">(Nível acima)</string>
+		<string name="install_reboot" version="2">A reiniciar daqui a %tw_sleep% segundo(s)</string>
+		<string name="adbbackup_error">Erro no Backup ADB. A sair..."</string>
+		<string name="adbbackup_control_error">Não é possível escrever no canal de controlo adb</string>
+		<string name="twrp_adbbu_option">A opção --twrp é requerida para ativar o twrp adb backup</string>
+		<string name="partition_not_found">caminho: {1} não encontrado na lista de partições</string>
+		<string name="copy_kernel_log">Log do Kernel copiado para {1}</string>
+		<string name="include_kernel_log">Incluir log do Kernel</string>
+		<string name="sha2_chk">Usar SHA2 para fazer hash</string>
+		<string name="unable_set_boot_slot">Erro ao alterar o slot do bootloader para {1}</string>
+	</resources>
+</language>
diff --git a/gui/theme/common/languages/sv.xml b/gui/theme/common/languages/sv.xml
index 73a6e45..076ee0b 100644
--- a/gui/theme/common/languages/sv.xml
+++ b/gui/theme/common/languages/sv.xml
@@ -13,8 +13,9 @@
 		<string name="vendor">Leverantör</string>
 		<string name="cache">Cache</string>
 		<string name="data">Data</string>
-		<string name="sdcard">SDCard</string>
+		<string name="sdcard">SD-kort</string>
 		<string name="internal">Intern lagring</string>
+		<string name="microsd">Micro SD-kort</string>
 		<string name="usbotg">USB OTG</string>
 		<string name="dalvik">Dalvik / ART Cache</string>
 		<string name="sdext">SD-EXT</string>
diff --git a/gui/theme/common/languages/tr.xml b/gui/theme/common/languages/tr.xml
index 4c3ee2c..f585adf 100644
--- a/gui/theme/common/languages/tr.xml
+++ b/gui/theme/common/languages/tr.xml
@@ -1,7 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--Generated by crowdin.com-->
+<?xml version="1.0"?>
+
 <language>
 	<display>Turkish</display>
+
 	<resources>
 		<!-- Font overrides - only change these if your language requires special characters -->
 		<resource name="font_l" type="fontoverride" filename="RobotoCondensed-Regular.ttf" scale="90" />
@@ -9,23 +10,29 @@
 		<resource name="font_s" type="fontoverride" filename="RobotoCondensed-Regular.ttf" scale="90" />
 		<resource name="fixed" type="fontoverride" filename="DroidSansMono.ttf" scale="100" />
 
+		<!-- Partition display names -->
 		<string name="system">Sistem</string>
 		<string name="system_image">Sistem İmajı</string>
-		<string name="vendor">Vendor</string>
-		<string name="vendor_image">Vendor İmajı</string>
+		<string name="vendor">Satıcı</string>
+		<string name="vendor_image">Satıcı İmajı</string>
 		<string name="boot">Boot</string>
 		<string name="recovery">Recovery</string>
 		<string name="cache">Önbellek</string>
 		<string name="data">Veri</string>
+		<string name="data_backup">Veri (depolama hariç)</string>
 		<string name="sdcard">SD Kart</string>
 		<string name="internal">Dahili Depolama</string>
-		<string name="microsd">Micro SDCard</string>
+		<string name="microsd">Micro SD Kart</string>
 		<string name="usbotg">USB OTG</string>
 		<string name="android_secure">Android Secure</string>
 		<string name="dalvik">Dalvik / ART Önbelleği</string>
+		<!-- This is a rarely used partition on a Micro SD card for a very old app2sd system -->
 		<string name="sdext">Harici SD</string>
 		<string name="adopted_data">Kabul Edilen Veri</string>
 		<string name="adopted_storage">Kabul Edilen Depolama</string>
+		<string name="autostorage">Depolama</string>
+
+		<!-- GUI XML strings -->
 		<string name="twrp_header">Team Win Recovery Project</string>
 		<string name="twrp_watch_header">TWRP %tw_version%</string>
 		<string name="cpu_temp">İşlemci: %tw_cpu_temp% °C</string>
@@ -43,6 +50,7 @@
 		<string name="tab_screen">EKRAN</string>
 		<string name="tab_vibration">TİTREŞİM</string>
 		<string name="tab_language">DİL</string>
+
 		<string name="install_btn">Yükle</string>
 		<string name="wipe_btn">Temizle</string>
 		<string name="backup_btn">Yedekle</string>
@@ -60,7 +68,7 @@
 		<string name="install_image_btn">İmaj Yükle</string>
 		<string name="install_select_file_hdr">Dosya Seç</string>
 		<string name="file_selector_folders_hdr">Klasörler</string>
-		<string name="select_file_from_storage">%tw_storage_display_name%\'dan dosya seç (%tw_storage_free_size% MB)</string>
+		<string name="select_file_from_storage">%tw_storage_display_name% içinden dosya seç (%tw_storage_free_size% MB)</string>
 		<string name="adb_sideload_btn">ADB Sideload</string>
 		<string name="install_hdr">Yükle</string>
 		<string name="select_storage_hdr">Depolama Seç</string>
@@ -70,12 +78,13 @@
 		<string name="zip_queue_count_s">%tw_zip_queue_count%/10 dosya:</string>
 		<string name="zip_warn1">Bu işlem uyumsuz yazılım yükleyebilir</string>
 		<string name="zip_warn2">ve cihazınızı kullanılamaz hale getirebilir.</string>
-		<string name="zip_back_cancel">Bu zipi eklememek için geriye basın.</string>
+		<string name="zip_back_cancel">Bu zip'i eklememek için geriye basın.</string>
 		<string name="zip_back_clear">Sırayı temizlemek için geri düğmesine basın.</string>
 		<string name="folder">Klasör:</string>
 		<string name="file">Dosya:</string>
 		<string name="zip_sig_chk">Zip imza doğrulaması</string>
 		<string name="inject_twrp_chk">Yükledikten sonra TWRP ekle</string>
+		<string name="install_reboot_chk">Yükleme tamamlandıktan sonra yeniden başlat</string>
 		<string name="options_hdr">Seçenekler</string>
 		<string name="confirm_flash_hdr">Flashlamayı Onayla</string>
 		<string name="zip_queue">Sıra:</string>
@@ -83,12 +92,12 @@
 		<string name="swipe_confirm">   Onayla</string>
 		<string name="zip_add_btn">Daha fazla zip ekle</string>
 		<string name="zip_clear_btn">Zip sırasını temizle</string>
-		<string name="install_zip_count_hdr">Zipi yükle %tw_zip_index%/%tw_zip_queue_count%</string>
+		<string name="install_zip_count_hdr">Zip'i yükle %tw_zip_index%/%tw_zip_queue_count%</string>
 		<string name="installing_zip_xml">Zip yükleniyor: %tw_file%</string>
 		<string name="failed">Başarısız</string>
 		<string name="successful">Başarılı</string>
-		<string name="install_failed">Kurulum Başarısız</string>
-		<string name="install_successful">Kurulum Başarılı</string>
+		<string name="install_failed">Yükleme Başarısız</string>
+		<string name="install_successful">Yükleme Başarılı</string>
 		<string name="wipe_cache_dalvik_btn">Cache/dalvik temizle</string>
 		<string name="reboot_system_btn">Sistemi Yeniden Başlat</string>
 		<string name="install_sel_target">Hedef Bölümü Seç</string>
@@ -101,12 +110,19 @@
 		<string name="wipe_cache_dalvik_complete">Önbellek ve Dalvik temizliği tamamlandı</string>
 		<string name="swipe_wipe">Temizlemek için Kaydır</string>
 		<string name="swipe_wipe_s">   Temizle</string>
-		<string name="no_os1">İS yüklü değil!</string>
-		<string name="no_osrb">Yeniden başlatmak istediğine emin misin?</string>
-		<string name="no_ospo">Kapatmak istediğine emin misin?</string>
+		<string name="no_os1">İşletim Sistemi yüklü değil!</string>
+		<string name="no_osrb">Yeniden başlatmak istediğinize emin misiniz?</string>
+		<string name="no_ospo">Kapatmak istediğinize emin misiniz?</string>
 		<string name="rebooting">Yeniden Başlatılıyor...</string>
 		<string name="swipe_reboot">Yeniden Başlatmak için Kaydır</string>
 		<string name="swipe_reboot_s">   Yeniden başlat</string>
+		<string name="reboot_install_app_hdr">TWRP Uygulaması yüklensin mi?</string>
+		<string name="reboot_install_app1">Resmi TWRP Uygulamasını yüklemek ister misiniz?</string>
+		<string name="reboot_install_app2">Uygulama, yeni TWRP sürümlerini kontrol edebilir.</string>
+		<string name="reboot_install_app_prompt_install">Yüklü değilse, TWRP uygulamasını yüklemek için sor</string>
+		<string name="reboot_install_app_system">Sistem Uygulaması olarak yükle</string>
+		<string name="reboot_installing_app">Uygulama yükleniyor...</string>
+		<string name="swipe_to_install_app">TWRP Uygulamasını yüklemek için kaydır</string>
 		<string name="swipe_flash">Flashlamayı onaylamak için kaydır</string>
 		<string name="confirm_action">Eylemi Onayla</string>
 		<string name="back_cancel">İptal etmek için geri düğmesine basın.</string>
@@ -114,7 +130,7 @@
 		<string name="wipe_hdr">Temizle</string>
 		<string name="factory_reset_hdr">Sıfırla</string>
 		<string name="factory_reset_btn">Sıfırla</string>
-		<string name="factory_reset1">Veriyi, Önbelleği, ve Dalvik\'i temizler</string>
+		<string name="factory_reset1">Veriyi, Önbelleği, ve Dalvik'i temizler</string>
 		<string name="factory_reset2">(dahili depolama hariç)</string>
 		<string name="factory_reset3">Çoğu zaman ihtiyacınız olan</string>
 		<string name="factory_reset4">tek temizlik budur.</string>
@@ -127,7 +143,7 @@
 		<string name="swipe_format_data_s">   Veriyi Biçimlendir</string>
 		<string name="factory_reset_complete">Sıfırlama Tamamlandı</string>
 		<string name="sel_part_hdr">Bölümleri Seç</string>
-		<string name="wipe_sel_confirm">Seçili Bölüm(ler) Temizlensin Mi?</string>
+		<string name="wipe_sel_confirm">Seçili Bölüm(ler) Temizlensin mi?</string>
 		<string name="wiping_part">Bölüm(ler) Temizleniyor...</string>
 		<string name="wipe_complete">Temizlik Tamamlandı</string>
 		<string name="sel_part_wipe">Temizlenecek Bölümleri Seçin:</string>
@@ -137,15 +153,16 @@
 		<string name="format_data_ptr1">Veriyi biçimlendirmek tüm uygulamalarınızı,</string>
 		<string name="format_data_ptr2">yedeklerinizi, resimlerinizi, videolarınızı, medyanızı, temizleyecek ve</string>
 		<string name="format_data_ptr3">dahili depolama üzerindeki şifrelemeyi kaldıracak.</string>
-		<string name="format_data_adopted">Adapte Dahili Depolama</string>
+		<string name="format_data_adopted">Kabul Edilen Depolama Dahil</string>
 		<string name="format_data_lcp1">Veriyi biçimlendirmek tüm uygulamalarınızı, yedeklerinizi, resimlerinizi, videolarınızı, medyanızı, temizleyecek ve</string>
 		<string name="format_data_lcp2">dahili depolama üzerindeki şifrelemeyi kaldıracak.</string>
 		<string name="format_data_wtc1">Veriyi biçimlendirmek tüm uygulamalarınızı,</string>
 		<string name="format_data_wtc2">yedeklerinizi ve medyanızı temizleyecek. Bu işlem geri alınamaz.</string>
 		<string name="format_data_undo">Bu işlem geri alınamaz.</string>
 		<string name="format_data_complete">Veriyi Biçimlendirme Tamamlandı</string>
-		<string name="yes_continue">Devam etmek için evet yazın.  İptal etmek için geriye basın.</string>
-		<string name="part_opt_hdr">Şu bölüm için bölümleme seçenekleri: %tw_partition_name%</string>
+		<!-- Translator note: the word "yes" must remain English! -->
+		<string name="yes_continue">Devam etmek için yes yazın.  İptal etmek için geriye basın.</string>
+		<string name="part_opt_hdr">%tw_partition_name% bölümü için bölümleme seçenekleri</string>
 		<string name="sel_act_hdr">Eylem Seç</string>
 		<string name="file_sys_opt">Dosya Sistemi Seçenekleri</string>
 		<string name="partition">Bölüm: %tw_partition_name%</string>
@@ -177,7 +194,7 @@
 		<string name="change_fs_btn_s">Değiştir</string>
 		<string name="change_fs_for_hdr">Dosya Sistemini Değiştir: %tw_partition_name%</string>
 		<string name="change_fs_for_hdr_s">Bölüm: %tw_partition_name% &gt; Dosya Sistemini Seç</string>
-		<string name="change_fs_warn1">Bazı ROM\'lar veya kerneller bazı dosya sistemlerini</string>
+		<string name="change_fs_warn1">Bazı ROM'lar veya kerneller bazı dosya sistemlerini</string>
 		<string name="change_fs_warn2">desteklemeyebilir. Dikkatli olun!</string>
 		<string name="change_fs_confirm">%tw_partition_name% değiştirilsin mi?</string>
 		<string name="formatting">Biçimlendiriliyor...</string>
@@ -200,7 +217,12 @@
 		<string name="enc_enabled">etkin</string>
 		<string name="enable_backup_comp_chk">Sıkıştırmayı etkinleştir</string>
 		<string name="skip_digest_backup_chk" version="2">Yedekleme sırasında Digest oluşturmayı geç</string>
-		<string name="disable_backup_space_chk">Boş Alan Denetimini Devre Dışı Bırak</string>
+		<string name="disable_backup_space_chk" version="2">Yedeklemeden önce boş alan denetimini devre dışı bırak</string>
+		<string name="current_boot_slot">Geçerli Yuva: %tw_active_slot%</string>
+		<string name="boot_slot_a">A Yuvası</string>
+		<string name="boot_slot_b">B Yuvası</string>
+		<string name="changing_boot_slot">Önyükleme Yuvasını Değiştir</string>
+		<string name="changing_boot_slot_complete">Önyükleme Yuvasını Değiştirme Tamamlandı</string>
 		<string name="refresh_sizes_btn">Boyutları Yenile</string>
 		<string name="swipe_backup">Yedeklemek için Kaydır</string>
 		<string name="append_date_btn">Tarih Ekle</string>
@@ -217,12 +239,12 @@
 		<string name="backup_complete">Yedekleme Tamamlandı</string>
 		<string name="restore_hdr">Geri Yükle</string>
 		<string name="sel_backup_hdr">Yedek Seç</string>
-		<string name="restore_sel_store_hdr">%tw_storage_display_name%\'dan yedek seç (%tw_storage_free_size% MB)</string>
+		<string name="restore_sel_store_hdr">%tw_storage_display_name% içinden yedek seç (%tw_storage_free_size% MB)</string>
 		<string name="restore_sel_pack_fs">Geri Yüklenecek Paketi Seçin:</string>
 		<string name="restore_enc_backup_hdr">Şifreli Yedek</string>
 		<string name="restore_dec_fail">Şifre yanlış, lütfen tekrar deneyin!</string>
 		<string name="del_backup_btn">Yedeği Sil</string>
-		<string name="del_backup_confirm">Yedek Silinsin Mi?</string>
+		<string name="del_backup_confirm">Yedek Silinsin mi?</string>
 		<string name="del_backup_confirm2">Bu işlem geri alınamaz!</string>
 		<string name="deleting_backup">Yedek Siliniyor...</string>
 		<string name="backup_deleted">Yedek Silme Tamamlandı</string>
@@ -230,14 +252,14 @@
 		<string name="swipe_delete_s">   Sil</string>
 		<string name="restore_try_decrypt">Şifreli Yedek - Çözülmeye Çalışılıyor</string>
 		<string name="restore_try_decrypt_s">Çözülmeye Çalışılıyor</string>
-		<string name="restore_backup_date">Yedek tarihi %tw_restore_file_date%</string>
+		<string name="restore_backup_date">Yedek tarihi: %tw_restore_file_date%</string>
 		<string name="restore_sel_part">Geri Yüklenecek Bölümleri Seç:</string>
-		<string name="restore_enable_digest_chk" version="2">Yedek Dosyalarının Digest Doğrulamasını Etkinleştir</string>
+		<string name="restore_enable_digest_chk" version="2">Yedek Dosyalarının Digest Doğrulamasını etkinleştir</string>
 		<string name="restore_complete">Geri Yükleme Tamamlandı</string>
 		<string name="swipe_restore">Geri Yüklemek için Kaydır</string>
 		<string name="swipe_restore_s">   Geri Yükle</string>
 		<string name="rename_backup_hdr">Yedeği Yeniden Adlandır</string>
-		<string name="rename_backup_confirm">Yedek Yeniden Adlandırılsın Mı?</string>
+		<string name="rename_backup_confirm">Yedek Yeniden Adlandırılsın mı?</string>
 		<string name="rename_backup_confirm2">Bu işlem geri alınamaz!</string>
 		<string name="renaming_backup">Yedek Yeniden Adlandırılıyor...</string>
 		<string name="rename_backup_complete">Yedek Yeniden Adlandırıldı</string>
@@ -247,10 +269,10 @@
 		<string name="mount_hdr">Bağla</string>
 		<string name="mount_sel_part">Bağlanacak Bölümleri Seç:</string>
 		<string name="mount_sys_ro_chk">Sistem bölümünü salt okunur bağla</string>
-		<string name="mount_sys_ro_s_chk">System RO Bağla</string>
+		<string name="mount_sys_ro_s_chk">Sistemi RO Bağla</string>
 		<string name="decrypt_data_btn">Veri Şifresini Çöz</string>
-		<string name="disable_mtp_btn">MTP\'yi Devre Dışı Bırak</string>
-		<string name="enable_mtp_btn">MTP\'yi Etkinleştir</string>
+		<string name="disable_mtp_btn">MTP'yi Devre Dışı Bırak</string>
+		<string name="enable_mtp_btn">MTP'yi Etkinleştir</string>
 		<string name="mount_usb_storage_btn">USB Depolamayı Bağla</string>
 		<string name="usb_storage_hdr">USB Depolama</string>
 		<string name="usb_stor_mnt1">USB Depolama Bağlandı</string>
@@ -261,7 +283,7 @@
 		<string name="rb_poweroff_btn">Kapat</string>
 		<string name="rb_recovery_btn">Recovery</string>
 		<string name="rb_bootloader_btn">Bootloader</string>
-		<string name="rb_download_btn">İndir</string>
+		<string name="rb_download_btn">Download</string>
 		<string name="turning_off">Kapatılıyor...</string>
 		<string name="swipe_power_off">Kapatmak için Kaydır</string>
 		<string name="swipe_power_off_s">Kapat</string>
@@ -269,12 +291,12 @@
 		<string name="sys_ro_keep">Sistem bölümü salt okunur kalsın mı?</string>
 		<string name="sys_rop1">TWRP resmi güncellemeleri almanızı kolaylaştırmak</string>
 		<string name="sys_rop2">için sistem bölümünüzü değiştirmeyebilir.</string>
-		<string name="sys_rop3">TWRP stock ROM\'un kendisini değiştirmesini</string>
+		<string name="sys_rop3">TWRP stock ROM'un kendisini değiştirmesini</string>
 		<string name="sys_rop4">engelleyemeyecek ve cihazınızı rootlamanızı istemeyecek.</string>
 		<string name="sys_rop5">Zip yüklemek veya adb işlemleri gerçekleştirmek</string>
 		<string name="sys_rop6">sistem bölümünü değiştirebilir.</string>
 		<string name="sys_rol1">TWRP resmi güncellemeleri almanızı kolaylaştırmak için sistem bölümünüzü değiştirmeyebilir.</string>
-		<string name="sys_rol2">TWRP stock ROM\'un kendisini değiştirmesini engelleyemeyecek ve cihazınızı rootlamanızı istemeyecek.</string>
+		<string name="sys_rol2">TWRP stock ROM'un kendisini değiştirmesini engelleyemeyecek ve cihazınızı rootlamanızı istemeyecek.</string>
 		<string name="sys_rol3">Zip yüklemek veya adb işlemleri gerçekleştirmek sistem bölümünü değiştirebilir.</string>
 		<string name="sys_ro_never_show_chk">Bu ekranı açılış sırasında tekrar gösterme</string>
 		<string name="sys_ro_keep_ro_btn">Salt Okunur Bırak</string>
@@ -287,8 +309,8 @@
 		<string name="use_rmrf_chk">Biçimlendirme yerine rm -rf kullan</string>
 		<string name="use24clock_chk">24-saat biçimini kullan</string>
 		<string name="rev_navbar_chk">Tersine çevrilmiş gezinti çubuğu düzeni</string>
-		<string name="simact_chk">Tema testi için eylemleri canlandır</string>
-		<string name="simfail_chk">Eylemler canlandırılamadı</string>
+		<string name="simact_chk">Tema testi için eylemleri taklit et</string>
+		<string name="simfail_chk">Eylemlerin başarısızlığını taklit et</string>
 		<string name="ctr_navbar_rdo">Merkezi gezinti çubuğu düğmeleri</string>
 		<string name="lft_navbar_rdo">Gezinti çubuğu düğmelerini sola hizala</string>
 		<string name="rht_navbar_rdo">Gezinti çubuğu düğmelerini sağa hizala</string>
@@ -300,29 +322,31 @@
 		<string name="settings_language_btn">Dil</string>
 		<string name="time_zone_hdr">Zaman Dilimi</string>
 		<string name="sel_tz_list">Zaman Dilimi Seç:</string>
-		<string name="utcm11">(UTC -11) Samoa, Midway Island</string>
+		<!-- Translator note: if it does not make sense to translate the locations or if it makes more sense,
+				feel free to change the location listed or drop the location entirely and just call it UTC -6 -->
+		<string name="utcm11">(UTC -11) Samoa, Midway Adası</string>
 		<string name="utcm10">(UTC -10) Hawaii</string>
 		<string name="utcm9">(UTC -9) Alaska</string>
-		<string name="utcm8">(UTC -8) Pacific Time</string>
-		<string name="utcm7">(UTC -7) Mountain Time</string>
-		<string name="utcm6">(UTC -6) Central Time</string>
-		<string name="utcm5">(UTC -5) Eastern Time</string>
-		<string name="utcm4">(UTC -4) Atlantic Time</string>
-		<string name="utcm3">(UTC -3) Brazil, Buenos Aires</string>
-		<string name="utcm2">(UTC -2) Mid-Atlantic</string>
-		<string name="utcm1">(UTC -1) Azores, Cape Verde</string>
-		<string name="utc0">(UTC  0) London, Dublin, Lisbon</string>
-		<string name="utcp1">(UTC +1) Berlin, Brussels, Paris</string>
-		<string name="utcp2">(UTC +2) Athens, Istanbul, South Africa</string>
-		<string name="utcp3">(UTC +3) Moscow, Baghdad</string>
-		<string name="utcp4">(UTC +4) Abu Dhabi, Tbilisi, Muscat</string>
-		<string name="utcp5">(UTC +5) Yekaterinburg, Islamabad</string>
-		<string name="utcp6">(UTC +6) Almaty, Dhaka, Colombo</string>
+		<string name="utcm8">(UTC -8) Pasifik Saati</string>
+		<string name="utcm7">(UTC -7) Dağ Saati</string>
+		<string name="utcm6">(UTC -6) Merkezi Saat</string>
+		<string name="utcm5">(UTC -5) Doğu Saati</string>
+		<string name="utcm4">(UTC -4) Atlantik Saati</string>
+		<string name="utcm3">(UTC -3) Brezilya, Buenos Aires</string>
+		<string name="utcm2">(UTC -2) Orta Atlantik</string>
+		<string name="utcm1">(UTC -1) Azorlar, Cape Verde</string>
+		<string name="utc0">(UTC  0) Londra, Dublin, Lizbon</string>
+		<string name="utcp1">(UTC +1) Berlin, Brüksel, Paris</string>
+		<string name="utcp2">(UTC +2) Atina, İstanbul, Güney Afrika</string>
+		<string name="utcp3">(UTC +3) Moskova, Bağdat</string>
+		<string name="utcp4">(UTC +4) Abu Dabi, Tiflis, Maskat</string>
+		<string name="utcp5">(UTC +5) Yekaterinburg, İslamabad</string>
+		<string name="utcp6">(UTC +6) Almatı, Dakka, Kolombo</string>
 		<string name="utcp7">(UTC +7) Bangkok, Hanoi, Jakarta</string>
-		<string name="utcp8">(UTC +8) Beijing, Singapore, Hong Kong</string>
-		<string name="utcp9">(UTC +9) Tokyo, Seoul, Yakutsk</string>
-		<string name="utcp10">(UTC +10) Eastern Australia, Guam</string>
-		<string name="utcp11">(UTC +11) Vladivostok, Solomon Islands</string>
+		<string name="utcp8">(UTC +8) Pekin, Singapur, Hong Kong</string>
+		<string name="utcp9">(UTC +9) Tokyo, Seul, Yakutsk</string>
+		<string name="utcp10">(UTC +10) Doğu Avustralya, Guam</string>
+		<string name="utcp11">(UTC +11) Vladivostok, Solomon Adaları</string>
 		<string name="utcp12">(UTC +12) Auckland, Wellington, Fiji</string>
 		<string name="sel_tz_offset">Ofset Seçin (Genellikle 0): %tw_time_zone_guioffset%</string>
 		<string name="tz_offset_none">Hiçbiri</string>
@@ -339,11 +363,11 @@
 		<string name="enable_timeout_chk">Ekran zaman aşımını etkinleştir</string>
 		<string name="screen_to_slider">Ekran zaman aşımı:</string>
 		<string name="screen_to_slider_s">Ekran zaman aşımı (0=devre dışı): %tw_screen_timeout_secs%</string>
-		<string name="screen_to_na">Ekran zaman aşımı ayarı kullanılabilir değil</string>
+		<string name="screen_to_na">Ekran zaman aşımı ayarı kullanılamıyor</string>
 		<string name="screen_bright_slider">Parlaklık: %tw_brightness_pct%%</string>
-		<string name="screen_bright_na">Parlaklık ayarı kullanılabilir değil</string>
+		<string name="screen_bright_na">Parlaklık ayarı kullanılamıyor</string>
 		<string name="vibration_hdr">Titreşim</string>
-		<string name="button_vibration_hdr">Düğme Titireşimi</string>
+		<string name="button_vibration_hdr">Düğme Titreşimi</string>
 		<string name="kb_vibration_hdr">Klavye Titreşimi</string>
 		<string name="act_vibration_hdr">Eylem Titreşimi</string>
 		<string name="button_vibration">Düğme Titreşimi:</string>
@@ -353,9 +377,10 @@
 		<string name="sel_lang_btn">Dil Seç</string>
 		<string name="set_language_btn">Dili Ayarla</string>
 		<string name="advanced_hdr">Gelişmiş</string>
-		<string name="copy_log_confirm">Kayıt SD Karta Kopyalansın Mı?</string>
-		<string name="copying_log">Kayıt SD Karta Kopyalanıyor...</string>
-		<string name="copy_log_complete">Kayıt Kopyalama Tamamlandı</string>
+		<string name="copy_log_confirm">Kayıt SD Karta Kopyalansın mı?</string>
+		<string name="copying_log" version="2">Kayıtları SD Karta Kopyala...</string>
+		<string name="copy_log_complete" version="2">Kayıtları Kopyalama Tamamlandı</string>
+		<string name="fix_context_btn">Bağlamları Düzelt</string>
 		<string name="part_sd_btn">SD Kartı Bölümle</string>
 		<string name="part_sd_s_btn">SD Kart</string>
 		<string name="file_manager_btn">Dosya Yöneticisi</string>
@@ -383,16 +408,16 @@
 		<string name="partitioning_sd2">Bu işlem birkaç dakika sürecek.</string>
 		<string name="part_sd_complete">Bölümleme Tamamlandı</string>
 		<string name="dumlock_hdr">HTC Dumlock</string>
-		<string name="dumlock_restore_btn">Orijinal Boot\'u Geri Yükle</string>
+		<string name="dumlock_restore_btn">Orijinal Boot'u Geri Yükle</string>
 		<string name="dumlock_restore_confirm">Orijinal boot imajı geri yüklensin mi?</string>
 		<string name="dumlock_restoring">Orijinal Boot Geri Yükleniyor...</string>
 		<string name="dumlock_restore_complete">Orijinal Boot Geri Yüklemesi Tamamlandı</string>
-		<string name="dumlock_reflash_btn">Recovery\'i Yeniden Flashla</string>
+		<string name="dumlock_reflash_btn">Recovery'yi Yeniden Flashla</string>
 		<string name="dumlock_reflash_confirm">Cihazın açılması için kurtarma yazılımı tekrar yüklensin mi?</string>
 		<string name="dumlock_reflashing">Cihazın açılması için kurtarma yazılımı tekrar yükleniyor...</string>
-		<string name="dumlock_reflash_complete">Cihazın açılması için kurtarma yazılımı tekrar yükleme tamamlandı</string>
+		<string name="dumlock_reflash_complete">Cihazın açılması için kurtarma yazılımını tekrar yükleme tamamlandı</string>
 		<string name="dumlock_install_btn">HTC Dumlock Yükle</string>
-		<string name="dumlock_install_confirm">HTC dumlock dosyaları ROM\'a yüklensin mi?</string>
+		<string name="dumlock_install_confirm">HTC dumlock dosyaları ROM'a yüklensin mi?</string>
 		<string name="dumlock_installing">HTC Dumlock Yükleniyor...</string>
 		<string name="dumlock_install_complete">HTC Dumlock Yüklemesi Tamamlandı</string>
 		<string name="swipe_to_unlock">Kilidi Açmak için Kaydır</string>
@@ -404,20 +429,20 @@
 		<string name="fm_choose_act">Eylem Seçin</string>
 		<string name="fm_selected">%tw_fm_type% seçili:</string>
 		<string name="fm_copy_btn">Kopyala</string>
-		<string name="fm_copy_file_btn">Dosya Kopyala</string>
-		<string name="fm_copy_folder_btn">Klasör Kopyala</string>
-		<string name="fm_copying">Kopyalanıyor</string>
+		<string name="fm_copy_file_btn">Dosyayı Kopyala</string>
+		<string name="fm_copy_folder_btn">Klasörü Kopyala</string>
+		<string name="fm_copying">Kopyala</string>
 		<string name="fm_move_btn">Taşı</string>
-		<string name="fm_moving">Taşınıyor</string>
+		<string name="fm_moving">Taşı</string>
 		<string name="fm_chmod755_btn">chmod 755</string>
 		<string name="fm_chmod755ing">chmod 755</string>
 		<string name="fm_chmod_btn">chmod</string>
 		<string name="fm_delete_btn">Sil</string>
-		<string name="fm_deleting">Siliniyor</string>
+		<string name="fm_deleting">Sil</string>
 		<string name="fm_rename_btn">Yeniden Adlandır</string>
 		<string name="fm_rename_file_btn">Dosyayı Yeniden Adlandır</string>
 		<string name="fm_rename_folder_btn">Klasörü Yeniden Adlandır</string>
-		<string name="fm_renaming">Yeniden Adlandırılıyor</string>
+		<string name="fm_renaming">Yeniden Adlandır</string>
 		<string name="fm_sel_dest">Hedef Klasörü Seçin</string>
 		<string name="fm_sel_curr_folder">Geçerli Klasörü Seç</string>
 		<string name="fm_rename_hdr">Yeniden Adlandır</string>
@@ -425,9 +450,12 @@
 		<string name="fm_perms">İzinler:</string>
 		<string name="fm_complete">Dosya İşlemi Tamamlandı</string>
 		<string name="decrypt_data_hdr">Veri Şifresini Çöz</string>
-		<string name="decrypt_data_enter_pass">Şifre Gir.</string>
+		<string name="decrypt_data_enter_pass">Şifre Girin.</string>
+		<string name="decrypt_data_failed">Şifre başarısız oldu, lütfen tekrar deneyin!</string>
+		<string name="decrypt_data_failed_pattern">Desen başarısız oldu, lütfen tekrar deneyin!</string>
 		<string name="decrypt_data_enter_pattern">Desen Girin.</string>
 		<string name="decrypt_data_trying">Şifre Çözülmeye Çalışılıyor</string>
+		<string name="decrypt_data_vold_os_missing">Vold şifresini çözmek için gerekli dosyalar eksik: {1}</string>
 		<string name="term_hdr">Terminal Komutu</string>
 		<string name="term_s_hdr">Terminal</string>
 		<string name="term_kill_btn">SONLANDIR</string>
@@ -435,11 +463,19 @@
 		<string name="adb_sideload_hdr">ADB Sideload</string>
 		<string name="sideload_wipe_dalvik_chk">Dalvik Önbelleğini Temizle</string>
 		<string name="sideload_wipe_cache_chk">Önbelleği Temizle</string>
-		<string name="swipe_to_sideload">Sideload\'u Başlatmak için Kaydır</string>
+		<string name="swipe_to_sideload">Sideload'u Başlatmak için Kaydır</string>
 		<string name="swipe_sideload">   Başlat</string>
 		<string name="sideload_confirm">ADB Sideload</string>
 		<string name="sideload_usage">Kullanım: adb sideload dosyaadı.zip</string>
 		<string name="sideload_complete">ADB Sideload Tamamlandı</string>
+		<string name="fix_contexts_hdr">Bağlamları Düzelt</string>
+		<string name="fix_contexts_note1">Not: Bağlamları düzeltme nadiren gereklidir.</string>
+		<string name="fix_contexts_note2">SELinux Bağlamlarını düzeltmek,</string>
+		<string name="fix_contexts_note3">cihazınızın düzgün olarak önyükleme yapmamasına neden olabilir.</string>
+		<string name="swipe_to_fix_contexts">Bağlamları Düzeltmek için Kaydır</string>
+		<string name="swipe_fix_contexts">   Bağlamları Düzelt</string>
+		<string name="fixing_contexts">Bağlamlar Düzeltiliyor...</string>
+		<string name="fix_contexts_complete">Bağlamları Düzeltme Tamamlandı</string>
 		<string name="reboot_hdr">Yeniden Başlat</string>
 		<string name="su_hdr">SuperSU Denetimi</string>
 		<string name="su_note1">Cihazınız rootlanmamış görünüyor.</string>
@@ -451,6 +487,8 @@
 		<string name="su_installing">SuperSU Yükleniyor</string>
 		<string name="sel_storage_list">Depolama Seç</string>
 		<string name="ok_btn">Tamam</string>
+
+		<!-- Various console messages - these consist of user displayed messages, oftentimes errors -->
 		<string name="no_kernel_selinux">Kernel SELinux içeriklerini okuma desteğine sahip değil.</string>
 		<string name="full_selinux">Tam SELinux desteği mevcut.</string>
 		<string name="no_selinux">SELinux desteği yok (libselinux yok).</string>
@@ -459,6 +497,8 @@
 		<string name="decrypt_success">Varsayılan şifre ile çözüldü.</string>
 		<string name="unable_to_decrypt">Varsayılan şifre ile çözülemedi. Veri Biçimlendirmesi yapmanız gerekebilir.</string>
 		<string name="generating_digest1" version="2">Digest Oluşturuluyor</string>
+		<!-- Message displayed during a backup if we are generating an Digest, ideally, leave the leading " * " to help align and separate this text from other console text -->
+		<string name="generating_digest2" version="2"> * Digest Oluşturuluyor</string>
 		<string name="generating_digest2" version="2"> * Digest oluşturuluyor...</string>
 		<string name="digest_created" version="2"> * Digest Oluşturuldu.</string>
 		<string name="digest_error" version="2"> * Digest Hatası!</string>
@@ -475,12 +515,14 @@
 		<string name="backup_started">[YEDEKLEME BAŞLATILDI]</string>
 		<string name="backup_folder"> * Yedekleme Klasörü: {1}</string>
 		<string name="fail_backup_folder">Yedekleme klasörü oluşturulamadı.</string>
-		<string name="avg_backup_fs">Dosya sistemleri için ortalama yedekleme oranı: {1} MB/sec</string>
-		<string name="avg_backup_img">Görüntülü sürücüler için ortalama yedekleme hızı: {1} MB/sec</string>
+		<string name="avg_backup_fs">Dosya sistemleri için ortalama yedekleme hızı: {1} MB/sn</string>
+		<string name="avg_backup_img">Görüntülü sürücüler için ortalama yedekleme hızı: {1} MB/sn</string>
 		<string name="total_backed_size">[{1} MB YEDEKLENDİ]</string>
 		<string name="backup_completed">[YEDEKLEME {1} SANİYEDE TAMAMLANDI]</string>
 		<string name="restore_started">[GERİ YÜKLEME BAŞLATILDI]</string>
 		<string name="restore_folder">Geri yükleme klasörü: \'{1}\'</string>
+		<!-- {1} is the partition display name and {2} is the number of seconds -->
+		<string name="restore_part_done">[{1} bitti ({2} saniye)]</string>
 		<string name="verifying_digest" version="2">Digest Doğrulanıyor</string>
 		<string name="skip_digest" version="2">Kullanıcı ayarına göre Digest denetimi geçiliyor.</string>
 		<string name="calc_restore">Geri yükleme ayrıntıları hesaplanıyor...</string>
@@ -490,7 +532,8 @@
 		<string name="restore_part_count">{1} bölüm geri yükleniyor...</string>
 		<string name="total_restore_size">Toplam geri yükleme boyutu {1}MB</string>
 		<string name="updating_system_details">Sistem Ayrıntıları Güncelleniyor</string>
-		<string name="restore_completed">[GERİ YÜKLEME {1} SANİYE İÇİNDE TAMAMLANDI]</string>
+		<string name="restore_completed">[GERİ YÜKLEME {1} SANİYEDE TAMAMLANDI]</string>
+		<!-- {1} is the path we could not open, {2} is strerror output -->
 		<string name="error_opening_strerr">Açma hatası: \'{1}\' ({2})</string>
 		<string name="unable_locate_part_backup_name">Bölüm yedek adına göre bulunamadı: \'{1}\'</string>
 		<string name="unable_find_part_path">\'{1}\' yolu için bölüm bulunamıyor</string>
@@ -501,13 +544,14 @@
 		<string name="dalvik_done">-- Dalvik Önbelleği Dizinleri Temizleme Tamamlandı!</string>
 		<string name="no_andsec">Android secure bölümü yok.</string>
 		<string name="unable_to_locate">{1} bulunamıyor.</string>
-		<string name="wiping_datamedia">Dahili depolama temizleniyor -- /veri/ortam...</string>
+		<string name="wiping_datamedia">Dahili depolama temizleniyor -- /data/media...</string>
 		<string name="unable_to_mount">{1} bağlanamadı</string>
 		<string name="unable_to_mount_internal">Dahili depolama bağlanamadı</string>
 		<string name="unable_to_mount_storage">Depolama bağlanamadı</string>
 		<string name="fail_decrypt">Verilerin şifresi çözülemedi.</string>
 		<string name="no_crypto_support">Şifreleme desteği bu yapı içine derlenmemiştir.</string>
-		<string name="decrypt_success_dev">Veri başarıyla deşifre edildi, yeni blok aygıtı: \'{1}\'</string>
+		<string name="decrypt_success_dev">Veri başarıyla çözüldü, yeni blok aygıtı: '{1}'</string>
+		<string name="decrypt_success_nodev">Veri başarıyla çözüldü</string>
 		<string name="done">Bitti.</string>
 		<string name="start_partition_sd">SD Kart Bölümleniyor...</string>
 		<string name="partition_sd_locate">Bölümlenecek cihaz bulunamadı.</string>
@@ -516,7 +560,7 @@
 		<string name="unable_rm_part">Bölüm tablosu kaldırılamadı.</string>
 		<string name="create_part">{1} bölümü oluşturuluyor...</string>
 		<string name="unable_to_create_part">{1} bölümü oluşturulamadı.</string>
-		<string name="format_sdext_as">Sd-ext, {1} olarak biçimlendiriliyor...</string>
+		<string name="format_sdext_as">Harici SD, {1} olarak biçimlendiriliyor...</string>
 		<string name="part_complete">Bölümleme tamamlandı.</string>
 		<string name="unable_to_open">\'{1}\' açılamadı.</string>
 		<string name="mtp_already_enabled">MTP zaten etkin</string>
@@ -533,18 +577,121 @@
 		<string name="repair_not_exist">{1} yok! Onarılamıyor!</string>
 		<string name="repairing_using">{2} kullanılarak {1} onarılıyor...</string>
 		<string name="unable_repair">{1} onarılamıyor.</string>
+		<string name="mount_data_footer">/data bağlanamadı ve kripto altbilgisi bulunamadı.</string>
+		<!-- {1} is the folder name that we could not create, {2} is strerror output -->
 		<string name="create_folder_strerr">\'{1}\' klasörü oluşturulamıyor ({2}).</string>
 		<string name="fail_mount">\'{1}\' bağlanamıyor ({2})</string>
 		<string name="fail_unmount">\'{1}\' çıkarılamıyor ({2})</string>
 		<string name="cannot_resize">{1} yeniden boyutlandırılamıyor.</string>
 		<string name="repair_resize">Yeniden boyutlandırmadan önce {1} onarılıyor.</string>
 		<string name="unable_resize">{1} yeniden boyutlandırılamıyor.</string>
+		<string name="no_digest_found" version="2">'{1}' için hiçbir digest dosyası bulunamadı. Geri yüklemek için Digest doğrulamasını etkinleştir seçeneğinin işaretini kaldırın.</string>
+		<string name="digest_fail_match" version="2">'{1}' ile digest eşleşmedi.</string>
+		<string name="digest_matched" version="2">'{1}' için digest eşleşti.</string>
+		<string name="fail_decrypt_tar">'{1}' tar dosyasının şifresini çözmek başarısız oldu</string>
+		<string name="format_data_msg">/data'yı tekrar kullanabilmek için recovery'yi yeniden başlatmanız gerekebilir.</string>
+		<string name="format_data_err">Şifrelemeyi kaldırmak için biçimlendirme yapılamıyor.</string>
 		<string name="formatting_using">{2} kullanılarak {1} biçimlendiriliyor...</string>
 		<string name="unable_to_wipe">{1} temizlenemiyor.</string>
 		<string name="cannot_wipe">{1} bölümü temizlenemiyor.</string>
 		<string name="remove_all">\'{1}\' altındaki tüm dosyalar kaldırılıyor</string>
 		<string name="wiping_data">/data/media temizlenmeden data temizleniyor ...</string>
 		<string name="backing_up">{1} yedekleniyor...</string>
+		<string name="backup_storage_warning">{1} yedekleri dahili depolama biriminde resim veya indirme gibi herhangi bir dosya içermiyor.</string>
+		<string name="backing">Yedekleme</string>
+		<string name="backup_size">'{1}' için yedek dosyası boyutu 0 bayt.</string>
+		<string name="datamedia_fs_restore">UYARI: Bu /data yedekleme {1} dosya sistemi ile yapıldı! {1} olarak değiştirilmedikçe yedekleme önyükleme yapmayabilir.</string>
+		<string name="restoring">{1} geri yükleniyor...</string>
+		<string name="restoring_hdr">Geri yükleniyor</string>
+		<string name="recreate_folder_err">{1} klasörü yeniden oluşturulamadı.</string>
+		<string name="img_size_err">İmaj boyutu hedef cihazdan daha büyük</string>
+		<string name="flashing">{1} flashlanıyor...</string>
+		<string name="backup_folder_set">Yedekleme klasörü '{1}' olarak ayarlandı</string>
+		<string name="locate_backup_err">'{1}' yedeği bulunamadı</string>
+		<string name="set_restore_opt">Geri yükleme seçeneklerini ayarlama: '{1}':</string>
+		<string name="digest_check_skip" version="2">Digest denetimini atlama açık</string>
+		<string name="ors_encrypt_restore_err">Şifrelenmiş bir yedeklemeyi geri yüklemek için OpenRecoveryScript kullanılamıyor.</string>
+		<string name="mounting">Bağlanıyor</string>
+		<string name="unmounting">Kaldırılıyor</string>
+		<string name="mounted">'{1}' bağlandı</string>
+		<string name="unmounted">'{1}' kaldırıldı</string>
+		<string name="setting">'{2}' '{1}' olarak ayarlı</string>
+		<string name="setting_empty">'{1}' boş olarak ayarlı</string>
+		<string name="making_dir1">Dizin Oluşturuluyor</string>
+		<string name="making_dir2">Dizin oluşturuluyor: '{1}'</string>
+		<string name="running_command">Komut Çalıştırılıyor</string>
+		<string name="sideload">ADB Sideload</string>
+		<string name="start_sideload">ADB sideload  özelliği başlatılıyor...</string>
+		<string name="need_new_adb">Bu cihaza sideload eklemek için adb 1.0.32 veya daha yenisine ihtiyacınız var.</string>
+		<string name="no_pwd">Parola sağlanmadı.</string>
+		<string name="done_ors">Komut dosyası işleme tamamlandı</string>
+		<string name="injecttwrp">TWRP boot imajına ekleniyor...</string>
+		<string name="zip_err">'{1}' zip dosyası yüklenemiyor</string>
+		<string name="installing_zip">'{1}' zip dosyası yükleniyor</string>
+		<string name="select_backup_opt">Yedekleme seçeneklerini ayarlama:</string>
+		<string name="compression_on">Sıkıştırma açık</string>
+		<string name="digest_off" version="2">Digest Oluşturma kapalı</string>
+		<string name="backup_fail">Yedekleme Başarısız</string>
+		<string name="backup_clean">Yedekleme Başarısız Oldu. Yedekleme Klasörü Temizleniyor.</string>
+		<string name="running_recovery_commands">Recovery Komutları Çalıştırılıyor</string>
+		<string name="recovery_commands_complete">Recovery Komutları Tamamlandı</string>
+		<string name="running_ors">OpenRecoveryScript Çalıştırılıyor</string>
+		<string name="ors_complete">OpenRecoveryScript Tamamlandı</string>
+		<string name="check_for_digest" version="2">Digest dosyası denetleniyor...</string>
+		<string name="invalid_zip_format">Geçersiz zip dosyası biçimi!</string>
+		<string name="fail_sysmap">'{1}' dosyası eşleştirilemedi</string>
+		<string name="verify_zip_sig">Zip imzası doğrulanıyor....</string>
+		<string name="verify_zip_fail">Zip imzası doğrulama başarısız oldu!</string>
+		<string name="verify_zip_done">Zip imzası başarıyla doğrulandı.</string>
+		<string name="zip_corrupt">Zip dosyası bozuk!</string>
+		<string name="no_digest" version="2">Digest denetimi geçiliyor: Digest dosyası bulunamadı</string>
+		<string name="digest_fail" version="2">Digest eşleşmiyor</string>
+		<string name="digest_match" version="2">Digest eşleşti</string>
+		<string name="pid_signal">{1} process ended with signal: {2}</string>
+		<string name="pid_error">{1} process ended with ERROR: {2}</string>
+		<string name="install_dumlock">HTC Dumlock sisteme yükleniyor...</string>
+		<string name="dumlock_restore">Boot geri yükleniyor...</string>
+		<string name="dumlock_reflash">Boot için recovery yeniden flashlanıyor...</string>
+		<string name="run_script">{1} komut dosyası çalıştırılıyor...</string>
+		<string name="rename_stock">Stok ROM'un TWRP'yi değiştirmesini önlemek için /systemde stok kurtarma dosyası yeniden adlandırıldı.</string>
+		<string name="split_backup">Yedek dosyayı birden fazla arşiv haline getirme...</string>
+		<string name="backup_error">Yedekleme hatası oluştu.</string>
+		<string name="restore_error">Geri yükleme işlemi sırasında hata oluştu.</string>
+		<string name="split_thread">{1} İş parçacığı kimliğini, {2} arşiv olarak bölüyor.</string>
+		<!-- These 2 items are saved in the data manager instead of resource manager, so %llu, etc is correct instead of {1} -->
+		<string name="file_progress">%llu / %llu dosya, %i%%</string>
+		<string name="size_progress">%lluMB / %lluMB, %i%%</string>
+		<string name="decrypt_cmd">Komut satırıyla veri bölümünün şifresi çözmeye çalışılıyor.</string>
+		<string name="base_pkg_err">Temel paketler yüklenemedi.</string>
+		<string name="simulating">Eylemler taklit ediliyor...</string>
 		<string name="backup_cancel">Yedekleme İptal Edildi</string>
+		<string name="config_twrp">TWRP'yi yapılandırma...</string>
+		<string name="config_twrp_err">Bu kernel ile TWRP yapılandırılamadı.</string>
+		<string name="copy_log">Recovery kaydı şuraya kopyalandı: {1}.</string>
+		<string name="max_queue">Maksimum zip kuyruğuna ulaşıldı!</string>
+		<string name="min_queue">Minimum zip kuyruğuna ulaşıldı!</string>
+		<string name="screenshot_saved">Ekran görüntüsü şuraya kaydedildi: {1}</string>
+		<string name="screenshot_err">Ekran görüntüsü alınamadı!</string>
+		<string name="zip_wipe_cache">Bir veya daha fazla zip, bir önbellek silme isteğinde bulundu - Şimdi önbellek siliniyor.</string>
+		<string name="and_sec_wipe_err">Android secure silinemez</string>
+		<string name="dalvik_wipe_err">Dalvik silinemedi</string>
+		<string name="auto_gen">(Otomatik Oluştur)</string>
+		<string name="curr_date">(Geçerli Tarih)</string>
+		<string name="backup_name_len">Yedekleme adı çok uzun.</string>
+		<string name="backup_name_invalid">'{1}' yedek adı geçersiz karakter içeriyor: '{1}'</string>
+		<string name="no_real_sdcard">Bu cihazın gerçek bir SD kartı yok! İptal ediliyor!</string>
+		<string name="cancel_sideload">ADB sideload iptal ediliyor...</string>
+		<string name="change_fs_err">Dosya sistemi değiştirilemiyor.</string>
+		<string name="theme_ver_err">Özel tema sürümü TWRP sürümü ile eşleşmiyor. Stok tema kullanılıyor.</string>
+		<string name="up_a_level">(Üst Dizin)</string>
+		<string name="install_reboot" version="2">%tw_sleep% saniye içinde yeniden başlatılıyor</string>
+		<string name="adbbackup_error">ADB Yedekleme Hatası. Çıkılıyor..."</string>
+		<string name="adbbackup_control_error">Adb kontrol kanalına yazılamıyor</string>
+		<string name="twrp_adbbu_option">--twrp adb yedeklemeyi etkinleştirmek için twrp seçeneği gerekiyor</string>
+		<string name="partition_not_found">yol: {1} bölüm listesinde bulunamadı</string>
+		<string name="copy_kernel_log">Kernel kaydı şuraya kopyalandı: {1}</string>
+		<string name="include_kernel_log">Kernel Kaydını Dahil Et</string>
+		<string name="sha2_chk">Hash için SHA2 kullan</string>
+		<string name="unable_set_boot_slot">Önyükleyici önyükleme yuvasını {1} olarak değiştiremiyor</string>
 	</resources>
 </language>
diff --git a/install.cpp b/install.cpp
index 7fbf5c0..4848755 100644
--- a/install.cpp
+++ b/install.cpp
@@ -178,28 +178,6 @@
     return INSTALL_ERROR;
   }
 
-  // Check for downgrade version.
-  int64_t build_timestamp =
-      android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
-  int64_t pkg_post_timestamp = 0;
-  // We allow to full update to the same version we are running, in case there
-  // is a problem with the current copy of that version.
-  if (metadata["post-timestamp"].empty() ||
-      !android::base::ParseInt(metadata["post-timestamp"].c_str(), &pkg_post_timestamp) ||
-      pkg_post_timestamp < build_timestamp) {
-    if (metadata["ota-downgrade"] != "yes") {
-      LOG(ERROR) << "Update package is older than the current build, expected a build "
-                    "newer than timestamp "
-                 << build_timestamp << " but package has timestamp " << pkg_post_timestamp
-                 << " and downgrade not allowed.";
-      return INSTALL_ERROR;
-    }
-    if (pkg_pre_build_fingerprint.empty()) {
-      LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
-      return INSTALL_ERROR;
-    }
-  }
-
   return 0;
 }
 
diff --git a/installcommand.cpp b/installcommand.cpp
index f9978f2..b306e87 100644
--- a/installcommand.cpp
+++ b/installcommand.cpp
@@ -159,30 +159,6 @@
         return INSTALL_ERROR;
     }
 
-    // Check for downgrade version.
-    int64_t build_timestampt = property_get_int64(
-            "ro.build.date.utc", std::numeric_limits<int64_t>::max());
-    int64_t pkg_post_timespampt = 0;
-    // We allow to full update to the same version we are running, in case there
-    // is a problem with the current copy of that version.
-    if (metadata["post-timestamp"].empty() ||
-        !android::base::ParseInt(metadata["post-timestamp"].c_str(),
-                                 &pkg_post_timespampt) ||
-        pkg_post_timespampt < build_timestampt) {
-        if (metadata["ota-downgrade"] != "yes") {
-            printf("Update package is older than the current build, expected a "
-                 "build newer than timestamp %" PRIu64 " but package has "
-                 "timestamp %" PRIu64 " and downgrade not allowed.\n",
-                 build_timestampt, pkg_post_timespampt);
-            return INSTALL_ERROR;
-        }
-        if (pkg_pre_build_fingerprint.empty()) {
-            printf("Downgrade package must have a pre-build version set, not "
-                 "allowed.\n");
-            return INSTALL_ERROR;
-        }
-    }
-
     return 0;
 }
 
diff --git a/minuitwrp/Android.mk b/minuitwrp/Android.mk
index 3f83c97..09bdb8d 100644
--- a/minuitwrp/Android.mk
+++ b/minuitwrp/Android.mk
@@ -48,7 +48,11 @@
 ifneq ($(wildcard external/libdrm/Android.mk),)
   LOCAL_CFLAGS += -DHAS_DRM
   LOCAL_SRC_FILES += graphics_drm.cpp
-  LOCAL_WHOLE_STATIC_LIBRARIES += libdrm
+  ifneq ($(wildcard external/libdrm/Android.common.mk),)
+    LOCAL_WHOLE_STATIC_LIBRARIES += libdrm_platform
+  else
+    LOCAL_WHOLE_STATIC_LIBRARIES += libdrm
+  endif
 endif
 
 LOCAL_C_INCLUDES += \
diff --git a/otautil/Android.mk b/otautil/Android.mk
index f7ca9a9..45e0f76 100644
--- a/otautil/Android.mk
+++ b/otautil/Android.mk
@@ -25,6 +25,12 @@
     libselinux \
     libbase
 
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -gt 26; echo $$?),0)
+# Android 8.1 header
+LOCAL_C_INCLUDES += \
+    system/core/libziparchive/include
+endif
+
 LOCAL_MODULE := libotautil
 LOCAL_CFLAGS := \
     -Werror \
diff --git a/partition.cpp b/partition.cpp
index 3957c65..59bd168 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -581,6 +581,18 @@
 			Process_TW_Flags(flagptr, Display_Error, 1); // Forcing the fstab to ver 1 because this data is coming from the /etc/twrp.flags which should be using the TWRP v1 flags format
 		}
 	}
+
+	if (Mount_Point == "/persist" && Can_Be_Mounted) {
+		bool mounted = Is_Mounted();
+		if (mounted || Mount(false)) {
+			// Read the backup settings file
+			DataManager::LoadPersistValues();
+			TWFunc::Fixup_Time_On_Boot("/persist/time/");
+			if (!mounted)
+				UnMount(false);
+		}
+	}
+
 	return true;
 }
 
diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk
index 7b950fc..b54dda2 100644
--- a/prebuilt/Android.mk
+++ b/prebuilt/Android.mk
@@ -34,6 +34,9 @@
 RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/fsck.fat
 RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/fatlabel
 RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/mkfs.fat
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 27; echo $$?),0)
+    RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/adbd
+endif
 RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/e2fsck
 RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/mke2fs
 RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/tune2fs
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 5df44c6..b7bcebe 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -881,9 +881,12 @@
 	}
 }
 
-void TWFunc::Fixup_Time_On_Boot()
+void TWFunc::Fixup_Time_On_Boot(const string& time_paths /* = "" */)
 {
 #ifdef QCOM_RTC_FIX
+	static bool fixed = false;
+	if (fixed)
+		return;
 
 	LOGINFO("TWFunc::Fixup_Time: Pre-fix date and time: %s\n", TWFunc::Get_Current_Date().c_str());
 
@@ -904,6 +907,7 @@
 		if (tv.tv_sec > 1405209403) { // Anything older then 12 Jul 2014 23:56:43 GMT will do nicely thank you ;)
 
 			LOGINFO("TWFunc::Fixup_Time: Date and time corrected: %s\n", TWFunc::Get_Current_Date().c_str());
+			fixed = true;
 			return;
 
 		}
@@ -925,22 +929,28 @@
 	// Like, ats_1 is for modem and ats_2 is for TOD (time of day?).
 	// Look at file time_genoff.h in CodeAurora, qcom-opensource/time-services
 
-	static const char *paths[] = { "/data/system/time/", "/data/time/"  };
+	std::vector<std::string> paths; // space separated list of paths
+	if (time_paths.empty()) {
+		paths = Split_String("/data/system/time/ /data/time/", " ");
+		if (!PartitionManager.Mount_By_Path("/data", false))
+			return;
+	} else {
+		// When specific path(s) are used, Fixup_Time needs those
+		// partitions to already be mounted!
+		paths = Split_String(time_paths, " ");
+	}
 
 	FILE *f;
 	offset = 0;
 	struct dirent *dt;
 	std::string ats_path;
 
-	if (!PartitionManager.Mount_By_Path("/data", false))
-		return;
-
 	// Prefer ats_2, it seems to be the one we want according to logcat on hammerhead
 	// - it is the one for ATS_TOD (time of day?).
 	// However, I never saw a device where the offset differs between ats files.
-	for (size_t i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i)
+	for (size_t i = 0; i < paths.size(); ++i)
 	{
-		DIR *d = opendir(paths[i]);
+		DIR *d = opendir(paths[i].c_str());
 		if (!d)
 			continue;
 
@@ -950,34 +960,38 @@
 				continue;
 
 			if (ats_path.empty() || strcmp(dt->d_name, "ats_2") == 0)
-				ats_path = std::string(paths[i]).append(dt->d_name);
+				ats_path = paths[i] + dt->d_name;
 		}
 
 		closedir(d);
 	}
 
-	if (ats_path.empty())
-	{
+	if (ats_path.empty()) {
 		LOGINFO("TWFunc::Fixup_Time: no ats files found, leaving untouched!\n");
-		return;
-	}
-
-	f = fopen(ats_path.c_str(), "r");
-	if (!f)
-	{
+	} else if ((f = fopen(ats_path.c_str(), "r")) == NULL) {
 		LOGINFO("TWFunc::Fixup_Time: failed to open file %s\n", ats_path.c_str());
-		return;
-	}
-
-	if (fread(&offset, sizeof(offset), 1, f) != 1)
-	{
+	} else if (fread(&offset, sizeof(offset), 1, f) != 1) {
 		LOGINFO("TWFunc::Fixup_Time: failed load uint64 from file %s\n", ats_path.c_str());
 		fclose(f);
-		return;
-	}
-	fclose(f);
+	} else {
+		fclose(f);
 
-	LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s, offset %llu\n", ats_path.c_str(), offset);
+		LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s, offset %llu\n", ats_path.c_str(), (unsigned long long) offset);
+		DataManager::SetValue("tw_qcom_ats_offset", (unsigned long long) offset, 1);
+		fixed = true;
+	}
+
+	if (!fixed) {
+		// Failed to get offset from ats file, check twrp settings
+		unsigned long long value;
+		if (DataManager::GetValue("tw_qcom_ats_offset", value) < 0) {
+			return;
+		} else {
+			offset = (uint64_t) value;
+			LOGINFO("TWFunc::Fixup_Time: Setting time offset from twrp setting file, offset %llu\n", (unsigned long long) offset);
+			// Do not consider the settings file as a definitive answer, keep fixed=false so next run will try ats files again
+		}
+	}
 
 	gettimeofday(&tv, NULL);
 
@@ -993,7 +1007,6 @@
 	settimeofday(&tv, NULL);
 
 	LOGINFO("TWFunc::Fixup_Time: Date and time corrected: %s\n", TWFunc::Get_Current_Date().c_str());
-
 #endif
 }
 
diff --git a/twrp-functions.hpp b/twrp-functions.hpp
index 9c149ea..a1f67f2 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -88,7 +88,7 @@
 	static string System_Property_Get(string Prop_Name);                // Returns value of Prop_Name from reading /system/build.prop
 	static string Get_Current_Date(void);                               // Returns the current date in ccyy-m-dd--hh-nn-ss format
 	static void Auto_Generate_Backup_Name();                            // Populates TW_BACKUP_NAME with a backup name based on current date and ro.build.display.id from /system/build.prop
-	static void Fixup_Time_On_Boot(); // Fixes time on devices which need it
+	static void Fixup_Time_On_Boot(const string& time_paths = ""); // Fixes time on devices which need it (time_paths is a space separated list of paths to check for ats_* files)
 	static std::vector<std::string> Split_String(const std::string& str, const std::string& delimiter, bool removeEmpty = true); // Splits string by delimiter
 	static bool Create_Dir_Recursive(const std::string& path, mode_t mode = 0755, uid_t uid = -1, gid_t gid = -1);  // Create directory and it's parents, if they don't exist. mode, uid and gid are set to all _newly_ created folders. If whole path exists, do nothing.
 	static int Set_Brightness(std::string brightness_value); // Well, you can read, it does what it says, passing return int from TWFunc::Write_File ;)
diff --git a/twrp.cpp b/twrp.cpp
index 8c2a24f..f72d691 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -116,17 +116,13 @@
 	gui_init();
 	printf("=> Linking mtab\n");
 	symlink("/proc/mounts", "/etc/mtab");
-	if (TWFunc::Path_Exists("/etc/twrp.fstab")) {
-		if (TWFunc::Path_Exists("/etc/recovery.fstab")) {
-			printf("Renaming regular /etc/recovery.fstab -> /etc/recovery.fstab.bak\n");
-			rename("/etc/recovery.fstab", "/etc/recovery.fstab.bak");
-		}
-		printf("Moving /etc/twrp.fstab -> /etc/recovery.fstab\n");
-		rename("/etc/twrp.fstab", "/etc/recovery.fstab");
+	std::string fstab_filename = "/etc/twrp.fstab";
+	if (!TWFunc::Path_Exists(fstab_filename)) {
+		fstab_filename = "/etc/recovery.fstab";
 	}
-	printf("=> Processing recovery.fstab\n");
-	if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) {
-		LOGERR("Failing out of recovery due to problem with recovery.fstab.\n");
+	printf("=> Processing %s\n", fstab_filename.c_str());
+	if (!PartitionManager.Process_Fstab(fstab_filename, 1)) {
+		LOGERR("Failing out of recovery due to problem with fstab.\n");
 		return -1;
 	}
 	PartitionManager.Output_Partition_Logging();