diff --git a/Duplicati/Library/Encryption/AESEncryption.cs b/Duplicati/Library/Encryption/AESEncryption.cs index 84f415589..a31cc2546 100644 --- a/Duplicati/Library/Encryption/AESEncryption.cs +++ b/Duplicati/Library/Encryption/AESEncryption.cs @@ -31,6 +31,12 @@ namespace Duplicati.Library.Encryption /// public class AESEncryption : EncryptionBase { + + /// + /// The commandline option supplied if an explicit thread level should be set (--aes-set-threadlevel) + /// + private const string COMMANDLINE_SET_THREADLEVEL = "aes-set-threadlevel"; + /// /// The key used to encrypt the data /// @@ -41,6 +47,11 @@ namespace Duplicati.Library.Encryption /// private static long m_cachedsizeoverhead = -1; + /// + /// The thread level to pass to SharpAESCrypt. 0 for default. + /// + private static int m_usethreadlevel = 0; + /// /// Default constructor, used to read file extension and supported commands /// @@ -56,8 +67,22 @@ namespace Duplicati.Library.Encryption { if(string.IsNullOrEmpty(passphrase)) throw new ArgumentException(Strings.AESEncryption.EmptyKeyError, "passphrase"); - + m_key = passphrase; + + string strTL; + if (options != null && options.TryGetValue(COMMANDLINE_SET_THREADLEVEL, out strTL)) + { + int useTL; + if (int.TryParse(strTL, out useTL)) + { + // finally set thread level in a range of 0 (default) to 4 + m_usethreadlevel = Math.Max(0, (Math.Min(4, useTL))); + } + } + + + } #region IEncryption Members @@ -107,7 +132,9 @@ namespace Duplicati.Library.Encryption /// An encrypted stream that can be written to public override Stream Encrypt(Stream input) { - return new SharpAESCrypt.SharpAESCrypt(m_key, input, SharpAESCrypt.OperationMode.Encrypt); + var cryptoStream = new SharpAESCrypt.SharpAESCrypt(m_key, input, SharpAESCrypt.OperationMode.Encrypt); + if (m_usethreadlevel != 0) cryptoStream.MaxCryptoThreads = m_usethreadlevel; + return cryptoStream; } /// @@ -117,7 +144,9 @@ namespace Duplicati.Library.Encryption /// The unencrypted stream public override Stream Decrypt(Stream input) { - return new SharpAESCrypt.SharpAESCrypt(m_key, input, SharpAESCrypt.OperationMode.Decrypt); + var cryptoStream = new SharpAESCrypt.SharpAESCrypt(m_key, input, SharpAESCrypt.OperationMode.Decrypt); + if (m_usethreadlevel != 0) cryptoStream.MaxCryptoThreads = m_usethreadlevel; + return cryptoStream; } /// @@ -129,6 +158,7 @@ namespace Duplicati.Library.Encryption get { return new List(new ICommandLineArgument[] { + new CommandLineArgument(COMMANDLINE_SET_THREADLEVEL, CommandLineArgument.ArgumentType.String, Strings.AESEncryption.AessetthreadlevelShort, Strings.AESEncryption.AessetthreadlevelLong), }); } } diff --git a/Duplicati/Library/Encryption/Strings.cs b/Duplicati/Library/Encryption/Strings.cs index d17d85e46..cd08ad033 100644 --- a/Duplicati/Library/Encryption/Strings.cs +++ b/Duplicati/Library/Encryption/Strings.cs @@ -4,6 +4,8 @@ namespace Duplicati.Library.Encryption.Strings { public static string Description_v2 { get { return LC.L(@"This module encrypts all files in the same way that AESCrypt does, using 256 bit AES encryption."); } } public static string DisplayName { get { return LC.L(@"AES-256 encryption, built in"); } } public static string EmptyKeyError { get { return LC.L(@"Blank or empty passphrase not allowed"); } } + public static string AessetthreadlevelLong { get { return LC.L(@"Use this option to set the thread level allowed for AES crypt operations. Valid values are 0 (uses default), or from 1 (no multithreading) to 4 (max. multithreading)"); } } + public static string AessetthreadlevelShort { get { return LC.L(@"Set thread level utilized for crypting (0-4)"); } } } internal static class EncryptionBase { public static string DecryptionError(string message) { return LC.L(@"Failed to decrypt data (invalid passphrase?): {0}", message); }