1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Fix determinism failures in cgtest.

Thanks to Pavel and his CI for pointing out what I'd forgotten: the
automated test of cmdgen.c expects that round-tripping a PPK file to
some other format and back will regenerate the identical file. Of
course, with a randomised salt in the new-look password hash, that
isn't true any more in normal usage.

Fixed by adding an option in the existing parameters structure to
provide a salt override. That shouldn't be used anywhere except
cgtest, but in cgtest, it restores the determinism we need.

Another potential (but not guaranteed) source of difference is the
automatic time-scaling of the Argon2 parameter choice. So I've turned
that off too, while I'm at it.
This commit is contained in:
Simon Tatham 2021-02-21 14:37:59 +00:00
parent 342972ee60
commit 8eb4cd5674
4 changed files with 30 additions and 1 deletions

View File

@ -24,6 +24,7 @@
#define get_random_data get_random_data_diagnostic #define get_random_data get_random_data_diagnostic
#define console_get_userpass_input console_get_userpass_input_diagnostic #define console_get_userpass_input console_get_userpass_input_diagnostic
#define main cmdgen_main #define main cmdgen_main
#define ppk_save_default_parameters ppk_save_cgtest_parameters
#include "cmdgen.c" #include "cmdgen.c"
@ -33,6 +34,22 @@
static bool cgtest_verbose = false; static bool cgtest_verbose = false;
const struct ppk_save_parameters ppk_save_cgtest_parameters = {
/* Replacement set of key derivation parameters that make this
* test suite run a bit faster and also add determinism: we don't
* try to auto-scale the number of passes (in case it gets
* different answers twice in the test suite when we were
* expecting two key files to compare equal), and we specify a
* passphrase salt. */
.argon2_flavour = Argon2id,
.argon2_mem = 16,
.argon2_passes_auto = false,
.argon2_passes = 2,
.argon2_parallelism = 1,
.salt = (const uint8_t *)"SameSaltEachTime",
.saltlen = 16,
};
/* /*
* Define the special versions of get_random_data and * Define the special versions of get_random_data and
* console_get_userpass_input that we need for this test rig. * console_get_userpass_input that we need for this test rig.

8
ssh.h
View File

@ -1243,6 +1243,14 @@ typedef struct ppk_save_parameters {
uint32_t argon2_milliseconds; /* if auto == true */ uint32_t argon2_milliseconds; /* if auto == true */
}; };
uint32_t argon2_parallelism; uint32_t argon2_parallelism;
/* The ability to choose a specific salt is only intended for the
* use of the automated test of PuTTYgen. It's a (mild) security
* risk to do it with any passphrase you actually care about,
* because it invalidates the entire point of having a salt in the
* first place. */
const uint8_t *salt;
size_t saltlen;
} ppk_save_parameters; } ppk_save_parameters;
extern const ppk_save_parameters ppk_save_default_parameters; extern const ppk_save_parameters ppk_save_default_parameters;

View File

@ -1507,7 +1507,10 @@ strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase,
/* Invent a salt for the password hash. */ /* Invent a salt for the password hash. */
strbuf *passphrase_salt = strbuf_new(); strbuf *passphrase_salt = strbuf_new();
random_read(strbuf_append(passphrase_salt, 16), 16); if (params.salt)
put_data(passphrase_salt, params.salt, params.saltlen);
else
random_read(strbuf_append(passphrase_salt, 16), 16);
cipher_mac_keys_blob = strbuf_new(); cipher_mac_keys_blob = strbuf_new();
ssh2_ppk_derive_keys(3, ciphertype, ssh2_ppk_derive_keys(3, ciphertype,

View File

@ -1153,6 +1153,7 @@ strbuf *ppk_save_sb_wrapper(ssh_key *key, const char *comment,
* choice of password hashing parameters, so this is easy. * choice of password hashing parameters, so this is easy.
*/ */
ppk_save_parameters save_params; ppk_save_parameters save_params;
memset(&save_params, 0, sizeof(save_params));
save_params.argon2_flavour = flavour; save_params.argon2_flavour = flavour;
save_params.argon2_mem = mem; save_params.argon2_mem = mem;
save_params.argon2_passes_auto = false; save_params.argon2_passes_auto = false;