nrf52840dk_dynamic_apps_and_policies/
app_id_assigner_name_metadata.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2025.
4
5//! AppID assigner based on name and credential check metadata.
6//!
7//! This assigns a short ID where the most significant four bits are from the
8//! credential checking metadata and the remaining bits are a CRC of the name.
9//!
10//! ```text
11//! 32         28                       0 bits
12//! +----------+------------------------+
13//! | metadata | CRC(name)              |
14//! +----------+------------------------+
15//! ```
16//!
17//! The intention is that the CRC makes the short ID generally unique, and the
18//! 4-bit metadata indicates the key that was used to verify the app's signing
19//! credential.
20
21use kernel::process::{Process, ProcessBinary, ShortId};
22use kernel::process_checker::Compress;
23
24pub struct AppIdAssignerNameMetadata {}
25
26impl AppIdAssignerNameMetadata {
27    pub fn new() -> Self {
28        Self {}
29    }
30}
31
32impl kernel::process_checker::Compress for AppIdAssignerNameMetadata {
33    fn to_short_id(&self, process: &ProcessBinary) -> ShortId {
34        // Get the stored metadata returned when this process had its credential
35        // checked.
36        let metadata = process.credential.get().map_or(0xF, |accepted_credential| {
37            accepted_credential
38                .metadata
39                .map_or(0xF, |metadata| metadata.metadata) as u32
40        });
41
42        let name = process.header.get_package_name().unwrap_or("");
43        let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes());
44
45        // Combine the metadata and CRC into the short id.
46        let sid = ((metadata & 0xF) << 28) | (sum & 0xFFFFFFF);
47
48        core::num::NonZeroU32::new(sid).into()
49    }
50}
51
52// We just use the generic version which compares Short IDs.
53impl kernel::process_checker::AppUniqueness for AppIdAssignerNameMetadata {
54    fn different_identifier(&self, process_a: &ProcessBinary, process_b: &ProcessBinary) -> bool {
55        self.to_short_id(process_a) != self.to_short_id(process_b)
56    }
57
58    fn different_identifier_process(
59        &self,
60        process_a: &ProcessBinary,
61        process_b: &dyn Process,
62    ) -> bool {
63        self.to_short_id(process_a) != process_b.short_app_id()
64    }
65
66    fn different_identifier_processes(
67        &self,
68        process_a: &dyn Process,
69        process_b: &dyn Process,
70    ) -> bool {
71        process_a.short_app_id() != process_b.short_app_id()
72    }
73}