예제 #1
0
        public override KdfParameters GetDefaultParameters()
        {
            KdfParameters p = base.GetDefaultParameters();

            p.SetUInt32(ParamVersion, MaxVersion);

            p.SetUInt64(ParamIterations, DefaultIterations);
            p.SetUInt64(ParamMemory, DefaultMemory);
            p.SetUInt32(ParamParallelism, DefaultParallelism);

            return(p);
        }
예제 #2
0
        public override KdfParameters GetDefaultParameters()
        {
            KdfParameters p = base.GetDefaultParameters();

            p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
            return(p);
        }
예제 #3
0
        protected void MaximizeParamUInt64(KdfParameters p, string strName,
                                           ulong uMin, ulong uMax, uint uMilliseconds, bool bInterpSearch)
        {
            if (p == null)
            {
                Debug.Assert(false); return;
            }
            if (string.IsNullOrEmpty(strName))
            {
                Debug.Assert(false); return;
            }
            if (uMin > uMax)
            {
                Debug.Assert(false); return;
            }

            if (uMax > (ulong.MaxValue >> 1))
            {
                Debug.Assert(false);
                uMax = ulong.MaxValue >> 1;

                if (uMin > uMax)
                {
                    p.SetUInt64(strName, uMin); return;
                }
            }

            byte[] pbMsg = new byte[32];
            for (int i = 0; i < pbMsg.Length; ++i)
            {
                pbMsg[i] = (byte)i;
            }

            ulong uLow    = uMin;
            ulong uHigh   = uMin + 1UL;
            long  tLow    = 0;
            long  tHigh   = 0;
            long  tTarget = (long)uMilliseconds;

            // Determine range
            while (uHigh <= uMax)
            {
                p.SetUInt64(strName, uHigh);

                // GC.Collect();
                Stopwatch sw = Stopwatch.StartNew();
                Transform(pbMsg, p);
                sw.Stop();

                tHigh = sw.ElapsedMilliseconds;
                if (tHigh > tTarget)
                {
                    break;
                }

                uLow    = uHigh;
                tLow    = tHigh;
                uHigh <<= 1;
            }
            if (uHigh > uMax)
            {
                uHigh = uMax; tHigh = 0;
            }
            if (uLow > uHigh)
            {
                uLow = uHigh;                          // Skips to end
            }
            // Find optimal number of iterations
            while ((uHigh - uLow) >= 2UL)
            {
                ulong u = (uHigh + uLow) >> 1;                 // Binary search
                // Interpolation search, if possible
                if (bInterpSearch && (tLow > 0) && (tHigh > tTarget) &&
                    (tLow <= tTarget))
                {
                    u = uLow + (((uHigh - uLow) * (ulong)(tTarget - tLow)) /
                                (ulong)(tHigh - tLow));
                    if ((u >= uLow) && (u <= uHigh))
                    {
                        u = Math.Max(u, uLow + 1UL);
                        u = Math.Min(u, uHigh - 1UL);
                    }
                    else
                    {
                        Debug.Assert(false);
                        u = (uHigh + uLow) >> 1;
                    }
                }

                p.SetUInt64(strName, u);

                // GC.Collect();
                Stopwatch sw = Stopwatch.StartNew();
                Transform(pbMsg, p);
                sw.Stop();

                long t = sw.ElapsedMilliseconds;
                if (t == tTarget)
                {
                    uLow = u; break;
                }
                else if (t > tTarget)
                {
                    uHigh = u; tHigh = t;
                }
                else
                {
                    uLow = u; tLow = t;
                }
            }

            p.SetUInt64(strName, uLow);
        }
예제 #4
0
        public override KdfParameters GetBestParameters(uint uMilliseconds)
        {
            KdfParameters p = GetDefaultParameters();
            ulong         uRounds;

#if !ModernKeePassLib
            // Try native method
            if (NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds))
            {
                p.SetUInt64(ParamRounds, uRounds);
                return(p);
            }
#endif
            if (TransformKeyBenchmarkGCrypt(uMilliseconds, out uRounds))
            {
                p.SetUInt64(ParamRounds, uRounds);
                return(p);
            }

            byte[] pbKey    = new byte[32];
            byte[] pbNewKey = new byte[32];
            for (int i = 0; i < pbKey.Length; ++i)
            {
                pbKey[i]    = (byte)i;
                pbNewKey[i] = (byte)i;
            }

#if ModernKeePassLib || KeePassUAP
            KeyParameter kp  = new KeyParameter(pbKey);
            AesEngine    aes = new AesEngine();
            aes.Init(true, kp);
#else
            byte[] pbIV = new byte[16];

            using (SymmetricAlgorithm a = CryptoUtil.CreateAes())
            {
                if (a.BlockSize != 128)                // AES block size
                {
                    Debug.Assert(false);
                    a.BlockSize = 128;
                }
                a.KeySize = 256;
                a.Mode    = CipherMode.ECB;

                using (ICryptoTransform t = a.CreateEncryptor(pbKey, pbIV))
                {
                    // !t.CanReuseTransform -- doesn't work with Mono
                    if ((t == null) || (t.InputBlockSize != 16) ||
                        (t.OutputBlockSize != 16))
                    {
                        Debug.Assert(false);
                        p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
                        return(p);
                    }
#endif

            uRounds = 0;
            int tStart = Environment.TickCount;
            while (true)
            {
                for (ulong j = 0; j < BenchStep; ++j)
                {
#if ModernKeePassLib || KeePassUAP
                    aes.ProcessBlock(pbNewKey, 0, pbNewKey, 0);
                    aes.ProcessBlock(pbNewKey, 16, pbNewKey, 16);
#else
                    t.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0);
                    t.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16);
#endif
                }

                uRounds += BenchStep;
                if (uRounds < BenchStep)                                // Overflow check
                {
                    uRounds = ulong.MaxValue;
                    break;
                }

                uint tElapsed = (uint)(Environment.TickCount - tStart);
                if (tElapsed > uMilliseconds)
                {
                    break;
                }
            }

            p.SetUInt64(ParamRounds, uRounds);
#if ModernKeePassLib || KeePassUAP
            aes.Reset();
#else
        }
    }
#endif
            return(p);
        }