Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        public override KdfParameters GetDefaultParameters()
        {
            KdfParameters p = base.GetDefaultParameters();

            p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
            return(p);
        }
Ejemplo n.º 3
0
        public override KdfParameters GetBestParameters(uint uMilliseconds)
        {
            const ulong uStep = 3001;
            ulong       uRounds;

            KdfParameters p = GetDefaultParameters();

            // Try native method
            if (NativeLib.TransformKeyBenchmark256(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 KeePassUAP
            KeyParameter kp  = new KeyParameter(pbKey);
            AesEngine    aes = new AesEngine();
            aes.Init(true, kp);
#else
            byte[] pbIV = new byte[16];
            Array.Clear(pbIV, 0, pbIV.Length);

            RijndaelManaged r = new RijndaelManaged();
            if (r.BlockSize != 128)            // AES block size
            {
                Debug.Assert(false);
                r.BlockSize = 128;
            }

            r.IV      = pbIV;
            r.Mode    = CipherMode.ECB;
            r.KeySize = 256;
            r.Key     = pbKey;
            ICryptoTransform iCrypt = r.CreateEncryptor();

            // !iCrypt.CanReuseTransform -- doesn't work with Mono
            if ((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
                (iCrypt.OutputBlockSize != 16))
            {
                Debug.Assert(false, "Invalid ICryptoTransform.");
                Debug.Assert(iCrypt.InputBlockSize == 16, "Invalid input block size!");
                Debug.Assert(iCrypt.OutputBlockSize == 16, "Invalid output block size!");

                p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
                return(p);
            }
#endif

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

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

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

            p.SetUInt64(ParamRounds, uRounds);
            return(p);
        }
Ejemplo n.º 4
0
        public override KdfParameters GetBestParameters(uint uMilliseconds)
        {
            KdfParameters p = GetDefaultParameters();
            ulong         uRounds;

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

            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 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 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 KeePassUAP
            aes.Reset();
#else
        }
    }
#endif
            return(p);
        }
Ejemplo n.º 5
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);
        }