dynamically tune sha512crypt rounds
As touched on in #12800 and #12855, sha512crypt's default number of rounds (5000) can be cracked relatively quickly by modern standards. But "fixing" this with a static, arbitrary number of rounds could adversely impact login speed and user experience, depending on platform.
I propose a middle-ground solution: tune the number of rounds based on platform capability to a target runtime. Multiple UX studies have cited 500ms (half a second) as an upper bound for user login delay tolerance.
This reference code detects the number of rounds near 500ms performance, using a simple approach: performing a test hash, and then applying its performance ratio to the rounds count. It then hashes the password with that number of rounds. It abstracts both the sha512crypt hashing and the dynamic rounds tuning into their own functions. It also improves salt entropy in passing, to match bcrypt and scrypt's 128 bits and to match the sha512crypt
The code is overly commented, to explain the reasoning behind various design choices, such as those informed by attack techniques well known in the password-cracking community.
Sample results for a few platforms at 500ms runtimes (I am actively soliciting for additional data points):
* AMD Geode LX800 500 MHz (alix2): rounds=11851 * AMD GX-412TC SOC (apu2): rounds=157921 * Intel(R) Celeron(R) CPU N3150 @ 1.60GHz: rounds=209662 * Pentium(R) Dual-Core CPU E5: rounds=568985 * 11th Gen Intel(R) Core(TM) i7-11700K @ 3.60GHz: rounds=1741092
Note especially these higher values. A modern CPU can run 1.7 million rounds of sha512crypt in half a second. By contrast, a medium-sized pentest cracking rig (equivalent of 6 GTX 1080s) can do a little over 2 billion rounds in half a second against a single hash (scaling downward across multiple salted hashes).
So while not even a strong hash can protect a single very weak password for long, strengthening these hashes can do a much better job of protecting midrange and stronger ones.