In the recent changeset I spotted a concern in the existing
nonce generation. The code appears to be using a randomly
generated value for each new op. This runs the risk of reusing
a nonce, should the RNG produce a cycle, or if enough requests
are generated (not an impossibility with high-bandwidth RDMA).
It's a critical security issue to never reuse a nonce for a
new data pattern encrypted with the same key, because the cipher
is compromised if this occurs. There is no need for the nonce
to be random, only different. With 11+ bytes of nonce, it
is possible to partition the field and manage this with a
simple counter. The session encryption can be rekeyed prior
to the counter wrap. The nonce field can then be a property
of the session.
Or, am I incorrect in my understanding of the following?
In fs/cifs/smb2ops.c:
3793 static void
3794 fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int
orig_len,
3795 struct smb_rqst *old_rq, __le16 cipher_type)
3796 {
3797 struct smb2_sync_hdr *shdr =
3798 (struct smb2_sync_hdr
*)old_rq->rq_iov[0].iov_base;
3799
3800 memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
3801 tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
3802 tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len);
3803 tr_hdr->Flags = cpu_to_le16(0x01);
--\
3804 if (cipher_type == SMB2_ENCRYPTION_AES128_GCM)
3805 get_random_bytes(&tr_hdr->Nonce, SMB3_AES128GCM_NONCE);
3806 else
3807 get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CCM_NONCE);
--/
3808 memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
3809 }
In MS-SMB2 section 2.2.41:
AES_CCM_Nonce (11 bytes): An implementation-specific value assigned for
every encrypted message. This MUST NOT be reused for all encrypted
messages within a session.
[several other similar statements throughout document]