kernel/utilities/
mut_imut_buffer.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! An enum that can contain a reference to either a mutable or an immutable
6//! buffer.
7//!
8//! This type is intended for internal use in implementations of HILs or
9//! abstractions which need to handle both mutable and immutable buffers.
10//!
11//! One motivating use case is keys for public key cryptography. Public keys are
12//! often distributed as constant values in the flash of a kernel image (e.g.,
13//! to verify signatures), which requires they be immutable. Copying them to
14//! RAM is expensive because these keys can be very large (e.g., 512 bytes for a
15//! 4096-bit RSA key). At the same time, some clients may use dynamically
16//! generated or received keys, which are stored in mutable RAM. Requiring that
17//! keys be immutable would discard `mut` on this memory. An implementation can
18//! use this type to store either mutable and immutable buffers. The OTBN
19//! (OpenTitan Big Number accelerator) is one example use of [`MutImutBuffer`].
20//!
21//! Because this type requires dynamic runtime checks that types match, it
22//! should not be used in any HILs or standard, external APIs. It is intended
23//! only for internal use within implementations.
24//!
25//! Usage
26//! -----
27//!
28//! ```rust
29//! use kernel::utilities::mut_imut_buffer::MutImutBuffer;
30//!
31//! let mut mutable = ['a', 'b', 'c', 'd'];
32//! let immutable = ['e', 'f', 'g', 'h'];
33//!
34//! let shared_buf = MutImutBuffer::Mutable(&mut mutable);
35//! let shared_buf2 = MutImutBuffer::Immutable(&immutable);
36//!  ```
37
38// Author: Alistair Francis
39
40/// An enum which can hold either a mutable or an immutable buffer.
41pub enum MutImutBuffer<'a, T> {
42    Mutable(&'a mut [T]),
43    Immutable(&'a [T]),
44}
45
46impl<T> MutImutBuffer<'_, T> {
47    /// Returns the length of the underlying buffer.
48    pub fn len(&self) -> usize {
49        match self {
50            MutImutBuffer::Mutable(buf) => buf.len(),
51            MutImutBuffer::Immutable(buf) => buf.len(),
52        }
53    }
54}