diff --git a/cproxy.c b/cproxy.c index 934ce3dc..5f2f15fc 100644 --- a/cproxy.c +++ b/cproxy.c @@ -21,7 +21,7 @@ static void hmacmd5_chap(const unsigned char *challenge, int challen, void *hmacmd5_ctx; int pwlen; - hmacmd5_ctx = hmacmd5_make_context(); + hmacmd5_ctx = hmacmd5_make_context(NULL); pwlen = strlen(passwd); if (pwlen>64) { diff --git a/ssh.c b/ssh.c index 957a378c..0b323d32 100644 --- a/ssh.c +++ b/ssh.c @@ -6565,6 +6565,17 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, crStopV; matched:; } + + /* If the cipher over-rides the mac, then pick it */ + if (s->cscipher_tobe && s->cscipher_tobe->required_mac) { + s->csmac_tobe = s->cscipher_tobe->required_mac; + s->csmac_etm_tobe = !!(s->csmac_tobe->etm_name); + } + if (s->sccipher_tobe && s->sccipher_tobe->required_mac) { + s->scmac_tobe = s->sccipher_tobe->required_mac; + s->scmac_etm_tobe = !!(s->scmac_tobe->etm_name); + } + if (s->pending_compression) { logevent("Server supports delayed compression; " "will try this later"); @@ -7078,7 +7089,7 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, ssh->csmac->free_context(ssh->cs_mac_ctx); ssh->csmac = s->csmac_tobe; ssh->csmac_etm = s->csmac_etm_tobe; - ssh->cs_mac_ctx = ssh->csmac->make_context(); + ssh->cs_mac_ctx = ssh->csmac->make_context(ssh->cs_cipher_ctx); if (ssh->cs_comp_ctx) ssh->cscomp->compress_cleanup(ssh->cs_comp_ctx); @@ -7146,7 +7157,7 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, ssh->scmac->free_context(ssh->sc_mac_ctx); ssh->scmac = s->scmac_tobe; ssh->scmac_etm = s->scmac_etm_tobe; - ssh->sc_mac_ctx = ssh->scmac->make_context(); + ssh->sc_mac_ctx = ssh->scmac->make_context(ssh->sc_cipher_ctx); if (ssh->sc_comp_ctx) ssh->sccomp->decompress_cleanup(ssh->sc_comp_ctx); diff --git a/ssh.h b/ssh.h index 81c003ba..0bcf2b67 100644 --- a/ssh.h +++ b/ssh.h @@ -250,7 +250,7 @@ void MD5Update(struct MD5Context *context, unsigned char const *buf, void MD5Final(unsigned char digest[16], struct MD5Context *context); void MD5Simple(void const *p, unsigned len, unsigned char output[16]); -void *hmacmd5_make_context(void); +void *hmacmd5_make_context(void *); void hmacmd5_free_context(void *handle); void hmacmd5_key(void *handle, void const *key, int len); void hmacmd5_do_hmac(void *handle, unsigned char const *blk, int len, @@ -296,6 +296,7 @@ void SHA384_Init(SHA384_State * s); void SHA384_Final(SHA384_State * s, unsigned char *output); void SHA384_Simple(const void *p, int len, unsigned char *output); +struct ssh_mac; struct ssh_cipher { void *(*make_context)(void); void (*free_context)(void *); @@ -319,6 +320,8 @@ struct ssh2_cipher { unsigned int flags; #define SSH_CIPHER_IS_CBC 1 const char *text_name; + /* If set, this takes priority over other MAC. */ + const struct ssh_mac *required_mac; }; struct ssh2_ciphers { @@ -327,7 +330,8 @@ struct ssh2_ciphers { }; struct ssh_mac { - void *(*make_context)(void); + /* Passes in the cipher context */ + void *(*make_context)(void *); void (*free_context)(void *); void (*setkey) (void *, unsigned char *key); /* whole-packet operations */ diff --git a/sshaes.c b/sshaes.c index 97935b7f..83cc1bb3 100644 --- a/sshaes.c +++ b/sshaes.c @@ -1173,49 +1173,56 @@ static const struct ssh2_cipher ssh_aes128_ctr = { aes_make_context, aes_free_context, aes_iv, aes128_key, aes_ssh2_sdctr, aes_ssh2_sdctr, "aes128-ctr", - 16, 128, 0, "AES-128 SDCTR" + 16, 128, 0, "AES-128 SDCTR", + NULL }; static const struct ssh2_cipher ssh_aes192_ctr = { aes_make_context, aes_free_context, aes_iv, aes192_key, aes_ssh2_sdctr, aes_ssh2_sdctr, "aes192-ctr", - 16, 192, 0, "AES-192 SDCTR" + 16, 192, 0, "AES-192 SDCTR", + NULL }; static const struct ssh2_cipher ssh_aes256_ctr = { aes_make_context, aes_free_context, aes_iv, aes256_key, aes_ssh2_sdctr, aes_ssh2_sdctr, "aes256-ctr", - 16, 256, 0, "AES-256 SDCTR" + 16, 256, 0, "AES-256 SDCTR", + NULL }; static const struct ssh2_cipher ssh_aes128 = { aes_make_context, aes_free_context, aes_iv, aes128_key, aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "aes128-cbc", - 16, 128, SSH_CIPHER_IS_CBC, "AES-128 CBC" + 16, 128, SSH_CIPHER_IS_CBC, "AES-128 CBC", + NULL }; static const struct ssh2_cipher ssh_aes192 = { aes_make_context, aes_free_context, aes_iv, aes192_key, aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "aes192-cbc", - 16, 192, SSH_CIPHER_IS_CBC, "AES-192 CBC" + 16, 192, SSH_CIPHER_IS_CBC, "AES-192 CBC", + NULL }; static const struct ssh2_cipher ssh_aes256 = { aes_make_context, aes_free_context, aes_iv, aes256_key, aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "aes256-cbc", - 16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC" + 16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC", + NULL }; static const struct ssh2_cipher ssh_rijndael_lysator = { aes_make_context, aes_free_context, aes_iv, aes256_key, aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, "rijndael-cbc@lysator.liu.se", - 16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC" + 16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC", + NULL }; static const struct ssh2_cipher *const aes_list[] = { diff --git a/ssharcf.c b/ssharcf.c index 06f235c5..cec65c11 100644 --- a/ssharcf.c +++ b/ssharcf.c @@ -102,14 +102,16 @@ const struct ssh2_cipher ssh_arcfour128_ssh2 = { arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour128_key, arcfour_block, arcfour_block, "arcfour128", - 1, 128, 0, "Arcfour-128" + 1, 128, 0, "Arcfour-128", + NULL }; const struct ssh2_cipher ssh_arcfour256_ssh2 = { arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour256_key, arcfour_block, arcfour_block, "arcfour256", - 1, 256, 0, "Arcfour-256" + 1, 256, 0, "Arcfour-256", + NULL }; static const struct ssh2_cipher *const arcfour_list[] = { diff --git a/sshblowf.c b/sshblowf.c index 70709f64..bf0b1641 100644 --- a/sshblowf.c +++ b/sshblowf.c @@ -643,14 +643,16 @@ static const struct ssh2_cipher ssh_blowfish_ssh2 = { blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key, blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk, "blowfish-cbc", - 8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC" + 8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC", + NULL }; static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = { blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key, blowfish_ssh2_sdctr, blowfish_ssh2_sdctr, "blowfish-ctr", - 8, 256, 0, "Blowfish-256 SDCTR" + 8, 256, 0, "Blowfish-256 SDCTR", + NULL }; static const struct ssh2_cipher *const blowfish_list[] = { diff --git a/sshdes.c b/sshdes.c index f54990e7..2f3e3c7a 100644 --- a/sshdes.c +++ b/sshdes.c @@ -949,14 +949,16 @@ static const struct ssh2_cipher ssh_3des_ssh2 = { des3_make_context, des3_free_context, des3_iv, des3_key, des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk, "3des-cbc", - 8, 168, SSH_CIPHER_IS_CBC, "triple-DES CBC" + 8, 168, SSH_CIPHER_IS_CBC, "triple-DES CBC", + NULL }; static const struct ssh2_cipher ssh_3des_ssh2_ctr = { des3_make_context, des3_free_context, des3_iv, des3_key, des3_ssh2_sdctr, des3_ssh2_sdctr, "3des-ctr", - 8, 168, 0, "triple-DES SDCTR" + 8, 168, 0, "triple-DES SDCTR", + NULL }; /* @@ -971,14 +973,16 @@ static const struct ssh2_cipher ssh_des_ssh2 = { des_make_context, des3_free_context, des3_iv, des_key, des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, "des-cbc", - 8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC" + 8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC", + NULL }; static const struct ssh2_cipher ssh_des_sshcom_ssh2 = { des_make_context, des3_free_context, des3_iv, des_key, des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, "des-cbc@ssh.com", - 8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC" + 8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC", + NULL }; static const struct ssh2_cipher *const des3_list[] = { diff --git a/sshmd5.c b/sshmd5.c index f34f851d..4988223e 100644 --- a/sshmd5.c +++ b/sshmd5.c @@ -221,7 +221,7 @@ void MD5Simple(void const *p, unsigned len, unsigned char output[16]) * useful elsewhere (SOCKS5 CHAP authentication uses HMAC-MD5). */ -void *hmacmd5_make_context(void) +void *hmacmd5_make_context(void *cipher_ctx) { return snewn(3, struct MD5Context); } diff --git a/sshsh256.c b/sshsh256.c index b583c9b3..8e3d4fc1 100644 --- a/sshsh256.c +++ b/sshsh256.c @@ -225,7 +225,7 @@ const struct ssh_hash ssh_sha256 = { * HMAC wrapper on it. */ -static void *sha256_make_context(void) +static void *sha256_make_context(void *cipher_ctx) { return snewn(3, SHA256_State); } diff --git a/sshsha.c b/sshsha.c index 4d24e7b2..2b2eead1 100644 --- a/sshsha.c +++ b/sshsha.c @@ -255,7 +255,7 @@ const struct ssh_hash ssh_sha1 = { * HMAC wrapper on it. */ -static void *sha1_make_context(void) +static void *sha1_make_context(void *cipher_ctx) { return snewn(3, SHA_State); }