1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-08 08:58:00 +00:00

Add 'next_message' methods to cipher and MAC vtables.

This provides a convenient hook to be called between SSH messages, for
the crypto components to do any per-message processing like
incrementing a sequence number.
This commit is contained in:
Simon Tatham 2022-08-16 18:27:06 +01:00
parent 9160c41e7b
commit 840043f06e
12 changed files with 66 additions and 0 deletions

View File

@ -52,6 +52,7 @@ static inline bool check_availability(const struct aes_extra *extra)
.setkey = aes ## impl_c ## _setkey, \
.encrypt = aes ## bits ## impl_c ## _cbc_encrypt, \
.decrypt = aes ## bits ## impl_c ## _cbc_decrypt, \
.next_message = nullcipher_next_message, \
.ssh2_id = "aes" #bits "-cbc", \
.blksize = 16, \
.real_keybits = bits, \
@ -69,6 +70,7 @@ static inline bool check_availability(const struct aes_extra *extra)
.setkey = aes ## impl_c ## _setkey, \
.encrypt = aes ## bits ## impl_c ## _sdctr, \
.decrypt = aes ## bits ## impl_c ## _sdctr, \
.next_message = nullcipher_next_message, \
.ssh2_id = "aes" #bits "-ctr", \
.blksize = 16, \
.real_keybits = bits, \

View File

@ -110,6 +110,7 @@ const ssh_cipheralg ssh_arcfour128_ssh2 = {
.setkey = arcfour_ssh2_setkey,
.encrypt = arcfour_ssh2_block,
.decrypt = arcfour_ssh2_block,
.next_message = nullcipher_next_message,
.ssh2_id = "arcfour128",
.blksize = 1,
.real_keybits = 128,
@ -125,6 +126,7 @@ const ssh_cipheralg ssh_arcfour256_ssh2 = {
.setkey = arcfour_ssh2_setkey,
.encrypt = arcfour_ssh2_block,
.decrypt = arcfour_ssh2_block,
.next_message = nullcipher_next_message,
.ssh2_id = "arcfour256",
.blksize = 1,
.real_keybits = 256,

View File

@ -654,6 +654,7 @@ const ssh_cipheralg ssh_blowfish_ssh1 = {
.setkey = blowfish_ssh_setkey,
.encrypt = blowfish_ssh1_encrypt_blk,
.decrypt = blowfish_ssh1_decrypt_blk,
.next_message = nullcipher_next_message,
.blksize = 8,
.real_keybits = 128,
.padded_keybytes = SSH1_SESSION_KEY_LENGTH,
@ -668,6 +669,7 @@ const ssh_cipheralg ssh_blowfish_ssh2 = {
.setkey = blowfish_ssh_setkey,
.encrypt = blowfish_ssh2_encrypt_blk,
.decrypt = blowfish_ssh2_decrypt_blk,
.next_message = nullcipher_next_message,
.ssh2_id = "blowfish-cbc",
.blksize = 8,
.real_keybits = 128,
@ -683,6 +685,7 @@ const ssh_cipheralg ssh_blowfish_ssh2_ctr = {
.setkey = blowfish_ssh_setkey,
.encrypt = blowfish_ssh2_sdctr,
.decrypt = blowfish_ssh2_sdctr,
.next_message = nullcipher_next_message,
.ssh2_id = "blowfish-ctr",
.blksize = 8,
.real_keybits = 256,

View File

@ -964,6 +964,7 @@ const ssh2_macalg ssh2_poly1305 = {
.setkey = poly_setkey,
.start = poly_start,
.genresult = poly_genresult,
.next_message = nullmac_next_message,
.text_name = poly_text_name,
.name = "",
.etm_name = "", /* Not selectable individually, just part of
@ -1061,6 +1062,7 @@ const ssh_cipheralg ssh2_chacha20_poly1305 = {
.decrypt = ccp_decrypt,
.encrypt_length = ccp_encrypt_length,
.decrypt_length = ccp_decrypt_length,
.next_message = nullcipher_next_message, // FIXME: can we use this?
.ssh2_id = "chacha20-poly1305@openssh.com",
.blksize = 1,
.real_keybits = 512,

View File

@ -689,6 +689,7 @@ const ssh_cipheralg ssh_des = {
.setkey = des_cbc_setkey,
.encrypt = des_cbc_encrypt,
.decrypt = des_cbc_decrypt,
.next_message = nullcipher_next_message,
.ssh2_id = "des-cbc",
.blksize = 8,
.real_keybits = 56,
@ -705,6 +706,7 @@ const ssh_cipheralg ssh_des_sshcom_ssh2 = {
.setkey = des_cbc_setkey,
.encrypt = des_cbc_encrypt,
.decrypt = des_cbc_decrypt,
.next_message = nullcipher_next_message,
.ssh2_id = "des-cbc@ssh.com",
.blksize = 8,
.real_keybits = 56,
@ -808,6 +810,7 @@ const ssh_cipheralg ssh_3des_ssh2 = {
.setkey = des3_cbc1_setkey,
.encrypt = des3_cbc1_cbc_encrypt,
.decrypt = des3_cbc1_cbc_decrypt,
.next_message = nullcipher_next_message,
.ssh2_id = "3des-cbc",
.blksize = 8,
.real_keybits = 168,
@ -905,6 +908,7 @@ const ssh_cipheralg ssh_3des_ssh2_ctr = {
.setkey = des3_sdctr_setkey,
.encrypt = des3_sdctr_encrypt_decrypt,
.decrypt = des3_sdctr_encrypt_decrypt,
.next_message = nullcipher_next_message,
.ssh2_id = "3des-ctr",
.blksize = 8,
.real_keybits = 168,
@ -1040,6 +1044,7 @@ const ssh_cipheralg ssh_3des_ssh1 = {
.setkey = des3_cbc3_setkey,
.encrypt = des3_cbc3_cbc_encrypt,
.decrypt = des3_cbc3_cbc_decrypt,
.next_message = nullcipher_next_message,
.blksize = 8,
.real_keybits = 168,
.padded_keybytes = 24,

View File

@ -167,6 +167,7 @@ const ssh2_macalg ssh_hmac_sha256 = {
.setkey = hmac_key,
.start = hmac_start,
.genresult = hmac_genresult,
.next_message = nullmac_next_message,
.text_name = hmac_text_name,
.name = "hmac-sha2-256",
.etm_name = "hmac-sha2-256-etm@openssh.com",
@ -182,6 +183,7 @@ const ssh2_macalg ssh_hmac_md5 = {
.setkey = hmac_key,
.start = hmac_start,
.genresult = hmac_genresult,
.next_message = nullmac_next_message,
.text_name = hmac_text_name,
.name = "hmac-md5",
.etm_name = "hmac-md5-etm@openssh.com",
@ -198,6 +200,7 @@ const ssh2_macalg ssh_hmac_sha1 = {
.setkey = hmac_key,
.start = hmac_start,
.genresult = hmac_genresult,
.next_message = nullmac_next_message,
.text_name = hmac_text_name,
.name = "hmac-sha1",
.etm_name = "hmac-sha1-etm@openssh.com",
@ -214,6 +217,7 @@ const ssh2_macalg ssh_hmac_sha1_96 = {
.setkey = hmac_key,
.start = hmac_start,
.genresult = hmac_genresult,
.next_message = nullmac_next_message,
.text_name = hmac_text_name,
.name = "hmac-sha1-96",
.etm_name = "hmac-sha1-96-etm@openssh.com",
@ -232,6 +236,7 @@ const ssh2_macalg ssh_hmac_sha1_buggy = {
.setkey = hmac_key,
.start = hmac_start,
.genresult = hmac_genresult,
.next_message = nullmac_next_message,
.text_name = hmac_text_name,
.name = "hmac-sha1",
.len = 20,
@ -249,6 +254,7 @@ const ssh2_macalg ssh_hmac_sha1_96_buggy = {
.setkey = hmac_key,
.start = hmac_start,
.genresult = hmac_genresult,
.next_message = nullmac_next_message,
.text_name = hmac_text_name,
.name = "hmac-sha1-96",
.len = 12,

12
ssh.h
View File

@ -651,6 +651,9 @@ struct ssh_cipheralg {
unsigned long seq);
void (*decrypt_length)(ssh_cipher *, void *blk, int len,
unsigned long seq);
/* For ciphers that update their state per logical message
* (typically, per unit independently MACed) */
void (*next_message)(ssh_cipher *);
const char *ssh2_id;
int blksize;
/* real_keybits is the number of bits of entropy genuinely used by
@ -695,9 +698,13 @@ static inline void ssh_cipher_encrypt_length(
static inline void ssh_cipher_decrypt_length(
ssh_cipher *c, void *blk, int len, unsigned long seq)
{ c->vt->decrypt_length(c, blk, len, seq); }
static inline void ssh_cipher_next_message(ssh_cipher *c)
{ c->vt->next_message(c); }
static inline const struct ssh_cipheralg *ssh_cipher_alg(ssh_cipher *c)
{ return c->vt; }
void nullcipher_next_message(ssh_cipher *);
struct ssh2_ciphers {
int nciphers;
const ssh_cipheralg *const *list;
@ -715,6 +722,7 @@ struct ssh2_macalg {
void (*setkey)(ssh2_mac *, ptrlen key);
void (*start)(ssh2_mac *);
void (*genresult)(ssh2_mac *, unsigned char *);
void (*next_message)(ssh2_mac *);
const char *(*text_name)(ssh2_mac *);
const char *name, *etm_name;
int len, keylen;
@ -734,6 +742,8 @@ static inline void ssh2_mac_start(ssh2_mac *m)
{ m->vt->start(m); }
static inline void ssh2_mac_genresult(ssh2_mac *m, unsigned char *out)
{ m->vt->genresult(m, out); }
static inline void ssh2_mac_next_message(ssh2_mac *m)
{ m->vt->next_message(m); }
static inline const char *ssh2_mac_text_name(ssh2_mac *m)
{ return m->vt->text_name(m); }
static inline const ssh2_macalg *ssh2_mac_alg(ssh2_mac *m)
@ -746,6 +756,8 @@ bool ssh2_mac_verresult(ssh2_mac *, const void *);
void ssh2_mac_generate(ssh2_mac *, void *, int, unsigned long seq);
bool ssh2_mac_verify(ssh2_mac *, const void *, int, unsigned long seq);
void nullmac_next_message(ssh2_mac *m);
/* Use a MAC in its raw form, outside SSH-2 context, to MAC a given
* string with a given key in the most obvious way. */
void mac_simple(const ssh2_macalg *alg, ptrlen key, ptrlen data, void *output);

View File

@ -513,6 +513,10 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
dts_consume(&s->stats->in, s->packetlen);
s->pktin->sequence = s->in.sequence++;
if (s->in.cipher)
ssh_cipher_next_message(s->in.cipher);
if (s->in.mac)
ssh2_mac_next_message(s->in.mac);
s->length = s->packetlen - s->pad;
assert(s->length >= 0);
@ -819,6 +823,10 @@ static void ssh2_bpp_format_packet_inner(struct ssh2_bpp_state *s, PktOut *pkt)
}
s->out.sequence++; /* whether or not we MACed */
if (s->out.cipher)
ssh_cipher_next_message(s->out.cipher);
if (s->out.mac)
ssh2_mac_next_message(s->out.mac);
dts_consume(&s->stats->out, origlen + padding);
}

View File

@ -273,6 +273,7 @@ FUNC(val_mac, ssh2_mac_new, ARG(macalg, alg), ARG(opt_val_cipher, cipher))
FUNC(void, ssh2_mac_setkey, ARG(val_mac, m), ARG(val_string_ptrlen, key))
FUNC(void, ssh2_mac_start, ARG(val_mac, m))
FUNC(void, ssh2_mac_update, ARG(val_mac, m), ARG(val_string_ptrlen, data))
FUNC(void, ssh2_mac_next_message, ARG(val_mac, m))
FUNC_WRAPPED(val_string, ssh2_mac_genresult, ARG(val_mac, m))
FUNC(val_string_asciz_const, ssh2_mac_text_name, ARG(val_mac, m))
@ -341,6 +342,7 @@ FUNC_WRAPPED(val_string, ssh_cipher_encrypt_length, ARG(val_cipher, c),
ARG(val_string_ptrlen, blk), ARG(uint, seq))
FUNC_WRAPPED(val_string, ssh_cipher_decrypt_length, ARG(val_cipher, c),
ARG(val_string_ptrlen, blk), ARG(uint, seq))
FUNC(void, ssh_cipher_next_message, ARG(val_cipher, c))
/*
* Integer Diffie-Hellman.

View File

@ -42,7 +42,9 @@ add_sources_from_current_dir(utils
memory.c
memxor.c
null_lp.c
nullcipher.c
nullkey.c
nullmac.c
nullseat.c
nullstrcmp.c
out_of_memory.c

11
utils/nullcipher.c Normal file
View File

@ -0,0 +1,11 @@
/*
* Implementation of shared trivial routines that ssh_cipher
* implementations might use.
*/
#include "ssh.h"
void nullcipher_next_message(ssh_cipher *cipher)
{
/* Most ciphers don't do anything at all with this */
}

11
utils/nullmac.c Normal file
View File

@ -0,0 +1,11 @@
/*
* Implementation of shared trivial routines that ssh2_mac
* implementations might use.
*/
#include "ssh.h"
void nullmac_next_message(ssh2_mac *m)
{
/* Most MACs don't do anything at all with this */
}