ZeroizeStrategy.md
1 # Using Zeroize in Arti. 2 3 The [`zeroize`] crate provides a best-effort mechanism to ensure that memory is 4 reset to zero before it is dropped. Here we describe what we use it for, and 5 why. 6 7 This document will not explain the limitations of the `zeroize` crate: for those, 8 see the crate's documentation. 9 10 ## What can Zeroize defend us against? 11 12 There are several ways that memory can get revealed to an attacker: 13 14 1. A programming bug might reveal uninitialized freed memory from the heap or 15 stack. This is less of a concern in safe Rust, but we still do link against 16 some code written in unsafe languages. 17 2. A programming bug might reveal in-use memory from a different allocation on 18 the heap or stack. This is also less of a concern in safe Rust. (Zeroize 19 cannot defend against this, since it only clears objects when they become 20 unused.) 21 3. The memory might be written to a swap file. (Zeroize cannot defend against 22 this, but it can limit the window of time during which the secrets are in RAM 23 to be swapped out.) 24 4. The memory might be revealed via a local attack by an attacker with physical 25 or administrative access. (Zeroize can't prevent this either, but it can 26 limit the window of time during which the secret are in RAM.) 27 28 So we see that zeroizing memory is not a categorical way to prevent 29 memory-exposure attacks. Instead, it is a defense-in-depth mechanism to limit 30 the impacts of these attacks if and when they occur. 31 32 There are several possible impacts of a memory exposure. The most important 33 ones seem to be, in decreasing order of severity. 34 35 1. The attacker might learn a private key, and thereby be able to impersonate a 36 relay or onion service. 37 2. The attacker might learn an ephemeral secret key, and thereby be able to 38 decrypt traffic that had been sent over the network. This would threaten 39 forward-secrecy. 40 3. The attacker might learn information that would help them perform traffic 41 analysis, like which guards a user was configured to use at a given time, or 42 information about a path through the network, or an IP address that the user 43 had been trying to connect to. 44 45 ## Analysis and policies 46 47 During an exposure of type 2, 3, or 4 above, `zeroize` will never render the 48 attack completely harmless: it will only limit its impact. Therefore, it 49 makes sense to use it as part of a defense-in-depth strategy to try to lower 50 the impact of these attacks if they occur. 51 52 Information of types 1 and 2 is fairly well contained in individual places in 53 the code. Information of type 3, however, is spread all over the place: it's 54 hard to categorically reason that any particular piece of data _wouldn't_ help 55 the attacker do traffic analysis. 56 57 Therefore, we are going to try to use `zeroize` to protect secret encryption 58 keys and private keys only. 59 60 Furthermore, though we will consider failure to use `zeroize` in these cases as 61 a bug, we will not treat it as a critical security bug: instead, we'll treat it 62 only as a missing defense-in-depth to be addressed under our usual update 63 schedule. 64 65 ## Other defenses 66 67 There are orthogonal defenses against these attacks that we don't consider here. 68 They include: 69 70 1. Encrypted swap 71 2. Reducing the amount of unsafe code, and sandboxing that code in a separate process. 72 3. Keeping secrets in memory pages marked as unswappable. 73 4. Disabling swap entirely. 74 5. OS-level mechanisms to make it harder for other processes to read the given 75 process's memory. 76 6. Replacement allocator implementations that just zeroize everything.