api_impl/context.rs
1// Copyright 2024 The Fuchsia Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::cell::RefCell;
6use std::ops::Range;
7
8use crate::crypto::Operations;
9use crate::props::Properties;
10use crate::storage::Storage;
11
12// Context stores information about the current state of the TA runtime during a
13// call into the TA. API entry points are expected to retrieve the current context
14// and provide the relevant portions to implementation entry points.
15pub struct Context {
16 pub properties: Properties,
17 pub storage: Storage,
18 pub operations: Operations,
19 pub mapped_param_ranges: Vec<Range<usize>>,
20}
21
22// The TA entry points are FFI calls that are expected to call back into the
23// runtime via the TEE_* entry points and so the control flow is unusual
24// compared to regular Rust code. Logically the context is part of the state
25// used by the runtime entry points. However, instead of carrying context
26// through parameters on the stack as purely Rust code would do we have to store
27// the context somewhere else and recover it from the FFI entry points. Instead,
28// the state is stored in a thread local.
29thread_local! {
30 static CURRENT_CONTEXT: RefCell<Context> = RefCell::new(Context::new());
31}
32
33pub fn with_current<F, R>(f: F) -> R
34where
35 F: FnOnce(&Context) -> R,
36{
37 CURRENT_CONTEXT.with_borrow(f)
38}
39
40pub fn with_current_mut<F, R>(f: F) -> R
41where
42 F: FnOnce(&mut Context) -> R,
43{
44 CURRENT_CONTEXT.with_borrow_mut(f)
45}
46
47impl Context {
48 pub fn new() -> Self {
49 Self {
50 properties: Properties::new(),
51 storage: Storage::new(),
52 operations: Operations::new(),
53 mapped_param_ranges: vec![],
54 }
55 }
56
57 pub fn cleanup_after_call(&mut self) {
58 self.mapped_param_ranges.clear();
59 }
60}