summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/ext4crypt/Android.mk12
-rw-r--r--crypto/ext4crypt/Decrypt.cpp720
-rw-r--r--crypto/ext4crypt/HashPassword.h2
-rw-r--r--crypto/ext4crypt/Keymaster.h1
-rw-r--r--crypto/ext4crypt/keystore_auth.cpp90
-rw-r--r--data.cpp53
-rw-r--r--data.hpp5
-rw-r--r--gui/theme/common/languages/cz.xml2
-rw-r--r--gui/theme/common/languages/de.xml2
-rw-r--r--gui/theme/common/languages/el.xml2
-rw-r--r--gui/theme/common/languages/fr.xml8
-rw-r--r--gui/theme/common/languages/it.xml4
-rw-r--r--gui/theme/common/languages/nl.xml26
-rw-r--r--gui/theme/common/languages/pl.xml2
-rw-r--r--gui/theme/common/languages/pt_BR.xml4
-rw-r--r--gui/theme/common/languages/pt_PT.xml698
-rw-r--r--gui/theme/common/languages/sv.xml3
-rw-r--r--gui/theme/common/languages/tr.xml301
-rw-r--r--install.cpp22
-rw-r--r--installcommand.cpp24
-rw-r--r--minuitwrp/Android.mk6
-rw-r--r--otautil/Android.mk6
-rw-r--r--partition.cpp12
-rw-r--r--prebuilt/Android.mk3
-rw-r--r--twrp-functions.cpp63
-rw-r--r--twrp-functions.hpp2
-rw-r--r--twrp.cpp16
27 files changed, 1695 insertions, 394 deletions
diff --git a/crypto/ext4crypt/Android.mk b/crypto/ext4crypt/Android.mk
index af5ab3af0..693b67518 100644
--- a/crypto/ext4crypt/Android.mk
+++ b/crypto/ext4crypt/Android.mk
@@ -28,6 +28,7 @@ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26; echo $$?),0)
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 @@ LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker64
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 2dab16646..c062f8ae4 100644
--- a/crypto/ext4crypt/Decrypt.cpp
+++ b/crypto/ext4crypt/Decrypt.cpp
@@ -287,10 +287,27 @@ bool Get_Password_Data(const std::string& spblob_path, const std::string& handle
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 @@ sp<IBinder> getKeystoreBinderRetry() {
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 @@ bool Find_Keystore_Alias_SubID_And_Prep_Files(const userid_t user_id, std::strin
/* 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 @@ std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const st
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 @@ std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const st
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");
- 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);
+ 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 {
- //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);
+ } 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;
- } else {
- //printf("keystore finish operation successful\n");
}
- stop_keystore();
return disk_decryption_secret_key;
}
@@ -677,11 +883,40 @@ std::string unwrapSyntheticPasswordBlob(const std::string& spblob_path, const st
#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 @@ bool Decrypt_User_Synth_Pass(const userid_t user_id, const std::string& Password
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 @@ bool Decrypt_User_Synth_Pass(const userid_t user_id, const std::string& Password
// 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 @@ bool Decrypt_User_Synth_Pass(const userid_t user_id, const std::string& Password
// 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("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
+ 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);
+ }
+ }
// 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 8abd0de71..4be107b51 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/Keymaster.h b/crypto/ext4crypt/Keymaster.h
index 11b3532ad..bd3f21985 100644
--- a/crypto/ext4crypt/Keymaster.h
+++ b/crypto/ext4crypt/Keymaster.h
@@ -22,6 +22,7 @@
#include <utility>
#include <keymaster/authorization_set.h>
+#include "Utils.h"
namespace android {
namespace vold {
diff --git a/crypto/ext4crypt/keystore_auth.cpp b/crypto/ext4crypt/keystore_auth.cpp
new file mode 100644
index 000000000..7d6eb24bf
--- /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 599b5c0d8..4dfbde2d0 100644
--- a/data.cpp
+++ b/data.cpp
@@ -230,7 +230,7 @@ int DataManager::ResetDefaults()
int DataManager::LoadValues(const string& filename)
{
- string str, dev_id;
+ string dev_id;
if (!mInitialized)
SetDefaultValues();
@@ -263,6 +263,44 @@ int DataManager::LoadValues(const string& filename)
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::Flush()
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 @@ int DataManager::SaveValues()
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 @@ int DataManager::GetValue(const string& varName, float& value)
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 790efc993..d61fe8e7c 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 @@ class DataManager
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 bb9fff930..479562217 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 9d953a784..e629ec37d 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 2af1a8ff6..271b08721 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 9768a6ab2..80e781a62 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 57cbe9ae0..71f7636b3 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 d4dd7bfee..e716a91a3 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 46fe43de2..77a6aa84f 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 7e301f157..fa7fa099f 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 000000000..1244f9b7d
--- /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 73a6e4581..076ee0b5e 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 4c3ee2cc7..f585adf04 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 7fbf5c01f..4848755ab 100644
--- a/install.cpp
+++ b/install.cpp
@@ -178,28 +178,6 @@ static int check_newer_ab_build(ZipArchiveHandle zip) {
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 f9978f27b..b306e872f 100644
--- a/installcommand.cpp
+++ b/installcommand.cpp
@@ -159,30 +159,6 @@ static int check_newer_ab_build(ZipWrap* zip)
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 3f83c9754..09bdb8d48 100644
--- a/minuitwrp/Android.mk
+++ b/minuitwrp/Android.mk
@@ -48,7 +48,11 @@ endif
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 f7ca9a9ee..45e0f765d 100644
--- a/otautil/Android.mk
+++ b/otautil/Android.mk
@@ -25,6 +25,12 @@ LOCAL_STATIC_LIBRARIES := \
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 3957c6542..59bd16831 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -581,6 +581,18 @@ bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error,
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 7b950fcef..b54dda288 100644
--- a/prebuilt/Android.mk
+++ b/prebuilt/Android.mk
@@ -34,6 +34,9 @@ RELINK_SOURCE_FILES += $(TARGET_RECOVERY_ROOT_OUT)/sbin/pigz
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 5df44c69a..b7bcebe2d 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -881,9 +881,12 @@ void TWFunc::Auto_Generate_Backup_Name() {
}
}
-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 @@ void TWFunc::Fixup_Time_On_Boot()
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 @@ void TWFunc::Fixup_Time_On_Boot()
// 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 @@ void TWFunc::Fixup_Time_On_Boot()
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;
+ } else {
+ fclose(f);
+
+ 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;
}
- fclose(f);
- LOGINFO("TWFunc::Fixup_Time: Setting time offset from file %s, offset %llu\n", ats_path.c_str(), offset);
+ 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 @@ void TWFunc::Fixup_Time_On_Boot()
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 9c149ea18..a1f67f237 100644
--- a/twrp-functions.hpp
+++ b/twrp-functions.hpp
@@ -88,7 +88,7 @@ public:
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 8c2a24f22..f72d691e8 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -116,17 +116,13 @@ int main(int argc, char **argv) {
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();