redoubt_buffer/
portable_buffer.rs

1// Copyright (c) 2025-2026 Federico Hoerth <memparanoid@gmail.com>
2// SPDX-License-Identifier: GPL-3.0-only
3// See LICENSE in the repository root for full license text.
4
5//! PortableBuffer - Standard allocation buffer (no-op security)
6//!
7//! Works everywhere, no special memory protection.
8//! Used as fallback when ProtectedBuffer is not available.
9
10extern crate alloc;
11
12use alloc::vec::Vec;
13
14use redoubt_zero::{RedoubtZero, ZeroizeOnDropSentinel};
15
16use crate::error::BufferError;
17use crate::traits::Buffer;
18
19/// A portable buffer backed by a standard Vec with automatic zeroization on drop.
20#[derive(RedoubtZero)]
21#[fast_zeroize(drop)]
22pub struct PortableBuffer {
23    inner: Vec<u8>,
24    __sentinel: ZeroizeOnDropSentinel,
25}
26
27impl PortableBuffer {
28    /// Creates a new PortableBuffer with the specified length.
29    pub fn create(len: usize) -> Self {
30        let inner = alloc::vec![0u8; len];
31
32        Self {
33            inner,
34            __sentinel: ZeroizeOnDropSentinel::default(),
35        }
36    }
37}
38
39// Safety: PortableBuffer owns its Vec and doesn't share references
40unsafe impl Send for PortableBuffer {}
41unsafe impl Sync for PortableBuffer {}
42
43impl core::fmt::Debug for PortableBuffer {
44    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
45        f.debug_struct("PortableBuffer")
46            .field("len", &self.len())
47            .finish_non_exhaustive()
48    }
49}
50
51impl Buffer for PortableBuffer {
52    fn open(
53        &mut self,
54        f: &mut dyn FnMut(&[u8]) -> Result<(), BufferError>,
55    ) -> Result<(), BufferError> {
56        f(&self.inner)
57    }
58
59    fn open_mut(
60        &mut self,
61        f: &mut dyn FnMut(&mut [u8]) -> Result<(), BufferError>,
62    ) -> Result<(), BufferError> {
63        f(&mut self.inner)
64    }
65
66    fn len(&self) -> usize {
67        self.inner.len()
68    }
69}