mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-18 03:20:59 -05:00
Merge the ssh1_cipher type into ssh2_cipher.
The aim of this reorganisation is to make it easier to test all the ciphers in PuTTY in a uniform way. It was inconvenient that there were two separate vtable systems for the ciphers used in SSH-1 and SSH-2 with different functionality. Now there's only one type, called ssh_cipher. But really it's the old ssh2_cipher, just renamed: I haven't made any changes to the API on the SSH-2 side. Instead, I've removed ssh1_cipher completely, and adapted the SSH-1 BPP to use the SSH-2 style API. (The relevant differences are that ssh1_cipher encapsulated both the sending and receiving directions in one object - so now ssh1bpp has to make a separate cipher instance per direction - and that ssh1_cipher automatically initialised the IV to all zeroes, which ssh1bpp now has to do by hand.) The previous ssh1_cipher vtable for single-DES has been removed completely, because when converted into the new API it became identical to the SSH-2 single-DES vtable; so now there's just one vtable for DES-CBC which works in both protocols. The other two SSH-1 ciphers each had to stay separate, because 3DES is completely different between SSH-1 and SSH-2 (three layers of CBC structure versus one), and Blowfish varies in endianness and key length between the two. (Actually, while I'm here, I've only just noticed that the SSH-1 Blowfish cipher mis-describes itself in log messages as Blowfish-128. In fact it passes the whole of the input key buffer, which has length SSH1_SESSION_KEY_LENGTH == 32 bytes == 256 bits. So it's actually Blowfish-256, and has been all along!)
This commit is contained in:
35
ssh1bpp.c
35
ssh1bpp.c
@ -17,7 +17,7 @@ struct ssh1_bpp_state {
|
||||
int chunk;
|
||||
PktIn *pktin;
|
||||
|
||||
ssh1_cipher *cipher;
|
||||
ssh_cipher *cipher_in, *cipher_out;
|
||||
|
||||
struct crcda_ctx *crcda_ctx;
|
||||
uint8_t iv[8]; /* for crcda */
|
||||
@ -57,8 +57,10 @@ BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx)
|
||||
static void ssh1_bpp_free(BinaryPacketProtocol *bpp)
|
||||
{
|
||||
struct ssh1_bpp_state *s = container_of(bpp, struct ssh1_bpp_state, bpp);
|
||||
if (s->cipher)
|
||||
ssh1_cipher_free(s->cipher);
|
||||
if (s->cipher_in)
|
||||
ssh_cipher_free(s->cipher_in);
|
||||
if (s->cipher_out)
|
||||
ssh_cipher_free(s->cipher_out);
|
||||
if (s->compctx)
|
||||
ssh_compressor_free(s->compctx);
|
||||
if (s->decompctx)
|
||||
@ -70,18 +72,21 @@ static void ssh1_bpp_free(BinaryPacketProtocol *bpp)
|
||||
}
|
||||
|
||||
void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
|
||||
const ssh1_cipheralg *cipher,
|
||||
const ssh_cipheralg *cipher,
|
||||
const void *session_key)
|
||||
{
|
||||
struct ssh1_bpp_state *s;
|
||||
assert(bpp->vt == &ssh1_bpp_vtable);
|
||||
s = container_of(bpp, struct ssh1_bpp_state, bpp);
|
||||
|
||||
assert(!s->cipher);
|
||||
assert(!s->cipher_in);
|
||||
assert(!s->cipher_out);
|
||||
|
||||
if (cipher) {
|
||||
s->cipher = ssh1_cipher_new(cipher);
|
||||
ssh1_cipher_sesskey(s->cipher, session_key);
|
||||
s->cipher_in = ssh_cipher_new(cipher);
|
||||
s->cipher_out = ssh_cipher_new(cipher);
|
||||
ssh_cipher_setkey(s->cipher_in, session_key);
|
||||
ssh_cipher_setkey(s->cipher_out, session_key);
|
||||
|
||||
assert(!s->crcda_ctx);
|
||||
s->crcda_ctx = crcda_make_context();
|
||||
@ -89,6 +94,10 @@ void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
|
||||
bpp_logevent("Initialised %s encryption", cipher->text_name);
|
||||
|
||||
memset(s->iv, 0, sizeof(s->iv));
|
||||
|
||||
assert(cipher->blksize <= sizeof(s->iv));
|
||||
ssh_cipher_setiv(s->cipher_in, s->iv);
|
||||
ssh_cipher_setiv(s->cipher_out, s->iv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,8 +166,8 @@ static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
|
||||
BPP_READ(s->data, s->biglen);
|
||||
|
||||
if (s->cipher && detect_attack(s->crcda_ctx,
|
||||
s->data, s->biglen, s->iv)) {
|
||||
if (s->cipher_in && detect_attack(s->crcda_ctx,
|
||||
s->data, s->biglen, s->iv)) {
|
||||
ssh_sw_abort(s->bpp.ssh,
|
||||
"Network attack (CRC compensation) detected!");
|
||||
crStopV;
|
||||
@ -168,8 +177,8 @@ static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
assert(s->biglen >= 8);
|
||||
memcpy(s->iv, s->data + s->biglen - 8, sizeof(s->iv));
|
||||
|
||||
if (s->cipher)
|
||||
ssh1_cipher_decrypt(s->cipher, s->data, s->biglen);
|
||||
if (s->cipher_in)
|
||||
ssh_cipher_decrypt(s->cipher_in, s->data, s->biglen);
|
||||
|
||||
s->realcrc = crc32_ssh1(make_ptrlen(s->data, s->biglen - 4));
|
||||
s->gotcrc = GET_32BIT(s->data + s->biglen - 4);
|
||||
@ -327,8 +336,8 @@ static void ssh1_bpp_format_packet(struct ssh1_bpp_state *s, PktOut *pkt)
|
||||
PUT_32BIT(pkt->data + pktoffs + 4 + biglen - 4, crc);
|
||||
PUT_32BIT(pkt->data + pktoffs, len);
|
||||
|
||||
if (s->cipher)
|
||||
ssh1_cipher_encrypt(s->cipher, pkt->data + pktoffs + 4, biglen);
|
||||
if (s->cipher_out)
|
||||
ssh_cipher_encrypt(s->cipher_out, pkt->data + pktoffs + 4, biglen);
|
||||
|
||||
bufchain_add(s->bpp.out_raw, pkt->data + pktoffs,
|
||||
biglen + 4); /* len(length+padding+type+data+CRC) */
|
||||
|
Reference in New Issue
Block a user