optee_utee/net/
optee.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 alloc::ffi::CString;
19use core::ptr;
20use optee_utee_sys as raw;
21
22use super::{Socket, SocketAdapter, SocketError};
23
24/// A setup parameter used for OP-TEE.
25pub struct Setup {
26    addr: CString,
27    port: u16,
28    version: raw::TEE_ipSocket_ipVersion,
29}
30
31impl Setup {
32    pub(crate) fn new(
33        addr: &str,
34        port: u16,
35        version: raw::TEE_ipSocket_ipVersion,
36    ) -> crate::Result<Self> {
37        Ok(Self {
38            addr: CString::new(addr).map_err(|_| crate::ErrorKind::BadParameters)?,
39            port,
40            version,
41        })
42    }
43    /// Construct a new IPv4 target parameter using the address and port. It
44    /// will return `BadParameters` if the address contains a `\0` character in
45    /// the middle.
46    pub fn new_v4(addr: &str, port: u16) -> crate::Result<Self> {
47        Self::new(addr, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
48    }
49    /// Construct a new IPv6 target parameter using the address and port. It
50    /// will return `BadParameters` if the address contains a `\0` character in
51    /// the middle.
52    pub fn new_v6(addr: &str, port: u16) -> crate::Result<Self> {
53        Self::new(addr, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_6)
54    }
55}
56
57/// An adapter for TCP sockets in OP-TEE. Typically, it is not used directly,
58/// but can be employed for wrapper operations, such as traffic control within
59/// the TEE.
60pub struct TcpAdapter(raw::TEE_iSocketHandle);
61/// An adapter for UDP sockets in OP-TEE. Typically, it is not used directly,
62/// but can be employed for wrapper operations, such as traffic control within
63/// the TEE.
64pub struct UdpAdapter(raw::TEE_iSocketHandle);
65/// A TcpStream that is compatible with OP-TEE.
66pub type TcpStream = Socket<TcpAdapter>;
67/// A UdpSocket that is compatible with OP-TEE.
68pub type UdpSocket = Socket<UdpAdapter>;
69
70fn handle_socket_operation_error(handle: raw::TEE_iSocketHandle, code: u32) -> SocketError {
71    match code {
72        raw::TEE_ISOCKET_ERROR_PROTOCOL => {
73            let protocol_error = unsafe { ((*raw::TEE_tcpSocket).error)(handle) };
74            SocketError::ErrorProtocol(protocol_error)
75        }
76        raw::TEE_ISOCKET_WARNING_PROTOCOL => {
77            let protocol_error = unsafe { ((*raw::TEE_tcpSocket).error)(handle) };
78            SocketError::WarningProtocol(protocol_error)
79        }
80        _ => SocketError::from_raw_error(code, 0),
81    }
82}
83
84impl SocketAdapter for TcpAdapter {
85    type Setup = Setup;
86    type Handle = Self;
87
88    fn open(setup: Self::Setup) -> Result<Self::Handle, SocketError> {
89        let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
90        let mut protocol_error: u32 = 0;
91        let mut setup = raw::TEE_tcpSocket_Setup {
92            ipVersion: setup.version,
93            server_addr: setup.addr.as_ptr() as _,
94            server_port: setup.port,
95        };
96        let ret = unsafe {
97            ((*raw::TEE_tcpSocket).open)(
98                &mut handle,
99                &mut setup as *mut raw::TEE_tcpSocket_Setup as _,
100                &mut protocol_error,
101            )
102        };
103        match ret {
104            raw::TEE_SUCCESS => Ok(Self(handle)),
105            _ => Err(SocketError::from_raw_error(ret, protocol_error)),
106        }
107    }
108    fn send(handle: &mut Self::Handle, buf: &[u8], timeout: u32) -> Result<usize, SocketError> {
109        let mut length: u32 = buf.len() as _;
110        let ret = unsafe {
111            ((*raw::TEE_tcpSocket).send)(handle.0, buf.as_ptr() as _, &mut length, timeout)
112        };
113        match ret {
114            raw::TEE_SUCCESS => Ok(length as usize),
115            _ => Err(handle_socket_operation_error(handle.0, ret)),
116        }
117    }
118    fn recv(handle: &mut Self::Handle, buf: &mut [u8], timeout: u32) -> Result<usize, SocketError> {
119        let mut length: u32 = buf.len() as _;
120        let ret = unsafe {
121            ((*raw::TEE_tcpSocket).recv)(handle.0, buf.as_mut_ptr() as _, &mut length, timeout)
122        };
123        match ret {
124            raw::TEE_SUCCESS => Ok(length as usize),
125            _ => Err(handle_socket_operation_error(handle.0, ret)),
126        }
127    }
128}
129
130impl Drop for TcpAdapter {
131    fn drop(&mut self) {
132        // Ignore any errors on close.
133        unsafe {
134            ((*raw::TEE_tcpSocket).close)(self.0);
135        }
136    }
137}
138
139impl SocketAdapter for UdpAdapter {
140    type Setup = Setup;
141    type Handle = Self;
142
143    fn open(setup: Self::Setup) -> Result<Self::Handle, SocketError> {
144        let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
145        let mut protocol_error: u32 = 0;
146        let mut setup = raw::TEE_udpSocket_Setup {
147            ipVersion: setup.version,
148            server_addr: setup.addr.as_ptr() as _,
149            server_port: setup.port,
150        };
151        let ret = unsafe {
152            ((*raw::TEE_udpSocket).open)(
153                &mut handle,
154                &mut setup as *mut raw::TEE_udpSocket_Setup as _,
155                &mut protocol_error,
156            )
157        };
158        match ret {
159            raw::TEE_SUCCESS => Ok(Self(handle)),
160            _ => Err(SocketError::from_raw_error(ret, protocol_error)),
161        }
162    }
163    fn send(handle: &mut Self::Handle, buf: &[u8], timeout: u32) -> Result<usize, SocketError> {
164        let mut length: u32 = buf.len() as _;
165        let ret = unsafe {
166            ((*raw::TEE_udpSocket).send)(handle.0, buf.as_ptr() as _, &mut length, timeout)
167        };
168        match ret {
169            raw::TEE_SUCCESS => Ok(length as usize),
170            _ => Err(handle_socket_operation_error(handle.0, ret)),
171        }
172    }
173    fn recv(handle: &mut Self::Handle, buf: &mut [u8], timeout: u32) -> Result<usize, SocketError> {
174        let mut length: u32 = buf.len() as _;
175        let ret = unsafe {
176            ((*raw::TEE_udpSocket).recv)(handle.0, buf.as_mut_ptr() as _, &mut length, timeout)
177        };
178        match ret {
179            raw::TEE_SUCCESS => Ok(length as usize),
180            _ => Err(handle_socket_operation_error(handle.0, ret)),
181        }
182    }
183}
184
185impl Drop for UdpAdapter {
186    fn drop(&mut self) {
187        // Ignore any errors on close.
188        unsafe {
189            ((*raw::TEE_udpSocket).close)(self.0);
190        }
191    }
192}