diff --git a/nonos-data/trust/capsules/wallpaper.manifest.bin b/nonos-data/trust/capsules/wallpaper.manifest.bin new file mode 100644 index 000000000..31cb54973 Binary files /dev/null and b/nonos-data/trust/capsules/wallpaper.manifest.bin differ diff --git a/nonos-data/trust/capsules/wallpaper.nonos_id_cert.bin b/nonos-data/trust/capsules/wallpaper.nonos_id_cert.bin new file mode 100644 index 000000000..995ac2f82 Binary files /dev/null and b/nonos-data/trust/capsules/wallpaper.nonos_id_cert.bin differ diff --git a/nonos-data/trust/keys/wallpaper_publisher_ed25519.pub b/nonos-data/trust/keys/wallpaper_publisher_ed25519.pub new file mode 100644 index 000000000..b17fa17e3 Binary files /dev/null and b/nonos-data/trust/keys/wallpaper_publisher_ed25519.pub differ diff --git a/nonos-data/trust/keys/wallpaper_publisher_mldsa65.pub b/nonos-data/trust/keys/wallpaper_publisher_mldsa65.pub new file mode 100644 index 000000000..8163e8368 Binary files /dev/null and b/nonos-data/trust/keys/wallpaper_publisher_mldsa65.pub differ diff --git a/src/userspace/capsule_wallpaper/embed.rs b/src/userspace/capsule_wallpaper/embed.rs index 672a01c4a..d1cf9f510 100644 --- a/src/userspace/capsule_wallpaper/embed.rs +++ b/src/userspace/capsule_wallpaper/embed.rs @@ -14,16 +14,26 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -// Compile-time embed of the userland wallpaper binary. The -// userland crate must be built first (`make nonos-mk-wallpaper`) -// or the kernel build with `nonos-capsule-wallpaper` will fail -// at this `include_bytes!` with a clear file-not-found. #[cfg(feature = "nonos-capsule-wallpaper")] pub(crate) const WALLPAPER_ELF: &[u8] = include_bytes!( "../../../userland/capsule_wallpaper/target/x86_64-nonos-user/release/wallpaper" ); +#[cfg(feature = "nonos-capsule-wallpaper")] +pub(crate) const WALLPAPER_NONOS_ID_CERT_BYTES: &[u8] = + include_bytes!("../../../nonos-data/trust/capsules/wallpaper.nonos_id_cert.bin"); + +#[cfg(feature = "nonos-capsule-wallpaper")] +pub(crate) const WALLPAPER_MANIFEST_BYTES: &[u8] = + include_bytes!("../../../nonos-data/trust/capsules/wallpaper.manifest.bin"); + #[cfg(not(feature = "nonos-capsule-wallpaper"))] pub(crate) const WALLPAPER_ELF: &[u8] = &[]; +#[cfg(not(feature = "nonos-capsule-wallpaper"))] +pub(crate) const WALLPAPER_NONOS_ID_CERT_BYTES: &[u8] = &[]; + +#[cfg(not(feature = "nonos-capsule-wallpaper"))] +pub(crate) const WALLPAPER_MANIFEST_BYTES: &[u8] = &[]; + pub(crate) const WALLPAPER_PATH: &str = "/capsules/wallpaper"; diff --git a/src/userspace/capsule_wallpaper/mod.rs b/src/userspace/capsule_wallpaper/mod.rs index 0cbb58f32..3e9e583de 100644 --- a/src/userspace/capsule_wallpaper/mod.rs +++ b/src/userspace/capsule_wallpaper/mod.rs @@ -28,7 +28,9 @@ mod embed; mod launch; mod seed; mod spawn; +mod state; pub use launch::launch; pub use seed::seed; pub use spawn::spawn_wallpaper_capsule; +pub use state::shared_state; diff --git a/src/userspace/capsule_wallpaper/spawn.rs b/src/userspace/capsule_wallpaper/spawn.rs index 5f4072b91..a1c38a2ab 100644 --- a/src/userspace/capsule_wallpaper/spawn.rs +++ b/src/userspace/capsule_wallpaper/spawn.rs @@ -14,55 +14,44 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use crate::kernel_core::process_spawn::capsule_spawn::SpawnError; - -#[cfg(not(feature = "nonos-production"))] -use super::embed::WALLPAPER_ELF; -#[cfg(not(feature = "nonos-production"))] +use super::embed::{WALLPAPER_ELF, WALLPAPER_MANIFEST_BYTES, WALLPAPER_NONOS_ID_CERT_BYTES}; +use super::state; use crate::capabilities::Capability; -#[cfg(not(feature = "nonos-production"))] -use crate::kernel_core::process_spawn::capsule_spawn::{self, CapsuleSpec}; +use crate::kernel_core::process_spawn::capsule_spawn::{self, CapsuleSpecVerified}; +use crate::security::nonos_id_cert::IdCertVerifyError; +use crate::security::nonos_trust_anchor::{ + decode as decode_trust_anchor, BAKED_TRUST_ANCHOR_POLICY, +}; -#[cfg(not(feature = "nonos-production"))] -const SERVICE_NAME: &str = "display"; -#[cfg(not(feature = "nonos-production"))] -const SERVICE_PORT: u32 = 4300; -#[cfg(not(feature = "nonos-production"))] -const REPLY_INBOX: &str = "endpoint.display.reply"; -#[cfg(not(feature = "nonos-production"))] -const REPLY_PORT: u32 = 4301; +pub use crate::kernel_core::process_spawn::capsule_spawn::SpawnError; -#[cfg(feature = "nonos-production")] -pub fn spawn_wallpaper_capsule() -> Result<(), SpawnError> { - Err(SpawnError::FeatureDisabled) -} +const SERVICE_NAME: &str = "wallpaper"; +const SERVICE_PORT: u32 = 4340; +const REPLY_INBOX: &str = "endpoint.wallpaper.reply"; +const REPLY_PORT: u32 = 4341; +const TARGET_TRIPLE: &str = "x86_64-nonos-user"; -#[cfg(not(feature = "nonos-production"))] pub fn spawn_wallpaper_capsule() -> Result<(), SpawnError> { - if WALLPAPER_ELF.is_empty() { - return Err(SpawnError::FeatureDisabled); - } - let mut caps_bits = 0u64; - for cap in [ - Capability::CoreExec, - Capability::Memory, - Capability::Debug, - Capability::GraphicsDisplayQuery, - Capability::GraphicsSurfaceCreate, - Capability::GraphicsSurfaceMap, - Capability::GraphicsPresent, - ] { - caps_bits |= cap.bit(); - } - let spec = CapsuleSpec { + let trust_anchor = decode_trust_anchor(BAKED_TRUST_ANCHOR_POLICY) + .map_err(|_| SpawnError::NonosIdCertRejected(IdCertVerifyError::TrustAnchorPolicy))?; + let spec = CapsuleSpecVerified { name: SERVICE_NAME, service_port: SERVICE_PORT, reply_inbox: REPLY_INBOX, reply_port: REPLY_PORT, elf: WALLPAPER_ELF, - caps_bits, + nonos_id_cert_bytes: WALLPAPER_NONOS_ID_CERT_BYTES, + manifest_bytes: WALLPAPER_MANIFEST_BYTES, + target_triple: TARGET_TRIPLE, + requested_caps: Capability::CoreExec.bit() + | Capability::IPC.bit() + | Capability::Memory.bit() + | Capability::Debug.bit() + | Capability::GraphicsDisplayQuery.bit() + | Capability::GraphicsSurfaceCreate.bit(), debug_tag: b"[WALLPAPER-DEBUG] load_elf_executable error:", }; - let _ = capsule_spawn::spawn(&spec)?; + let pid = capsule_spawn::spawn_verified(&spec, &trust_anchor, None)?; + state::set_alive(pid); Ok(()) } diff --git a/src/userspace/capsule_wallpaper/state.rs b/src/userspace/capsule_wallpaper/state.rs new file mode 100644 index 000000000..f18bb639b --- /dev/null +++ b/src/userspace/capsule_wallpaper/state.rs @@ -0,0 +1,27 @@ +// NONOS Operating System +// Copyright (C) 2026 NONOS Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use crate::services::lifecycle::CapsuleState; + +static STATE: CapsuleState = CapsuleState::new(); + +pub(super) fn set_alive(pid: u32) { + STATE.set_alive(pid); +} + +pub fn shared_state() -> &'static CapsuleState { + &STATE +} diff --git a/src/userspace/init/entry.rs b/src/userspace/init/entry.rs index 813ce7f37..b94b5a1e9 100644 --- a/src/userspace/init/entry.rs +++ b/src/userspace/init/entry.rs @@ -407,10 +407,10 @@ fn spawn_process_manager_capsule() { fn spawn_wallpaper_capsule() { use crate::userspace::capsule_wallpaper; super::capsule_boot::boot( - "DISPLAY", - "display", + "WALLPAPER", + "wallpaper", capsule_wallpaper::spawn_wallpaper_capsule, - || Some("display"), + capsule_wallpaper::shared_state, ); }