Skip to content

Accidental unlocking of secrets #109

@andrewwhitehead

Description

@andrewwhitehead

I put together a quick example where two Secret instances may end up on the same page, such that dropping the second one will munlock the first one prior to it being dropped (make sure to test debug and release mode):

Secret::<u64>::zero(|a| {
    let addr1 = &*a as *const _ as usize;
    let addr2 = Secret::<u64>::zero(|b| &*b as *const _ as usize);
    println!("distance: {}", addr1.abs_diff(addr2));
})

I've found that in this case, increasing the size of the Secret instance such that it always takes up a page on the stack can help to prevent this issue. For example, updating it to:

pub struct Secret<T: Bytes> {
    spacer: [u8; 4096],
    /// The internal protected memory for the [`Secret`].
    data: T,
}

The spacer size could potentially be larger, notably the page size is 16384 bytes on recent Macs. Alternatively, it appears that the alignment on Secret can be set to a larger value which would also have a similar effect:

#[repr(align(4096))]
pub struct Secret<T: Bytes> {
    /// The internal protected memory for the [`Secret`].
    data: T,
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions