1

I want to use Rust's zeroize crate for zeroizing BTreeMap entries. But zeroize doesn't seems to provide an out-of-the-box implementation for BTreeMap.

Currently, I'm resorting to clear to remove the map's entries.

Q1. How safe is it to use simply clear out my secrets stored in the map & without zeroizing them?

Q2. How can I use zeroize with std::collection::BTreeMap? I think I've to iterate over each element to zeroize it. An additional complexity with this approach is that my map contains "complex" generic structs. So will I have to zeroize turtle all the way down?

Q2.a) Any other crates that might help me with zeroizing BTreeMap like mine?

My struct eg:

let my_map1: BTreeMap<usize, MyStruct1<G1Projective>> = BTreeMap::new();

#[derive(Clone, Debug, Serialize, Deserialize)]
struct MyStruct1<G: MyTrait1 + MyTrait2> {
  #[serde(serialize_with: .., deserialize_with: ..)]
  field1: G,

  #[serde(serialize_with: .., deserialize_with: ..)]
  field2: Vec<G>,
}
NewToCode
  • 174
  • 8
  • You can `zeroize` a mutable iterator, so any datastrcture that allows iterating over its elements (as a `BTreeMap` does) and which contains zeroizable members (that depends on `MyStruct1` is very easy to zeroize. – jthulhu Jul 28 '23 at 11:18

1 Answers1

5

You don't need to zeroize the whole hierarchy of structs that hold a field that holds a secret. You only need to implement Zeroize on the field itself. The easiest way to do that is to simply use the Zeroizing wrapper, e.g.:

use zeroize::Zeroizing;

struct User {
    username: String,
    password: Zeroizing<String>,
};

Then the passwords will be cleared whenever a User is destroyed (including when you clear a BTreeMap, or even simply let it go out of scope).

Note however that simply storing any kind of secret in a BTreeMap is inherently insecure, because adding (or removing) items in the map may cause other items to be reallocated or moved and the original memory location will not be cleared in that case, only the final location when the map is cleared or dropped.

Jmb
  • 18,893
  • 2
  • 28
  • 55
  • When you say that storing a secret in `BTreeMap` is not secure, does that include Zeroized secrets, or not? I'd expect not... but it's a bit confusing at the moment. – Matthieu M. Jul 28 '23 at 10:10
  • Yes that includes zeroized secrects, see https://docs.rs/zeroize/latest/zeroize/#stackheap-zeroing-notes What it says about `Vec` and `String` also applies to `BTreeMap`, except that for `BTreeMap` there is no equivalent to `reserve` or `with_capacity` to work around the issue. – Jmb Jul 28 '23 at 10:16
  • 5
    To elaborate on what I just said, storing a `Zeroizing` or `Zeroizing>` in a `BTreeMap` should be fine because the `BTreeMap` doesn't hold the secret data itself, only a reference to it. However storing e.g. a `Zeroizing<[u8; 16]>` is insecure because then the secret data is held directly in the `BTreeMap`. – Jmb Jul 28 '23 at 10:28
  • @Jmb Is storing `Zeroizing>` still safe when I'm **cloning** it? – NewToCode Jul 31 '23 at 11:29
  • @MatthieuM. What do you think about my cloning question in the comments? – NewToCode Aug 01 '23 at 16:01
  • @NewToCode: I have no idea, and it probably warrants a different question -- comments are meant to be removed. – Matthieu M. Aug 01 '23 at 16:33