From a1e980d10343356a72de01cb7fba2993673ed8c2 Mon Sep 17 00:00:00 2001
From: Valere <valeref@matrix.org>
Date: Fri, 29 Apr 2022 10:37:53 +0200
Subject: [PATCH] fix doing password stretching on main thread

---
 changelog.d/5871.bugfix                                |  1 +
 .../secrets/DefaultSharedSecretStorageService.kt       | 10 +++++-----
 2 files changed, 6 insertions(+), 5 deletions(-)
 create mode 100644 changelog.d/5871.bugfix

diff --git a/changelog.d/5871.bugfix b/changelog.d/5871.bugfix
new file mode 100644
index 0000000000..b223ddd141
--- /dev/null
+++ b/changelog.d/5871.bugfix
@@ -0,0 +1 @@
+Fix UX freezing when creating secure backup
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
index 972c03e92a..8c877593e7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
@@ -66,7 +66,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
                                      key: SsssKeySpec?,
                                      keyName: String,
                                      keySigner: KeySigner?): SsssKeyCreationInfo {
-        return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.main) {
+        return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
             val bytes = (key as? RawBytesKeySpec)?.privateKey
                     ?: ByteArray(32).also {
                         SecureRandom().nextBytes(it)
@@ -99,7 +99,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
                                                    passphrase: String,
                                                    keySigner: KeySigner,
                                                    progressListener: ProgressListener?): SsssKeyCreationInfo {
-        return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.main) {
+        return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
             val privatePart = generatePrivateKeyWithPassword(passphrase, progressListener)
 
             val storageKeyContent = SecretStorageKeyContent(
@@ -158,7 +158,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
     }
 
     override suspend fun storeSecret(name: String, secretBase64: String, keys: List<SharedSecretStorageService.KeyRef>) {
-        withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.main) {
+        withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
             val encryptedContents = HashMap<String, EncryptedSecretContent>()
             keys.forEach {
                 val keyId = it.keyId
@@ -316,7 +316,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
         val algorithm = key.keyInfo.content
         if (SSSS_ALGORITHM_CURVE25519_AES_SHA2 == algorithm.algorithm) {
             val keySpec = secretKey as? RawBytesKeySpec ?: throw SharedSecretStorageError.BadKeyFormat
-            return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.main) {
+            return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
                 // decrypt from recovery key
                 withOlmDecryption { olmPkDecryption ->
                     olmPkDecryption.setPrivateKey(keySpec.privateKey)
@@ -331,7 +331,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
             }
         } else if (SSSS_ALGORITHM_AES_HMAC_SHA2 == algorithm.algorithm) {
             val keySpec = secretKey as? RawBytesKeySpec ?: throw SharedSecretStorageError.BadKeyFormat
-            return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.main) {
+            return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
                 decryptAesHmacSha2(keySpec, name, secretContent)
             }
         } else {