From 085a481c7c4656c58f3127b68363df431ccab1a6 Mon Sep 17 00:00:00 2001 From: Alex's Bot Date: Fri, 7 Aug 2026 13:51:13 +0000 Subject: [PATCH] backup-shard: redact the shamir share in Debug output KeyOS logs whole shards at debug level while servicing a keycard, so the derived Debug put enough share material in the log to rebuild the master seed. Only the two leaf structs need the manual impl; Shard and ShardVersion compose from them. Found by the KeyOS security audit (SFT-7342). Co-Authored-By: Claude Opus 5 --- backup-shard/src/lib.rs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/backup-shard/src/lib.rs b/backup-shard/src/lib.rs index 1a709153..f38d28d4 100644 --- a/backup-shard/src/lib.rs +++ b/backup-shard/src/lib.rs @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: © 2025 Foundation Devices, Inc. // SPDX-License-Identifier: GPL-3.0-or-later +use std::fmt; + use dcbor::{CBOR, CBOREncodable, Map}; #[derive(Debug, Default, Clone, PartialEq, zeroize::ZeroizeOnDrop)] @@ -324,7 +326,7 @@ impl TryFrom for ShardVersion { } } -#[derive(Debug, Default, Clone, PartialEq, zeroize::ZeroizeOnDrop)] +#[derive(Default, Clone, PartialEq, zeroize::ZeroizeOnDrop)] #[cfg_attr( feature = "keyos", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) @@ -337,6 +339,18 @@ pub struct ShardV0 { pub part_of_magic_backup: bool, } +impl fmt::Debug for ShardV0 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ShardV0") + .field("device_id", &self.device_id) + .field("seed_fingerprint", &self.seed_fingerprint) + .field("seed_shamir_share", &"") + .field("seed_shamir_share_index", &self.seed_shamir_share_index) + .field("part_of_magic_backup", &self.part_of_magic_backup) + .finish() + } +} + impl ShardV0 { pub const VERSION: u8 = 0; } @@ -425,7 +439,7 @@ impl TryFrom for ShardV0 { } } -#[derive(Debug, Clone, PartialEq, zeroize::ZeroizeOnDrop)] +#[derive(Clone, PartialEq, zeroize::ZeroizeOnDrop)] #[cfg_attr( feature = "keyos", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) @@ -441,6 +455,21 @@ pub struct ShardV1 { pub scheme_share_count: usize, } +impl fmt::Debug for ShardV1 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ShardV1") + .field("device_id", &self.device_id) + .field("seed_fingerprint", &self.seed_fingerprint) + .field("seed_shamir_share", &"") + .field("seed_shamir_share_index", &self.seed_shamir_share_index) + .field("part_of_magic_backup", &self.part_of_magic_backup) + .field("timestamp", &self.timestamp) + .field("scheme_threshold", &self.scheme_threshold) + .field("scheme_share_count", &self.scheme_share_count) + .finish() + } +} + impl ShardV1 { pub const VERSION: u8 = 1; }