Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonce reuse in bcachefs is more dangerous than other filesystems #637

Open
hashbrowncipher opened this issue Jan 22, 2024 · 1 comment
Open

Comments

@hashbrowncipher
Copy link
Contributor

As discussed in the encryption documentation, bcachefs uses deterministic nonces in encrypting its data. This leads to concerns about nonce reuse, which are discussed in the same documentation. The current design leaves users of encryption at risk from threats that are well-addressed by other disk encryption implementations, particularly AES-XTS.

In the scenario I am considering, the attacker receives two fully encrypted filesystem images. The first image (call it "prod") contains an encrypted filesystem. The second image contains the same filesystem, which has been copied to another machine (call it "testing", because it is intended to represent a machine in a testing environment). After the copy, the owner of the drives continued writing to both images. The newly-written data in the prod image is secret, and unpredictable to the attacker. The newly-written data in the testing image is known to the attacker. At no point did the attacker have online access to the disks or to the kernels which mounted them: the attacker only has their knowledge of the "testing" plaintext and access to the disks themselves.

Given this setting, the attacker may recover the plaintext of the prod disk as prod ciphertext XOR testing ciphertext XOR testing known plaintext. This attack is largely mitigated in other disk encryption implementations through the use of a block cipher like AES-XTS, which encrypts 128 bits of data at a time. But since bcachefs uses a keystream generator (ChaCha20, or potentially AES-GCM in the future), each bit is encrypted on a bit-by-bit basis and therefore revealed on a bit-by-bit basis.

I believe that mitigating this issue will require injection of external entropy. In practice, the easiest way to do this would be to derive the extent data key as KDF(superblock key, random seed) (ChaCha20 could likely be used as the KDF). The randomly chosen seed would be generated once per potential "fork event", and will need to be stored on the filesystem for as long as the encrypted data remains live. This storage requirement is significantly lower than the requirement of a per-extent data key, while still preventing concerns about nonce reuse.

@YellowOnion
Copy link
Collaborator

Journal entries use their sequence number - which is unique for a given filesystem.

This attack seems to apply for journal as well, which is probably far worse than mere deterministic nonce for a single extent, since that is also used for btree node nonce, and could potentially compromise metadata and data location for the entire file system.

The randomly chosen seed would be generated once per potential "fork event"

This would ofc be each journal sequence step.

I seems to me a simple journal nonce should be created via the above method, and perhaps it's possible to take the journal nounce + key version, or similar.

disclaimer: IANAC

the superblock is also missing a MAC, so it's easy to tamper with.

koverstreet pushed a commit that referenced this issue May 27, 2024
Xiumei reports the following splat when netlabel and TCP socket are used:

 =============================
 WARNING: suspicious RCU usage
 6.9.0-rc2+ #637 Not tainted
 -----------------------------
 net/ipv4/cipso_ipv4.c:1880 suspicious rcu_dereference_protected() usage!

 other info that might help us debug this:

 rcu_scheduler_active = 2, debug_locks = 1
 1 lock held by ncat/23333:
  #0: ffffffff906030c0 (rcu_read_lock){....}-{1:2}, at: netlbl_sock_setattr+0x25/0x1b0

 stack backtrace:
 CPU: 11 PID: 23333 Comm: ncat Kdump: loaded Not tainted 6.9.0-rc2+ #637
 Hardware name: Supermicro SYS-6027R-72RF/X9DRH-7TF/7F/iTF/iF, BIOS 3.0  07/26/2013
 Call Trace:
  <TASK>
  dump_stack_lvl+0xa9/0xc0
  lockdep_rcu_suspicious+0x117/0x190
  cipso_v4_sock_setattr+0x1ab/0x1b0
  netlbl_sock_setattr+0x13e/0x1b0
  selinux_netlbl_socket_post_create+0x3f/0x80
  selinux_socket_post_create+0x1a0/0x460
  security_socket_post_create+0x42/0x60
  __sock_create+0x342/0x3a0
  __sys_socket_create.part.22+0x42/0x70
  __sys_socket+0x37/0xb0
  __x64_sys_socket+0x16/0x20
  do_syscall_64+0x96/0x180
  ? do_user_addr_fault+0x68d/0xa30
  ? exc_page_fault+0x171/0x280
  ? asm_exc_page_fault+0x22/0x30
  entry_SYSCALL_64_after_hwframe+0x71/0x79
 RIP: 0033:0x7fbc0ca3fc1b
 Code: 73 01 c3 48 8b 0d 05 f2 1b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 29 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d d5 f1 1b 00 f7 d8 64 89 01 48
 RSP: 002b:00007fff18635208 EFLAGS: 00000246 ORIG_RAX: 0000000000000029
 RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fbc0ca3fc1b
 RDX: 0000000000000006 RSI: 0000000000000001 RDI: 0000000000000002
 RBP: 000055d24f80f8a0 R08: 0000000000000003 R09: 0000000000000001

R10: 0000000000020000 R11: 0000000000000246 R12: 000055d24f80f8a0
 R13: 0000000000000000 R14: 000055d24f80fb88 R15: 0000000000000000
  </TASK>

The current implementation of cipso_v4_sock_setattr() replaces IP options
under the assumption that the caller holds the socket lock; however, such
assumption is not true, nor needed, in selinux_socket_post_create() hook.

Let all callers of cipso_v4_sock_setattr() specify the "socket lock held"
condition, except selinux_socket_post_create() _ where such condition can
safely be set as true even without holding the socket lock.

Fixes: f6d8bd0 ("inet: add RCU protection to inet->opt")
Reported-by: Xiumei Mu <[email protected]>
Signed-off-by: Davide Caratti <[email protected]>
Acked-by: Casey Schaufler <[email protected]>
Acked-by: Paul Moore <[email protected]>
Link: https://lore.kernel.org/r/f4260d000a3a55b9e8b6a3b4e3fffc7da9f82d41.1715359817.git.dcaratti@redhat.com
Signed-off-by: Jakub Kicinski <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants