зеркало из https://github.com/github/putty.git
Refactor the ssh_hash vtable. (NFC)
The idea is to arrange that an ssh_hash object can be reused without having to free it and allocate a new one. So the 'final' method has been replaced with 'digest', which does everything except the trailing free; and there's also a new pair of methods 'reset' and 'copyfrom' which overwrite the state of a hash with either the starting state or a copy of another state. Meanwhile, the 'new' allocator function has stopped performing 'reset' as a side effect; now it _just_ does the administrative stuff (allocation, setting up vtables), and returns an object which isn't yet ready to receive any actual data, expecting that the caller will either reset it or copy another hash state into it. In particular, that means that the SHA-384 / SHA-512 pair no longer need separate 'new' methods, because only the 'reset' part has to change between them. This commit makes no change to the user-facing API of wrapper functions in ssh.h, except to add new functions which nothing yet calls. The user-facing ssh_hash_new() calls the new and reset methods in succession, and the copy and final methods still exist to do new+copy and digest+free.
This commit is contained in:
Родитель
859c81e838
Коммит
156762fc02
26
ssh.h
26
ssh.h
|
@ -715,8 +715,9 @@ struct ssh_hash {
|
|||
|
||||
struct ssh_hashalg {
|
||||
ssh_hash *(*new)(const ssh_hashalg *alg);
|
||||
ssh_hash *(*copy)(ssh_hash *);
|
||||
void (*final)(ssh_hash *, unsigned char *); /* ALSO FREES THE ssh_hash! */
|
||||
void (*reset)(ssh_hash *);
|
||||
void (*copyfrom)(ssh_hash *dest, ssh_hash *src);
|
||||
void (*digest)(ssh_hash *, unsigned char *);
|
||||
void (*free)(ssh_hash *);
|
||||
int hlen; /* output length in bytes */
|
||||
int blocklen; /* length of the hash's input block, or 0 for N/A */
|
||||
|
@ -726,16 +727,27 @@ struct ssh_hashalg {
|
|||
};
|
||||
|
||||
static inline ssh_hash *ssh_hash_new(const ssh_hashalg *alg)
|
||||
{ return alg->new(alg); }
|
||||
static inline ssh_hash *ssh_hash_copy(ssh_hash *h)
|
||||
{ return h->vt->copy(h); }
|
||||
static inline void ssh_hash_final(ssh_hash *h, unsigned char *out)
|
||||
{ h->vt->final(h, out); }
|
||||
{ ssh_hash *h = alg->new(alg); if (h) h->vt->reset(h); return h; }
|
||||
static inline ssh_hash *ssh_hash_copy(ssh_hash *orig)
|
||||
{ ssh_hash *h = orig->vt->new(orig->vt); h->vt->copyfrom(h, orig); return h; }
|
||||
static inline void ssh_hash_digest(ssh_hash *h, unsigned char *out)
|
||||
{ h->vt->digest(h, out); }
|
||||
static inline void ssh_hash_free(ssh_hash *h)
|
||||
{ h->vt->free(h); }
|
||||
static inline const ssh_hashalg *ssh_hash_alg(ssh_hash *h)
|
||||
{ return h->vt; }
|
||||
|
||||
/* The reset and copyfrom vtable methods return void. But for call-site
|
||||
* convenience, these wrappers return their input pointer. */
|
||||
static inline ssh_hash *ssh_hash_reset(ssh_hash *h)
|
||||
{ h->vt->reset(h); return h; }
|
||||
static inline ssh_hash *ssh_hash_copyfrom(ssh_hash *dest, ssh_hash *src)
|
||||
{ dest->vt->copyfrom(dest, src); return dest; }
|
||||
|
||||
/* ssh_hash_final emits the digest _and_ frees the ssh_hash */
|
||||
static inline void ssh_hash_final(ssh_hash *h, unsigned char *out)
|
||||
{ h->vt->digest(h, out); h->vt->free(h); }
|
||||
|
||||
/* Handy macros for defining all those text-name fields at once */
|
||||
#define HASHALG_NAMES_BARE(base) \
|
||||
base, NULL, base
|
||||
|
|
26
sshmd5.c
26
sshmd5.c
|
@ -235,24 +235,24 @@ struct md5_hash {
|
|||
static ssh_hash *md5_new(const ssh_hashalg *alg)
|
||||
{
|
||||
struct md5_hash *h = snew(struct md5_hash);
|
||||
MD5Init(&h->state);
|
||||
h->hash.vt = alg;
|
||||
BinarySink_DELEGATE_INIT(&h->hash, &h->state);
|
||||
return &h->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *md5_copy(ssh_hash *hashold)
|
||||
static void md5_reset(ssh_hash *hash)
|
||||
{
|
||||
struct md5_hash *hold, *hnew;
|
||||
ssh_hash *hashnew = md5_new(hashold->vt);
|
||||
struct md5_hash *h = container_of(hash, struct md5_hash, hash);
|
||||
MD5Init(&h->state);
|
||||
}
|
||||
|
||||
hold = container_of(hashold, struct md5_hash, hash);
|
||||
hnew = container_of(hashnew, struct md5_hash, hash);
|
||||
static void md5_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
struct md5_hash *copy = container_of(hcopy, struct md5_hash, hash);
|
||||
struct md5_hash *orig = container_of(horig, struct md5_hash, hash);
|
||||
|
||||
hnew->state = hold->state;
|
||||
BinarySink_COPIED(&hnew->state);
|
||||
|
||||
return hashnew;
|
||||
copy->state = orig->state;
|
||||
BinarySink_COPIED(©->state);
|
||||
}
|
||||
|
||||
static void md5_free(ssh_hash *hash)
|
||||
|
@ -263,13 +263,13 @@ static void md5_free(ssh_hash *hash)
|
|||
sfree(h);
|
||||
}
|
||||
|
||||
static void md5_final(ssh_hash *hash, unsigned char *output)
|
||||
static void md5_digest(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
struct md5_hash *h = container_of(hash, struct md5_hash, hash);
|
||||
MD5Final(output, &h->state);
|
||||
md5_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_md5 = {
|
||||
md5_new, md5_copy, md5_final, md5_free, 16, 64, HASHALG_NAMES_BARE("MD5"),
|
||||
md5_new, md5_reset, md5_copyfrom, md5_digest, md5_free,
|
||||
16, 64, HASHALG_NAMES_BARE("MD5"),
|
||||
};
|
||||
|
|
100
sshsh256.c
100
sshsh256.c
|
@ -98,7 +98,7 @@ static ssh_hash *sha256_select(const ssh_hashalg *alg)
|
|||
}
|
||||
|
||||
const ssh_hashalg ssh_sha256 = {
|
||||
sha256_select, NULL, NULL, NULL,
|
||||
sha256_select, NULL, NULL, NULL, NULL,
|
||||
32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "dummy selector vtable"),
|
||||
};
|
||||
|
||||
|
@ -276,26 +276,28 @@ static ssh_hash *sha256_sw_new(const ssh_hashalg *alg)
|
|||
{
|
||||
sha256_sw *s = snew(sha256_sw);
|
||||
|
||||
memcpy(s->core, sha256_initial_state, sizeof(s->core));
|
||||
|
||||
sha256_block_setup(&s->blk);
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha256_sw_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *sha256_sw_copy(ssh_hash *hash)
|
||||
static void sha256_sw_reset(ssh_hash *hash)
|
||||
{
|
||||
sha256_sw *s = container_of(hash, sha256_sw, hash);
|
||||
sha256_sw *copy = snew(sha256_sw);
|
||||
|
||||
memcpy(copy, s, sizeof(*copy));
|
||||
memcpy(s->core, sha256_initial_state, sizeof(s->core));
|
||||
sha256_block_setup(&s->blk);
|
||||
}
|
||||
|
||||
static void sha256_sw_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
sha256_sw *copy = container_of(hcopy, sha256_sw, hash);
|
||||
sha256_sw *orig = container_of(horig, sha256_sw, hash);
|
||||
|
||||
memcpy(copy, orig, sizeof(*copy));
|
||||
BinarySink_COPIED(copy);
|
||||
BinarySink_DELEGATE_INIT(©->hash, copy);
|
||||
|
||||
return ©->hash;
|
||||
}
|
||||
|
||||
static void sha256_sw_free(ssh_hash *hash)
|
||||
|
@ -315,18 +317,18 @@ static void sha256_sw_write(BinarySink *bs, const void *vp, size_t len)
|
|||
sha256_sw_block(s->core, s->blk.block);
|
||||
}
|
||||
|
||||
static void sha256_sw_final(ssh_hash *hash, uint8_t *digest)
|
||||
static void sha256_sw_digest(ssh_hash *hash, uint8_t *digest)
|
||||
{
|
||||
sha256_sw *s = container_of(hash, sha256_sw, hash);
|
||||
|
||||
sha256_block_pad(&s->blk, BinarySink_UPCAST(s));
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
PUT_32BIT_MSB_FIRST(digest + 4*i, s->core[i]);
|
||||
sha256_sw_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha256_sw = {
|
||||
sha256_sw_new, sha256_sw_copy, sha256_sw_final, sha256_sw_free,
|
||||
sha256_sw_new, sha256_sw_reset, sha256_sw_copyfrom, sha256_sw_digest,
|
||||
sha256_sw_free,
|
||||
32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "unaccelerated"),
|
||||
};
|
||||
|
||||
|
@ -602,13 +604,24 @@ static sha256_ni *sha256_ni_alloc(void)
|
|||
return s;
|
||||
}
|
||||
|
||||
FUNC_ISA static ssh_hash *sha256_ni_new(const ssh_hashalg *alg)
|
||||
static ssh_hash *sha256_ni_new(const ssh_hashalg *alg)
|
||||
{
|
||||
if (!sha256_hw_available_cached())
|
||||
return NULL;
|
||||
|
||||
sha256_ni *s = sha256_ni_alloc();
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha256_ni_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
FUNC_ISA static void sha256_ni_reset(ssh_hash *hash)
|
||||
{
|
||||
sha256_ni *s = container_of(hash, sha256_ni, hash);
|
||||
|
||||
/* Initialise the core vectors in their storage order */
|
||||
s->core[0] = _mm_set_epi64x(
|
||||
0x6a09e667bb67ae85ULL, 0x510e527f9b05688cULL);
|
||||
|
@ -616,26 +629,19 @@ FUNC_ISA static ssh_hash *sha256_ni_new(const ssh_hashalg *alg)
|
|||
0x3c6ef372a54ff53aULL, 0x1f83d9ab5be0cd19ULL);
|
||||
|
||||
sha256_block_setup(&s->blk);
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha256_ni_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *sha256_ni_copy(ssh_hash *hash)
|
||||
static void sha256_ni_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
sha256_ni *s = container_of(hash, sha256_ni, hash);
|
||||
sha256_ni *copy = sha256_ni_alloc();
|
||||
sha256_ni *copy = container_of(hcopy, sha256_ni, hash);
|
||||
sha256_ni *orig = container_of(horig, sha256_ni, hash);
|
||||
|
||||
void *ptf_save = copy->pointer_to_free;
|
||||
*copy = *s; /* structure copy */
|
||||
*copy = *orig; /* structure copy */
|
||||
copy->pointer_to_free = ptf_save;
|
||||
|
||||
BinarySink_COPIED(copy);
|
||||
BinarySink_DELEGATE_INIT(©->hash, copy);
|
||||
|
||||
return ©->hash;
|
||||
}
|
||||
|
||||
static void sha256_ni_free(ssh_hash *hash)
|
||||
|
@ -656,7 +662,7 @@ static void sha256_ni_write(BinarySink *bs, const void *vp, size_t len)
|
|||
sha256_ni_block(s->core, s->blk.block);
|
||||
}
|
||||
|
||||
FUNC_ISA static void sha256_ni_final(ssh_hash *hash, uint8_t *digest)
|
||||
FUNC_ISA static void sha256_ni_digest(ssh_hash *hash, uint8_t *digest)
|
||||
{
|
||||
sha256_ni *s = container_of(hash, sha256_ni, hash);
|
||||
|
||||
|
@ -677,12 +683,11 @@ FUNC_ISA static void sha256_ni_final(ssh_hash *hash, uint8_t *digest)
|
|||
__m128i *output = (__m128i *)digest;
|
||||
_mm_storeu_si128(output, dcba);
|
||||
_mm_storeu_si128(output+1, hgfe);
|
||||
|
||||
sha256_ni_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha256_hw = {
|
||||
sha256_ni_new, sha256_ni_copy, sha256_ni_final, sha256_ni_free,
|
||||
sha256_ni_new, sha256_ni_reset, sha256_ni_copyfrom, sha256_ni_digest,
|
||||
sha256_ni_free,
|
||||
32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "SHA-NI accelerated"),
|
||||
};
|
||||
|
||||
|
@ -818,28 +823,31 @@ static ssh_hash *sha256_neon_new(const ssh_hashalg *alg)
|
|||
|
||||
sha256_neon *s = snew(sha256_neon);
|
||||
|
||||
s->core.abcd = vld1q_u32(sha256_initial_state);
|
||||
s->core.efgh = vld1q_u32(sha256_initial_state + 4);
|
||||
|
||||
sha256_block_setup(&s->blk);
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha256_neon_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *sha256_neon_copy(ssh_hash *hash)
|
||||
static void sha256_neon_reset(ssh_hash *hash)
|
||||
{
|
||||
sha256_neon *s = container_of(hash, sha256_neon, hash);
|
||||
sha256_neon *copy = snew(sha256_neon);
|
||||
|
||||
*copy = *s; /* structure copy */
|
||||
s->core.abcd = vld1q_u32(sha256_initial_state);
|
||||
s->core.efgh = vld1q_u32(sha256_initial_state + 4);
|
||||
|
||||
sha256_block_setup(&s->blk);
|
||||
}
|
||||
|
||||
static void sha256_neon_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
sha256_neon *copy = container_of(hcopy, sha256_neon, hash);
|
||||
sha256_neon *orig = container_of(horig, sha256_neon, hash);
|
||||
|
||||
*copy = *orig; /* structure copy */
|
||||
|
||||
BinarySink_COPIED(copy);
|
||||
BinarySink_DELEGATE_INIT(©->hash, copy);
|
||||
|
||||
return ©->hash;
|
||||
}
|
||||
|
||||
static void sha256_neon_free(ssh_hash *hash)
|
||||
|
@ -858,18 +866,18 @@ static void sha256_neon_write(BinarySink *bs, const void *vp, size_t len)
|
|||
sha256_neon_block(&s->core, s->blk.block);
|
||||
}
|
||||
|
||||
static void sha256_neon_final(ssh_hash *hash, uint8_t *digest)
|
||||
static void sha256_neon_digest(ssh_hash *hash, uint8_t *digest)
|
||||
{
|
||||
sha256_neon *s = container_of(hash, sha256_neon, hash);
|
||||
|
||||
sha256_block_pad(&s->blk, BinarySink_UPCAST(s));
|
||||
vst1q_u8(digest, vrev32q_u8(vreinterpretq_u8_u32(s->core.abcd)));
|
||||
vst1q_u8(digest + 16, vrev32q_u8(vreinterpretq_u8_u32(s->core.efgh)));
|
||||
sha256_neon_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha256_hw = {
|
||||
sha256_neon_new, sha256_neon_copy, sha256_neon_final, sha256_neon_free,
|
||||
sha256_neon_new, sha256_neon_reset, sha256_neon_copyfrom,
|
||||
sha256_neon_digest, sha256_neon_free,
|
||||
32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "NEON accelerated"),
|
||||
};
|
||||
|
||||
|
@ -895,12 +903,14 @@ static ssh_hash *sha256_stub_new(const ssh_hashalg *alg)
|
|||
|
||||
#define STUB_BODY { unreachable("Should never be called"); }
|
||||
|
||||
static ssh_hash *sha256_stub_copy(ssh_hash *hash) STUB_BODY
|
||||
static void sha256_stub_reset(ssh_hash *hash) STUB_BODY
|
||||
static void sha256_stub_copyfrom(ssh_hash *hash, ssh_hash *orig) STUB_BODY
|
||||
static void sha256_stub_free(ssh_hash *hash) STUB_BODY
|
||||
static void sha256_stub_final(ssh_hash *hash, uint8_t *digest) STUB_BODY
|
||||
static void sha256_stub_digest(ssh_hash *hash, uint8_t *digest) STUB_BODY
|
||||
|
||||
const ssh_hashalg ssh_sha256_hw = {
|
||||
sha256_stub_new, sha256_stub_copy, sha256_stub_final, sha256_stub_free,
|
||||
sha256_stub_new, sha256_stub_reset, sha256_stub_copyfrom,
|
||||
sha256_stub_digest, sha256_stub_free,
|
||||
32, 64, HASHALG_NAMES_ANNOTATED(
|
||||
"SHA-256", "!NONEXISTENT ACCELERATED VERSION!"),
|
||||
};
|
||||
|
|
35
sshsh512.c
35
sshsh512.c
|
@ -307,24 +307,24 @@ struct sha512_hash {
|
|||
static ssh_hash *sha512_new(const ssh_hashalg *alg)
|
||||
{
|
||||
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;
|
||||
return ssh_hash_reset(&h->hash);
|
||||
}
|
||||
|
||||
static ssh_hash *sha512_copy(ssh_hash *hashold)
|
||||
static void sha512_reset(ssh_hash *hash)
|
||||
{
|
||||
struct sha512_hash *hold, *hnew;
|
||||
ssh_hash *hashnew = sha512_new(hashold->vt);
|
||||
struct sha512_hash *h = container_of(hash, struct sha512_hash, hash);
|
||||
SHA512_Init(&h->state);
|
||||
}
|
||||
|
||||
hold = container_of(hashold, struct sha512_hash, hash);
|
||||
hnew = container_of(hashnew, struct sha512_hash, hash);
|
||||
static void sha512_copyfrom(ssh_hash *hashnew, ssh_hash *hashold)
|
||||
{
|
||||
struct sha512_hash *hold = container_of(hashold, struct sha512_hash, hash);
|
||||
struct sha512_hash *hnew = container_of(hashnew, struct sha512_hash, hash);
|
||||
|
||||
hnew->state = hold->state;
|
||||
BinarySink_COPIED(&hnew->state);
|
||||
|
||||
return hashnew;
|
||||
}
|
||||
|
||||
static void sha512_free(ssh_hash *hash)
|
||||
|
@ -335,35 +335,30 @@ static void sha512_free(ssh_hash *hash)
|
|||
sfree(h);
|
||||
}
|
||||
|
||||
static void sha512_final(ssh_hash *hash, unsigned char *output)
|
||||
static void sha512_digest(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
struct sha512_hash *h = container_of(hash, struct sha512_hash, hash);
|
||||
SHA512_Final(&h->state, output);
|
||||
sha512_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha512 = {
|
||||
sha512_new, sha512_copy, sha512_final, sha512_free,
|
||||
sha512_new, sha512_reset, sha512_copyfrom, sha512_digest, sha512_free,
|
||||
64, BLKSIZE, HASHALG_NAMES_BARE("SHA-512"),
|
||||
};
|
||||
|
||||
static ssh_hash *sha384_new(const ssh_hashalg *alg)
|
||||
static void sha384_reset(ssh_hash *hash)
|
||||
{
|
||||
struct sha512_hash *h = snew(struct sha512_hash);
|
||||
struct sha512_hash *h = container_of(hash, struct sha512_hash, 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)
|
||||
static void sha384_digest(ssh_hash *hash, unsigned char *output)
|
||||
{
|
||||
struct sha512_hash *h = container_of(hash, struct sha512_hash, hash);
|
||||
SHA384_Final(&h->state, output);
|
||||
sha512_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha384 = {
|
||||
sha384_new, sha512_copy, sha384_final, sha512_free,
|
||||
sha512_new, sha384_reset, sha512_copyfrom, sha384_digest, sha512_free,
|
||||
48, BLKSIZE, HASHALG_NAMES_BARE("SHA-384"),
|
||||
};
|
||||
|
|
99
sshsha.c
99
sshsha.c
|
@ -98,7 +98,7 @@ static ssh_hash *sha1_select(const ssh_hashalg *alg)
|
|||
}
|
||||
|
||||
const ssh_hashalg ssh_sha1 = {
|
||||
sha1_select, NULL, NULL, NULL,
|
||||
sha1_select, NULL, NULL, NULL, NULL,
|
||||
20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "dummy selector vtable"),
|
||||
};
|
||||
|
||||
|
@ -259,26 +259,28 @@ static ssh_hash *sha1_sw_new(const ssh_hashalg *alg)
|
|||
{
|
||||
sha1_sw *s = snew(sha1_sw);
|
||||
|
||||
memcpy(s->core, sha1_initial_state, sizeof(s->core));
|
||||
|
||||
sha1_block_setup(&s->blk);
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha1_sw_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *sha1_sw_copy(ssh_hash *hash)
|
||||
static void sha1_sw_reset(ssh_hash *hash)
|
||||
{
|
||||
sha1_sw *s = container_of(hash, sha1_sw, hash);
|
||||
sha1_sw *copy = snew(sha1_sw);
|
||||
|
||||
memcpy(copy, s, sizeof(*copy));
|
||||
memcpy(s->core, sha1_initial_state, sizeof(s->core));
|
||||
sha1_block_setup(&s->blk);
|
||||
}
|
||||
|
||||
static void sha1_sw_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
sha1_sw *copy = container_of(hcopy, sha1_sw, hash);
|
||||
sha1_sw *orig = container_of(horig, sha1_sw, hash);
|
||||
|
||||
memcpy(copy, orig, sizeof(*copy));
|
||||
BinarySink_COPIED(copy);
|
||||
BinarySink_DELEGATE_INIT(©->hash, copy);
|
||||
|
||||
return ©->hash;
|
||||
}
|
||||
|
||||
static void sha1_sw_free(ssh_hash *hash)
|
||||
|
@ -298,18 +300,17 @@ static void sha1_sw_write(BinarySink *bs, const void *vp, size_t len)
|
|||
sha1_sw_block(s->core, s->blk.block);
|
||||
}
|
||||
|
||||
static void sha1_sw_final(ssh_hash *hash, uint8_t *digest)
|
||||
static void sha1_sw_digest(ssh_hash *hash, uint8_t *digest)
|
||||
{
|
||||
sha1_sw *s = container_of(hash, sha1_sw, hash);
|
||||
|
||||
sha1_block_pad(&s->blk, BinarySink_UPCAST(s));
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
PUT_32BIT_MSB_FIRST(digest + 4*i, s->core[i]);
|
||||
sha1_sw_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha1_sw = {
|
||||
sha1_sw_new, sha1_sw_copy, sha1_sw_final, sha1_sw_free,
|
||||
sha1_sw_new, sha1_sw_reset, sha1_sw_copyfrom, sha1_sw_digest, sha1_sw_free,
|
||||
20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "unaccelerated"),
|
||||
};
|
||||
|
||||
|
@ -573,39 +574,42 @@ static sha1_ni *sha1_ni_alloc(void)
|
|||
return s;
|
||||
}
|
||||
|
||||
FUNC_ISA static ssh_hash *sha1_ni_new(const ssh_hashalg *alg)
|
||||
static ssh_hash *sha1_ni_new(const ssh_hashalg *alg)
|
||||
{
|
||||
if (!sha1_hw_available_cached())
|
||||
return NULL;
|
||||
|
||||
sha1_ni *s = sha1_ni_alloc();
|
||||
|
||||
/* Initialise the core vectors in their storage order */
|
||||
s->core[0] = _mm_set_epi64x(
|
||||
0x67452301efcdab89ULL, 0x98badcfe10325476ULL);
|
||||
s->core[1] = _mm_set_epi32(0xc3d2e1f0, 0, 0, 0);
|
||||
|
||||
sha1_block_setup(&s->blk);
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha1_ni_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *sha1_ni_copy(ssh_hash *hash)
|
||||
FUNC_ISA static void sha1_ni_reset(ssh_hash *hash)
|
||||
{
|
||||
sha1_ni *s = container_of(hash, sha1_ni, hash);
|
||||
sha1_ni *copy = sha1_ni_alloc();
|
||||
|
||||
/* Initialise the core vectors in their storage order */
|
||||
s->core[0] = _mm_set_epi64x(
|
||||
0x67452301efcdab89ULL, 0x98badcfe10325476ULL);
|
||||
s->core[1] = _mm_set_epi32(0xc3d2e1f0, 0, 0, 0);
|
||||
|
||||
sha1_block_setup(&s->blk);
|
||||
}
|
||||
|
||||
static void sha1_ni_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
sha1_ni *copy = container_of(hcopy, sha1_ni, hash);
|
||||
sha1_ni *orig = container_of(horig, sha1_ni, hash);
|
||||
|
||||
void *ptf_save = copy->pointer_to_free;
|
||||
*copy = *s; /* structure copy */
|
||||
*copy = *orig; /* structure copy */
|
||||
copy->pointer_to_free = ptf_save;
|
||||
|
||||
BinarySink_COPIED(copy);
|
||||
BinarySink_DELEGATE_INIT(©->hash, copy);
|
||||
|
||||
return ©->hash;
|
||||
}
|
||||
|
||||
static void sha1_ni_free(ssh_hash *hash)
|
||||
|
@ -626,7 +630,7 @@ static void sha1_ni_write(BinarySink *bs, const void *vp, size_t len)
|
|||
sha1_ni_block(s->core, s->blk.block);
|
||||
}
|
||||
|
||||
FUNC_ISA static void sha1_ni_final(ssh_hash *hash, uint8_t *digest)
|
||||
FUNC_ISA static void sha1_ni_digest(ssh_hash *hash, uint8_t *digest)
|
||||
{
|
||||
sha1_ni *s = container_of(hash, sha1_ni, hash);
|
||||
|
||||
|
@ -645,12 +649,10 @@ FUNC_ISA static void sha1_ni_final(ssh_hash *hash, uint8_t *digest)
|
|||
/* Finally, store the leftover word */
|
||||
uint32_t e = _mm_extract_epi32(s->core[1], 3);
|
||||
PUT_32BIT_MSB_FIRST(digest + 16, e);
|
||||
|
||||
sha1_ni_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha1_hw = {
|
||||
sha1_ni_new, sha1_ni_copy, sha1_ni_final, sha1_ni_free,
|
||||
sha1_ni_new, sha1_ni_reset, sha1_ni_copyfrom, sha1_ni_digest, sha1_ni_free,
|
||||
20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "SHA-NI accelerated"),
|
||||
};
|
||||
|
||||
|
@ -813,28 +815,31 @@ static ssh_hash *sha1_neon_new(const ssh_hashalg *alg)
|
|||
|
||||
sha1_neon *s = snew(sha1_neon);
|
||||
|
||||
s->core.abcd = vld1q_u32(sha1_initial_state);
|
||||
s->core.e = sha1_initial_state[4];
|
||||
|
||||
sha1_block_setup(&s->blk);
|
||||
|
||||
s->hash.vt = alg;
|
||||
BinarySink_INIT(s, sha1_neon_write);
|
||||
BinarySink_DELEGATE_INIT(&s->hash, s);
|
||||
return &s->hash;
|
||||
}
|
||||
|
||||
static ssh_hash *sha1_neon_copy(ssh_hash *hash)
|
||||
static void sha1_neon_reset(ssh_hash *hash)
|
||||
{
|
||||
sha1_neon *s = container_of(hash, sha1_neon, hash);
|
||||
sha1_neon *copy = snew(sha1_neon);
|
||||
|
||||
*copy = *s; /* structure copy */
|
||||
s->core.abcd = vld1q_u32(sha1_initial_state);
|
||||
s->core.e = sha1_initial_state[4];
|
||||
|
||||
sha1_block_setup(&s->blk);
|
||||
}
|
||||
|
||||
static void sha1_neon_copyfrom(ssh_hash *hcopy, ssh_hash *horig)
|
||||
{
|
||||
sha1_neon *copy = container_of(hcopy, sha1_neon, hash);
|
||||
sha1_neon *orig = container_of(horig, sha1_neon, hash);
|
||||
|
||||
*copy = *orig; /* structure copy */
|
||||
|
||||
BinarySink_COPIED(copy);
|
||||
BinarySink_DELEGATE_INIT(©->hash, copy);
|
||||
|
||||
return ©->hash;
|
||||
}
|
||||
|
||||
static void sha1_neon_free(ssh_hash *hash)
|
||||
|
@ -853,18 +858,18 @@ static void sha1_neon_write(BinarySink *bs, const void *vp, size_t len)
|
|||
sha1_neon_block(&s->core, s->blk.block);
|
||||
}
|
||||
|
||||
static void sha1_neon_final(ssh_hash *hash, uint8_t *digest)
|
||||
static void sha1_neon_digest(ssh_hash *hash, uint8_t *digest)
|
||||
{
|
||||
sha1_neon *s = container_of(hash, sha1_neon, hash);
|
||||
|
||||
sha1_block_pad(&s->blk, BinarySink_UPCAST(s));
|
||||
vst1q_u8(digest, vrev32q_u8(vreinterpretq_u8_u32(s->core.abcd)));
|
||||
PUT_32BIT_MSB_FIRST(digest + 16, s->core.e);
|
||||
sha1_neon_free(hash);
|
||||
}
|
||||
|
||||
const ssh_hashalg ssh_sha1_hw = {
|
||||
sha1_neon_new, sha1_neon_copy, sha1_neon_final, sha1_neon_free,
|
||||
sha1_neon_new, sha1_neon_reset, sha1_neon_copyfrom, sha1_neon_digest,
|
||||
sha1_neon_free,
|
||||
20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "NEON accelerated"),
|
||||
};
|
||||
|
||||
|
@ -890,12 +895,14 @@ static ssh_hash *sha1_stub_new(const ssh_hashalg *alg)
|
|||
|
||||
#define STUB_BODY { unreachable("Should never be called"); }
|
||||
|
||||
static ssh_hash *sha1_stub_copy(ssh_hash *hash) STUB_BODY
|
||||
static void sha1_stub_reset(ssh_hash *hash) STUB_BODY
|
||||
static void sha1_stub_copyfrom(ssh_hash *hash, ssh_hash *orig) STUB_BODY
|
||||
static void sha1_stub_free(ssh_hash *hash) STUB_BODY
|
||||
static void sha1_stub_final(ssh_hash *hash, uint8_t *digest) STUB_BODY
|
||||
static void sha1_stub_digest(ssh_hash *hash, uint8_t *digest) STUB_BODY
|
||||
|
||||
const ssh_hashalg ssh_sha1_hw = {
|
||||
sha1_stub_new, sha1_stub_copy, sha1_stub_final, sha1_stub_free,
|
||||
sha1_stub_new, sha1_stub_reset, sha1_stub_copyfrom, sha1_stub_digest,
|
||||
sha1_stub_free,
|
||||
20, 64, HASHALG_NAMES_ANNOTATED(
|
||||
"SHA-1", "!NONEXISTENT ACCELERATED VERSION!"),
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче