private static void CopyKdfSettings(PwDatabase sourceDb, Settings settings, PwDatabase targetDatabase) { // Create a clone of the KdfParameters object. As cloning is not supportet serialize and deserialize targetDatabase.KdfParameters = KdfParameters.DeserializeExt(KdfParameters.SerializeExt(sourceDb.KdfParameters)); if (Equals(targetDatabase.KdfParameters.KdfUuid, UuidAes)) { // Allow override of AesKdf transformation rounds if (settings.KeyTransformationRounds != 0) { // Set keyTransformationRounds (min PwDefs.DefaultKeyEncryptionRounds) targetDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, Math.Max(PwDefs.DefaultKeyEncryptionRounds, settings.KeyTransformationRounds)); } } else if (Equals(targetDatabase.KdfParameters.KdfUuid, UuidArgon2)) { // Allow override of Agon2Kdf transformation rounds if (settings.Argon2ParamIterations != 0) { // Set paramIterations (min default value == 2) targetDatabase.KdfParameters.SetUInt64(Argon2Kdf.ParamIterations, Math.Max(2, settings.Argon2ParamIterations)); } // Allow override of Agon2Kdf memory setting if (settings.Argon2ParamMemory != 0) { // Set ParamMemory (min default value == 1048576 == 1 MB) targetDatabase.KdfParameters.SetUInt64(Argon2Kdf.ParamMemory, Math.Max(1048576, settings.Argon2ParamMemory)); } // Allow override of Agon2Kdf parallelism setting if (settings.Argon2ParamParallelism != 0) { // Set ParamParallelism (min default value == 2 MB) targetDatabase.KdfParameters.SetUInt32(Argon2Kdf.ParamParallelism, settings.Argon2ParamParallelism); } } }
private byte[] GenerateHeader() { byte[] pbHeader; using (MemoryStream ms = new MemoryStream()) { MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature1)); MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature2)); MemUtil.Write(ms, MemUtil.UInt32ToBytes(m_uFileVersion)); WriteHeaderField(ms, KdbxHeaderFieldID.CipherID, m_pwDatabase.DataCipherUuid.UuidBytes); int nCprID = (int)m_pwDatabase.Compression; WriteHeaderField(ms, KdbxHeaderFieldID.CompressionFlags, MemUtil.UInt32ToBytes((uint)nCprID)); WriteHeaderField(ms, KdbxHeaderFieldID.MasterSeed, m_pbMasterSeed); if (m_uFileVersion < FileVersion32_4) { Debug.Assert(m_pwDatabase.KdfParameters.KdfUuid.Equals( (new AesKdf()).Uuid)); WriteHeaderField(ms, KdbxHeaderFieldID.TransformSeed, m_pwDatabase.KdfParameters.GetByteArray(AesKdf.ParamSeed)); WriteHeaderField(ms, KdbxHeaderFieldID.TransformRounds, MemUtil.UInt64ToBytes(m_pwDatabase.KdfParameters.GetUInt64( AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds))); } else { WriteHeaderField(ms, KdbxHeaderFieldID.KdfParameters, KdfParameters.SerializeExt(m_pwDatabase.KdfParameters)); } if (m_pbEncryptionIV.Length > 0) { WriteHeaderField(ms, KdbxHeaderFieldID.EncryptionIV, m_pbEncryptionIV); } if (m_uFileVersion < FileVersion32_4) { WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamKey, m_pbInnerRandomStreamKey); WriteHeaderField(ms, KdbxHeaderFieldID.StreamStartBytes, m_pbStreamStartBytes); int nIrsID = (int)m_craInnerRandomStream; WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamID, MemUtil.Int32ToBytes(nIrsID)); } // Write public custom data only when there is at least one item, // because KDBX 3.1 didn't support this field yet if (m_pwDatabase.PublicCustomData.Count > 0) { WriteHeaderField(ms, KdbxHeaderFieldID.PublicCustomData, VariantDictionary.Serialize(m_pwDatabase.PublicCustomData)); } WriteHeaderField(ms, KdbxHeaderFieldID.EndOfHeader, new byte[] { (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' }); pbHeader = ms.ToArray(); } return(pbHeader); }