byte_array_ops/byte_array/trust/
insecure_ops.rs

1//! this module is only included when there are no hardening features activated at compile time
2
3use super::super::model::*;
4use alloc::vec::Vec;
5use core::fmt::{Debug, Display, Formatter};
6
7impl From<ByteArray> for Vec<u8> {
8    /// This conversion and ownership transfer is only available in non-hardened modes
9    fn from(arr: ByteArray) -> Self {
10        arr.bytes // Zero-cost move
11    }
12}
13
14impl ByteArray {
15    /// This transforms the bytearray into an owned vector an is thus unavailable in hardned modes
16    /// Allowing this in hardened modes means giving over control of resource sanitization to user
17    /// which would not guarantee a proper purge TODO add security handbook readme
18    pub fn to_vec(self) -> Vec<u8> {
19        self.into()
20    }
21
22    /// truncate function similar to [`Vec::truncate`]. This is the insecure implementation
23    /// TODO move this as part of the SecureReallocationProvider trait which collects all common
24    /// vector methods that might cause reallocation
25    pub fn truncate(&mut self, len: usize) {
26        self.bytes.truncate(len)
27    }
28}
29
30#[cfg(test)]
31mod tests_non_hardened_only {
32    use super::*;
33    use alloc::vec;
34    use alloc::vec::Vec;
35
36    #[test]
37    fn test_roundtrip_vec() {
38        let original = vec![0x01, 0x02, 0x03, 0x04];
39        let arr = ByteArray::from(original.clone());
40        let extracted: Vec<u8> = arr.clone().into();
41        let extracted_through_method = arr.to_vec();
42
43        assert_eq!(original, extracted);
44        assert_eq!(original, extracted_through_method)
45    }
46    #[test]
47    fn test_into_vec() {
48        let arr: ByteArray = vec![0xde, 0xad, 0xbe, 0xef].into();
49
50        let extracted: Vec<u8> = arr.clone().into();
51        let extracted_via_method = arr.to_vec();
52
53        assert_eq!(extracted, vec![0xde, 0xad, 0xbe, 0xef]);
54        assert_eq!(extracted_via_method, extracted)
55    }
56
57    #[test]
58    fn test_into_vec_empty() {
59        let arr = ByteArray::default();
60
61        let extracted: Vec<u8> = arr.clone().into();
62
63        let extracted_via_method = arr.to_vec();
64
65        assert!(extracted.is_empty());
66        assert!(extracted_via_method.is_empty());
67    }
68
69    #[test]
70    fn test_truncate_to_smaller_length() {
71        let mut arr: ByteArray = vec![0x01, 0x02, 0x03, 0x04, 0x05].into();
72        arr.truncate(3);
73
74        assert_eq!(arr.len(), 3);
75        assert_eq!(arr.as_bytes(), [0x01, 0x02, 0x03]);
76    }
77
78    #[test]
79    fn test_truncate_to_zero() {
80        let mut arr: ByteArray = vec![0xaa, 0xbb, 0xcc].into();
81        arr.truncate(0);
82
83        assert_eq!(arr.len(), 0);
84        assert!(arr.is_empty());
85    }
86
87    #[test]
88    fn test_truncate_to_same_length() {
89        let mut arr: ByteArray = vec![0x01, 0x02, 0x03].into();
90        arr.truncate(3);
91
92        assert_eq!(arr.len(), 3);
93        assert_eq!(arr.as_bytes(), [0x01, 0x02, 0x03]);
94    }
95
96    #[test]
97    fn test_truncate_to_larger_length() {
98        let mut arr: ByteArray = vec![0x01, 0x02].into();
99        arr.truncate(10);
100
101        // Should have no effect when truncating to larger size
102        assert_eq!(arr.len(), 2);
103        assert_eq!(arr.as_bytes(), [0x01, 0x02]);
104    }
105
106    #[test]
107    fn test_truncate_empty_array() {
108        let mut arr = ByteArray::default();
109        arr.truncate(0);
110
111        assert!(arr.is_empty());
112    }
113
114    #[test]
115    fn test_truncate_single_byte() {
116        let mut arr: ByteArray = vec![0xff, 0xee, 0xdd].into();
117        arr.truncate(1);
118
119        assert_eq!(arr.len(), 1);
120        assert_eq!(arr.as_bytes(), [0xff]);
121    }
122}
123
124/// this is insecure as it might exposes internal byte array data for example in system logs and is
125/// thus only available in insecure modes. If the user wants to do it nonetheless he shall override
126/// the default display provider TODO
127impl Display for ByteArray {
128    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
129        self.bytes.fmt(f)
130    }
131}
132
133/// this is the insecure version of debug impl that leaks byte array data
134impl Debug for ByteArray {
135    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
136        <ByteArray as Display>::fmt(self, f)
137    }
138}