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.
45//! 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.
2021use kernel::process::{Process, ProcessBinary, ShortId};
22use kernel::process_checker::Compress;
2324pub struct AppIdAssignerNameMetadata {}
2526impl AppIdAssignerNameMetadata {
27pub fn new() -> Self {
28Self {}
29 }
30}
3132impl kernel::process_checker::Compress for AppIdAssignerNameMetadata {
33fn to_short_id(&self, process: &ProcessBinary) -> ShortId {
34// Get the stored metadata returned when this process had its credential
35 // checked.
36let metadata = process.credential.get().map_or(0xF, |accepted_credential| {
37 accepted_credential
38 .metadata
39 .map_or(0xF, |metadata| metadata.metadata) as u32
40 });
4142let name = process.header.get_package_name().unwrap_or("");
43let sum = kernel::utilities::helpers::crc32_posix(name.as_bytes());
4445// Combine the metadata and CRC into the short id.
46let sid = ((metadata & 0xF) << 28) | (sum & 0xFFFFFFF);
4748 core::num::NonZeroU32::new(sid).into()
49 }
50}
5152// We just use the generic version which compares Short IDs.
53impl kernel::process_checker::AppUniqueness for AppIdAssignerNameMetadata {
54fn different_identifier(&self, process_a: &ProcessBinary, process_b: &ProcessBinary) -> bool {
55self.to_short_id(process_a) != self.to_short_id(process_b)
56 }
5758fn different_identifier_process(
59&self,
60 process_a: &ProcessBinary,
61 process_b: &dyn Process,
62 ) -> bool {
63self.to_short_id(process_a) != process_b.short_app_id()
64 }
6566fn 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}