KeePassLib.Cryptography.KeyDerivation.AesKdf.GetBestParameters C# (CSharp) Method

GetBestParameters() public method

public GetBestParameters ( uint uMilliseconds ) : KeePassLib.Cryptography.KeyDerivation.KdfParameters
uMilliseconds uint
return KeePassLib.Cryptography.KeyDerivation.KdfParameters
		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;
		}
	}