aws_lc_rs/
buffer.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0 OR ISC
3
4//! This module exposes a buffer type used in crate APIs returning private keys and other "private"
5//! contents.
6
7#![allow(clippy::module_name_repetitions)]
8
9use alloc::borrow::Cow;
10use core::fmt;
11use core::marker::PhantomData;
12
13use zeroize::Zeroize;
14
15/// This is a buffer type for some data exposed by various APIs in this crate.
16///
17/// `T` acts as a discriminant between different kinds of data.
18///
19/// The buffer will be zeroed on drop if it is owned.
20pub struct Buffer<'a, T>(Cow<'a, [u8]>, PhantomData<T>);
21
22impl<T> Drop for Buffer<'_, T> {
23    fn drop(&mut self) {
24        if let Cow::Owned(b) = &mut self.0 {
25            b.zeroize();
26        }
27    }
28}
29
30impl<'a, T> Buffer<'a, T> {
31    pub(crate) fn new(owned: Vec<u8>) -> Buffer<'a, T> {
32        Buffer(Cow::Owned(owned), PhantomData)
33    }
34
35    pub(crate) fn take_from_slice(slice: &mut [u8]) -> Buffer<'a, T> {
36        let owned = slice.to_vec();
37        slice.zeroize();
38        Buffer(Cow::Owned(owned), PhantomData)
39    }
40}
41
42impl<T> fmt::Debug for Buffer<'_, T> {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
44        f.write_str("Buffer(...)")
45    }
46}
47
48impl<T> AsRef<[u8]> for Buffer<'_, T> {
49    #[inline]
50    fn as_ref(&self) -> &[u8] {
51        self.0.as_ref()
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_new() {
61        let buffer: Buffer<u8> = Buffer::new(vec![1, 2, 3]);
62        assert_eq!(buffer.as_ref(), &[1, 2, 3]);
63    }
64
65    #[test]
66    fn test_take_from_slice() {
67        let mut slice = [1, 2, 3];
68        let buffer: Buffer<u8> = Buffer::take_from_slice(&mut slice);
69        assert_eq!(buffer.as_ref(), &[1, 2, 3]);
70        assert_eq!(slice, [0, 0, 0]);
71    }
72}