Open briansmith opened 9 years ago
I decided not to do any, but instead leave it up to ring-ffi to do it. See https://github.com/briansmith/ring-ffi/issues/3.
Can this be reopened? I've had users ask me whether I could do this: https://github.com/est31/rcgen/issues/47
Can this be reopened? I've had users ask me whether I could do this: est31/rcgen#47
Sure.
Destructor/drop-based zeroization as people intuitively think about it has limited value because it's impractical to use an allowlist-type approach to make sure every sensitive thing is zeroized. Instead it would be better to use an allocator that automatically zeroizes on deallocation (like BoringSSL does in FIPS mode, IIRC).
For example, let's say you're implementing HTTPS. There are secret values in the TLS layer and in the HTTP layer, e.g. cookie header fields and secret payloads in HTTP message bodies. The distinction between zeroizing things in the crypto library vs. TLS library vs. HTTP library is pretty arbitrary. I don't know of any HTTP libraries in widespread use that are zeroizing buffers. The same goes for JSON parsing libraries and other libraries that are used to process the secret data after it is decrypted.
Also, zeroization can only protect data that is not being used. It doesn't protect data that is still in use. This makes zeroization a mitigation with limited benefit. Probably the non-technical (PR) benefits of it outweigh the technical benefits in practice.
Despite all that, I'm not opposed to doing this.
Excited to see ring
development continue with the goal of a "FIPS mode".
Instead it would be better to use an allocator that automatically zeroizes on deallocation (like BoringSSL does in FIPS mode, IIRC).
Does the roadmap for FIPS mode include destructor-based zeroization for applicable ring
types or will compliance be left to platform-specific allocator implementations?
My bias is toward the former, some context:
The limitations stated above are valid, but destructor-based zeroization has become somewhat of an unofficial best-practice/expectation for Rust cryptographic crates - particularly for containers of secret key material (pkcs8::SecretDocument
or rsa::PrivateKey
, for example).
For usecases/deployments where shipping a custom allocator is undesirable or infeasible, ring
's lack of zeroization presents a challenge: using ring
types within a larger Rust project reduces overall security posture with respect to memory introspection/forensics. ring
becomes the weak link in the chain of key material containers.
On most operating systems, pages don't get zero-ed immediately on process exit - only if that particular page happens to be requested by another process in the future. This means ring
usage can leave secrets in memory after an application has terminated.
ring
secret key containers don't implement Copy
. That's a reasonable intentional design choice, but it does mean that custom zeroizing newtypes can't have correctness guarantees upheld via the type system. There's no clean zeroization workaround that I'm aware of.
I'd love to see support for destructor-based zeroization in ring
, even if opt-in via feature flag.
EDIT: typos. Also note that allocator-based zeroization would apply to heap-stored secrets, but stack-stored buffers might still be recoverable (no guarantee the stack frame will be overwritten in a particular execution). Destructor-based would cover both the stack and heap.
BoringSSL and OpenSSL attempt to do zeroization of key material. Should ring? In particular, should we zeroize HMAC key material?