Skip to content

Shared secret stored on stack, making zeroization ineffective? #70

Description

@faern

Awesome that you added zeroize support in #51! But it seems to only clear internal state. The most important data, the actual decapsulated shared secret returned from Decapsulate::decapsulate is returned in an array placed directly on the stack.

This probably means the compiler sprinkles copies of this data in many places in memory, with no effective way to clear it out. As a user of the library can I feel safe that after I have performed a decapsulation and returned control upstream, other code running in the same thread can't find the secret on stack? Or other processes running after my process exits. I currently don't think so? Since you did add the zeroize feature I trust you acknowledge the core problem and want to address it? I'd love to be told I'm wrong and that I missed some part of this, making the current API not leak secrets into memory.

The best way I know of to solve this is to let the encapsulate and decapsulate methods take mutable references to the buffers where the output secrets should be stored. And potentially with more ergonomic helper variants just returning the secrets in a Box<Secretz> type that properly implements zeroization. The Classic McEliece library did exactly this.

I reported the same issue towards the Kyber implementation we used before trying to move over to ml-kem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions