1616// under the License.
1717
1818use crate :: { Error , ErrorKind , Result , Uuid } ;
19- use optee_utee_sys as raw;
20- #[ cfg( not( feature = "std" ) ) ]
21- use alloc:: vec:: Vec ;
2219#[ cfg( not( feature = "std" ) ) ]
23- use alloc:: borrow:: ToOwned ;
20+ use alloc:: { borrow:: ToOwned , vec:: Vec } ;
21+ use optee_utee_sys as raw;
2422
2523pub struct LoadablePlugin {
26- uuid : Uuid
24+ uuid : Uuid ,
2725}
2826
2927pub struct LoadablePluginCommand < ' a > {
@@ -35,7 +33,9 @@ pub struct LoadablePluginCommand<'a> {
3533
3634impl LoadablePlugin {
3735 pub fn new ( uuid : & Uuid ) -> Self {
38- Self { uuid : uuid. to_owned ( ) }
36+ Self {
37+ uuid : uuid. to_owned ( ) ,
38+ }
3939 }
4040 /// Invoke plugin with given request data, use when you want to post something into REE.
4141 /// ``` rust,no_run
@@ -50,7 +50,7 @@ impl LoadablePlugin {
5050 /// # Ok(())
5151 /// # }
5252 /// ```
53- /// Caution: the size of the shared buffer is set to the len of data, you could get a
53+ /// Caution: the size of the shared buffer is set to the len of data, you could get a
5454 /// ShortBuffer error if Plugin return more data than shared buffer, in that case,
5555 /// use invoke_with_capacity and set the capacity manually.
5656 pub fn invoke ( & self , command_id : u32 , subcommand_id : u32 , data : & [ u8 ] ) -> Result < Vec < u8 > > {
@@ -79,7 +79,7 @@ impl LoadablePlugin {
7979 /// ```no_run
8080 /// # use optee_utee::{LoadablePluginCommand, Uuid, LoadablePlugin, trace_println};
8181 /// # use optee_utee::ErrorKind;
82- /// # fn main() -> optee_utee::Result<()> {
82+ /// # fn main() -> optee_utee::Result<()> {
8383 /// # let command_id = 0;
8484 /// # let subcommand_id = 0;
8585 /// # let capacity = 0;
@@ -178,44 +178,10 @@ impl<'a> LoadablePluginCommand<'a> {
178178pub mod test_loadable_plugin {
179179 extern crate std;
180180 use super :: * ;
181- use core:: ffi:: c_char;
182- use once_cell:: sync:: Lazy ;
183- use optee_utee_sys:: { TEE_Result , TEE_UUID } ;
181+ use alloc:: string:: ToString ;
182+ use optee_utee_sys:: { mock_api, mock_utils:: SERIAL_TEST_LOCK } ;
184183 use rand:: distributions:: Alphanumeric ;
185184 use rand:: Rng ;
186- use std:: collections:: HashMap ;
187- use std:: sync:: RwLock ;
188-
189- static REE_RETURN_VALUES : RwLock < Lazy < HashMap < ( u32 , u32 ) , Vec < u8 > > > > =
190- RwLock :: new ( Lazy :: new ( || HashMap :: new ( ) ) ) ;
191- static REE_EXPECTED_VALUES : RwLock < Lazy < HashMap < ( u32 , u32 ) , Vec < u8 > > > > =
192- RwLock :: new ( Lazy :: new ( || HashMap :: new ( ) ) ) ;
193-
194- fn set_ree_return_value ( cmd : u32 , sub_cmd : u32 , value : Vec < u8 > ) {
195- let mut values = REE_RETURN_VALUES . write ( ) . unwrap ( ) ;
196- let key = ( cmd, sub_cmd) ;
197- assert ! ( !values. contains_key( & key) ) ;
198- values. insert ( key, value) ;
199- }
200-
201- fn set_ree_expected_value ( cmd : u32 , sub_cmd : u32 , value : Vec < u8 > ) {
202- let mut values = REE_EXPECTED_VALUES . write ( ) . unwrap ( ) ;
203- let key = ( cmd, sub_cmd) ;
204- assert ! ( !values. contains_key( & key) ) ;
205- values. insert ( key, value) ;
206- }
207-
208- fn get_ree_return_value ( cmd : u32 , sub_cmd : u32 ) -> Vec < u8 > {
209- let values = REE_RETURN_VALUES . read ( ) . unwrap ( ) ;
210- let key = ( cmd, sub_cmd) ;
211- values. get ( & key) . unwrap ( ) . to_owned ( )
212- }
213-
214- fn get_ree_expected_value ( cmd : u32 , sub_cmd : u32 ) -> Vec < u8 > {
215- let values = REE_EXPECTED_VALUES . read ( ) . unwrap ( ) ;
216- let key = ( cmd, sub_cmd) ;
217- values. get ( & key) . unwrap ( ) . to_owned ( )
218- }
219185
220186 fn generate_random_bytes ( len : usize ) -> Vec < u8 > {
221187 rand:: thread_rng ( )
@@ -228,119 +194,129 @@ pub mod test_loadable_plugin {
228194 request_size : usize ,
229195 response_size : usize ,
230196 ) -> ( u32 , u32 , Vec < u8 > , Vec < u8 > ) {
231- let cmd: u32 = rand:: thread_rng ( ) . r#gen ( ) ;
232- let sub_cmd: u32 = rand:: thread_rng ( ) . r#gen ( ) ;
197+ let cmd: u32 = rand:: random ( ) ;
198+ let sub_cmd: u32 = rand:: random ( ) ;
233199 let random_request: Vec < u8 > = generate_random_bytes ( request_size) ;
234200 let random_response: Vec < u8 > = generate_random_bytes ( response_size) ;
235201 ( cmd, sub_cmd, random_request, random_response)
236202 }
237203
238- #[ no_mangle]
239- extern "C" fn tee_invoke_supp_plugin (
240- _uuid : * const TEE_UUID ,
241- cmd : u32 ,
242- sub_cmd : u32 ,
243- buf : * mut c_char ,
244- len : usize ,
245- outlen : * mut usize ,
246- ) -> TEE_Result {
247- // must convert buf to u8, for in some platform c_char was treated as i8
248- let inbuf = unsafe { core:: slice:: from_raw_parts_mut ( buf as * mut u8 , len) } ;
249- std:: println!(
250- "*plugin*: receive value: {:?} length {:?}" ,
251- inbuf,
252- inbuf. len( )
253- ) ;
254- let expected_value = get_ree_expected_value ( cmd, sub_cmd) ;
255- assert_eq ! ( inbuf, expected_value. as_slice( ) ) ;
256-
257- let return_value = get_ree_return_value ( cmd, sub_cmd) ;
258- assert ! ( return_value. len( ) <= len) ;
259- std:: println!( "*plugin*: write value '{:?}' to buffer" , return_value) ;
204+ fn random_uuid ( ) -> Uuid {
205+ Uuid :: new_raw (
206+ rand:: random ( ) ,
207+ rand:: random ( ) ,
208+ rand:: random ( ) ,
209+ rand:: random ( ) ,
210+ )
211+ }
260212
261- inbuf[ 0 ..return_value. len ( ) ] . copy_from_slice ( & return_value) ;
262- unsafe {
263- * outlen = return_value. len ( ) ;
264- }
265- return raw:: TEE_SUCCESS ;
213+ fn expect_success_request (
214+ ctx : & mock_api:: extension:: __tee_invoke_supp_plugin:: Context ,
215+ exp_uuid : & Uuid ,
216+ exp_cmd : u32 ,
217+ exp_sub_cmd : u32 ,
218+ exp_request : & [ u8 ] ,
219+ exp_response : & [ u8 ] ,
220+ ) {
221+ let exp_request = exp_request. to_vec ( ) ;
222+ let exp_response = exp_response. to_vec ( ) ;
223+ let exp_uuid = exp_uuid. to_string ( ) ;
224+ ctx. expect ( )
225+ . return_once_st ( move |uuid, cmd, sub_cmd, buf, len, outlen| {
226+ let request_uuid = Uuid :: from ( unsafe { * uuid } ) . to_string ( ) ;
227+ debug_assert_eq ! ( exp_uuid, request_uuid) ;
228+ debug_assert_eq ! ( cmd, exp_cmd) ;
229+ debug_assert_eq ! ( sub_cmd, exp_sub_cmd) ;
230+ debug_assert_eq ! (
231+ unsafe { core:: slice:: from_raw_parts( buf as * mut u8 , exp_request. len( ) ) } ,
232+ exp_request. as_slice( )
233+ ) ;
234+ debug_assert ! ( len >= exp_response. len( ) ) ;
235+ let buffer: & mut [ u8 ] =
236+ unsafe { core:: slice:: from_raw_parts_mut ( buf as * mut u8 , len) } ;
237+ buffer[ 0 ..exp_response. len ( ) ] . copy_from_slice ( & exp_response) ;
238+ unsafe { * outlen = exp_response. len ( ) } ;
239+ raw:: TEE_SUCCESS
240+ } ) ;
266241 }
267242
268243 #[ test]
269244 fn test_invoke ( ) {
270- let plugin = LoadablePlugin {
271- uuid : Uuid :: parse_str ( "7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10" ) . unwrap ( ) ,
272- } ;
245+ let _lock = SERIAL_TEST_LOCK . lock ( ) . expect ( "should get the lock" ) ;
246+
247+ let uuid: Uuid = random_uuid ( ) ;
248+ let plugin = LoadablePlugin :: new ( & uuid) ;
273249 const REQUEST_LEN : usize = 32 ;
250+ let run_test = |request_size : usize , response_size : usize | {
251+ let ( cmd, sub_cmd, request, exp_response) =
252+ generate_test_pairs ( request_size, response_size) ;
253+ let fn1 = mock_api:: extension:: tee_invoke_supp_plugin_context ( ) ;
254+ expect_success_request ( & fn1, & uuid, cmd, sub_cmd, & request, & exp_response) ;
255+ let response = plugin. invoke ( cmd, sub_cmd, & request) . expect ( "should be ok" ) ;
256+ std:: println!( "*TA*: response is {:?}" , response) ;
257+ debug_assert_eq ! ( response, exp_response) ;
258+ } ;
274259
275260 // test calling with output size less than input
276- let ( cmd, sub_cmd, request, exp_response) =
277- generate_test_pairs ( REQUEST_LEN , REQUEST_LEN / 2 ) ;
278- set_ree_expected_value ( cmd, sub_cmd, request. clone ( ) ) ;
279- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
280- let response = plugin. invoke ( cmd, sub_cmd, & request) . unwrap ( ) ;
281- std:: println!( "*TA*: response is {:?}" , response) ;
282- assert_eq ! ( response, exp_response) ;
283-
261+ run_test ( REQUEST_LEN , REQUEST_LEN / 2 ) ;
284262 // test calling with output size equals to input
285- let ( cmd, sub_cmd, request, exp_response) = generate_test_pairs ( REQUEST_LEN , REQUEST_LEN ) ;
286- set_ree_expected_value ( cmd, sub_cmd, request. clone ( ) ) ;
287- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
288- let response = plugin. invoke ( cmd, sub_cmd, & request) . unwrap ( ) ;
289- std:: println!( "*TA*: response is {:?}" , response) ;
290- assert_eq ! ( response, exp_response) ;
263+ run_test ( REQUEST_LEN , REQUEST_LEN ) ;
264+ // test calling with output size greater than input.
265+ // Mark: Without explicitly setting the response size, this function
266+ // must not be called with a response size larger than the request size.
267+ {
268+ let ( cmd, sub_cmd, request, exp_response) =
269+ generate_test_pairs ( REQUEST_LEN , 2 * REQUEST_LEN ) ;
270+ let fn1 = mock_api:: extension:: tee_invoke_supp_plugin_context ( ) ;
271+ fn1. expect ( ) . return_once_st ( move |_, _, _, _, _, outlen| {
272+ unsafe { * outlen = exp_response. len ( ) } ;
273+ raw:: TEE_SUCCESS
274+ } ) ;
275+ let err = plugin
276+ . invoke ( cmd, sub_cmd, & request)
277+ . expect_err ( "should be err" ) ;
278+ debug_assert_eq ! ( err. kind( ) , ErrorKind :: ShortBuffer ) ;
279+ }
291280 }
292281
282+ // This test is equivalent to test_invoke, with the added verification that
283+ // capacity permits the response size to be larger than the request.
293284 #[ test]
294285 fn test_invoke_with_capacity ( ) {
295- let plugin = LoadablePlugin {
296- uuid : Uuid :: parse_str ( "7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10" ) . unwrap ( ) ,
297- } ;
286+ let _lock = SERIAL_TEST_LOCK . lock ( ) . expect ( "should get the lock" ) ;
287+ let uuid: Uuid = random_uuid ( ) ;
288+ let plugin = LoadablePlugin :: new ( & uuid ) ;
298289 const RESPONSE_LEN : usize = 32 ;
299290
300- // test calling with output size less than input
301- let ( cmd, sub_cmd, request, exp_response) =
302- generate_test_pairs ( 2 * RESPONSE_LEN , RESPONSE_LEN ) ;
303- set_ree_expected_value ( cmd, sub_cmd, request. clone ( ) ) ;
304- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
305- let response = plugin
306- . invoke_with_capacity ( cmd, sub_cmd, exp_response. len ( ) )
307- . chain_write_body ( & request)
308- . call ( )
309- . unwrap ( ) ;
310- std:: println!( "*TA*: response is {:?}" , response) ;
311- assert_eq ! ( response, exp_response) ;
291+ let run_test = |request_size : usize , response_size : usize | {
292+ let ( cmd, sub_cmd, request, exp_response) =
293+ generate_test_pairs ( request_size, response_size) ;
294+ let fn1 = mock_api:: extension:: tee_invoke_supp_plugin_context ( ) ;
295+ expect_success_request ( & fn1, & uuid, cmd, sub_cmd, & request, & exp_response) ;
312296
313- // test calling with output size equals to input
314- let ( cmd, sub_cmd, request, exp_response) = generate_test_pairs ( RESPONSE_LEN , RESPONSE_LEN ) ;
315- set_ree_expected_value ( cmd, sub_cmd, request. clone ( ) ) ;
316- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
317- let response = plugin
318- . invoke_with_capacity ( cmd, sub_cmd, exp_response. len ( ) )
319- . chain_write_body ( & request)
320- . call ( )
321- . unwrap ( ) ;
322- std:: println!( "*TA*: response is {:?}" , response) ;
323- assert_eq ! ( response, exp_response) ;
297+ let response = plugin
298+ . invoke_with_capacity ( cmd, sub_cmd, exp_response. len ( ) )
299+ . chain_write_body ( & request)
300+ . call ( )
301+ . unwrap ( ) ;
302+ std:: println!( "*TA*: response is {:?}" , response) ;
303+ debug_assert_eq ! ( response, exp_response) ;
304+ } ;
324305
306+ // test calling with output size less than input
307+ run_test ( 2 * RESPONSE_LEN , RESPONSE_LEN ) ;
308+ // test calling with output size equals to input
309+ run_test ( RESPONSE_LEN , RESPONSE_LEN ) ;
325310 // test calling with output size greater than input
326- let ( cmd, sub_cmd, mut request, exp_response) =
327- generate_test_pairs ( RESPONSE_LEN / 2 , RESPONSE_LEN ) ;
328- request. resize ( exp_response. len ( ) , 0 ) ;
329- set_ree_expected_value ( cmd, sub_cmd, request. clone ( ) ) ;
330- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
331- let response = plugin
332- . invoke_with_capacity ( cmd, sub_cmd, exp_response. len ( ) )
333- . chain_write_body ( & request)
334- . call ( )
335- . unwrap ( ) ;
336- std:: println!( "*TA*: response is {:?}" , response) ;
337- assert_eq ! ( response, exp_response) ;
311+ run_test ( RESPONSE_LEN / 2 , RESPONSE_LEN ) ;
338312 }
313+
339314 #[ test]
340315 fn test_invoke_with_writer ( ) {
341- let plugin = LoadablePlugin {
342- uuid : Uuid :: parse_str ( "7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10" ) . unwrap ( ) ,
343- } ;
316+ let _lock = SERIAL_TEST_LOCK . lock ( ) . expect ( "should get the lock" ) ;
317+ let uuid: Uuid = random_uuid ( ) ;
318+ let plugin = LoadablePlugin :: new ( & uuid) ;
319+ let fn1 = mock_api:: extension:: tee_invoke_supp_plugin_context ( ) ;
344320 // impl a writer for Command
345321 struct Wrapper < ' a , ' b > ( & ' b mut LoadablePluginCommand < ' a > ) ;
346322 impl < ' a , ' b > std:: io:: Write for Wrapper < ' a , ' b > {
@@ -362,28 +338,30 @@ pub mod test_loadable_plugin {
362338 let ( cmd, sub_cmd, _, exp_response) = generate_test_pairs ( 0 , buffer_len) ;
363339 let mut plugin_cmd = plugin. invoke_with_capacity ( cmd, sub_cmd, buffer_len) ;
364340 exp_request. resize ( exp_response. len ( ) , 0 ) ;
365- set_ree_expected_value ( cmd , sub_cmd , exp_request ) ;
366- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
341+
342+ expect_success_request ( & fn1 , & uuid , cmd, sub_cmd, & exp_request , & exp_response) ;
367343 serde_json:: to_writer ( Wrapper ( & mut plugin_cmd) , & test_data) . unwrap ( ) ;
368344 let response = plugin_cmd. call ( ) . unwrap ( ) ;
369345 std:: println!( "*TA*: response is {:?}" , response) ;
370- assert_eq ! ( response, exp_response) ;
346+ debug_assert_eq ! ( response, exp_response) ;
371347 }
348+
372349 #[ test]
373350 fn test_invoke_with_no_data ( ) {
374- let plugin = LoadablePlugin {
375- uuid : Uuid :: parse_str ( "7dd54ee6-a705-4e4d-8b6b-aa5024dfcd10" ) . unwrap ( ) ,
376- } ;
351+ let _lock = SERIAL_TEST_LOCK . lock ( ) . expect ( "should get the lock" ) ;
352+
353+ let uuid: Uuid = random_uuid ( ) ;
354+ let plugin = LoadablePlugin :: new ( & uuid) ;
355+ let fn1 = mock_api:: extension:: tee_invoke_supp_plugin_context ( ) ;
377356 const OUTPUT_LEN : usize = 50 ;
378- let ( cmd, sub_cmd, _, exp_response) = generate_test_pairs ( 0 , OUTPUT_LEN ) ;
379- let exp_request = vec ! [ 0_u8 ; OUTPUT_LEN ] ;
380- set_ree_expected_value ( cmd, sub_cmd, exp_request) ;
381- set_ree_return_value ( cmd, sub_cmd, exp_response. clone ( ) ) ;
357+ let ( cmd, sub_cmd, request, exp_response) = generate_test_pairs ( 0 , OUTPUT_LEN ) ;
358+ expect_success_request ( & fn1, & uuid, cmd, sub_cmd, & request, & exp_response) ;
359+
382360 let response = plugin
383361 . invoke_with_capacity ( cmd, sub_cmd, OUTPUT_LEN )
384362 . call ( )
385363 . unwrap ( ) ;
386364 std:: println!( "*TA*: response is {:?}" , response) ;
387- assert_eq ! ( response, exp_response) ;
365+ debug_assert_eq ! ( response, exp_response) ;
388366 }
389367}
0 commit comments