Skip to content

Commit

Permalink
appid: support opaque return value for accept
Browse files Browse the repository at this point in the history
If a credential checker accepts a credential, it may now return a
nonzero usize with information about the accepted credential.
  • Loading branch information
bradjc committed Jul 5, 2024
1 parent 7b0a0ea commit d7ee56d
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 14 deletions.
4 changes: 2 additions & 2 deletions capsules/system/src/process_checker/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl ClientVerify<32_usize> for AppCheckerSha256 {
Ok(true) => {
self.client.map(|c| {
c.check_done(
Ok(CheckResult::Accept),
Ok(CheckResult::Accept(None)),
self.credentials.take().unwrap(),
self.binary.take().unwrap(),
);
Expand Down Expand Up @@ -291,7 +291,7 @@ impl<'a> DeferredCallClient for AppCheckerRsaSimulated<'a> {
let result = if cred.format() == TbfFooterV2CredentialsType::Rsa3072Key
|| cred.format() == TbfFooterV2CredentialsType::Rsa4096Key
{
Ok(CheckResult::Accept)
Ok(CheckResult::Accept(None))
} else {
Ok(CheckResult::Pass)
};
Expand Down
2 changes: 1 addition & 1 deletion capsules/system/src/process_checker/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl<
let binary = self.binary.take().unwrap();
let cred = self.credentials.take().unwrap();
let check_result = if result.unwrap_or(false) {
Ok(CheckResult::Accept)
Ok(CheckResult::Accept(None))
} else {
Ok(CheckResult::Pass)
};
Expand Down
9 changes: 8 additions & 1 deletion doc/reference/trd-appid.md
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ which credentials, are acceptable and which are rejected.

```rust
pub enum CheckResult {
Accept,
Accept(Option<core::num::NonZeroUsize>),
Pass,
Reject
}
Expand Down Expand Up @@ -581,6 +581,13 @@ each `TbfFooterV2Credentials` footer it encounters, the kernel calls
`check_credentials` on the provided `AppCredentialsPolicy`. If
`check_credentials` returns `CheckResult::Accept`, the kernel stops processing
credentials and stores the process binary in the process binaries array.
When an `AppCredentialsPolicy` accepts a credential it may include an opaque
nonzero `usize` value. This will be stored along with the accepted credential
and allows the `AppCredentialsPolicy` to share information about the accepted
credential. For example, if `AppCredentialsPolicy` is checking signatures, the
opaque value may communicate the owner of the private key that validated the
signature. This information may be useful when assigning `ShortId`s.

If the
`AppCredentialsPolicy` returns `CheckResult::Reject`, the kernel stops processing
credentials and does not load the process binary.
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ pub trait Process {
/// Return the credential which the credential checker approved if the
/// credential checker approved a credential. If the process was allowed to
/// run without credentials, return `None`.
fn get_credential(&self) -> Option<TbfFooterV2Credentials>;
fn get_credential(&self) -> Option<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)>;

/// Returns how many times this process has been restarted.
fn get_restart_count(&self) -> usize;
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/process_binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub struct ProcessBinary {
/// Optional credential that was used to approve this application. This is
/// set if the process is checked by a credential checker and a specific
/// credential was used to approve this process. Otherwise this is `None`.
pub credential: OptionalCell<TbfFooterV2Credentials>,
pub credential: OptionalCell<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)>,
}

impl ProcessBinary {
Expand Down Expand Up @@ -249,7 +249,9 @@ impl ProcessBinary {
})
}

pub fn get_credential(&self) -> Option<TbfFooterV2Credentials> {
pub fn get_credential(
&self,
) -> Option<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)> {
self.credential.get()
}

Expand Down
15 changes: 11 additions & 4 deletions kernel/src/process_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ impl fmt::Debug for ProcessCheckError {
#[derive(Debug)]
pub enum CheckResult {
/// Accept the credential and run the binary.
Accept,
///
/// The associated value is an optional opaque nonzero usize the credential
/// checker can return to communication some information about the accepted
/// credential.
Accept(Option<core::num::NonZeroUsize>),
/// Go to the next credential or in the case of the last one fall
/// back to the default policy.
Pass,
Expand Down Expand Up @@ -183,7 +187,10 @@ pub trait ProcessCheckerMachineClient {
fn done(
&self,
process_binary: ProcessBinary,
result: Result<Option<TbfFooterV2Credentials>, ProcessCheckError>,
result: Result<
Option<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)>,
ProcessCheckError,
>,
);
}

Expand Down Expand Up @@ -431,10 +438,10 @@ impl AppCredentialsPolicyClient<'static> for ProcessCheckerMachine {
debug!("Checking: check_done gave result {:?}", result);
}
let cont = match result {
Ok(CheckResult::Accept) => {
Ok(CheckResult::Accept(opaque)) => {
self.client.map(|client| {
if let Some(pb) = self.process_binary.take() {
client.done(pb, Ok(Some(credentials)))
client.done(pb, Ok(Some((credentials, opaque))))
}
});
false
Expand Down
5 changes: 4 additions & 1 deletion kernel/src/process_loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,10 @@ impl<'a, C: Chip> crate::process_checker::ProcessCheckerMachineClient
fn done(
&self,
process_binary: ProcessBinary,
result: Result<Option<TbfFooterV2Credentials>, crate::process_checker::ProcessCheckError>,
result: Result<
Option<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)>,
crate::process_checker::ProcessCheckError,
>,
) {
// Check if this process was approved by the checker.
match result {
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/process_standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ pub struct ProcessStandard<'a, C: 'static + Chip> {

/// Credential that was approved for this process, or `None` if the
/// credential was permitted to run without an accepted credential.
credential: Option<TbfFooterV2Credentials>,
credential: Option<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)>,

/// State saved on behalf of the process each time the app switches to the
/// kernel.
Expand Down Expand Up @@ -256,7 +256,7 @@ impl<C: Chip> Process for ProcessStandard<'_, C> {
}
}

fn get_credential(&self) -> Option<TbfFooterV2Credentials> {
fn get_credential(&self) -> Option<(TbfFooterV2Credentials, Option<core::num::NonZeroUsize>)> {
self.credential
}

Expand Down

0 comments on commit d7ee56d

Please sign in to comment.