9
$\begingroup$

You may already have heard it: KeePass v2.35 has support for a new database format (KDBX4) which allows for the use of Argon2 (more precisely: Argon2d) as the password-based key derivation function (PBKDF).

However Argon2 has three independent parameters, called iteration count, memory usage and parallelism in the GUI. Furthermore it offers to measure how many iterations it can squeeze into one second. But if you "just" hit the button for this it's gonna use 1MB and a parellelism value of 2.

So my question: Is "just" adjusting the iteration count the best strategy to get the most security out of Argon2 or is there a better approach?


OK, so here's the more concrete situation for which the best strategy is searched: An x86 architecture PC, with basically unlimited amounts of RAM (let's just take 4GB+ as an approximation of unlimited), with a very limited number of parallel cores and with a very "tight" time budget of up to 1 second.
Now for the definition of the term "best": Given the above scenario the best strategy for parameter-selection is the one that allows for the biggest hurden on an GPU- / FPGA- / ASIC- based (in terms of the time-area-product) attacker while fitting the constraints.
As this is also intended as a ressource for persons without much of a crypto background, please keep possible strategies as concrete as possible.

$\endgroup$
2
  • 1
    $\begingroup$ Possible duplicate of What is the recommended number of iterations for Argon2? $\endgroup$
    – otus
    Jan 29, 2017 at 17:51
  • $\begingroup$ @otus while certainly related I don't think it's a strict duplicate, after all the average user probably has no clue on the upper bound on the memory side of things. Also that question only asks about the iterations for Argon2i instead of the full set for Argon2d for a deployment scenario where there's plenty of memory. $\endgroup$
    – SEJPM
    Jan 29, 2017 at 17:53

1 Answer 1

7
$\begingroup$

The first thing to note is that KeePass uses Argon2d which is the Argon2-variant with data-dependent memory access.

Now it's best to (roughly) follow the guidelines lined out in the Argon2 specification (RFC draft):

  • Figure out the maximum number h of threads that can be initiated by each call to Argon2._ This means you should set the parallelism value to match your physical core count, ie 2 if you have a dual-core, 4 if you have a quad-core, ... You should double this value if you have (true) hyper-threading enabled on your CPU.
  • Optional: If you want to use the key-derivation on a lower power device (such as your phone), you need to figure out first how much RAM it has available during average use. This will be your upper limit for memory usage.
  • Optional: If you have less than 8GB of RAM on your machine, figure out how much is available during average use. The minimal value of this and the previous point will be the upper bound for memory.
  • Pick an iteration count between 1 and maybe 5. The higher you pick the harder it is for an attacker to reduce the memory required. Analysis suggests that low, single digit values are good, but going slightly higher should increase the penalty when trying to reduce memory usage. But do not higher this value indefinitely because while it would increase the penalties for reducing memory for an attacker, it could very well make the difference between you using 25MB and 500MB of memory and 500MB with "medium" penalties for reduction is likely going to be much worse for an attacker than 25MB with "high" penalties for reduction.
  • Figure out the actual memory usage parameter. To do this you pick a rather low value like 100MB or a tenth of your maximal budget and test how long it takes. If it takes not long enough increase the memory usage. The used time will roughly scale linear with the memory usage, that is, if you double the memory usage, you will get a doubled time. You want to tweak this time value to your liking, but about 1 second is recommended for disk-encryption or password databases.
  • If you hit the maximal memory budget, don't go over it (thinks will end badly), but rather increase the iteration count now. Also note here that the used time will scale linear with the iteration count, that is, double the iteration count and it will take about twice as long.

Overall your parameters should take maybe one second for the computation on your intended usage machine where you have to unlock the database often.

So…

TL;DR:

Set the parallelism to your thread count (double the core count if you have hyperthreading), set the iteration count in the range 1-5 and set the memory usage as high as you can while staying within your time and memory budget.


thanks to axapaxa for pointing out that the thread count should be used.
thanks to Luis Casillas for pointing me to the RFC draft and making me improve this answer.

$\endgroup$
5
  • 3
    $\begingroup$ Why not set parallelism to amount of thread count? Argon should be fairly good with HT as you have some memory access and some integer calculations (at cost of possibly having to lower iteration count somewhat). $\endgroup$
    – axapaxa
    Jan 29, 2017 at 19:41
  • 5
    $\begingroup$ The bullet points you give do not in fact match the recommendations given in the Argon2 specification you link, or those of the draft RFC. In particular, if by "iteration count" you mean the $t$ parameter, the recommendations I'm aware of suggest setting $t = 1$ for Argon2d. As I understand it, the preferred method for increasing Argon2d's cost is giving it more memory; you resort to raising $t$ if you've already given the function the max memory amount you'd picked, but it's still coming in under the run time you want. $\endgroup$ Aug 23, 2017 at 20:58
  • $\begingroup$ @axapaxa In my testing, I found you can set that the thread count quite high for future compatibility without negatively impacting performance in the present. On a 4 thread laptop, I was able to set the thread count up to 64 without any measurable slowdown. $\endgroup$ Jul 2, 2021 at 15:36
  • $\begingroup$ @SurpriseDog Increased parallelism beyond what you have on your machine doesn't slow down your own hash speed. Instead it increases the speed an attacker could theoretically solve the hashes. It's essentially like raising the speed limit on the argon2d hash-highway. Your 4-core-car isn't gonna go any faster but an attackers NVIDIA-Ferrari with 10k cores may go 5-10x faster and be easier to scale because it'll take longer for them to hit GPU memory bottlenecks. $\endgroup$ Nov 25 at 1:48
  • $\begingroup$ This has already been asked and answered: crypto.stackexchange.com/questions/105468/… - Increasing parallelism has a tiny hit on performance, but no cost to the security of the algorithm. It's assumed any attacker is already using a many GPU system to crack the hash anyway. $\endgroup$ Dec 2 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.