From 1eca1e6ee28d9891e5087241fd92ffaa6c362962 Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Wed, 23 Oct 2024 06:54:22 +0200 Subject: [PATCH 1/4] Add some debug logs and change some log messages --- .../attestation-agent/Cargo.toml | 8 ++ .../src/bin/ttrpc-aa/server.rs | 43 +++--- .../attestation-agent/src/lib.rs | 131 ++++++++---------- 3 files changed, 90 insertions(+), 92 deletions(-) diff --git a/attestation-agent/attestation-agent/Cargo.toml b/attestation-agent/attestation-agent/Cargo.toml index 59b563d86..c2d26665e 100644 --- a/attestation-agent/attestation-agent/Cargo.toml +++ b/attestation-agent/attestation-agent/Cargo.toml @@ -85,3 +85,11 @@ openssl = ["kbs_protocol?/openssl"] bin = ["clap", "env_logger", "tokio/rt-multi-thread"] grpc = ["prost", "tonic", "tonic-build", "tokio/signal"] ttrpc = ["dep:ttrpc", "ttrpc-codegen", "protobuf", "tokio/signal"] + +[profile.dev] +opt-level = 0 # No optimization +debug = true # This should be true for debug builds + +[profile.release] +opt-level = 3 # Optimization level +debug = true # This should be true for release builds diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs index 55d3c497d..4f19fc574 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs @@ -8,7 +8,7 @@ use ::ttrpc::proto::Code; use anyhow::*; use async_trait::async_trait; use attestation_agent::{AttestationAPIs, AttestationAgent}; -use log::{debug, error}; +use log::{debug, error, info}; use std::collections::HashMap; use std::sync::Arc; @@ -35,17 +35,17 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: GetTokenRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): get token ..."); + debug!("AA (ttrpc): Received get_token request with TokenType: {}", req.TokenType); let token = self.inner.get_token(&req.TokenType).await.map_err(|e| { - error!("AA (ttrpc): get token failed\n {e:?}"); + error!("AA (ttrpc): get token failed: {e:?}"); let mut error_status = ::ttrpc::proto::Status::new(); error_status.set_code(Code::INTERNAL); error_status.set_message(format!("[ERROR:{AGENT_NAME}] AA-KBC get token failed")); ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): Get token successfully!"); + debug!("AA (ttrpc): Successfully retrieved token"); let mut reply = GetTokenResponse::new(); reply.Token = token; @@ -58,22 +58,21 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: GetEvidenceRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): get evidence ..."); + debug!("AA (ttrpc): Received get_evidence request with RuntimeData size: {}", req.RuntimeData.len()); let evidence = self .inner .get_evidence(&req.RuntimeData) .await .map_err(|e| { - error!("AA (ttrpc): get evidence failed:\n {e:?}"); + error!("AA (ttrpc): get evidence failed: {e:?}"); let mut error_status = ::ttrpc::proto::Status::new(); error_status.set_code(Code::INTERNAL); - error_status - .set_message(format!("[ERROR:{AGENT_NAME}] AA-KBC get evidence failed")); + error_status.set_message(format!("[ERROR:{AGENT_NAME}] AA-KBC get evidence failed")); ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): Get evidence successfully!"); + debug!("AA (ttrpc): Successfully retrieved evidence"); let mut reply = GetEvidenceResponse::new(); reply.Evidence = evidence; @@ -86,7 +85,7 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: ExtendRuntimeMeasurementRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): extend runtime measurement ..."); + debug!("AA (ttrpc): Received extend_runtime_measurement request with Domain: {}, Operation: {}, Content: {}", req.Domain, req.Operation, req.Content); self.inner .extend_runtime_measurement( @@ -97,7 +96,7 @@ impl AttestationAgentService for AA { ) .await .map_err(|e| { - error!("AA (ttrpc): extend runtime measurement failed:\n {e:?}"); + error!("AA (ttrpc): extend runtime measurement failed: {e:?}"); let mut error_status = ::ttrpc::proto::Status::new(); error_status.set_code(Code::INTERNAL); error_status.set_message(format!( @@ -106,7 +105,7 @@ impl AttestationAgentService for AA { ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): extend runtime measurement succeeded."); + debug!("AA (ttrpc): Successfully extended runtime measurement"); let reply = ExtendRuntimeMeasurementResponse::new(); ::ttrpc::Result::Ok(reply) } @@ -116,13 +115,13 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: UpdateConfigurationRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): update configuration ..."); + debug!("AA (ttrpc): Received update_configuration request with config: {}", req.config); self.inner .update_configuration(&req.config) .await .map_err(|e| { - error!("AA (ttrpc): update configuration failed:\n {e:?}"); + error!("AA (ttrpc): update configuration failed: {e:?}"); let mut error_status = ::ttrpc::proto::Status::new(); error_status.set_code(Code::INTERNAL); error_status.set_message(format!( @@ -131,7 +130,7 @@ impl AttestationAgentService for AA { ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): update configuration succeeded."); + debug!("AA (ttrpc): Successfully updated configuration"); let reply = UpdateConfigurationResponse::new(); ::ttrpc::Result::Ok(reply) } @@ -141,23 +140,24 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, _req: GetTeeTypeRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): get tee type ..."); + debug!("AA (ttrpc): Received get_tee_type request"); let tee = self.inner.get_tee_type(); let res = serde_json::to_string(&tee) .map_err(|e| { - error!("AA (ttrpc): get tee type failed:\n {e:?}"); + error!("AA (ttrpc): get tee type failed: {e:?}"); let mut error_status = ::ttrpc::proto::Status::new(); error_status.set_code(Code::INTERNAL); - error_status - .set_message(format!("[ERROR:{AGENT_NAME}] AA-KBC get tee type failed")); + error_status.set_message(format!("[ERROR:{AGENT_NAME}] AA-KBC get tee type failed")); ::ttrpc::Error::RpcStatus(error_status) })? .trim_end_matches('"') .trim_start_matches('"') .to_string(); - debug!("AA (ttrpc): get tee type succeeded."); + + debug!("AA (ttrpc): Successfully retrieved tee type: {}", res); + let mut reply = GetTeeTypeResponse::new(); reply.tee = res; ::ttrpc::Result::Ok(reply) @@ -165,8 +165,11 @@ impl AttestationAgentService for AA { } pub fn start_ttrpc_service(aa: AttestationAgent) -> Result> { + info!("Starting TTRPC service for Attestation Agent"); let service = AA { inner: aa }; let service = Arc::new(service); let get_resource_service = create_attestation_agent_service(service); + info!("TTRPC service for Attestation Agent started successfully"); Ok(get_resource_service) } + diff --git a/attestation-agent/attestation-agent/src/lib.rs b/attestation-agent/attestation-agent/src/lib.rs index fea8136a9..4ab19b434 100644 --- a/attestation-agent/attestation-agent/src/lib.rs +++ b/attestation-agent/attestation-agent/src/lib.rs @@ -17,50 +17,17 @@ mod eventlog; pub mod token; use eventlog::{Content, EventLog, LogEntry}; -use log::{debug, info, warn}; +use log::{debug, info, warn, error}; use token::*; use crate::config::Config; -/// Attestation Agent (AA for short) is a rust library crate for attestation procedure -/// in confidential containers. It provides kinds of service APIs related to attestation, -/// including the following -/// - `get_token`: get attestation token from remote services, e.g. attestation services. -/// - `get_evidence`: get hardware TEE signed evidence due to given runtime_data, s.t. -/// report data. -/// - `extend_runtime_measurement`: extend the runtime measurement. This will extend the -/// current hardware runtime measurement register (if any) or PCR for (v)TPM (under -/// development) platforms -/// with a runtime event. -/// - `check_init_data`: check if the given data slice matches the current confidential -/// computing environment's host data field, e.g. MRCONFIGID for TDX, HOSTDATA for SNP. -/// -/// # Example -/// -/// ```no_run -/// use attestation_agent::AttestationAgent; -/// use attestation_agent::AttestationAPIs; -/// -/// // initialize with empty config -/// let mut aa = AttestationAgent::new(None).unwrap(); -/// -/// let _quote = aa.get_evidence(&[0;64]); -/// ``` - -/// `AttestationAPIs` defines the service APIs of attestation agent that need to make requests -/// to the Relying Party (Key Broker Service) in Confidential Containers. -/// -/// For every service API, the `kbc_name` and `kbs_uri` is necessary, `kbc_name` tells -/// attestation agent which KBC module it should use and `kbs_uri` specifies the KBS address. #[async_trait] pub trait AttestationAPIs { - /// Get attestation Token async fn get_token(&self, token_type: &str) -> Result>; - /// Get TEE hardware signed evidence that includes the runtime data. async fn get_evidence(&self, runtime_data: &[u8]) -> Result>; - /// Extend runtime measurement register async fn extend_runtime_measurement( &self, domain: &str, @@ -69,7 +36,6 @@ pub trait AttestationAPIs { register_index: Option, ) -> Result<()>; - /// Check the initdata binding async fn check_init_data(&self, init_data: &[u8]) -> Result; fn get_tee_type(&self) -> Tee; @@ -85,43 +51,55 @@ pub struct AttestationAgent { impl AttestationAgent { pub async fn init(&mut self) -> Result<()> { + info!("Initializing AttestationAgent..."); + let config = self.config.read().await; + debug!("Configuration loaded: {:?}", config); + if config.eventlog_config.enable_eventlog { + info!("Event log is enabled, initializing..."); let alg = config.eventlog_config.eventlog_algorithm; let pcr = config.eventlog_config.init_pcr; let init_entry = LogEntry::Init(alg); let digest = init_entry.digest_with(alg); - let mut eventlog = EventLog::new()?; - eventlog.write_log(&init_entry).context("write INIT log")?; + let mut eventlog = EventLog::new().context("Failed to initialize event log")?; + eventlog.write_log(&init_entry).context("Failed to write INIT log")?; self.attester .extend_runtime_measurement(digest, pcr) .await - .context("write INIT entry")?; + .context("Failed to extend runtime measurement with INIT entry")?; self.eventlog = Some(Mutex::new(eventlog)); + debug!("Event log initialized successfully."); + } else { + warn!("Event log is disabled."); } + info!("AttestationAgent initialization completed."); Ok(()) } - /// Create a new instance of [AttestationAgent]. pub fn new(config_path: Option<&str>) -> Result { + info!("Creating new AttestationAgent instance..."); + let config = match config_path { Some(config_path) => { info!("Using AA config file: {config_path}"); - Config::try_from(config_path)? + Config::try_from(config_path).context("Failed to load configuration from file")? } None => { - warn!("No AA config file specified. Using a default configuration."); - Config::new()? + warn!("No config file specified, using default configuration."); + Config::new().context("Failed to create default configuration")? } }; let config = RwLock::new(config); let tee = detect_tee_type(); - let attester: BoxedAttester = tee.try_into()?; + info!("Detected TEE type: {:?}", tee); + + let attester: BoxedAttester = tee.try_into().context("Failed to create attester")?; Ok(AttestationAgent { config, @@ -131,24 +109,23 @@ impl AttestationAgent { }) } - /// This is a workaround API for initdata in CoCo. Once - /// a better design is implemented we can deprecate the API. - /// See https://github.com/kata-containers/kata-containers/issues/9468 pub async fn update_configuration(&self, conf: &str) -> Result<()> { - let mut tmpfile = tempfile::NamedTempFile::new()?; - let _ = tmpfile.write(conf.as_bytes())?; - tmpfile.flush()?; + info!("Updating configuration..."); + let mut tmpfile = tempfile::NamedTempFile::new().context("Failed to create temp file")?; + let _ = tmpfile.write(conf.as_bytes()).context("Failed to write to temp file")?; + tmpfile.flush().context("Failed to flush temp file")?; let config = Config::try_from( tmpfile .path() .as_os_str() .to_str() - .expect("tempfile will not create non-unicode char"), - // Here we can use `expect()` because tempfile crate will generate file name - // only including numbers and alphabet (0-9, a-z, A-Z) - )?; + .expect("Tempfile name should be valid UTF-8"), + ) + .context("Failed to load configuration from temp file")?; + *(self.config.write().await) = config; + info!("Configuration updated successfully."); Ok(()) } } @@ -156,38 +133,41 @@ impl AttestationAgent { #[async_trait] impl AttestationAPIs for AttestationAgent { async fn get_token(&self, token_type: &str) -> Result> { + debug!("Getting token for type: {}", token_type); let token_type = TokenType::from_str(token_type).context("Unsupported token type")?; match token_type { #[cfg(feature = "kbs")] token::TokenType::Kbs => { + info!("Getting KBS token..."); token::kbs::KbsTokenGetter::new(&self.config.read().await.token_configs.kbs) .get_token() .await + .context("Failed to get KBS token") } #[cfg(feature = "coco_as")] token::TokenType::CoCoAS => { + info!("Getting CoCoAS token..."); token::coco_as::CoCoASTokenGetter::new( &self.config.read().await.token_configs.coco_as, ) .get_token() .await + .context("Failed to get CoCoAS token") } } } - /// Get TEE hardware signed evidence that includes the runtime data. async fn get_evidence(&self, runtime_data: &[u8]) -> Result> { - let evidence = self.attester.get_evidence(runtime_data.to_vec()).await?; + info!("Getting evidence..."); + let evidence = self + .attester + .get_evidence(runtime_data.to_vec()) + .await + .context("Failed to get evidence")?; Ok(evidence.into_bytes()) } - /// Extend runtime measurement register. Parameters - /// - `events`: a event slice. Any single event will be calculated into a hash digest to extend the current - /// platform's RTMR. - /// - `register_index`: a target PCR that will be used to extend RTMR. Note that different platform - /// would have its own strategy to map a PCR index into a architectual RTMR index. If not given, a default one - /// will be used. async fn extend_runtime_measurement( &self, domain: &str, @@ -195,8 +175,10 @@ impl AttestationAPIs for AttestationAgent { content: &str, register_index: Option, ) -> Result<()> { + info!("Extending runtime measurement for domain: {}, operation: {}", domain, operation); + let Some(ref eventlog) = self.eventlog else { - bail!("Extend eventlog not enabled when launching!"); + bail!("Extend eventlog not enabled!"); }; let (pcr, log_entry, alg) = { @@ -204,11 +186,11 @@ impl AttestationAPIs for AttestationAgent { let pcr = register_index.unwrap_or_else(|| { let pcr = config.eventlog_config.init_pcr; - debug!("No PCR index provided, use default {pcr}"); + debug!("No PCR index provided, using default: {}", pcr); pcr }); - let content: Content = content.try_into()?; + let content: Content = content.try_into().context("Failed to parse content")?; let log_entry = LogEntry::Event { domain, @@ -222,26 +204,31 @@ impl AttestationAPIs for AttestationAgent { let digest = log_entry.digest_with(alg); { - // perform atomicly in this block let mut eventlog = eventlog.lock().await; self.attester .extend_runtime_measurement(digest, pcr) - .await?; + .await + .context("Failed to extend runtime measurement")?; - eventlog.write_log(&log_entry)?; + eventlog.write_log(&log_entry).context("Failed to write log entry")?; } + + info!("Runtime measurement extended successfully."); Ok(()) } - /// Check the initdata binding. If current platform does not support initdata - /// injection, return `InitdataResult::Unsupported`. async fn check_init_data(&self, init_data: &[u8]) -> Result { - self.attester.check_init_data(init_data).await + info!("Checking init data..."); + let result = self + .attester + .check_init_data(init_data) + .await + .context("Failed to check init data")?; + Ok(result) } - /// Get the tee type of current platform. If no platform is detected, - /// `Sample` will be returned. fn get_tee_type(&self) -> Tee { self.tee } } + From 9d105aeb81491320bd95bc8d0f44beeefc03dd20 Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Wed, 23 Oct 2024 13:58:43 +0200 Subject: [PATCH 2/4] Add some debug logs and change some log messages --- attestation-agent/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attestation-agent/Makefile b/attestation-agent/Makefile index ed2dce50b..bbc144df3 100644 --- a/attestation-agent/Makefile +++ b/attestation-agent/Makefile @@ -115,7 +115,7 @@ else endif build: - cd attestation-agent && $(RUST_FLAGS) cargo build $(release) --no-default-features --features "$(features)" $(binary) $(LIBC_FLAG) + cd attestation-agent && RUST_LOG=debug $(RUST_FLAGS) cargo build $(release) --no-default-features --features "$(features)" $(binary) $(LIBC_FLAG) mv $(TARGET_DIR)/$(binary_name) $(TARGET) TARGET := $(TARGET_DIR)/$(BIN_NAME) From 27d98c7000e606059c5fdfbfecb676b6b13b3b93 Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Thu, 24 Oct 2024 06:03:59 +0200 Subject: [PATCH 3/4] Add some debug logs and change some log messages --- attestation-agent/attestation-agent/src/config/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/attestation-agent/attestation-agent/src/config/mod.rs b/attestation-agent/attestation-agent/src/config/mod.rs index 69994115f..8e36c5030 100644 --- a/attestation-agent/attestation-agent/src/config/mod.rs +++ b/attestation-agent/attestation-agent/src/config/mod.rs @@ -50,7 +50,7 @@ impl Default for EventlogConfig { Self { eventlog_algorithm: HashAlgorithm::Sha384, init_pcr: DEFAULT_PCR_INDEX, - enable_eventlog: false, + enable_eventlog: true, } } } @@ -94,7 +94,7 @@ impl TryFrom<&str> for Config { .add_source(config::File::with_name(config_path)) .set_default("eventlog_config.eventlog_algorithm", DEFAULT_EVENTLOG_HASH)? .set_default("eventlog_config.init_pcr", DEFAULT_PCR_INDEX)? - .set_default("eventlog_config.enable_eventlog", "false")? + .set_default("eventlog_config.enable_eventlog", "true")? .build()?; let cfg = c.try_deserialize()?; From 2d886440531a74da5490917ab45a569d58266e3e Mon Sep 17 00:00:00 2001 From: Gaurav Kumar Date: Mon, 28 Oct 2024 08:40:46 +0100 Subject: [PATCH 4/4] Change debug to info log level --- .../attestation-agent/src/bin/ttrpc-aa/server.rs | 16 ++++++++-------- attestation-agent/attestation-agent/src/lib.rs | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs index 4f19fc574..0d8b792e4 100644 --- a/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs +++ b/attestation-agent/attestation-agent/src/bin/ttrpc-aa/server.rs @@ -35,7 +35,7 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: GetTokenRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): Received get_token request with TokenType: {}", req.TokenType); + info!("AA (ttrpc): Received get_token request with TokenType: {}", req.TokenType); let token = self.inner.get_token(&req.TokenType).await.map_err(|e| { error!("AA (ttrpc): get token failed: {e:?}"); @@ -45,7 +45,7 @@ impl AttestationAgentService for AA { ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): Successfully retrieved token"); + info!("AA (ttrpc): Successfully retrieved token"); let mut reply = GetTokenResponse::new(); reply.Token = token; @@ -58,7 +58,7 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: GetEvidenceRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): Received get_evidence request with RuntimeData size: {}", req.RuntimeData.len()); + info!("AA (ttrpc): Received get_evidence request with RuntimeData size: {}", req.RuntimeData.len()); let evidence = self .inner @@ -72,7 +72,7 @@ impl AttestationAgentService for AA { ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): Successfully retrieved evidence"); + info!("AA (ttrpc): Successfully retrieved evidence"); let mut reply = GetEvidenceResponse::new(); reply.Evidence = evidence; @@ -85,7 +85,7 @@ impl AttestationAgentService for AA { _ctx: &::ttrpc::r#async::TtrpcContext, req: ExtendRuntimeMeasurementRequest, ) -> ::ttrpc::Result { - debug!("AA (ttrpc): Received extend_runtime_measurement request with Domain: {}, Operation: {}, Content: {}", req.Domain, req.Operation, req.Content); + info!("AA (ttrpc): Received extend_runtime_measurement request with Domain: {}, Operation: {}, Content: {}", req.Domain, req.Operation, req.Content); self.inner .extend_runtime_measurement( @@ -105,7 +105,7 @@ impl AttestationAgentService for AA { ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): Successfully extended runtime measurement"); + info!("AA (ttrpc): Successfully extended runtime measurement"); let reply = ExtendRuntimeMeasurementResponse::new(); ::ttrpc::Result::Ok(reply) } @@ -130,7 +130,7 @@ impl AttestationAgentService for AA { ::ttrpc::Error::RpcStatus(error_status) })?; - debug!("AA (ttrpc): Successfully updated configuration"); + info!("AA (ttrpc): Successfully updated configuration"); let reply = UpdateConfigurationResponse::new(); ::ttrpc::Result::Ok(reply) } @@ -156,7 +156,7 @@ impl AttestationAgentService for AA { .trim_start_matches('"') .to_string(); - debug!("AA (ttrpc): Successfully retrieved tee type: {}", res); + info!("AA (ttrpc): Successfully retrieved tee type: {}", res); let mut reply = GetTeeTypeResponse::new(); reply.tee = res; diff --git a/attestation-agent/attestation-agent/src/lib.rs b/attestation-agent/attestation-agent/src/lib.rs index 4ab19b434..24e3d3313 100644 --- a/attestation-agent/attestation-agent/src/lib.rs +++ b/attestation-agent/attestation-agent/src/lib.rs @@ -54,7 +54,7 @@ impl AttestationAgent { info!("Initializing AttestationAgent..."); let config = self.config.read().await; - debug!("Configuration loaded: {:?}", config); + info!("Configuration loaded: {:?}", config); if config.eventlog_config.enable_eventlog { info!("Event log is enabled, initializing..."); @@ -72,7 +72,7 @@ impl AttestationAgent { .context("Failed to extend runtime measurement with INIT entry")?; self.eventlog = Some(Mutex::new(eventlog)); - debug!("Event log initialized successfully."); + info!("Event log initialized successfully."); } else { warn!("Event log is disabled."); } @@ -186,7 +186,7 @@ impl AttestationAPIs for AttestationAgent { let pcr = register_index.unwrap_or_else(|| { let pcr = config.eventlog_config.init_pcr; - debug!("No PCR index provided, using default: {}", pcr); + info!("No PCR index provided, using default: {}", pcr); pcr });