if (type == SSH2_MSG_NEWKEYS) { if (kex==NULL || mac==NULL || enc==NULL || comp==NULL) fatal("packet_send2: no KEX"); if (mac->md != NULL) mac->enabled = 1; DBG(debug("cipher_init send_context")); cipher_init(&send_context, enc->cipher, enc->key, enc->cipher->key_len, enc->iv, enc->cipher->block_size); clear_enc_keys(enc, kex->we_need); if (comp->type != 0 && comp->enabled == 0) { comp->enabled = 1; if (! packet_compression) packet_start_compression(6); } }
if (type == SSH2_MSG_NEWKEYS) set_newkeys(MODE_OUT);
packet_send2(void){	static u_int32_t seqnr = 0;	u_char *macbuf = NULL;	char *cp;	u_int packet_length = 0;	u_int i, padlen, len;	u_int32_t rand = 0;	int type;	Enc *enc   = NULL;	Mac *mac   = NULL;	Comp *comp = NULL;	int block_size;	if (kex != NULL) {		enc  = &kex->enc[MODE_OUT];		mac  = &kex->mac[MODE_OUT];		comp = &kex->comp[MODE_OUT];	}	block_size = enc ? enc->cipher->block_size : 8;	cp = buffer_ptr(&outgoing_packet);	type = cp[5] & 0xff;#ifdef PACKET_DEBUG	fprintf(stderr, "plain:     ");	buffer_dump(&outgoing_packet);#endif	if (comp && comp->enabled) {		len = buffer_len(&outgoing_packet);		/* skip header, compress only payload */		buffer_consume(&outgoing_packet, 5);		buffer_clear(&compression_buffer);		buffer_compress(&outgoing_packet, &compression_buffer);		buffer_clear(&outgoing_packet);		buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);		buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),		    buffer_len(&compression_buffer));		DBG(debug("compression: raw %d compressed %d", len,		    buffer_len(&outgoing_packet)));	}	/* sizeof (packet_len + pad_len + payload) */	len = buffer_len(&outgoing_packet);	/*	 * calc size of padding, alloc space, get random data,	 * minimum padding is 4 bytes	 */	padlen = block_size - (len % block_size);	if (padlen < 4)		padlen += block_size;	buffer_append_space(&outgoing_packet, &cp, padlen);	if (enc && enc->cipher->number != SSH_CIPHER_NONE) {		/* random padding */		for (i = 0; i < padlen; i++) {			if (i % 4 == 0)				rand = arc4random();			cp[i] = rand & 0xff;			rand >>= 8;		}	} else {		/* clear padding */		memset(cp, 0, padlen);	}	/* packet_length includes payload, padding and padding length field */	packet_length = buffer_len(&outgoing_packet) - 4;	cp = buffer_ptr(&outgoing_packet);	PUT_32BIT(cp, packet_length);	cp[4] = padlen & 0xff;	DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));	/* compute MAC over seqnr and packet(length fields, payload, padding) */	if (mac && mac->enabled) {		macbuf = mac_compute(mac, seqnr,		    (u_char *) buffer_ptr(&outgoing_packet),		    buffer_len(&outgoing_packet));		DBG(debug("done calc MAC out #%d", seqnr));	}	/* encrypt packet and append to output buffer. */	buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));	packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),	    buffer_len(&outgoing_packet));	/* append unencrypted MAC */	if (mac && mac->enabled)		buffer_append(&output, (char *)macbuf, mac->mac_len);#ifdef PACKET_DEBUG	fprintf(stderr, "encrypted: ");	buffer_dump(&output);#endif	/* increment sequence number for outgoing packets */	if (++seqnr == 0)		log("outgoing seqnr wraps around");	buffer_clear(&outgoing_packet);	if (type == SSH2_MSG_NEWKEYS) {		if (kex==NULL || mac==NULL || enc==NULL || comp==NULL)			fatal("packet_send2: no KEX");		if (mac->md != NULL)			mac->enabled = 1;		DBG(debug("cipher_init send_context"));		cipher_init(&send_context, enc->cipher,		    enc->key, enc->cipher->key_len,		    enc->iv, enc->cipher->block_size);		clear_enc_keys(enc, kex->we_need);		if (comp->type != 0 && comp->enabled == 0) {			comp->enabled = 1;			if (! packet_compression)				packet_start_compression(6);		}	}}