linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* AES CCM/GCM nonce generation possible issue
@ 2020-10-23 18:42 Tom Talpey
  2020-10-23 19:31 ` Fwd: " Steve French
  0 siblings, 1 reply; 2+ messages in thread
From: Tom Talpey @ 2020-10-23 18:42 UTC (permalink / raw)
  To: linux-cifs

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]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Fwd: AES CCM/GCM nonce generation possible issue
  2020-10-23 18:42 AES CCM/GCM nonce generation possible issue Tom Talpey
@ 2020-10-23 19:31 ` Steve French
  0 siblings, 0 replies; 2+ messages in thread
From: Steve French @ 2020-10-23 19:31 UTC (permalink / raw)
  To: Jeremy Allison, Stefan (metze) Metzmacher, Tom Talpey, CIFS

Interestingly Samba client appears to partition nonce high and nonce
low based on what I see in smbXcli_base.c and do something similar to
what you suggested.

---------- Forwarded message ---------
From: Tom Talpey <tom@talpey.com>
Date: Fri, Oct 23, 2020 at 2:22 PM
Subject: AES CCM/GCM nonce generation possible issue
To: linux-cifs@vger.kernel.org <linux-cifs@vger.kernel.org>


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]


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-10-23 19:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-23 18:42 AES CCM/GCM nonce generation possible issue Tom Talpey
2020-10-23 19:31 ` Fwd: " Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).