mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Turn SSH hashes into a classoid.
The new version of ssh_hash has the same nice property as ssh2_mac, that I can make the generic interface object type function directly as a BinarySink so that clients don't have to call h->sink() and worry about the separate sink object they get back from that.
This commit is contained in:
parent
853bd8b284
commit
4f9a90fc1a
99
ssh.c
99
ssh.c
@ -668,8 +668,7 @@ enum RekeyClass {
|
||||
|
||||
struct ssh_tag {
|
||||
char *v_c, *v_s;
|
||||
void *exhash;
|
||||
BinarySink *exhash_bs;
|
||||
ssh_hash *exhash;
|
||||
|
||||
Socket s;
|
||||
|
||||
@ -4780,11 +4779,10 @@ static void add_to_commasep(strbuf *buf, const char *data)
|
||||
static void ssh2_mkkey(Ssh ssh, strbuf *out, Bignum K, unsigned char *H,
|
||||
char chr, int keylen)
|
||||
{
|
||||
const struct ssh_hash *h = ssh->kex->hash;
|
||||
const struct ssh_hashalg *h = ssh->kex->hash;
|
||||
int keylen_padded;
|
||||
unsigned char *key;
|
||||
void *s, *s2;
|
||||
BinarySink *bs;
|
||||
ssh_hash *s, *s2;
|
||||
|
||||
if (keylen == 0)
|
||||
return;
|
||||
@ -4805,32 +4803,30 @@ static void ssh2_mkkey(Ssh ssh, strbuf *out, Bignum K, unsigned char *H,
|
||||
key = strbuf_append(out, keylen_padded);
|
||||
|
||||
/* First hlen bytes. */
|
||||
s = h->init();
|
||||
bs = h->sink(s);
|
||||
s = ssh_hash_new(h);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
|
||||
put_mp_ssh2(bs, K);
|
||||
put_data(bs, H, h->hlen);
|
||||
put_byte(bs, chr);
|
||||
put_data(bs, ssh->v2_session_id, ssh->v2_session_id_len);
|
||||
h->final(s, key);
|
||||
put_mp_ssh2(s, K);
|
||||
put_data(s, H, h->hlen);
|
||||
put_byte(s, chr);
|
||||
put_data(s, ssh->v2_session_id, ssh->v2_session_id_len);
|
||||
ssh_hash_final(s, key);
|
||||
|
||||
/* Subsequent blocks of hlen bytes. */
|
||||
if (keylen_padded > h->hlen) {
|
||||
int offset;
|
||||
|
||||
s = h->init();
|
||||
bs = h->sink(s);
|
||||
s = ssh_hash_new(h);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
|
||||
put_mp_ssh2(bs, K);
|
||||
put_data(bs, H, h->hlen);
|
||||
put_mp_ssh2(s, K);
|
||||
put_data(s, H, h->hlen);
|
||||
|
||||
for (offset = h->hlen; offset < keylen_padded; offset += h->hlen) {
|
||||
put_data(bs, key + offset - h->hlen, h->hlen);
|
||||
s2 = h->copy(s);
|
||||
h->final(s2, key + offset);
|
||||
put_data(s, key + offset - h->hlen, h->hlen);
|
||||
s2 = ssh_hash_copy(s);
|
||||
ssh_hash_final(s2, key + offset);
|
||||
}
|
||||
|
||||
h->free(s);
|
||||
ssh_hash_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5600,14 +5596,13 @@ static void do_ssh2_transport(void *vctx)
|
||||
get_string(pktin); /* server->client language */
|
||||
s->ignorepkt = get_bool(pktin) && !s->guessok;
|
||||
|
||||
ssh->exhash = ssh->kex->hash->init();
|
||||
ssh->exhash_bs = ssh->kex->hash->sink(ssh->exhash);
|
||||
put_stringz(ssh->exhash_bs, ssh->v_c);
|
||||
put_stringz(ssh->exhash_bs, ssh->v_s);
|
||||
put_string(ssh->exhash_bs, s->our_kexinit, s->our_kexinitlen);
|
||||
ssh->exhash = ssh_hash_new(ssh->kex->hash);
|
||||
put_stringz(ssh->exhash, ssh->v_c);
|
||||
put_stringz(ssh->exhash, ssh->v_s);
|
||||
put_string(ssh->exhash, s->our_kexinit, s->our_kexinitlen);
|
||||
sfree(s->our_kexinit);
|
||||
/* Include the type byte in the hash of server's KEXINIT */
|
||||
put_string(ssh->exhash_bs,
|
||||
put_string(ssh->exhash,
|
||||
(const char *)BinarySource_UPCAST(pktin)->data - 1,
|
||||
BinarySource_UPCAST(pktin)->len + 1);
|
||||
|
||||
@ -5844,18 +5839,18 @@ static void do_ssh2_transport(void *vctx)
|
||||
* involve user interaction. */
|
||||
set_busy_status(ssh->frontend, BUSY_NOT);
|
||||
|
||||
put_stringpl(ssh->exhash_bs, s->hostkeydata);
|
||||
put_stringpl(ssh->exhash, s->hostkeydata);
|
||||
if (dh_is_gex(ssh->kex)) {
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
|
||||
put_uint32(ssh->exhash_bs, DH_MIN_SIZE);
|
||||
put_uint32(ssh->exhash_bs, s->pbits);
|
||||
put_uint32(ssh->exhash, DH_MIN_SIZE);
|
||||
put_uint32(ssh->exhash, s->pbits);
|
||||
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
|
||||
put_uint32(ssh->exhash_bs, DH_MAX_SIZE);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->p);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->g);
|
||||
put_uint32(ssh->exhash, DH_MAX_SIZE);
|
||||
put_mp_ssh2(ssh->exhash, s->p);
|
||||
put_mp_ssh2(ssh->exhash, s->g);
|
||||
}
|
||||
put_mp_ssh2(ssh->exhash_bs, s->e);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->f);
|
||||
put_mp_ssh2(ssh->exhash, s->e);
|
||||
put_mp_ssh2(ssh->exhash, s->f);
|
||||
|
||||
dh_cleanup(ssh->kex_ctx);
|
||||
freebn(s->f);
|
||||
@ -5893,19 +5888,19 @@ static void do_ssh2_transport(void *vctx)
|
||||
}
|
||||
|
||||
s->hostkeydata = get_string(pktin);
|
||||
put_stringpl(ssh->exhash_bs, s->hostkeydata);
|
||||
put_stringpl(ssh->exhash, s->hostkeydata);
|
||||
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
|
||||
|
||||
{
|
||||
strbuf *pubpoint = strbuf_new();
|
||||
ssh_ecdhkex_getpublic(s->eckey, BinarySink_UPCAST(pubpoint));
|
||||
put_string(ssh->exhash_bs, pubpoint->u, pubpoint->len);
|
||||
put_string(ssh->exhash, pubpoint->u, pubpoint->len);
|
||||
strbuf_free(pubpoint);
|
||||
}
|
||||
|
||||
{
|
||||
ptrlen keydata = get_string(pktin);
|
||||
put_stringpl(ssh->exhash_bs, keydata);
|
||||
put_stringpl(ssh->exhash, keydata);
|
||||
s->K = ssh_ecdhkex_getkey(s->eckey, keydata.ptr, keydata.len);
|
||||
if (!get_err(pktin) && !s->K) {
|
||||
ssh_ecdhkex_freekey(s->eckey);
|
||||
@ -6100,7 +6095,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
if (ssh->hostkey_alg) {
|
||||
s->hkey = ssh_key_new_pub(ssh->hostkey_alg,
|
||||
s->hostkeydata);
|
||||
put_string(ssh->exhash_bs,
|
||||
put_string(ssh->exhash,
|
||||
s->hostkeydata.ptr, s->hostkeydata.len);
|
||||
}
|
||||
/*
|
||||
@ -6149,18 +6144,18 @@ static void do_ssh2_transport(void *vctx)
|
||||
set_busy_status(ssh->frontend, BUSY_NOT);
|
||||
|
||||
if (!s->hkey)
|
||||
put_stringz(ssh->exhash_bs, "");
|
||||
put_stringz(ssh->exhash, "");
|
||||
if (dh_is_gex(ssh->kex)) {
|
||||
/* min, preferred, max */
|
||||
put_uint32(ssh->exhash_bs, s->pbits);
|
||||
put_uint32(ssh->exhash_bs, s->pbits);
|
||||
put_uint32(ssh->exhash_bs, s->pbits * 2);
|
||||
put_uint32(ssh->exhash, s->pbits);
|
||||
put_uint32(ssh->exhash, s->pbits);
|
||||
put_uint32(ssh->exhash, s->pbits * 2);
|
||||
|
||||
put_mp_ssh2(ssh->exhash_bs, s->p);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->g);
|
||||
put_mp_ssh2(ssh->exhash, s->p);
|
||||
put_mp_ssh2(ssh->exhash, s->g);
|
||||
}
|
||||
put_mp_ssh2(ssh->exhash_bs, s->e);
|
||||
put_mp_ssh2(ssh->exhash_bs, s->f);
|
||||
put_mp_ssh2(ssh->exhash, s->e);
|
||||
put_mp_ssh2(ssh->exhash, s->f);
|
||||
|
||||
/*
|
||||
* MIC verification is done below, after we compute the hash
|
||||
@ -6192,7 +6187,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
}
|
||||
|
||||
s->hostkeydata = get_string(pktin);
|
||||
put_stringpl(ssh->exhash_bs, s->hostkeydata);
|
||||
put_stringpl(ssh->exhash, s->hostkeydata);
|
||||
s->hkey = ssh_key_new_pub(ssh->hostkey_alg, s->hostkeydata);
|
||||
|
||||
rsakeydata = get_string(pktin);
|
||||
@ -6203,7 +6198,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
crStopV;
|
||||
}
|
||||
|
||||
put_stringpl(ssh->exhash_bs, rsakeydata);
|
||||
put_stringpl(ssh->exhash, rsakeydata);
|
||||
|
||||
/*
|
||||
* Next, set up a shared secret K, of precisely KLEN -
|
||||
@ -6249,7 +6244,7 @@ static void do_ssh2_transport(void *vctx)
|
||||
put_string(s->pktout, outstr, outstrlen);
|
||||
ssh_pkt_write(ssh, s->pktout);
|
||||
|
||||
put_string(ssh->exhash_bs, outstr, outstrlen);
|
||||
put_string(ssh->exhash, outstr, outstrlen);
|
||||
|
||||
strbuf_free(buf);
|
||||
sfree(outstr);
|
||||
@ -6270,9 +6265,9 @@ static void do_ssh2_transport(void *vctx)
|
||||
}
|
||||
}
|
||||
|
||||
put_mp_ssh2(ssh->exhash_bs, s->K);
|
||||
assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
|
||||
ssh->kex->hash->final(ssh->exhash, s->exchange_hash);
|
||||
put_mp_ssh2(ssh->exhash, s->K);
|
||||
assert(ssh_hash_alg(ssh->exhash)->hlen <= sizeof(s->exchange_hash));
|
||||
ssh_hash_final(ssh->exhash, s->exchange_hash);
|
||||
|
||||
#ifndef NO_GSSAPI
|
||||
if (ssh->kex->main_type == KEXTYPE_GSS) {
|
||||
|
37
ssh.h
37
ssh.h
@ -331,11 +331,12 @@ int detect_attack(struct crcda_ctx *ctx, unsigned char *buf, uint32 len,
|
||||
/*
|
||||
* SSH2 RSA key exchange functions
|
||||
*/
|
||||
struct ssh_hash;
|
||||
struct ssh_hashalg;
|
||||
struct RSAKey *ssh_rsakex_newkey(const void *data, int len);
|
||||
void ssh_rsakex_freekey(struct RSAKey *key);
|
||||
int ssh_rsakex_klen(struct RSAKey *key);
|
||||
void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
|
||||
void ssh_rsakex_encrypt(const struct ssh_hashalg *h,
|
||||
unsigned char *in, int inlen,
|
||||
unsigned char *out, int outlen, struct RSAKey *key);
|
||||
|
||||
/*
|
||||
@ -527,20 +528,30 @@ int ssh2_mac_verresult(ssh2_mac *, const void *);
|
||||
void ssh2_mac_generate(ssh2_mac *, void *, int, unsigned long seq);
|
||||
int ssh2_mac_verify(ssh2_mac *, const void *, int, unsigned long seq);
|
||||
|
||||
struct ssh_hash {
|
||||
void *(*init)(void); /* also allocates context */
|
||||
void *(*copy)(const void *);
|
||||
BinarySink *(*sink) (void *);
|
||||
void (*final)(void *, unsigned char *); /* also frees context */
|
||||
void (*free)(void *);
|
||||
typedef struct ssh_hash {
|
||||
const struct ssh_hashalg *vt;
|
||||
BinarySink_DELEGATE_IMPLEMENTATION;
|
||||
} ssh_hash;
|
||||
|
||||
struct ssh_hashalg {
|
||||
ssh_hash *(*new)(const struct ssh_hashalg *alg);
|
||||
ssh_hash *(*copy)(ssh_hash *);
|
||||
void (*final)(ssh_hash *, unsigned char *); /* ALSO FREES THE ssh_hash! */
|
||||
void (*free)(ssh_hash *);
|
||||
int hlen; /* output length in bytes */
|
||||
const char *text_name;
|
||||
};
|
||||
|
||||
#define ssh_hash_new(alg) ((alg)->new(alg))
|
||||
#define ssh_hash_copy(ctx) ((ctx)->vt->copy(ctx))
|
||||
#define ssh_hash_final(ctx, out) ((ctx)->vt->final(ctx, out))
|
||||
#define ssh_hash_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh_hash_alg(ctx) ((ctx)->vt)
|
||||
|
||||
struct ssh_kex {
|
||||
const char *name, *groupname;
|
||||
enum { KEXTYPE_DH, KEXTYPE_RSA, KEXTYPE_ECDH, KEXTYPE_GSS } main_type;
|
||||
const struct ssh_hash *hash;
|
||||
const struct ssh_hashalg *hash;
|
||||
const void *extra; /* private to the kex methods */
|
||||
};
|
||||
|
||||
@ -625,10 +636,10 @@ extern const struct ssh2_ciphers ssh2_aes;
|
||||
extern const struct ssh2_ciphers ssh2_blowfish;
|
||||
extern const struct ssh2_ciphers ssh2_arcfour;
|
||||
extern const struct ssh2_ciphers ssh2_ccp;
|
||||
extern const struct ssh_hash ssh_sha1;
|
||||
extern const struct ssh_hash ssh_sha256;
|
||||
extern const struct ssh_hash ssh_sha384;
|
||||
extern const struct ssh_hash ssh_sha512;
|
||||
extern const struct ssh_hashalg ssh_sha1;
|
||||
extern const struct ssh_hashalg ssh_sha256;
|
||||
extern const struct ssh_hashalg ssh_sha384;
|
||||
extern const struct ssh_hashalg ssh_sha512;
|
||||
extern const struct ssh_kexes ssh_diffiehellman_group1;
|
||||
extern const struct ssh_kexes ssh_diffiehellman_group14;
|
||||
extern const struct ssh_kexes ssh_diffiehellman_gex;
|
||||
|
18
sshecc.c
18
sshecc.c
@ -1688,7 +1688,7 @@ static int BinarySource_get_point(BinarySource *src, struct ec_point *point)
|
||||
|
||||
struct ecsign_extra {
|
||||
struct ec_curve *(*curve)(void);
|
||||
const struct ssh_hash *hash;
|
||||
const struct ssh_hashalg *hash;
|
||||
|
||||
/* These fields are used by the OpenSSH PEM format importer/exporter */
|
||||
const unsigned char *oid;
|
||||
@ -2227,7 +2227,7 @@ static int ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
Bignum r, s;
|
||||
unsigned char digest[512 / 8];
|
||||
int digestLen;
|
||||
void *hashctx;
|
||||
ssh_hash *hashctx;
|
||||
|
||||
BinarySource_BARE_INIT(src, sigstr.ptr, sigstr.len);
|
||||
|
||||
@ -2241,9 +2241,9 @@ static int ecdsa_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
|
||||
digestLen = extra->hash->hlen;
|
||||
assert(digestLen <= sizeof(digest));
|
||||
hashctx = extra->hash->init();
|
||||
put_data(extra->hash->sink(hashctx), data.ptr, data.len);
|
||||
extra->hash->final(hashctx, digest);
|
||||
hashctx = ssh_hash_new(extra->hash);
|
||||
put_data(hashctx, data.ptr, data.len);
|
||||
ssh_hash_final(hashctx, digest);
|
||||
|
||||
/* Verify the signature */
|
||||
ret = _ecdsa_verify(&ec->publicKey, digest, digestLen, r, s);
|
||||
@ -2363,14 +2363,14 @@ static void ecdsa_sign(ssh_key *key, const void *data, int datalen,
|
||||
put_byte(bs, bignum_byte(s, i));
|
||||
freebn(s);
|
||||
} else {
|
||||
void *hashctx;
|
||||
ssh_hash *hashctx;
|
||||
strbuf *substr;
|
||||
|
||||
digestLen = extra->hash->hlen;
|
||||
assert(digestLen <= sizeof(digest));
|
||||
hashctx = extra->hash->init();
|
||||
put_data(extra->hash->sink(hashctx), data, datalen);
|
||||
extra->hash->final(hashctx, digest);
|
||||
hashctx = ssh_hash_new(extra->hash);
|
||||
put_data(hashctx, data, datalen);
|
||||
ssh_hash_final(hashctx, digest);
|
||||
|
||||
/* Do the signature */
|
||||
_ecdsa_sign(ec->privateKey, ec->publicKey.curve, digest, digestLen, &r, &s);
|
||||
|
22
sshrsa.c
22
sshrsa.c
@ -783,7 +783,7 @@ int ssh_rsakex_klen(struct RSAKey *rsa)
|
||||
return bignum_bitcount(rsa->modulus);
|
||||
}
|
||||
|
||||
static void oaep_mask(const struct ssh_hash *h, void *seed, int seedlen,
|
||||
static void oaep_mask(const struct ssh_hashalg *h, void *seed, int seedlen,
|
||||
void *vdata, int datalen)
|
||||
{
|
||||
unsigned char *data = (unsigned char *)vdata;
|
||||
@ -791,16 +791,14 @@ static void oaep_mask(const struct ssh_hash *h, void *seed, int seedlen,
|
||||
|
||||
while (datalen > 0) {
|
||||
int i, max = (datalen > h->hlen ? h->hlen : datalen);
|
||||
void *s;
|
||||
BinarySink *bs;
|
||||
ssh_hash *s;
|
||||
unsigned char hash[SSH2_KEX_MAX_HASH_LEN];
|
||||
|
||||
assert(h->hlen <= SSH2_KEX_MAX_HASH_LEN);
|
||||
s = h->init();
|
||||
bs = h->sink(s);
|
||||
put_data(bs, seed, seedlen);
|
||||
put_uint32(bs, count);
|
||||
h->final(s, hash);
|
||||
s = ssh_hash_new(h);
|
||||
put_data(s, seed, seedlen);
|
||||
put_uint32(s, count);
|
||||
ssh_hash_final(s, hash);
|
||||
count++;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
@ -811,7 +809,8 @@ static void oaep_mask(const struct ssh_hash *h, void *seed, int seedlen,
|
||||
}
|
||||
}
|
||||
|
||||
void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
|
||||
void ssh_rsakex_encrypt(const struct ssh_hashalg *h,
|
||||
unsigned char *in, int inlen,
|
||||
unsigned char *out, int outlen, struct RSAKey *rsa)
|
||||
{
|
||||
Bignum b1, b2;
|
||||
@ -866,7 +865,10 @@ void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
|
||||
out[i + 1] = random_byte();
|
||||
/* At position 1+HLEN, the data block DB, consisting of: */
|
||||
/* The hash of the label (we only support an empty label here) */
|
||||
h->final(h->init(), out + HLEN + 1);
|
||||
{
|
||||
ssh_hash *s = ssh_hash_new(h);
|
||||
ssh_hash_final(s, 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. */
|
||||
|
62
sshsh256.c
62
sshsh256.c
@ -204,51 +204,51 @@ void SHA256_Simple(const void *p, int len, unsigned char *output) {
|
||||
* Thin abstraction for things where hashes are pluggable.
|
||||
*/
|
||||
|
||||
static void *sha256_init(void)
|
||||
{
|
||||
SHA256_State *s;
|
||||
struct sha256_hash {
|
||||
SHA256_State state;
|
||||
ssh_hash hash;
|
||||
};
|
||||
|
||||
s = snew(SHA256_State);
|
||||
SHA256_Init(s);
|
||||
return s;
|
||||
static ssh_hash *sha256_new(const struct ssh_hashalg *alg)
|
||||
{
|
||||
struct sha256_hash *h = snew(struct sha256_hash);
|
||||
SHA256_Init(&h->state);
|
||||
h->hash.vt = alg;
|
||||
BinarySink_DELEGATE_INIT(&h->hash, &h->state);
|
||||
return &h->hash;
|
||||
}
|
||||
|
||||
static void *sha256_copy(const void *vold)
|
||||
static ssh_hash *sha256_copy(ssh_hash *hashold)
|
||||
{
|
||||
const SHA256_State *old = (const SHA256_State *)vold;
|
||||
SHA256_State *s;
|
||||
struct sha256_hash *hold, *hnew;
|
||||
ssh_hash *hashnew = sha256_new(hashold->vt);
|
||||
|
||||
s = snew(SHA256_State);
|
||||
*s = *old;
|
||||
BinarySink_COPIED(s);
|
||||
return s;
|
||||
hold = FROMFIELD(hashold, struct sha256_hash, hash);
|
||||
hnew = FROMFIELD(hashnew, struct sha256_hash, hash);
|
||||
|
||||
hnew->state = hold->state;
|
||||
BinarySink_COPIED(&hnew->state);
|
||||
|
||||
return hashnew;
|
||||
}
|
||||
|
||||
static void sha256_free(void *handle)
|
||||
static void sha256_free(ssh_hash *hash)
|
||||
{
|
||||
SHA256_State *s = handle;
|
||||
struct sha256_hash *h = FROMFIELD(hash, struct sha256_hash, hash);
|
||||
|
||||
smemclr(s, sizeof(*s));
|
||||
sfree(s);
|
||||
smemclr(h, sizeof(*h));
|
||||
sfree(h);
|
||||
}
|
||||
|
||||
static BinarySink *sha256_sink(void *handle)
|
||||
static void sha256_final(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
SHA256_State *s = handle;
|
||||
return BinarySink_UPCAST(s);
|
||||
struct sha256_hash *h = FROMFIELD(hash, struct sha256_hash, hash);
|
||||
SHA256_Final(&h->state, output);
|
||||
sha256_free(hash);
|
||||
}
|
||||
|
||||
static void sha256_final(void *handle, unsigned char *output)
|
||||
{
|
||||
SHA256_State *s = handle;
|
||||
|
||||
SHA256_Final(s, output);
|
||||
sha256_free(s);
|
||||
}
|
||||
|
||||
const struct ssh_hash ssh_sha256 = {
|
||||
sha256_init, sha256_copy, sha256_sink, sha256_final, sha256_free,
|
||||
32, "SHA-256"
|
||||
const struct ssh_hashalg ssh_sha256 = {
|
||||
sha256_new, sha256_copy, sha256_final, sha256_free, 32, "SHA-256"
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
115
sshsh512.c
115
sshsh512.c
@ -327,74 +327,71 @@ void SHA384_Simple(const void *p, int len, unsigned char *output) {
|
||||
* Thin abstraction for things where hashes are pluggable.
|
||||
*/
|
||||
|
||||
static void *sha512_init(void)
|
||||
{
|
||||
SHA512_State *s;
|
||||
|
||||
s = snew(SHA512_State);
|
||||
SHA512_Init(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void *sha512_copy(const void *vold)
|
||||
{
|
||||
const SHA512_State *old = (const SHA512_State *)vold;
|
||||
SHA512_State *s;
|
||||
|
||||
s = snew(SHA512_State);
|
||||
*s = *old;
|
||||
BinarySink_COPIED(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void sha512_free(void *handle)
|
||||
{
|
||||
SHA512_State *s = handle;
|
||||
|
||||
smemclr(s, sizeof(*s));
|
||||
sfree(s);
|
||||
}
|
||||
|
||||
static BinarySink *sha512_sink(void *handle)
|
||||
{
|
||||
SHA512_State *s = handle;
|
||||
return BinarySink_UPCAST(s);
|
||||
}
|
||||
|
||||
static void sha512_final(void *handle, unsigned char *output)
|
||||
{
|
||||
SHA512_State *s = handle;
|
||||
|
||||
SHA512_Final(s, output);
|
||||
sha512_free(s);
|
||||
}
|
||||
|
||||
const struct ssh_hash ssh_sha512 = {
|
||||
sha512_init, sha512_copy, sha512_sink, sha512_final, sha512_free,
|
||||
64, "SHA-512"
|
||||
struct sha512_hash {
|
||||
SHA512_State state;
|
||||
ssh_hash hash;
|
||||
};
|
||||
|
||||
static void *sha384_init(void)
|
||||
static ssh_hash *sha512_new(const struct ssh_hashalg *alg)
|
||||
{
|
||||
SHA512_State *s;
|
||||
|
||||
s = snew(SHA512_State);
|
||||
SHA384_Init(s);
|
||||
return s;
|
||||
struct sha512_hash *h = snew(struct sha512_hash);
|
||||
SHA512_Init(&h->state);
|
||||
h->hash.vt = alg;
|
||||
BinarySink_DELEGATE_INIT(&h->hash, &h->state);
|
||||
return &h->hash;
|
||||
}
|
||||
|
||||
static void sha384_final(void *handle, unsigned char *output)
|
||||
static ssh_hash *sha512_copy(ssh_hash *hashold)
|
||||
{
|
||||
SHA512_State *s = handle;
|
||||
struct sha512_hash *hold, *hnew;
|
||||
ssh_hash *hashnew = sha512_new(hashold->vt);
|
||||
|
||||
SHA384_Final(s, output);
|
||||
smemclr(s, sizeof(*s));
|
||||
sfree(s);
|
||||
hold = FROMFIELD(hashold, struct sha512_hash, hash);
|
||||
hnew = FROMFIELD(hashnew, struct sha512_hash, hash);
|
||||
|
||||
hnew->state = hold->state;
|
||||
BinarySink_COPIED(&hnew->state);
|
||||
|
||||
return hashnew;
|
||||
}
|
||||
|
||||
const struct ssh_hash ssh_sha384 = {
|
||||
sha384_init, sha512_copy, sha512_sink, sha384_final, sha512_free,
|
||||
48, "SHA-384"
|
||||
static void sha512_free(ssh_hash *hash)
|
||||
{
|
||||
struct sha512_hash *h = FROMFIELD(hash, struct sha512_hash, hash);
|
||||
|
||||
smemclr(h, sizeof(*h));
|
||||
sfree(h);
|
||||
}
|
||||
|
||||
static void sha512_final(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
struct sha512_hash *h = FROMFIELD(hash, struct sha512_hash, hash);
|
||||
SHA512_Final(&h->state, output);
|
||||
sha512_free(hash);
|
||||
}
|
||||
|
||||
const struct ssh_hashalg ssh_sha512 = {
|
||||
sha512_new, sha512_copy, sha512_final, sha512_free, 64, "SHA-512"
|
||||
};
|
||||
|
||||
static ssh_hash *sha384_new(const struct ssh_hashalg *alg)
|
||||
{
|
||||
struct sha512_hash *h = snew(struct sha512_hash);
|
||||
SHA384_Init(&h->state);
|
||||
h->hash.vt = alg;
|
||||
BinarySink_DELEGATE_INIT(&h->hash, &h->state);
|
||||
return &h->hash;
|
||||
}
|
||||
|
||||
static void sha384_final(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
struct sha512_hash *h = FROMFIELD(hash, struct sha512_hash, hash);
|
||||
SHA384_Final(&h->state, output);
|
||||
sha512_free(hash);
|
||||
}
|
||||
|
||||
const struct ssh_hashalg ssh_sha384 = {
|
||||
sha384_new, sha512_copy, sha384_final, sha512_free, 48, "SHA-384"
|
||||
};
|
||||
|
||||
#ifdef TEST
|
||||
|
61
sshsha.c
61
sshsha.c
@ -232,50 +232,51 @@ void SHA_Simple(const void *p, int len, unsigned char *output)
|
||||
* Thin abstraction for things where hashes are pluggable.
|
||||
*/
|
||||
|
||||
static void *sha1_init(void)
|
||||
{
|
||||
SHA_State *s;
|
||||
struct sha1_hash {
|
||||
SHA_State state;
|
||||
ssh_hash hash;
|
||||
};
|
||||
|
||||
s = snew(SHA_State);
|
||||
SHA_Init(s);
|
||||
return s;
|
||||
static ssh_hash *sha1_new(const struct ssh_hashalg *alg)
|
||||
{
|
||||
struct sha1_hash *h = snew(struct sha1_hash);
|
||||
SHA_Init(&h->state);
|
||||
h->hash.vt = alg;
|
||||
BinarySink_DELEGATE_INIT(&h->hash, &h->state);
|
||||
return &h->hash;
|
||||
}
|
||||
|
||||
static void *sha1_copy(const void *vold)
|
||||
static ssh_hash *sha1_copy(ssh_hash *hashold)
|
||||
{
|
||||
const SHA_State *old = (const SHA_State *)vold;
|
||||
SHA_State *s;
|
||||
struct sha1_hash *hold, *hnew;
|
||||
ssh_hash *hashnew = sha1_new(hashold->vt);
|
||||
|
||||
s = snew(SHA_State);
|
||||
*s = *old;
|
||||
BinarySink_COPIED(s);
|
||||
return s;
|
||||
hold = FROMFIELD(hashold, struct sha1_hash, hash);
|
||||
hnew = FROMFIELD(hashnew, struct sha1_hash, hash);
|
||||
|
||||
hnew->state = hold->state;
|
||||
BinarySink_COPIED(&hnew->state);
|
||||
|
||||
return hashnew;
|
||||
}
|
||||
|
||||
static void sha1_free(void *handle)
|
||||
static void sha1_free(ssh_hash *hash)
|
||||
{
|
||||
SHA_State *s = handle;
|
||||
struct sha1_hash *h = FROMFIELD(hash, struct sha1_hash, hash);
|
||||
|
||||
smemclr(s, sizeof(*s));
|
||||
sfree(s);
|
||||
smemclr(h, sizeof(*h));
|
||||
sfree(h);
|
||||
}
|
||||
|
||||
static BinarySink *sha1_sink(void *handle)
|
||||
static void sha1_final(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
SHA_State *s = handle;
|
||||
return BinarySink_UPCAST(s);
|
||||
struct sha1_hash *h = FROMFIELD(hash, struct sha1_hash, hash);
|
||||
SHA_Final(&h->state, output);
|
||||
sha1_free(hash);
|
||||
}
|
||||
|
||||
static void sha1_final(void *handle, unsigned char *output)
|
||||
{
|
||||
SHA_State *s = handle;
|
||||
|
||||
SHA_Final(s, output);
|
||||
sha1_free(s);
|
||||
}
|
||||
|
||||
const struct ssh_hash ssh_sha1 = {
|
||||
sha1_init, sha1_copy, sha1_sink, sha1_final, sha1_free, 20, "SHA-1"
|
||||
const struct ssh_hashalg ssh_sha1 = {
|
||||
sha1_new, sha1_copy, sha1_final, sha1_free, 20, "SHA-1"
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user