diff --git a/Cargo.toml b/Cargo.toml index 86a6723..321a0c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ delog = "0.1.6" hkdf = { version = "0.12", optional = true } rand_core = { version = "0.6.4", default-features = false } sha2 = { version = "0.10", default-features = false, optional = true } -littlefs2 = "0.4.0" +littlefs2-core = "0.1" salty = { version = "0.3.0", default-features = false } digest = { version = "0.10.7", default-features = false } hex-literal = { version = "0.4.0", optional = true } @@ -81,8 +81,7 @@ log-warn = [] log-error = [] [patch.crates-io] -trussed = { git = "https://github.com/nitrokey/trussed.git", rev = "540ad725ef44f0d6d3d2da7dd6ec0bacffaeb5bf" } -littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "960e57d9fc0d209308c8e15dc26252bbe1ff6ba8" } +trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "046478b7a4f6e2315acf9112d98308379c2e3eee" } trussed-chunked = { path = "extensions/chunked" } trussed-hkdf = { path = "extensions/hkdf" } diff --git a/src/chunked/store.rs b/src/chunked/store.rs index a8e769b..479c20b 100644 --- a/src/chunked/store.rs +++ b/src/chunked/store.rs @@ -1,9 +1,9 @@ // Copyright (C) Nitrokey GmbH // SPDX-License-Identifier: Apache-2.0 or MIT -use littlefs2::fs::OpenOptions; -use littlefs2::io::SeekFrom; -use littlefs2::path; +use littlefs2_core::path; +use littlefs2_core::FileOpenFlags; +use littlefs2_core::SeekFrom; use trussed::store::{create_directories, DynFile, DynFilesystem, Store}; use trussed::types::{Bytes, Location, Message, Path, PathBuf}; @@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize}; /// Enumeration of possible methods to seek within an file that was just opened /// Used in the [`read_chunk`](crate::store::read_chunk) and [`write_chunk`](crate::store::write_chunk) calls, -/// Where [`SeekFrom::Current`](littlefs2::io::SeekFrom::Current) would not make sense. +/// Where [`SeekFrom::Current`](littlefs2_core::SeekFrom::Current) would not make sense. #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum OpenSeekFrom { Start(u32), @@ -69,8 +69,8 @@ pub fn fs_write_chunk( contents: &[u8], pos: OpenSeekFrom, ) -> Result<(), Error> { - fs.open_file_with_options_and_then( - &|options| options.read(true).write(true), + fs.open_file_with_flags_and_then( + FileOpenFlags::READ | FileOpenFlags::WRITE, path, &mut |file| { file.seek(pos.into())?; @@ -129,8 +129,6 @@ pub fn move_file( store .fs(from_location) .open_file_and_then(from_path, &mut |from_file| { - let mut options = OpenOptions::new(); - options.write(true).create(true).truncate(true); store .fs(to_location) .create_file_and_then(to_path, &mut |to_file| copy_file_data(from_file, to_file)) @@ -141,7 +139,7 @@ pub fn move_file( }) } -fn copy_file_data(from: &dyn DynFile, to: &dyn DynFile) -> Result<(), littlefs2::io::Error> { +fn copy_file_data(from: &dyn DynFile, to: &dyn DynFile) -> Result<(), littlefs2_core::Error> { let mut buf = [0; 1024]; loop { let read = from.read(&mut buf)?; @@ -270,8 +268,8 @@ pub fn append_file( let path = actual_path(client_id, path)?; store .fs(location) - .open_file_with_options_and_then( - &|options| options.write(true).append(true), + .open_file_with_flags_and_then( + FileOpenFlags::WRITE | FileOpenFlags::APPEND, &path, &mut |file| { file.write_all(data)?; diff --git a/src/manage.rs b/src/manage.rs index 7c45e20..1e1e437 100644 --- a/src/manage.rs +++ b/src/manage.rs @@ -1,7 +1,7 @@ // Copyright (C) Nitrokey GmbH // SPDX-License-Identifier: Apache-2.0 or MIT -use littlefs2::{fs::DirEntry, path, path::Path}; +use littlefs2_core::{path, DirEntry, Path}; use trussed::{ serde_extensions::{Extension, ExtensionImpl}, store::Store, @@ -22,7 +22,7 @@ pub struct State { /// The path start all start with the root. Here is an example such function: /// ```rust ///# use trussed::types::{Path, Location}; - ///# use littlefs2::path; + ///# use littlefs2_core::path; /// fn should_preserve(path: &Path, location: Location) -> bool { /// (location == Location::Internal && path == path!("/client1/dat/to_save_internal")) /// || (location == Location::External && path == path!("/client1/dat/to_save_external")) diff --git a/tests/chunked.rs b/tests/chunked.rs index 7b8c753..7dd222b 100644 --- a/tests/chunked.rs +++ b/tests/chunked.rs @@ -3,14 +3,14 @@ #![cfg(all(feature = "virt", feature = "chunked"))] -use littlefs2::path::PathBuf; +use littlefs2_core::{path, PathBuf}; use trussed::{client::FilesystemClient, syscall, try_syscall, types::Location, Bytes}; use trussed_chunked::{utils, ChunkedClient}; use trussed_staging::virt::with_ram_client; fn test_write_all(location: Location) { with_ram_client("test chunked", |mut client| { - let path = PathBuf::from("foo"); + let path = PathBuf::from(path!("foo")); utils::write_all(&mut client, location, path.clone(), &[48; 1234], None, None).unwrap(); let data = syscall!(client.start_chunked_read(location, path)).data; @@ -22,7 +22,7 @@ fn test_write_all(location: Location) { fn test_write_all_small(location: Location) { with_ram_client("test chunked", |mut client| { - let path = PathBuf::from("foo2"); + let path = PathBuf::from(path!("foo2")); utils::write_all(&mut client, location, path.clone(), &[48; 1023], None, None).unwrap(); let data = syscall!(client.start_chunked_read(location, path)).data; @@ -51,27 +51,28 @@ fn write_all_internal() { #[test] fn filesystem() { with_ram_client("chunked-tests", |mut client| { - assert!( - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) - .metadata - .is_none(), - ); + assert!(syscall!( + client.entry_metadata(Location::Internal, PathBuf::from(path!("test_file"))) + ) + .metadata + .is_none(),); let data = Bytes::from_slice(b"test data").unwrap(); syscall!(client.write_file( Location::Internal, - PathBuf::from("test_file"), + PathBuf::from(path!("test_file")), data.clone(), None, )); let recv_data = - syscall!(client.read_file(Location::Internal, PathBuf::from("test_file"))).data; + syscall!(client.read_file(Location::Internal, PathBuf::from(path!("test_file")))).data; assert_eq!(data, recv_data); // ======== CHUNKED READS ======== - let first_data = - syscall!(client.start_chunked_read(Location::Internal, PathBuf::from("test_file"),)); + let first_data = syscall!( + client.start_chunked_read(Location::Internal, PathBuf::from(path!("test_file"))) + ); assert_eq!(&first_data.data, &data); assert_eq!(first_data.len, data.len()); @@ -83,7 +84,11 @@ fn filesystem() { let large_data2 = Bytes::from_slice(&[1; 1024]).unwrap(); let more_data = Bytes::from_slice(&[2; 42]).unwrap(); // ======== CHUNKED WRITES ======== - syscall!(client.start_chunked_write(Location::Internal, PathBuf::from("test_file"), None)); + syscall!(client.start_chunked_write( + Location::Internal, + PathBuf::from(path!("test_file")), + None + )); syscall!(client.write_file_chunk(large_data.clone())); syscall!(client.write_file_chunk(large_data2.clone())); @@ -91,8 +96,9 @@ fn filesystem() { // ======== CHUNKED READS ======== let full_len = large_data.len() + large_data2.len() + more_data.len(); - let first_data = - syscall!(client.start_chunked_read(Location::Internal, PathBuf::from("test_file"),)); + let first_data = syscall!( + client.start_chunked_read(Location::Internal, PathBuf::from(path!("test_file"))) + ); assert_eq!(&first_data.data, &large_data); assert_eq!(first_data.len, full_len); @@ -109,40 +115,45 @@ fn filesystem() { assert_eq!(empty_data.len, full_len); let metadata = - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) + syscall!(client.entry_metadata(Location::Internal, PathBuf::from(path!("test_file")))) .metadata .unwrap(); assert!(metadata.is_file()); // ======== ABORTED CHUNKED WRITES ======== - syscall!(client.start_chunked_write(Location::Internal, PathBuf::from("test_file"), None)); + syscall!(client.start_chunked_write( + Location::Internal, + PathBuf::from(path!("test_file")), + None + )); syscall!(client.write_file_chunk(large_data.clone())); syscall!(client.write_file_chunk(large_data2)); syscall!(client.abort_chunked_write()); // Old data is still there after abort - let partial_data = - syscall!(client.start_chunked_read(Location::Internal, PathBuf::from("test_file"))); + let partial_data = syscall!( + client.start_chunked_read(Location::Internal, PathBuf::from(path!("test_file"))) + ); assert_eq!(&partial_data.data, &large_data); assert_eq!(partial_data.len, full_len); // This returns an error because the name doesn't exist - assert!( - try_syscall!(client.remove_file(Location::Internal, PathBuf::from("bad_name"))) - .is_err() - ); + assert!(try_syscall!( + client.remove_file(Location::Internal, PathBuf::from(path!("bad_name"))) + ) + .is_err()); let metadata = - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) + syscall!(client.entry_metadata(Location::Internal, PathBuf::from(path!("test_file")))) .metadata .unwrap(); assert!(metadata.is_file()); - syscall!(client.remove_file(Location::Internal, PathBuf::from("test_file"))); - assert!( - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) - .metadata - .is_none(), - ); + syscall!(client.remove_file(Location::Internal, PathBuf::from(path!("test_file")))); + assert!(syscall!( + client.entry_metadata(Location::Internal, PathBuf::from(path!("test_file"))) + ) + .metadata + .is_none(),); }) } diff --git a/tests/encrypted-chunked.rs b/tests/encrypted-chunked.rs index 9740f7b..1ecfae5 100644 --- a/tests/encrypted-chunked.rs +++ b/tests/encrypted-chunked.rs @@ -3,7 +3,7 @@ #![cfg(all(feature = "virt", feature = "chunked"))] -use littlefs2::path::PathBuf; +use littlefs2_core::{path, PathBuf}; use serde_byte_array::ByteArray; use trussed::{ client::CryptoClient, client::FilesystemClient, syscall, try_syscall, types::Location, Bytes, @@ -18,7 +18,7 @@ use trussed_staging::virt::with_ram_client; fn test_write_all(location: Location) { with_ram_client("test chunked", |mut client| { let key = syscall!(client.generate_secret_key(32, Location::Volatile)).key; - let path = PathBuf::from("foo"); + let path = PathBuf::from(path!("foo")); utils::write_all( &mut client, location, @@ -40,7 +40,7 @@ fn test_write_all(location: Location) { fn test_write_all_small(location: Location) { with_ram_client("test chunked", |mut client| { let key = syscall!(client.generate_secret_key(32, Location::Volatile)).key; - let path = PathBuf::from("foo2"); + let path = PathBuf::from(path!("foo2")); utils::write_all( &mut client, location, @@ -78,10 +78,11 @@ fn write_all_internal() { #[test] fn encrypted_filesystem() { with_ram_client("chunked-tests", |mut client| { + let path = PathBuf::from(path!("test_file")); let key = syscall!(client.generate_secret_key(32, Location::Volatile)).key; assert!( - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) + syscall!(client.entry_metadata(Location::Internal, path.clone())) .metadata .is_none(), ); @@ -92,7 +93,7 @@ fn encrypted_filesystem() { // ======== CHUNKED WRITES ======== syscall!(client.start_encrypted_chunked_write( Location::Internal, - PathBuf::from("test_file"), + path.clone(), key, Some(ByteArray::from([0; 8])), None @@ -104,11 +105,7 @@ fn encrypted_filesystem() { // ======== CHUNKED READS ======== let full_len = large_data.len() + large_data2.len() + more_data.len(); - syscall!(client.start_encrypted_chunked_read( - Location::Internal, - PathBuf::from("test_file"), - key - )); + syscall!(client.start_encrypted_chunked_read(Location::Internal, path.clone(), key)); let first_data = syscall!(client.read_file_chunk()); assert_eq!(&first_data.data, &large_data); assert_eq!(first_data.len, full_len); @@ -126,16 +123,15 @@ fn encrypted_filesystem() { Err(Error::MechanismNotAvailable) ); - let metadata = - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) - .metadata - .unwrap(); + let metadata = syscall!(client.entry_metadata(Location::Internal, path.clone())) + .metadata + .unwrap(); assert!(metadata.is_file()); // ======== ABORTED CHUNKED WRITES ======== syscall!(client.start_encrypted_chunked_write( Location::Internal, - PathBuf::from("test_file"), + path.clone(), key, Some(ByteArray::from([1; 8])), None @@ -146,11 +142,7 @@ fn encrypted_filesystem() { syscall!(client.abort_chunked_write()); // Old data is still there after abort - syscall!(client.start_encrypted_chunked_read( - Location::Internal, - PathBuf::from("test_file"), - key - )); + syscall!(client.start_encrypted_chunked_read(Location::Internal, path.clone(), key)); let first_data = syscall!(client.read_file_chunk()); assert_eq!(&first_data.data, &large_data); assert_eq!(first_data.len, full_len); @@ -169,19 +161,18 @@ fn encrypted_filesystem() { ); // This returns an error because the name doesn't exist - assert!( - try_syscall!(client.remove_file(Location::Internal, PathBuf::from("bad_name"))) - .is_err() - ); - let metadata = - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) - .metadata - .unwrap(); + assert!(try_syscall!( + client.remove_file(Location::Internal, PathBuf::from(path!("bad_name"))) + ) + .is_err()); + let metadata = syscall!(client.entry_metadata(Location::Internal, path.clone())) + .metadata + .unwrap(); assert!(metadata.is_file()); - syscall!(client.remove_file(Location::Internal, PathBuf::from("test_file"))); + syscall!(client.remove_file(Location::Internal, path.clone())); assert!( - syscall!(client.entry_metadata(Location::Internal, PathBuf::from("test_file"))) + syscall!(client.entry_metadata(Location::Internal, path.clone())) .metadata .is_none(), ); diff --git a/tests/hpke.rs b/tests/hpke.rs index 900c809..786dceb 100644 --- a/tests/hpke.rs +++ b/tests/hpke.rs @@ -3,7 +3,7 @@ #![cfg(all(feature = "virt", feature = "hpke"))] -use littlefs2::path; +use littlefs2_core::path; use trussed::client::{CryptoClient, X255}; use trussed::{ syscall, diff --git a/tests/manage.rs b/tests/manage.rs index b29374a..3f4d1e5 100644 --- a/tests/manage.rs +++ b/tests/manage.rs @@ -3,7 +3,7 @@ #![cfg(all(feature = "virt", feature = "manage"))] -use littlefs2::path; +use littlefs2_core::path; use trussed::client::FilesystemClient; use trussed::syscall; use trussed::types::{Bytes, Location, Path}; @@ -24,103 +24,103 @@ fn device_factory_reset() { |[mut client1, mut client2]| { syscall!(client1.write_file( Location::Internal, - "to_save_internal".into(), + path!("to_save_internal").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client1.write_file( Location::External, - "to_save_external".into(), + path!("to_save_external").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client1.write_file( Location::Volatile, - "to_save_volatile".into(), + path!("to_save_volatile").into(), Bytes::from_slice(b"data").unwrap(), None )); syscall!(client1.write_file( Location::Internal, - "to_delete_internal".into(), + path!("to_delete_internal").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client1.write_file( Location::External, - "to_delete_external".into(), + path!("to_delete_external").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client1.write_file( Location::Volatile, - "to_delete_volatile".into(), + path!("to_delete_volatile").into(), Bytes::from_slice(b"data").unwrap(), None )); syscall!(client2.write_file( Location::Internal, - "to_delete_internal".into(), + path!("to_delete_internal").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client2.write_file( Location::External, - "to_delete_external".into(), + path!("to_delete_external").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client2.write_file( Location::Volatile, - "to_delete_volatile".into(), + path!("to_delete_volatile").into(), Bytes::from_slice(b"data").unwrap(), None )); syscall!(client1.factory_reset_device()); - assert!( - syscall!(client1.entry_metadata(Location::Internal, "to_save_internal".into())) - .metadata - .is_some() - ); - assert!( - syscall!(client1.entry_metadata(Location::External, "to_save_external".into())) - .metadata - .is_some() - ); - assert!( - syscall!(client1.entry_metadata(Location::Volatile, "to_save_volatile".into())) - .metadata - .is_some() - ); assert!(syscall!( - client1.entry_metadata(Location::Internal, "to_delete_internal".into()) + client1.entry_metadata(Location::Internal, path!("to_save_internal").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::External, path!("to_save_external").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::Volatile, path!("to_save_volatile").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::Internal, path!("to_delete_internal").into()) ) .metadata .is_none()); assert!(syscall!( - client1.entry_metadata(Location::External, "to_delete_external".into()) + client1.entry_metadata(Location::External, path!("to_delete_external").into()) ) .metadata .is_none()); assert!(syscall!( - client1.entry_metadata(Location::Volatile, "to_delete_volatile".into()) + client1.entry_metadata(Location::Volatile, path!("to_delete_volatile").into()) ) .metadata .is_none()); assert!(syscall!( - client2.entry_metadata(Location::Internal, "to_delete_internal".into()) + client2.entry_metadata(Location::Internal, path!("to_delete_internal").into()) ) .metadata .is_none()); assert!(syscall!( - client2.entry_metadata(Location::External, "to_delete_external".into()) + client2.entry_metadata(Location::External, path!("to_delete_external").into()) ) .metadata .is_none()); assert!(syscall!( - client2.entry_metadata(Location::Volatile, "to_delete_volatile".into()) + client2.entry_metadata(Location::Volatile, path!("to_delete_volatile").into()) ) .metadata .is_none()); @@ -136,120 +136,120 @@ fn client_factory_reset() { |[mut client1, mut client2]| { syscall!(client1.write_file( Location::Internal, - "to_save_internal".into(), + path!("to_save_internal").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client1.write_file( Location::External, - "to_save_external".into(), + path!("to_save_external").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client1.write_file( Location::Volatile, - "to_save_volatile".into(), + path!("to_save_volatile").into(), Bytes::from_slice(b"data").unwrap(), None )); syscall!(client2.write_file( Location::Internal, - "to_delete_internal".into(), + path!("to_delete_internal").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client2.write_file( Location::External, - "to_delete_external".into(), + path!("to_delete_external").into(), Bytes::from_slice(b"data").unwrap(), None, )); syscall!(client2.write_file( Location::Volatile, - "to_delete_volatile".into(), + path!("to_delete_volatile").into(), Bytes::from_slice(b"data").unwrap(), None )); syscall!(client1.factory_reset_client(path!("client1"))); - assert!( - syscall!(client1.entry_metadata(Location::Internal, "to_save_internal".into())) - .metadata - .is_some() - ); - assert!( - syscall!(client1.entry_metadata(Location::External, "to_save_external".into())) - .metadata - .is_some() - ); - assert!( - syscall!(client1.entry_metadata(Location::Volatile, "to_save_volatile".into())) - .metadata - .is_some() - ); assert!(syscall!( - client1.entry_metadata(Location::Internal, "to_delete_internal".into()) + client1.entry_metadata(Location::Internal, path!("to_save_internal").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::External, path!("to_save_external").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::Volatile, path!("to_save_volatile").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::Internal, path!("to_delete_internal").into()) ) .metadata .is_none()); assert!(syscall!( - client1.entry_metadata(Location::External, "to_delete_external".into()) + client1.entry_metadata(Location::External, path!("to_delete_external").into()) ) .metadata .is_none()); assert!(syscall!( - client1.entry_metadata(Location::Volatile, "to_delete_volatile".into()) + client1.entry_metadata(Location::Volatile, path!("to_delete_volatile").into()) ) .metadata .is_none()); // DATA for other clients is still there assert!(syscall!( - client2.entry_metadata(Location::Internal, "to_delete_internal".into()) + client2.entry_metadata(Location::Internal, path!("to_delete_internal").into()) ) .metadata .is_some()); assert!(syscall!( - client2.entry_metadata(Location::External, "to_delete_external".into()) + client2.entry_metadata(Location::External, path!("to_delete_external").into()) ) .metadata .is_some()); assert!(syscall!( - client2.entry_metadata(Location::Volatile, "to_delete_volatile".into()) + client2.entry_metadata(Location::Volatile, path!("to_delete_volatile").into()) ) .metadata .is_some()); syscall!(client1.factory_reset_client(path!("client2"))); - assert!( - syscall!(client1.entry_metadata(Location::Internal, "to_save_internal".into())) - .metadata - .is_some() - ); - assert!( - syscall!(client1.entry_metadata(Location::External, "to_save_external".into())) - .metadata - .is_some() - ); - assert!( - syscall!(client1.entry_metadata(Location::Volatile, "to_save_volatile".into())) - .metadata - .is_some() - ); + assert!(syscall!( + client1.entry_metadata(Location::Internal, path!("to_save_internal").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::External, path!("to_save_external").into()) + ) + .metadata + .is_some()); + assert!(syscall!( + client1.entry_metadata(Location::Volatile, path!("to_save_volatile").into()) + ) + .metadata + .is_some()); // DATA for other clients is deleted assert!(syscall!( - client2.entry_metadata(Location::Internal, "to_delete_internal".into()) + client2.entry_metadata(Location::Internal, path!("to_delete_internal").into()) ) .metadata .is_none()); assert!(syscall!( - client2.entry_metadata(Location::External, "to_delete_external".into()) + client2.entry_metadata(Location::External, path!("to_delete_external").into()) ) .metadata .is_none()); assert!(syscall!( - client2.entry_metadata(Location::Volatile, "to_delete_volatile".into()) + client2.entry_metadata(Location::Volatile, path!("to_delete_volatile").into()) ) .metadata .is_none()); diff --git a/tests/wrap_key_to_file.rs b/tests/wrap_key_to_file.rs index b31f53e..1357846 100644 --- a/tests/wrap_key_to_file.rs +++ b/tests/wrap_key_to_file.rs @@ -3,6 +3,7 @@ #![cfg(all(feature = "virt", feature = "wrap-key-to-file"))] +use littlefs2_core::path; use trussed::client::CryptoClient; use trussed::syscall; use trussed::types::{ @@ -101,7 +102,7 @@ fn chacha_wraptofile() { )) .key; - let path = PathBuf::from("test_file"); + let path = PathBuf::from(path!("test_file")); let key2 = syscall!(client.generate_secret_key(32, Volatile)).key;