optee_utee/
uuid.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::{ErrorKind, Result};
19use core::fmt;
20use hex;
21use optee_utee_sys as raw;
22use uuid as uuid_crate;
23
24/// A Universally Unique Resource Identifier (UUID) type as defined in RFC4122.
25/// The value is used to identify a trusted application.
26#[derive(Copy, Clone)]
27pub struct Uuid {
28    raw: raw::TEE_UUID,
29}
30
31impl Uuid {
32    /// Parses a Uuid from a string of hexadecimal digits with optional hyphens.
33    ///
34    /// # Examples
35    ///
36    /// ``` rust,no_run
37    /// # use optee_utee::Uuid;
38    /// # fn main() -> optee_utee::Result<()> {
39    ///
40    /// let uuid = Uuid::parse_str("8abcf200-2450-11e4-abe2-0002a5d5c51b")?;
41    /// # Ok(())
42    /// # }
43    /// ```
44    pub fn parse_str(input: &str) -> Result<Uuid> {
45        let uuid = uuid_crate::Uuid::parse_str(input).map_err(|_| ErrorKind::BadFormat)?;
46        let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = uuid.as_fields();
47        Ok(Self::new_raw(
48            time_low,
49            time_mid,
50            time_hi_and_version,
51            *clock_seq_and_node,
52        ))
53    }
54
55    /// Creates a `Uuid` using the supplied big-endian bytes.
56    ///
57    /// # Examples
58    ///
59    /// ``` rust,no_run
60    /// # use optee_utee::Uuid;
61    /// let bytes: [u8; 16] = [70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62,];
62    /// let uuid = Uuid::from_bytes(bytes);
63    /// ```
64    pub fn from_bytes(bytes: [u8; 16]) -> Uuid {
65        let uuid = uuid_crate::Uuid::from_bytes(bytes);
66        let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = uuid.as_fields();
67        Self::new_raw(time_low, time_mid, time_hi_and_version, *clock_seq_and_node)
68    }
69
70    /// Creates a `Uuid` using a slice of supplied big-endian bytes.
71    ///
72    /// # Examples
73    ///
74    /// ``` rust,no_run
75    /// # use optee_utee::Uuid;
76    /// # fn main() -> optee_utee::Result<()> {
77    /// let bytes: &[u8; 16] = &[70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62,];
78    /// let uuid = Uuid::from_slice(bytes)?;
79    /// # Ok(())
80    /// # }
81    /// ```
82    pub fn from_slice(b: &[u8]) -> Result<Uuid> {
83        let uuid = uuid_crate::Uuid::from_slice(b).map_err(|_| ErrorKind::BadFormat)?;
84        let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = uuid.as_fields();
85        Ok(Self::new_raw(
86            time_low,
87            time_mid,
88            time_hi_and_version,
89            *clock_seq_and_node,
90        ))
91    }
92
93    /// Creates a raw TEE client uuid object with specified parameters.
94    pub fn new_raw(
95        time_low: u32,
96        time_mid: u16,
97        time_hi_and_version: u16,
98        clock_seq_and_nod: [u8; 8],
99    ) -> Uuid {
100        let raw_uuid = raw::TEE_UUID {
101            timeLow: time_low,
102            timeMid: time_mid,
103            timeHiAndVersion: time_hi_and_version,
104            clockSeqAndNode: clock_seq_and_nod,
105        };
106        Self { raw: raw_uuid }
107    }
108
109    /// Converts a uuid to a const raw `TEE_UUID` pointer.
110    pub fn as_raw_ptr(&self) -> *const raw::TEE_UUID {
111        &self.raw
112    }
113}
114
115impl fmt::Display for Uuid {
116    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117        write!(
118            f,
119            "{:08x}-{:04x}-{:04x}-{}-{}",
120            self.raw.timeLow,
121            self.raw.timeMid,
122            self.raw.timeHiAndVersion,
123            hex::encode(&self.raw.clockSeqAndNode[0..2]),
124            hex::encode(&self.raw.clockSeqAndNode[2..8]),
125        )
126    }
127}
128
129impl From<raw::TEE_UUID> for Uuid {
130    fn from(raw: raw::TEE_UUID) -> Self {
131        Uuid { raw }
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    extern crate alloc;
138    use super::*;
139    use alloc::string::ToString;
140
141    #[test]
142    fn test_to_string() {
143        let uuids = [
144            "00173366-2aca-49bc-beb7-10c975e6131e", // uuid with timeLow leading zeros
145            "11173366-0aca-49bc-beb7-10c975e6131e", // uuid with timeMid leading zeros
146            "11173366-2aca-09bc-beb7-10c975e6131e", // uuid with timeHiAndVersion leading zeros
147            "11173366-2aca-19bc-beb7-10c975e6131e", // random uuid
148        ];
149        for origin in uuids.iter() {
150            let uuid = Uuid::parse_str(origin).expect("Test UUID should be valid");
151            let formatted = uuid.to_string();
152            assert_eq!(*origin, formatted);
153        }
154    }
155}