]> git.apps.os.sepia.ceph.com Git - ceph.git/commit
msg/async/ProtocolV2: avoid AES-GCM nonce reuse vulnerabilities
authorIlya Dryomov <idryomov@gmail.com>
Fri, 6 Mar 2020 19:16:45 +0000 (20:16 +0100)
committerAbhishek Lekshmanan <abhishek@suse.com>
Wed, 8 Apr 2020 15:30:42 +0000 (17:30 +0200)
commit47c7e623546a7a33bd6bbddfb899fa9c9a40f40a
treecaeaca37e75fe7a1671c907eaed2dc76ff4722bb
parent3785e7545afd75b456c490696ad03b28c8bc15c3
msg/async/ProtocolV2: avoid AES-GCM nonce reuse vulnerabilities

The secure mode uses AES-128-GCM with 96-bit nonces consisting of a
32-bit counter followed by a 64-bit salt.  The counter is incremented
after processing each frame, the salt is fixed for the duration of
the session.  Both are initialized from the session key generated
during session negotiation, so the counter starts with essentially
a random value.  It is allowed to wrap, and, after 2**32 frames, it
repeats, resulting in nonce reuse (the actual sequence numbers that
the messenger works with are 64-bit, so the session continues on).

Because of how GCM works, this completely breaks both confidentiality
and integrity aspects of the secure mode.  A single nonce reuse reveals
the XOR of two plaintexts and almost completely reveals the subkey
used for producing authentication tags.  After a few nonces get used
twice, all confidentiality and integrity goes out the window and the
attacker can potentially encrypt-authenticate plaintext of their
choice.

We can't easily change the nonce format to extend the counter to
64 bits (and possibly XOR it with a longer salt).  Instead, just
remember the initial nonce and cut the session before it repeats,
forcing renegotiation.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
Reviewed-by: Sage Weil <sage@redhat.com>
Conflicts:
src/msg/async/ProtocolV2.cc [ context: commit 697aafa2aad2
  ("msg/async/ProtocolV2: remove unused parameter") not in
  nautilus ]
src/msg/async/ProtocolV2.h [ context: commit ed3ec4c01d17
  ("msg: Build target 'common' without using namespace in
  headers") not in nautilus ]
src/msg/async/ProtocolV2.cc
src/msg/async/ProtocolV2.h
src/msg/async/crypto_onwire.cc
src/msg/async/crypto_onwire.h