From: Ben Harris Date: Wed, 24 Jun 2015 20:58:11 +0000 (+0100) Subject: When encrypting packet length with ChaCha20, treat sequence number as 32 bits. X-Git-Tag: 0.68~511 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=307aaccc59f6fbfdf7b980ae709c083786044163;hp=--cc;p=PuTTY.git When encrypting packet length with ChaCha20, treat sequence number as 32 bits. While ChaCha20 takes a 64-bit nonce, SSH-2 defines the message sequence number to wrap at 2^32 and OpenSSH stores it in a u_int32_t, so the upper 32 bits should always be zero. PuTTY was getting this wrong, and either using an incorrect nonce or causing GCC to complain about an invalid shift, depending on the size of "unsigned long". Now I think it gets it right. --- 307aaccc59f6fbfdf7b980ae709c083786044163 diff --git a/sshccp.c b/sshccp.c index 35aa43fb..82aca02b 100644 --- a/sshccp.c +++ b/sshccp.c @@ -1290,7 +1290,11 @@ static void ccp_length_op(struct ccp_context *ctx, unsigned char *blk, int len, unsigned long seq) { unsigned char iv[8]; - PUT_32BIT_LSB_FIRST(iv, seq >> 32); + /* + * According to RFC 4253 (section 6.4), the packet sequence number wraps + * at 2^32, so its 32 high-order bits will always be zero. + */ + PUT_32BIT_LSB_FIRST(iv, 0); PUT_32BIT_LSB_FIRST(iv + 4, seq); chacha20_iv(&ctx->a_cipher, iv); chacha20_iv(&ctx->b_cipher, iv);