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}