diff --git a/cgtest.c b/cgtest.c index 39f8881f..62988576 100644 --- a/cgtest.c +++ b/cgtest.c @@ -24,6 +24,7 @@ #define get_random_data get_random_data_diagnostic #define console_get_userpass_input console_get_userpass_input_diagnostic #define main cmdgen_main +#define ppk_save_default_parameters ppk_save_cgtest_parameters #include "cmdgen.c" @@ -33,6 +34,22 @@ 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 * console_get_userpass_input that we need for this test rig. diff --git a/ssh.h b/ssh.h index d09e003a..45675ce8 100644 --- a/ssh.h +++ b/ssh.h @@ -1243,6 +1243,14 @@ typedef struct ppk_save_parameters { uint32_t argon2_milliseconds; /* if auto == true */ }; 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; extern const ppk_save_parameters ppk_save_default_parameters; diff --git a/sshpubk.c b/sshpubk.c index e1f9e921..fc840f44 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -1507,7 +1507,10 @@ strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase, /* Invent a salt for the password hash. */ 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(); ssh2_ppk_derive_keys(3, ciphertype, diff --git a/testcrypt.c b/testcrypt.c index 8db09227..bb05e1e1 100644 --- a/testcrypt.c +++ b/testcrypt.c @@ -1153,6 +1153,7 @@ strbuf *ppk_save_sb_wrapper(ssh_key *key, const char *comment, * choice of password hashing parameters, so this is easy. */ ppk_save_parameters save_params; + memset(&save_params, 0, sizeof(save_params)); save_params.argon2_flavour = flavour; save_params.argon2_mem = mem; save_params.argon2_passes_auto = false;