diff --git a/src/KeePassLib2Android/Cryptography/KeyDerivation/AesKdf.cs b/src/KeePassLib2Android/Cryptography/KeyDerivation/AesKdf.cs index fcc7cda6..0b82f94e 100644 --- a/src/KeePassLib2Android/Cryptography/KeyDerivation/AesKdf.cs +++ b/src/KeePassLib2Android/Cryptography/KeyDerivation/AesKdf.cs @@ -122,7 +122,7 @@ namespace KeePassLib.Cryptography.KeyDerivation // Try to use the native library first if(NativeLib.TransformKey256(pbNewKey, pbKeySeed32, uNumRounds)) return CryptoUtil.HashSha256(pbNewKey); - + if(TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds)) return CryptoUtil.HashSha256(pbNewKey); } diff --git a/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs b/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs index e2c7c2b7..7dc0cfe0 100644 --- a/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs +++ b/src/Kp2aBusinessLogic/database/KdbDatabaseFormat.cs @@ -13,10 +13,10 @@ using Java.Util; using KeePassLib; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; +using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Interfaces; using KeePassLib.Keys; using KeePassLib.Security; -using Exception = System.Exception; using PwIcon = KeePassLib.PwIcon; using Random = System.Random; @@ -63,7 +63,10 @@ namespace keepass2android var dbv3 = importer.OpenDatabase(hashingStream, password, keyfileStream); db.Name = dbv3.Name; - db.KeyEncryptionRounds = (ulong) dbv3.NumKeyEncRounds; + db.KdfParameters = (new AesKdf()).GetDefaultParameters(); + db.KdfParameters.SetUInt64(AesKdf.ParamRounds, (ulong)dbv3.NumKeyEncRounds); + + db.RootGroup = ConvertGroup(dbv3.RootGroup); if (dbv3.Algorithm == PwEncryptionAlgorithm.Rjindal) { @@ -235,7 +238,20 @@ namespace keepass2android keyfileContents = new MemoryStream(keyfile.RawFileData.ReadData()); } db.SetMasterKey(password, keyfileContents); - db.NumRounds = (long) kpDatabase.KeyEncryptionRounds; + + AesKdf kdf = new AesKdf(); + if (!kdf.Uuid.Equals(kpDatabase.KdfParameters.KdfUuid)) + db.NumRounds = (uint)PwDefs.DefaultKeyEncryptionRounds; + else + { + ulong uRounds = kpDatabase.KdfParameters.GetUInt64( + AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds); + uRounds = Math.Min(uRounds, 0xFFFFFFFEUL); + + db.NumRounds = (uint)uRounds; + } + + db.Name = kpDatabase.Name; if (kpDatabase.DataCipherUuid.Equals(StandardAesEngine.AesUuid)) { diff --git a/src/Kp2aBusinessLogic/database/edit/CreateDB.cs b/src/Kp2aBusinessLogic/database/edit/CreateDB.cs index f599c7d0..f35df74c 100644 --- a/src/Kp2aBusinessLogic/database/edit/CreateDB.cs +++ b/src/Kp2aBusinessLogic/database/edit/CreateDB.cs @@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file using System.Collections.Generic; using Android.Content; using KeePassLib; +using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Serialization; using KeePassLib.Keys; @@ -65,7 +66,7 @@ namespace keepass2android db.KpDatabase.New(_ioc, _key); - db.KpDatabase.KeyEncryptionRounds = DefaultEncryptionRounds; + db.KpDatabase.KdfParameters = (new AesKdf()).GetDefaultParameters(); db.KpDatabase.Name = "Keepass2Android Password Database"; //re-set the name of the root group because the PwDatabase uses UrlUtil which is not appropriate for all file storages: db.KpDatabase.RootGroup.Name = _app.GetFileStorage(_ioc).GetFilenameWithoutPathAndExt(_ioc); diff --git a/src/keepass2android/addons/OtpKeyProv/OtpUtil.cs b/src/keepass2android/addons/OtpKeyProv/OtpUtil.cs index e2f79fd8..92026c6a 100644 --- a/src/keepass2android/addons/OtpKeyProv/OtpUtil.cs +++ b/src/keepass2android/addons/OtpKeyProv/OtpUtil.cs @@ -26,6 +26,7 @@ using System.Diagnostics; using KeePassLib.Cryptography; using KeePassLib.Cryptography.Cipher; +using KeePassLib.Cryptography.KeyDerivation; using KeePassLib.Keys; using KeePassLib.Utility; @@ -72,7 +73,7 @@ namespace OtpKeyProv Array.Copy(pbData, pbEnc, pbData.Length); Salsa20Cipher enc = new Salsa20Cipher(pbKey32, pbIV8); - enc.Encrypt(pbEnc, pbEnc.Length, true); + enc.Encrypt(pbEnc, 0, pbEnc.Length); return ("s20://" + Convert.ToBase64String(pbEnc, Base64FormattingOptions.None)); @@ -90,7 +91,7 @@ namespace OtpKeyProv Array.Copy(pbIV16, 0, pbIV8, 0, 8); Salsa20Cipher dec = new Salsa20Cipher(pbKey32, pbIV8); - dec.Encrypt(pb, pb.Length, true); + dec.Encrypt(pb, 0, pb.Length); return pb; } @@ -102,7 +103,7 @@ namespace OtpKeyProv byte[] pbHash = sha256.ComputeHash(pbData); sha256.Clear(); - if(!CompositeKey.TransformKeyManaged(pbHash, pbTrfKey32, uTrfRounds)) + if(!AesKdf.TransformKeyManaged(pbHash, pbTrfKey32, uTrfRounds)) return null; sha256 = new SHA256Managed(); diff --git a/src/keepass2android/settings/DatabaseSettingsActivity.cs b/src/keepass2android/settings/DatabaseSettingsActivity.cs index ad20f4ac..52e6ec4a 100644 --- a/src/keepass2android/settings/DatabaseSettingsActivity.cs +++ b/src/keepass2android/settings/DatabaseSettingsActivity.cs @@ -344,11 +344,11 @@ namespace keepass2android Database db = App.Kp2a.GetDb(); if (db.Loaded) { - Preference rounds = FindPreference(GetString(Resource.String.rounds_key)); + /*Preference rounds = FindPreference(GetString(Resource.String.rounds_key)); rounds.PreferenceChange += (sender, e) => SetRounds(db, e.Preference); rounds.Enabled = db.CanWrite; SetRounds(db, rounds); - + */ PrepareDefaultUsername(db); PrepareDatabaseName(db); PrepareMasterPassword(); @@ -797,11 +797,11 @@ namespace keepass2android return targetIoc; } - + /* private void SetRounds(Database db, Preference rounds) { rounds.Summary = db.KpDatabase.KeyEncryptionRounds.ToString(CultureInfo.InvariantCulture); - } + }*/ private void SetAlgorithm(Database db, Preference algorithm) { diff --git a/src/keepass2android/settings/RoundsPreference.cs b/src/keepass2android/settings/RoundsPreference.cs index 90ae9b11..234de33b 100644 --- a/src/keepass2android/settings/RoundsPreference.cs +++ b/src/keepass2android/settings/RoundsPreference.cs @@ -23,6 +23,7 @@ using Android.Widget; using Android.Preferences; using KeePassLib; using Android.Util; +using KeePassLib.Cryptography.KeyDerivation; namespace keepass2android.settings { @@ -37,14 +38,33 @@ namespace keepass2android.settings View view = base.OnCreateDialogView(); RoundsView = (TextView) view.FindViewById(Resource.Id.rounds); - - Database db = App.Kp2a.GetDb(); - ulong numRounds = db.KpDatabase.KeyEncryptionRounds; + + + ulong numRounds = KeyEncryptionRounds; RoundsView.Text = numRounds.ToString(CultureInfo.InvariantCulture); return view; } - + + public ulong KeyEncryptionRounds + { + get + { + AesKdf kdf = new AesKdf(); + if (!kdf.Uuid.Equals(App.Kp2a.GetDb().KpDatabase.KdfParameters.KdfUuid)) + return (uint) PwDefs.DefaultKeyEncryptionRounds; + else + { + ulong uRounds = App.Kp2a.GetDb().KpDatabase.KdfParameters.GetUInt64( + AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds); + uRounds = Math.Min(uRounds, 0xFFFFFFFEUL); + + return (uint) uRounds; + } + } + set { App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, value); } + } + public RoundsPreference(Context context, IAttributeSet attrs):base(context, attrs) { } @@ -70,14 +90,14 @@ namespace keepass2android.settings Database db = App.Kp2a.GetDb(); - ulong oldRounds = db.KpDatabase.KeyEncryptionRounds; + ulong oldRounds = KeyEncryptionRounds; if (oldRounds == rounds) { return; } - db.KpDatabase.KeyEncryptionRounds = rounds; + KeyEncryptionRounds = rounds; Handler handler = new Handler(); SaveDb save = new SaveDb(Context, App.Kp2a, new AfterSave(Context, handler, oldRounds, this)); @@ -109,7 +129,7 @@ namespace keepass2android.settings } else { DisplayMessage(_ctx); - App.Kp2a.GetDb().KpDatabase.KeyEncryptionRounds = _oldRounds; + App.Kp2a.GetDb().KpDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, _oldRounds); } base.Run();