Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions litebox_common_optee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl<Platform: litebox::platform::RawPointerProvider> SyscallRequest<Platform> {
pub fn try_from_raw(syscall_number: usize, ctx: &PtRegs) -> Result<Self, Errno> {
let ctx = SyscallContext::from_pt_regs(ctx);
let sysnr = u32::try_from(syscall_number).map_err(|_| Errno::ENOSYS)?;
let dispatcher = match TeeSyscallNr::try_from(sysnr).unwrap_or(TeeSyscallNr::Unknown) {
let dispatcher = match TeeSyscallNr::try_from(sysnr).map_err(|_| Errno::ENOSYS)? {
TeeSyscallNr::Return => SyscallRequest::Return {
ret: ctx.syscall_arg(0),
},
Expand Down Expand Up @@ -240,10 +240,7 @@ impl<Platform: litebox::platform::RawPointerProvider> SyscallRequest<Platform> {
buf: Platform::RawMutPointer::from_usize(ctx.syscall_arg(0)),
blen: ctx.syscall_arg(1),
},
TeeSyscallNr::Unknown => {
return Err(Errno::ENOSYS);
}
_ => todo!(),
_ => return Err(Errno::ENOSYS),
};

Ok(dispatcher)
Expand Down Expand Up @@ -1131,7 +1128,7 @@ impl<Platform: litebox::platform::RawPointerProvider> LdelfSyscallRequest<Platfo
pub fn try_from_raw(syscall_number: usize, ctx: &PtRegs) -> Result<Self, Errno> {
let ctx = SyscallContext::from_pt_regs(ctx);
let sysnr = u32::try_from(syscall_number).map_err(|_| Errno::ENOSYS)?;
let dispatcher = match LdelfSyscallNr::try_from(sysnr).unwrap_or(LdelfSyscallNr::Unknown) {
let dispatcher = match LdelfSyscallNr::try_from(sysnr).map_err(|_| Errno::ENOSYS)? {
LdelfSyscallNr::Return => LdelfSyscallRequest::Return {
ret: ctx.syscall_arg(0),
},
Expand Down Expand Up @@ -1180,7 +1177,7 @@ impl<Platform: litebox::platform::RawPointerProvider> LdelfSyscallRequest<Platfo
buf: Platform::RawMutPointer::from_usize(ctx.syscall_arg(0)),
num_bytes: ctx.syscall_arg(1),
},
_ => todo!("implement ldelf syscall number: {}", sysnr),
_ => return Err(Errno::ENOSYS),
};

Ok(dispatcher)
Expand Down
2 changes: 0 additions & 2 deletions litebox_common_optee/src/syscall_nr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ pub enum TeeSyscallNr {
StorageObjSeek = SYSCALL_STORAGE_OBJ_SEEK,
ObjGenerateKey = SYSCALL_OBJ_GENERATE_KEY,
CacheOperation = SYSCALL_CACHE_OPERATION,
Unknown = 0xffff_ffff,
}

const LDELF_RETURN: u32 = 0;
Expand Down Expand Up @@ -157,5 +156,4 @@ pub enum LdelfSyscallNr {
SetProt = LDELF_SET_PROT,
Remap = LDELF_REMAP,
GenRndNum = LDELF_GEN_RND_NUM,
Unknown = 0xffff_ffff,
}
97 changes: 54 additions & 43 deletions litebox_shim_optee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,26 +389,30 @@ impl Task {
prop_type,
} => {
if let Some(buf_length) = blen.read_at_offset(0)
&& usize::try_from(buf_length).unwrap() <= MAX_KERNEL_BUF_SIZE
&& (buf_length as usize) <= MAX_KERNEL_BUF_SIZE
{
let mut prop_buf = vec![0u8; usize::try_from(buf_length).unwrap()];
let mut prop_buf = vec![0u8; buf_length as usize];
if name.as_usize() != 0 || name_len.as_usize() != 0 {
todo!("return the name of a given property index")
#[cfg(debug_assertions)]
todo!("return the name of a given property index");
#[cfg(not(debug_assertions))]
Err(TeeResult::NotSupported)
} else {
self.sys_get_property(
prop_set,
index,
None,
None,
&mut prop_buf,
blen,
prop_type,
)
.and_then(|()| {
buf.copy_from_slice(0, &prop_buf)
.ok_or(TeeResult::ShortBuffer)?;
Ok(())
})
}
self.sys_get_property(
prop_set,
index,
None,
None,
&mut prop_buf,
blen,
prop_type,
)
.and_then(|()| {
buf.copy_from_slice(0, &prop_buf)
.ok_or(TeeResult::ShortBuffer)?;
Ok(())
})
} else {
Err(TeeResult::BadParameters)
}
Expand Down Expand Up @@ -534,7 +538,12 @@ impl Task {
})
}
}
_ => todo!(),
_ => {
#[cfg(debug_assertions)]
todo!("unsupported syscall request");
#[cfg(not(debug_assertions))]
Err(TeeResult::NotSupported)
}
};

ctx.rax = match res {
Expand Down Expand Up @@ -686,7 +695,7 @@ impl Task {
})
}
}
_ => todo!(),
_ => Err(TeeResult::NotSupported),
};

ctx.rax = match res {
Expand Down Expand Up @@ -742,10 +751,10 @@ impl Task {
.ok_or(ElfLoaderError::InvalidStackAddr)?;

Ok(ThreadInitState::Ta {
cmd_id: usize::try_from(cmd_id.unwrap_or(0)).unwrap(),
cmd_id: cmd_id.unwrap_or(0) as usize,
params_address: ta_stack.get_params_address(),
session_id: usize::try_from(session_id.unwrap_or(self.session_id)).unwrap(),
func_id: usize::try_from(func_id).unwrap(),
session_id: session_id.unwrap_or(self.session_id) as usize,
func_id: func_id as usize,
entry_point: self.get_ta_entry_point(),
stack_top: ta_stack.get_cur_stack_top(),
})
Expand Down Expand Up @@ -814,7 +823,7 @@ impl Task {
if let Some(ldelf_arg_address) = ldelf_arg_address {
let ldelf_arg_ptr = UserConstPtr::<LdelfArg>::from_usize(ldelf_arg_address);
if let Some(ldef_arg) = ldelf_arg_ptr.read_at_offset(0) {
let entry_func = usize::try_from(ldef_arg.entry_func).unwrap();
let entry_func = ldef_arg.entry_func.truncate();
// If `ldelf` has been successfully executed, it loads the given TA and stores the TA's entry
// point into `ldelf_arg.entry_func`.
self.set_ta_entry_point(entry_func);
Expand Down Expand Up @@ -870,12 +879,12 @@ where
{
if let Some(src_slice) = src.to_owned_slice(src_len)
&& let Some(length) = dst_len.read_at_offset(0)
&& usize::try_from(length).unwrap() <= MAX_KERNEL_BUF_SIZE
&& length <= MAX_KERNEL_BUF_SIZE as u64
{
let mut length = usize::try_from(length).unwrap();
let mut length: usize = length.truncate();
let mut kernel_buf = vec![0u8; length];
syscall_fn(task, state, &src_slice, &mut kernel_buf, &mut length).and_then(|()| {
let _ = dst_len.write_at_offset(0, u64::try_from(length).unwrap());
let _ = dst_len.write_at_offset(0, length as u64);
dst.copy_from_slice(0, &kernel_buf[..length])
.ok_or(TeeResult::OutOfMemory)
})
Expand Down Expand Up @@ -974,33 +983,35 @@ impl TeeObjMap {
) -> Result<(), TeeResult> {
let mut inner = self.inner.lock();
if let Some(tee_obj) = inner.get_mut(&handle) {
tee_obj.initialize();

if user_attrs.is_empty() {
tee_obj.initialize();
return Ok(());
}

// TODO: support multiple attributes (e.g., two-key crypto algorithms like AES-XTS)
match user_attrs[0].attribute_id {
TeeAttributeType::SecretValue => {
let key_addr: usize = user_attrs[0].a.truncate();
let key_len: usize = user_attrs[0].b.truncate();
// TODO: revisit buffer size limits based on OP-TEE spec and deployment constraints
if key_len > MAX_KERNEL_BUF_SIZE {
return Err(TeeResult::BadParameters);
}
let key_ptr = UserConstPtr::<u8>::from_usize(key_addr);
let Some(key_box) = key_ptr.to_owned_slice(key_len) else {
return Err(TeeResult::BadParameters);
};
tee_obj.set_key(&key_box);
if user_attrs[0].attribute_id == TeeAttributeType::SecretValue {
let key_addr: usize = user_attrs[0].a.truncate();
let key_len: usize = user_attrs[0].b.truncate();
// TODO: revisit buffer size limits based on OP-TEE spec and deployment constraints
if key_len > MAX_KERNEL_BUF_SIZE {
return Err(TeeResult::BadParameters);
}
_ => todo!(
let key_ptr = UserConstPtr::<u8>::from_usize(key_addr);
let Some(key_box) = key_ptr.to_owned_slice(key_len) else {
return Err(TeeResult::BadParameters);
};
tee_obj.set_key(&key_box);
} else {
#[cfg(debug_assertions)]
todo!(
"handle attribute ID: {}",
user_attrs[0].attribute_id.value()
),
);
#[cfg(not(debug_assertions))]
return Err(TeeResult::NotSupported);
}

tee_obj.initialize();
Ok(())
} else {
Err(TeeResult::ItemNotFound)
Expand Down
6 changes: 4 additions & 2 deletions litebox_shim_optee/src/loader/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl litebox_common_linux::loader::MapMemory for ElfFileInMemory<'_> {

self.task
.sys_mprotect(UserMutPtr::from_usize(mapped_addr), len, prot.flags())
.expect("sys_mprotect failed");
.map_err(ElfLoaderError::ProtectError)?;
Ok(())
}

Expand Down Expand Up @@ -265,6 +265,8 @@ pub enum ElfLoaderError {
LoadError(#[from] litebox_common_linux::loader::ElfLoadError<Errno>),
#[error("invalid stack")]
InvalidStackAddr,
#[error("failed to set memory protection")]
ProtectError(Errno),
#[error("failed to mmap")]
MappingError(#[from] MappingError),
#[error("TA binary UUID does not match expected UUID")]
Expand All @@ -274,7 +276,7 @@ pub enum ElfLoaderError {
impl From<ElfLoaderError> for litebox_common_linux::errno::Errno {
fn from(value: ElfLoaderError) -> Self {
match value {
ElfLoaderError::OpenError(e) => e,
ElfLoaderError::OpenError(e) | ElfLoaderError::ProtectError(e) => e,
ElfLoaderError::ParseError(e) => e.into(),
ElfLoaderError::InvalidStackAddr | ElfLoaderError::MappingError(_) => {
litebox_common_linux::errno::Errno::ENOMEM
Expand Down
12 changes: 2 additions & 10 deletions litebox_shim_optee/src/loader/ta_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,7 @@ impl TaStack {
}
self.push_bytes(bytes)?;
self.params
.set_values(
self.num_params,
u64::try_from(self.get_cur_stack_top()).unwrap(),
u64::try_from(len).unwrap(),
)
.set_values(self.num_params, self.get_cur_stack_top() as u64, len as u64)
.ok()?;
} else {
return None;
Expand All @@ -194,11 +190,7 @@ impl TaStack {
TeeParamType::MemrefOutput => {
self.pos = self.pos.checked_sub(len)?;
self.params
.set_values(
self.num_params,
u64::try_from(self.get_cur_stack_top()).unwrap(),
u64::try_from(len).unwrap(),
)
.set_values(self.num_params, self.get_cur_stack_top() as u64, len as u64)
.ok()?;
}
_ => {
Expand Down
14 changes: 6 additions & 8 deletions litebox_shim_optee/src/msg_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,10 @@ impl<const ALIGN: usize> ShmRefMap<ALIGN> {
if page_offset >= ALIGN as u64 || aligned_size == 0 {
return Err(OpteeSmcReturnCode::EBadAddr);
}
let num_pages = usize::try_from(aligned_size).unwrap() / ALIGN;
let aligned_size_usize: usize = aligned_size.truncate();
let num_pages = aligned_size_usize / ALIGN;
let mut pages = Vec::with_capacity(num_pages);
let mut cur_addr = usize::try_from(shm_ref_pages_data_phys_addr).unwrap();
let mut cur_addr: usize = shm_ref_pages_data_phys_addr.truncate();
loop {
let mut cur_ptr = NormalWorldConstPtr::<ShmRefPagesData, ALIGN>::with_usize(cur_addr)
.map_err(|_| OpteeSmcReturnCode::EBadAddr)?;
Expand All @@ -699,24 +700,21 @@ impl<const ALIGN: usize> ShmRefMap<ALIGN> {
break;
} else {
pages.push(
PhysPageAddr::new(usize::try_from(*page).unwrap())
PhysPageAddr::new((*page).truncate())
.ok_or(OpteeSmcReturnCode::EBadAddr)?,
);
}
}
if pages_data.next_page_data == 0 || pages.len() == num_pages {
break;
} else {
cur_addr = usize::try_from(pages_data.next_page_data).unwrap();
cur_addr = pages_data.next_page_data.truncate();
}
}

self.insert(
shm_ref,
ShmInfo::new(
pages.into_boxed_slice(),
usize::try_from(page_offset).unwrap(),
)?,
ShmInfo::new(pages.into_boxed_slice(), page_offset.truncate())?,
)?;
Ok(())
}
Expand Down
35 changes: 27 additions & 8 deletions litebox_shim_optee/src/syscalls/cryp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,17 @@ impl Task {
if let Some(handle) = cryp_state.get_object_handle(false)
&& tee_obj_map.exists(handle)
{
#[cfg(debug_assertions)]
todo!("support two-key algorithms");
#[cfg(not(debug_assertions))]
return Err(TeeResult::NotSupported);
}

let Some(cipher) = create_cipher(cryp_state.algorithm(), key, iv) else {
#[cfg(debug_assertions)]
todo!("implement algorithm {}", cryp_state.algorithm() as u32);
#[cfg(not(debug_assertions))]
return Err(TeeResult::NotSupported);
};
tee_cryp_state_map.set_cipher(state, &cipher)?;
Ok(())
Expand Down Expand Up @@ -165,7 +171,17 @@ impl Task {
return Err(TeeResult::ShortBuffer);
}
if let Some(mut map) = tee_cryp_state_map.get_mut(state) {
if let &mut Some(ref mut cipher) = &mut map.get_mut(&state).unwrap().get_mut_cipher() {
// Check last_block before applying the cipher so we don't mutate
// dst_slice and then return an error.
if last_block {
#[cfg(debug_assertions)]
todo!("support algorithms which have a certain finalization logic");
#[cfg(not(debug_assertions))]
return Err(TeeResult::NotSupported);
}
if let Some(state_entry) = map.get_mut(&state)
&& let Some(cipher) = state_entry.get_mut_cipher()
{
dst_slice.copy_from_slice(src_slice);
match cipher {
Cipher::Aes128Ctr(aes128ctr) => {
Expand All @@ -179,11 +195,13 @@ impl Task {
}
}
*dst_len = src_slice.len();
Ok(())
} else {
#[cfg(debug_assertions)]
todo!("handle unimplemented cipher");
#[cfg(not(debug_assertions))]
Err(TeeResult::NotImplemented)
}
if last_block {
todo!("support algorithms which have a certain finalization logic");
}
Ok(())
} else {
Err(TeeResult::BadParameters)
}
Expand Down Expand Up @@ -247,14 +265,15 @@ impl Task {
) -> Result<(), TeeResult> {
let tee_obj_map = &self.tee_obj_map;
if attrs.len() > 1 {
#[cfg(debug_assertions)]
todo!("handle multiple attributes");
#[cfg(not(debug_assertions))]
return Err(TeeResult::NotSupported);
}
if !tee_obj_map.exists(obj) {
return Err(TeeResult::BadState);
}
tee_obj_map
.populate(obj, attrs)
.map_err(|_| TeeResult::BadParameters)
tee_obj_map.populate(obj, attrs)
}

pub(crate) fn sys_cryp_obj_copy(
Expand Down
Loading
Loading