mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Adopt the new hash API functions where they're useful.
This commit switches as many ssh_hash_free / ssh_hash_new pairs as possible to reuse the previous hash object via ssh_hash_reset. Also a few other cleanups: use the wrapper function hash_simple() where possible, and I've also introduced ssh_hash_digest_nondestructive() and switched to that where possible as well.
This commit is contained in:
parent
3fd334b5ca
commit
1344d4d1cd
6
import.c
6
import.c
@ -516,9 +516,9 @@ static void openssh_pem_derivekey(
|
||||
h = ssh_hash_new(&ssh_md5);
|
||||
put_datapl(h, passphrase);
|
||||
put_data(h, iv, 8);
|
||||
ssh_hash_final(h, keybuf);
|
||||
ssh_hash_digest(h, keybuf);
|
||||
|
||||
h = ssh_hash_new(&ssh_md5);
|
||||
ssh_hash_reset(h);
|
||||
put_data(h, keybuf, 16);
|
||||
put_datapl(h, passphrase);
|
||||
put_data(h, iv, 8);
|
||||
@ -1932,7 +1932,7 @@ static void sshcom_derivekey(ptrlen passphrase, uint8_t *keybuf)
|
||||
|
||||
h = ssh_hash_new(&ssh_md5);
|
||||
put_datapl(h, passphrase);
|
||||
ssh_hash_final(ssh_hash_copy(h), keybuf);
|
||||
ssh_hash_digest_nondestructive(h, keybuf);
|
||||
put_data(h, keybuf, 16);
|
||||
ssh_hash_final(h, keybuf + 16);
|
||||
}
|
||||
|
7
ssh.h
7
ssh.h
@ -748,6 +748,13 @@ static inline ssh_hash *ssh_hash_copyfrom(ssh_hash *dest, ssh_hash *src)
|
||||
static inline void ssh_hash_final(ssh_hash *h, unsigned char *out)
|
||||
{ h->vt->digest(h, out); h->vt->free(h); }
|
||||
|
||||
/* ssh_hash_digest_nondestructive generates a finalised hash from the
|
||||
* given object without changing its state, so you can continue
|
||||
* appending data to get a hash of an extended string. */
|
||||
static inline void ssh_hash_digest_nondestructive(ssh_hash *h,
|
||||
unsigned char *out)
|
||||
{ ssh_hash_final(ssh_hash_copy(h), out); }
|
||||
|
||||
/* Handy macros for defining all those text-name fields at once */
|
||||
#define HASHALG_NAMES_BARE(base) \
|
||||
base, NULL, base
|
||||
|
@ -275,25 +275,25 @@ static void ssh2_mkkey(
|
||||
put_data(h, H, hlen);
|
||||
put_byte(h, chr);
|
||||
put_data(h, s->session_id, s->session_id_len);
|
||||
ssh_hash_final(h, key);
|
||||
ssh_hash_digest(h, key);
|
||||
|
||||
/* Subsequent blocks of hlen bytes. */
|
||||
if (keylen_padded > hlen) {
|
||||
int offset;
|
||||
|
||||
h = ssh_hash_new(s->kex_alg->hash);
|
||||
ssh_hash_reset(h);
|
||||
if (!(s->ppl.remote_bugs & BUG_SSH2_DERIVEKEY))
|
||||
put_mp_ssh2(h, K);
|
||||
put_data(h, H, hlen);
|
||||
|
||||
for (offset = hlen; offset < keylen_padded; offset += hlen) {
|
||||
put_data(h, key + offset - hlen, hlen);
|
||||
ssh_hash *h2 = ssh_hash_copy(h);
|
||||
ssh_hash_final(h2, key + offset);
|
||||
ssh_hash_digest_nondestructive(h, key + offset);
|
||||
}
|
||||
|
||||
ssh_hash_free(h);
|
||||
}
|
||||
|
||||
ssh_hash_free(h);
|
||||
}
|
||||
|
||||
/*
|
||||
|
4
sshdss.c
4
sshdss.c
@ -399,12 +399,12 @@ mp_int *dss_gen_k(const char *id_string, mp_int *modulus,
|
||||
h = ssh_hash_new(&ssh_sha512);
|
||||
put_asciz(h, id_string);
|
||||
put_mp_ssh2(h, private_key);
|
||||
ssh_hash_final(h, digest512);
|
||||
ssh_hash_digest(h, digest512);
|
||||
|
||||
/*
|
||||
* Now hash that digest plus the message hash.
|
||||
*/
|
||||
h = ssh_hash_new(&ssh_sha512);
|
||||
ssh_hash_reset(h);
|
||||
put_data(h, digest512, sizeof(digest512));
|
||||
put_data(h, digest, digest_len);
|
||||
ssh_hash_final(h, digest512);
|
||||
|
15
sshhmac.c
15
sshhmac.c
@ -98,11 +98,7 @@ static void hmac_key(ssh2_mac *mac, ptrlen key)
|
||||
*/
|
||||
sb = strbuf_new_nm();
|
||||
strbuf_append(sb, ctx->hashalg->hlen);
|
||||
|
||||
ssh_hash *htmp = ssh_hash_new(ctx->hashalg);
|
||||
put_datapl(htmp, key);
|
||||
ssh_hash_final(htmp, sb->u);
|
||||
|
||||
hash_simple(ctx->hashalg, key, sb->u);
|
||||
kp = sb->u;
|
||||
klen = sb->len;
|
||||
} else {
|
||||
@ -140,11 +136,10 @@ static void hmac_genresult(ssh2_mac *mac, unsigned char *output)
|
||||
struct hmac *ctx = container_of(mac, struct hmac, mac);
|
||||
ssh_hash *htmp;
|
||||
|
||||
/* Leave h_live in place, so that the SSH-2 BPP can continue
|
||||
* regenerating test results from different-length prefixes of the
|
||||
* packet */
|
||||
htmp = ssh_hash_copy(ctx->h_live);
|
||||
ssh_hash_final(htmp, ctx->digest);
|
||||
/* Leave h_live and h_outer in place, so that the SSH-2 BPP can
|
||||
* continue regenerating test results from different-length
|
||||
* prefixes of the packet */
|
||||
ssh_hash_digest_nondestructive(ctx->h_live, ctx->digest);
|
||||
|
||||
htmp = ssh_hash_copy(ctx->h_outer);
|
||||
put_data(htmp, ctx->digest, ctx->hashalg->hlen);
|
||||
|
@ -273,9 +273,9 @@ void prng_add_entropy(prng *pr, unsigned source_id, ptrlen data)
|
||||
prngdebug("prng entropy reseed #%"PRIu32"\n", reseed_index);
|
||||
for (size_t i = 0; i < NCOLLECTORS; i++) {
|
||||
prngdebug("emptying collector %zu\n", i);
|
||||
ssh_hash_final(pi->collectors[i], pi->pending_output);
|
||||
ssh_hash_digest(pi->collectors[i], pi->pending_output);
|
||||
put_data(&pi->Prng, pi->pending_output, pi->hashalg->hlen);
|
||||
pi->collectors[i] = ssh_hash_new(pi->hashalg);
|
||||
ssh_hash_reset(pi->collectors[i]);
|
||||
if (reseed_index & 1)
|
||||
break;
|
||||
reseed_index >>= 1;
|
||||
|
@ -372,9 +372,7 @@ bool rsa_ssh1_savekey(const Filename *filename, RSAKey *key,
|
||||
if (passphrase) {
|
||||
unsigned char keybuf[16];
|
||||
|
||||
ssh_hash *h = ssh_hash_new(&ssh_md5);
|
||||
put_data(h, passphrase, strlen(passphrase));
|
||||
ssh_hash_final(h, keybuf);
|
||||
hash_simple(&ssh_md5, ptrlen_from_asciz(passphrase), keybuf);
|
||||
des3_encrypt_pubkey(keybuf, buf->u + estart, buf->len - estart);
|
||||
smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */
|
||||
}
|
||||
@ -591,8 +589,8 @@ static void ssh2_ppk_derivekey(ptrlen passphrase, uint8_t *key)
|
||||
h = ssh_hash_new(&ssh_sha1);
|
||||
put_uint32(h, 0);
|
||||
put_datapl(h, passphrase);
|
||||
ssh_hash_final(h, key + 0);
|
||||
h = ssh_hash_new(&ssh_sha1);
|
||||
ssh_hash_digest(h, key + 0);
|
||||
ssh_hash_reset(h);
|
||||
put_uint32(h, 1);
|
||||
put_datapl(h, passphrase);
|
||||
ssh_hash_final(h, key + 20);
|
||||
|
18
sshrsa.c
18
sshrsa.c
@ -832,16 +832,17 @@ static void oaep_mask(const ssh_hashalg *h, void *seed, int seedlen,
|
||||
unsigned char *data = (unsigned char *)vdata;
|
||||
unsigned count = 0;
|
||||
|
||||
ssh_hash *s = ssh_hash_new(h);
|
||||
|
||||
while (datalen > 0) {
|
||||
int i, max = (datalen > h->hlen ? h->hlen : datalen);
|
||||
ssh_hash *s;
|
||||
unsigned char hash[MAX_HASH_LEN];
|
||||
|
||||
ssh_hash_reset(s);
|
||||
assert(h->hlen <= MAX_HASH_LEN);
|
||||
s = ssh_hash_new(h);
|
||||
put_data(s, seed, seedlen);
|
||||
put_uint32(s, count);
|
||||
ssh_hash_final(s, hash);
|
||||
ssh_hash_digest(s, hash);
|
||||
count++;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
@ -850,6 +851,8 @@ static void oaep_mask(const ssh_hashalg *h, void *seed, int seedlen,
|
||||
data += max;
|
||||
datalen -= max;
|
||||
}
|
||||
|
||||
ssh_hash_free(s);
|
||||
}
|
||||
|
||||
strbuf *ssh_rsakex_encrypt(RSAKey *rsa, const ssh_hashalg *h, ptrlen in)
|
||||
@ -907,10 +910,7 @@ strbuf *ssh_rsakex_encrypt(RSAKey *rsa, const ssh_hashalg *h, ptrlen in)
|
||||
random_read(out + 1, HLEN);
|
||||
/* At position 1+HLEN, the data block DB, consisting of: */
|
||||
/* The hash of the label (we only support an empty label here) */
|
||||
{
|
||||
ssh_hash *s = ssh_hash_new(h);
|
||||
ssh_hash_final(s, out + HLEN + 1);
|
||||
}
|
||||
hash_simple(h, PTRLEN_LITERAL(""), out + HLEN + 1);
|
||||
/* A bunch of zero octets */
|
||||
memset(out + 2*HLEN + 1, 0, outlen - (2*HLEN + 1));
|
||||
/* A single 1 octet, followed by the input message data. */
|
||||
@ -953,7 +953,6 @@ mp_int *ssh_rsakex_decrypt(
|
||||
int outlen, i;
|
||||
unsigned char *out;
|
||||
unsigned char labelhash[64];
|
||||
ssh_hash *hash;
|
||||
BinarySource src[1];
|
||||
const int HLEN = h->hlen;
|
||||
|
||||
@ -987,8 +986,7 @@ mp_int *ssh_rsakex_decrypt(
|
||||
}
|
||||
/* Check the label hash at position 1+HLEN */
|
||||
assert(HLEN <= lenof(labelhash));
|
||||
hash = ssh_hash_new(h);
|
||||
ssh_hash_final(hash, labelhash);
|
||||
hash_simple(h, PTRLEN_LITERAL(""), labelhash);
|
||||
if (memcmp(out + HLEN + 1, labelhash, HLEN)) {
|
||||
sfree(out);
|
||||
return NULL;
|
||||
|
10
testcrypt.c
10
testcrypt.c
@ -623,6 +623,16 @@ mp_int *monty_modulus_wrapper(MontyContext *mc)
|
||||
}
|
||||
#define monty_modulus monty_modulus_wrapper
|
||||
|
||||
strbuf *ssh_hash_digest_wrapper(ssh_hash *h)
|
||||
{
|
||||
strbuf *sb = strbuf_new();
|
||||
void *p = strbuf_append(sb, ssh_hash_alg(h)->hlen);
|
||||
ssh_hash_digest(h, p);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh_hash_digest
|
||||
#define ssh_hash_digest ssh_hash_digest_wrapper
|
||||
|
||||
strbuf *ssh_hash_final_wrapper(ssh_hash *h)
|
||||
{
|
||||
strbuf *sb = strbuf_new();
|
||||
|
@ -122,7 +122,9 @@ FUNC3(void, ecc_edwards_get_affine, val_epoint, out_val_mpint, out_val_mpint)
|
||||
* API by the hash object also functioning as a BinarySink.
|
||||
*/
|
||||
FUNC1(opt_val_hash, ssh_hash_new, hashalg)
|
||||
FUNC1(void, ssh_hash_reset, val_hash)
|
||||
FUNC1(val_hash, ssh_hash_copy, val_hash)
|
||||
FUNC1(val_string, ssh_hash_digest, val_hash)
|
||||
FUNC1(val_string, ssh_hash_final, consumed_val_hash)
|
||||
FUNC2(void, ssh_hash_update, val_hash, val_string_ptrlen)
|
||||
|
||||
|
14
testsc.c
14
testsc.c
@ -104,6 +104,7 @@ static uint64_t random_counter = 0;
|
||||
static const char *random_seedstr = NULL;
|
||||
static uint8_t random_buf[MAX_HASH_LEN];
|
||||
static size_t random_buf_limit = 0;
|
||||
static ssh_hash *random_hash;
|
||||
|
||||
static void random_seed(const char *seedstr)
|
||||
{
|
||||
@ -118,12 +119,12 @@ void random_read(void *vbuf, size_t size)
|
||||
uint8_t *buf = (uint8_t *)vbuf;
|
||||
while (size-- > 0) {
|
||||
if (random_buf_limit == 0) {
|
||||
ssh_hash *h = ssh_hash_new(&ssh_sha256);
|
||||
put_asciz(h, random_seedstr);
|
||||
put_uint64(h, random_counter);
|
||||
ssh_hash_reset(random_hash);
|
||||
put_asciz(random_hash, random_seedstr);
|
||||
put_uint64(random_hash, random_counter);
|
||||
random_counter++;
|
||||
random_buf_limit = ssh_hash_alg(h)->hlen;
|
||||
ssh_hash_final(h, random_buf);
|
||||
random_buf_limit = ssh_hash_alg(random_hash)->hlen;
|
||||
ssh_hash_digest(random_hash, random_buf);
|
||||
}
|
||||
*buf++ = random_buf[random_buf_limit--];
|
||||
}
|
||||
@ -1395,6 +1396,7 @@ int main(int argc, char **argv)
|
||||
bool test_names_given = false;
|
||||
|
||||
memset(tests_to_run, 1, sizeof(tests_to_run));
|
||||
random_hash = ssh_hash_new(&ssh_sha256);
|
||||
|
||||
while (--argc > 0) {
|
||||
char *p = *++argv;
|
||||
@ -1555,6 +1557,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
ssh_hash_free(random_hash);
|
||||
|
||||
if (npass == nrun) {
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
|
@ -86,11 +86,7 @@ static char *obfuscate_name(const char *realname)
|
||||
* We don't want to give away the length of the hostname either,
|
||||
* so having got it back out of CryptProtectMemory we now hash it.
|
||||
*/
|
||||
{
|
||||
ssh_hash *h = ssh_hash_new(&ssh_sha256);
|
||||
put_string(h, cryptdata, cryptlen);
|
||||
ssh_hash_final(h, digest);
|
||||
}
|
||||
hash_simple(&ssh_sha256, make_ptrlen(cryptdata, cryptlen), digest);
|
||||
|
||||
sfree(cryptdata);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user