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.
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);