version 1.87, 2002/01/24 21:13:23 |
version 1.88, 2002/02/14 23:41:01 |
|
|
fatal("packet_set_connection: cannot load cipher 'none'"); |
fatal("packet_set_connection: cannot load cipher 'none'"); |
connection_in = fd_in; |
connection_in = fd_in; |
connection_out = fd_out; |
connection_out = fd_out; |
cipher_init(&send_context, none, "", 0, NULL, 0); |
cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT); |
cipher_init(&receive_context, none, "", 0, NULL, 0); |
cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT); |
newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; |
newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; |
if (!initialized) { |
if (!initialized) { |
initialized = 1; |
initialized = 1; |
|
|
buffer_free(&compression_buffer); |
buffer_free(&compression_buffer); |
buffer_compress_uninit(); |
buffer_compress_uninit(); |
} |
} |
|
cipher_cleanup(&send_context); |
|
cipher_cleanup(&receive_context); |
} |
} |
|
|
/* Sets remote side protocol flags. */ |
/* Sets remote side protocol flags. */ |
|
|
fatal("packet_set_encryption_key: unknown cipher number %d", number); |
fatal("packet_set_encryption_key: unknown cipher number %d", number); |
if (keylen < 20) |
if (keylen < 20) |
fatal("packet_set_encryption_key: keylen too small: %d", keylen); |
fatal("packet_set_encryption_key: keylen too small: %d", keylen); |
cipher_init(&receive_context, cipher, key, keylen, NULL, 0); |
cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT); |
cipher_init(&send_context, cipher, key, keylen, NULL, 0); |
cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT); |
} |
} |
|
|
/* Start constructing a packet to send. */ |
/* Start constructing a packet to send. */ |
|
|
|
|
/* Insert padding. Initialized to zero in packet_start1() */ |
/* Insert padding. Initialized to zero in packet_start1() */ |
padding = 8 - len % 8; |
padding = 8 - len % 8; |
if (send_context.cipher->number != SSH_CIPHER_NONE) { |
if (!send_context.plaintext) { |
cp = buffer_ptr(&outgoing_packet); |
cp = buffer_ptr(&outgoing_packet); |
for (i = 0; i < padding; i++) { |
for (i = 0; i < padding; i++) { |
if (i % 4 == 0) |
if (i % 4 == 0) |
|
|
PUT_32BIT(buf, len); |
PUT_32BIT(buf, len); |
buffer_append(&output, buf, 4); |
buffer_append(&output, buf, 4); |
cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
buffer_len(&outgoing_packet)); |
buffer_len(&outgoing_packet)); |
|
|
#ifdef PACKET_DEBUG |
#ifdef PACKET_DEBUG |
|
|
Mac *mac; |
Mac *mac; |
Comp *comp; |
Comp *comp; |
CipherContext *cc; |
CipherContext *cc; |
|
int encrypt; |
|
|
debug("newkeys: mode %d", mode); |
debug("newkeys: mode %d", mode); |
|
|
cc = (mode == MODE_OUT) ? &send_context : &receive_context; |
if (mode == MODE_OUT) { |
|
cc = &send_context; |
|
encrypt = CIPHER_ENCRYPT; |
|
} else { |
|
cc = &receive_context; |
|
encrypt = CIPHER_DECRYPT; |
|
} |
if (newkeys[mode] != NULL) { |
if (newkeys[mode] != NULL) { |
debug("newkeys: rekeying"); |
debug("newkeys: rekeying"); |
/* todo: free old keys, reset compression/cipher-ctxt; */ |
cipher_cleanup(cc); |
memset(cc, 0, sizeof(*cc)); |
|
enc = &newkeys[mode]->enc; |
enc = &newkeys[mode]->enc; |
mac = &newkeys[mode]->mac; |
mac = &newkeys[mode]->mac; |
comp = &newkeys[mode]->comp; |
comp = &newkeys[mode]->comp; |
|
|
if (mac->md != NULL) |
if (mac->md != NULL) |
mac->enabled = 1; |
mac->enabled = 1; |
DBG(debug("cipher_init_context: %d", mode)); |
DBG(debug("cipher_init_context: %d", mode)); |
cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len, |
cipher_init(cc, enc->cipher, enc->key, enc->key_len, |
enc->iv, enc->cipher->block_size); |
enc->iv, enc->block_size, encrypt); |
memset(enc->iv, 0, enc->cipher->block_size); |
memset(enc->iv, 0, enc->block_size); |
memset(enc->key, 0, enc->cipher->key_len); |
memset(enc->key, 0, enc->key_len); |
if (comp->type != 0 && comp->enabled == 0) { |
if (comp->type != 0 && comp->enabled == 0) { |
packet_init_compression(); |
packet_init_compression(); |
if (mode == MODE_OUT) |
if (mode == MODE_OUT) |
|
|
mac = &newkeys[MODE_OUT]->mac; |
mac = &newkeys[MODE_OUT]->mac; |
comp = &newkeys[MODE_OUT]->comp; |
comp = &newkeys[MODE_OUT]->comp; |
} |
} |
block_size = enc ? enc->cipher->block_size : 8; |
block_size = enc ? enc->block_size : 8; |
|
|
ucp = buffer_ptr(&outgoing_packet); |
ucp = buffer_ptr(&outgoing_packet); |
type = ucp[5]; |
type = ucp[5]; |
|
|
extra_pad = 0; |
extra_pad = 0; |
} |
} |
cp = buffer_append_space(&outgoing_packet, padlen); |
cp = buffer_append_space(&outgoing_packet, padlen); |
if (enc && enc->cipher->number != SSH_CIPHER_NONE) { |
if (enc && !send_context.plaintext) { |
/* random padding */ |
/* random padding */ |
for (i = 0; i < padlen; i++) { |
for (i = 0; i < padlen; i++) { |
if (i % 4 == 0) |
if (i % 4 == 0) |
|
|
} |
} |
/* encrypt packet and append to output buffer. */ |
/* encrypt packet and append to output buffer. */ |
cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
buffer_len(&outgoing_packet)); |
buffer_len(&outgoing_packet)); |
/* append unencrypted MAC */ |
/* append unencrypted MAC */ |
if (mac && mac->enabled) |
if (mac && mac->enabled) |
|
|
* (C)1998 CORE-SDI, Buenos Aires Argentina |
* (C)1998 CORE-SDI, Buenos Aires Argentina |
* Ariel Futoransky(futo@core-sdi.com) |
* Ariel Futoransky(futo@core-sdi.com) |
*/ |
*/ |
if (receive_context.cipher->number != SSH_CIPHER_NONE && |
if (!receive_context.plaintext && |
detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED) |
detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED) |
packet_disconnect("crc32 compensation attack: network attack detected"); |
packet_disconnect("crc32 compensation attack: network attack detected"); |
|
|
/* Decrypt data to incoming_packet. */ |
/* Decrypt data to incoming_packet. */ |
buffer_clear(&incoming_packet); |
buffer_clear(&incoming_packet); |
cp = buffer_append_space(&incoming_packet, padded_len); |
cp = buffer_append_space(&incoming_packet, padded_len); |
cipher_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); |
cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len); |
|
|
buffer_consume(&input, padded_len); |
buffer_consume(&input, padded_len); |
|
|
|
|
comp = &newkeys[MODE_IN]->comp; |
comp = &newkeys[MODE_IN]->comp; |
} |
} |
maclen = mac && mac->enabled ? mac->mac_len : 0; |
maclen = mac && mac->enabled ? mac->mac_len : 0; |
block_size = enc ? enc->cipher->block_size : 8; |
block_size = enc ? enc->block_size : 8; |
|
|
if (packet_length == 0) { |
if (packet_length == 0) { |
/* |
/* |
|
|
return SSH_MSG_NONE; |
return SSH_MSG_NONE; |
buffer_clear(&incoming_packet); |
buffer_clear(&incoming_packet); |
cp = buffer_append_space(&incoming_packet, block_size); |
cp = buffer_append_space(&incoming_packet, block_size); |
cipher_decrypt(&receive_context, cp, buffer_ptr(&input), |
cipher_crypt(&receive_context, cp, buffer_ptr(&input), |
block_size); |
block_size); |
ucp = buffer_ptr(&incoming_packet); |
ucp = buffer_ptr(&incoming_packet); |
packet_length = GET_32BIT(ucp); |
packet_length = GET_32BIT(ucp); |
|
|
buffer_dump(&input); |
buffer_dump(&input); |
#endif |
#endif |
cp = buffer_append_space(&incoming_packet, need); |
cp = buffer_append_space(&incoming_packet, need); |
cipher_decrypt(&receive_context, cp, buffer_ptr(&input), need); |
cipher_crypt(&receive_context, cp, buffer_ptr(&input), need); |
buffer_consume(&input, need); |
buffer_consume(&input, need); |
/* |
/* |
* compute MAC over seqnr and packet, |
* compute MAC over seqnr and packet, |