1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 11:32:48 -05:00

Introduce PPK file format version 3.

This removes both uses of SHA-1 in the file format: it was used as the
MAC protecting the key file against tamperproofing, and also used in
the key derivation step that converted the user's passphrase to cipher
and MAC keys.

The MAC is simply upgraded from HMAC-SHA-1 to HMAC-SHA-256; it is
otherwise unchanged in how it's applied (in particular, to what data).

The key derivation is totally reworked, to be based on Argon2, which
I've just added to the code base. This should make stolen encrypted
key files more resistant to brute-force attack.

Argon2 has assorted configurable parameters for memory and CPU usage;
the new key format includes all those parameters. So there's no reason
we can't have them under user control, if a user wants to be
particularly vigorous or particularly lightweight with their own key
files. They could even switch to one of the other flavours of Argon2,
if they thought side channels were an especially large or small risk
in their particular environment. In this commit I haven't added any UI
for controlling that kind of thing, but the PPK loading function is
all set up to cope, so that can all be added in a future commit
without having to change the file format.

While I'm at it, I've also switched the CBC encryption to using a
random IV (or rather, one derived from the passphrase along with the
cipher and MAC keys). That's more like normal SSH-2 practice.
This commit is contained in:
Simon Tatham
2021-02-20 10:17:45 +00:00
parent 0faeb82ccd
commit 08d17140a0
10 changed files with 444 additions and 60 deletions

17
ssh.h
View File

@ -1234,9 +1234,22 @@ int rsa1_load_s(BinarySource *src, RSAKey *key,
int rsa1_load_f(const Filename *filename, RSAKey *key,
const char *passphrase, const char **errorstr);
strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase);
typedef struct ppk_save_parameters {
Argon2Flavour argon2_flavour;
uint32_t argon2_mem; /* in Kb */
bool argon2_passes_auto;
union {
uint32_t argon2_passes; /* if auto == false */
uint32_t argon2_milliseconds; /* if auto == true */
};
uint32_t argon2_parallelism;
} ppk_save_parameters;
extern const ppk_save_parameters ppk_save_default_parameters;
strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase,
const ppk_save_parameters *params);
bool ppk_save_f(const Filename *filename, ssh2_userkey *key,
const char *passphrase);
const char *passphrase, const ppk_save_parameters *params);
strbuf *rsa1_save_sb(RSAKey *key, const char *passphrase);
bool rsa1_save_f(const Filename *filename, RSAKey *key,
const char *passphrase);