usecrate::service::{api_to_storage, binder_error, gsc_to_storage}; use binder::Strong; use gsc_svc_client::GscServiceClient; use pinweaver_api::{
connect_pinweaver, DelayScheduleEntry, IPinWeaver, InsertMode, LeafId, LeafSet, TryAuthResponse,
}; use pinweaver_storage_api::{
request::{CommitOpRequest, StartOpRequest},
response::{StartOpResponse, StartOpResponseData, StartTryAuthResponseData},
util::{DeserializeExact, ForwardTipcSerialize, SerdeVec},
StorageRequest, StorageResponse, EMPTY_TREE_HASH,
}; use std::convert::AsRef; use tipc::{Deserialize, Handle, Serialize, Serializer}; use tpm_commands::pinweaver::{Pinweaver, UnimportedLeafData}; use zerocopy::FromBytes;
/// TODO drop this when it is stabilized in std.
macro_rules! assert_matches {
($first:expr, $($second:pat_param)|+ $(if $third:expr)?) => { let a = $first; if !matches!(&a, $($second)|+ $(if $third)?) {
panic!( "'{}' does not match '{}'; Got '{:?}'",
stringify!($first),
stringify!($($second)|+ $(if $third)?),
a
);
}
};
}
fn serialize_handle(&mutself, _handle: &'a Handle) -> Result<Self::Ok, Self::Error> {
panic!("no handles should be used");
}
}
/// A test-only helper to provide access to the storage daemon through IPinweaver. fn storage_request(
pinweaver: &dyn IPinWeaver,
request: &StorageRequest,
) -> binder::Result<StorageResponse> { letmut serializer = TestSerializer::default();
ForwardTipcSerialize(request).serialize(&mut serializer).expect("serialize failed"); let buffer = pinweaver.testStorage(serializer.0.as_slice())?; let resp = DeserializeExact::<StorageResponse>::deserialize(buffer.as_slice(), &yle='color:red'>mut [])
.expect("deserialize failed");
Ok(resp.0)
}
#[test] fn pinweaver_smoke_test() { // Start from a known state. let pinweaver: Strong<dyn IPinWeaver> =
connect_pinweaver().expect("connect_pinweaver() failed");
// Insert a fresh leaf.
pinweaver
.insert(
&DEFAULT_LEAF_ID,
&DEFAULT_LOW_ENTROPY_SECRET,
&DEFAULT_HIGH_ENTROPY_SECRET,
&DEFAULT_RESET_SECRET,
&DEFAULT_DELAY_SCHEDULE,
InsertMode::NEW_ONLY,
)
.expect("insert() failed");
log::info!("After first insert()");
// Insert with replacement.
pinweaver
.insert(
&DEFAULT_LEAF_ID,
&DEFAULT_LOW_ENTROPY_SECRET,
&DEFAULT_HIGH_ENTROPY_SECRET,
&DEFAULT_RESET_SECRET,
&DEFAULT_DELAY_SCHEDULE,
InsertMode::REPLACE_EXISTING,
)
.expect("insert() failed");
log::info!("After second insert()");
// Insert that fails with WouldReplace.
assert_eq!(
pinweaver.insert(
&DEFAULT_LEAF_ID,
&DEFAULT_LOW_ENTROPY_SECRET,
&DEFAULT_HIGH_ENTROPY_SECRET,
&DEFAULT_RESET_SECRET,
&DEFAULT_DELAY_SCHEDULE,
InsertMode::NEW_ONLY,
),
Err(binder_error::leaf_exists())
);
log::info!("After third insert()");
// Try Auth that succeeds.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &DEFAULT_LOW_ENTROPY_SECRET),
Ok(TryAuthResponse::HighEntropySecret(s)) if s == &DEFAULT_HIGH_ENTROPY_SECRET
);
// Try Auth that fails.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &[0u8; 32]),
Err(s) if s == &binder_error::low_entropy_auth_failed()
);
// Try Auth during back-off.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &DEFAULT_LOW_ENTROPY_SECRET),
Ok(TryAuthResponse::SecondsToWait(s)) if *s > 0
);
// Reset Retries with wrong secret.
assert_matches!(
pinweaver.resetRetries(&DEFAULT_LEAF_ID, false, &DEFAULT_LOW_ENTROPY_SECRET),
Err(s) if s == &binder_error::auth_failed()
);
// Reset Retries that succeeds.
assert_matches!(pinweaver.resetRetries(&DEFAULT_LEAF_ID, false, &DEFAULT_RESET_SECRET), Ok(())); // Make sure the back-off is cleared.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &DEFAULT_LOW_ENTROPY_SECRET),
Ok(TryAuthResponse::HighEntropySecret(s)) if s == &DEFAULT_HIGH_ENTROPY_SECRET
);
// Remove that succeeds.
pinweaver.remove(&DEFAULT_LEAF_ID).expect("remove() failed");
// Remove that failes with DoesNotExist.
assert_eq!(pinweaver.remove(&DEFAULT_LEAF_ID), Err(binder_error::leaf_not_found()));
// Check that large secrets work.
pinweaver
.insert(
&DEFAULT_LEAF_ID,
&DEFAULT_LOW_ENTROPY_SECRET,
&DEFAULT_LARGE_SECRET,
&DEFAULT_RESET_SECRET,
&DEFAULT_DELAY_SCHEDULE,
InsertMode::NEW_ONLY,
)
.expect("insert() failed");
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &DEFAULT_LOW_ENTROPY_SECRET),
Ok(TryAuthResponse::HighEntropySecret(s)) if s == &DEFAULT_LARGE_SECRET
);
let gsc = GscServiceClient::default(); letmut buffer = Vec::new(); let log_entries = gsc.get_log(None, &mut buffer).expect("get_log() failed");
assert!(log_entries.len() > 0);
let _ = storage_request(pinweaver.as_ref(), &StorageRequest::GetStatus);
for id in0i32..3 {
pinweaver
.insert(
&LeafId { leafSet: LeafSet::WEAVER, id },
&DEFAULT_LOW_ENTROPY_SECRET,
&DEFAULT_HIGH_ENTROPY_SECRET,
&DEFAULT_RESET_SECRET,
&DEFAULT_DELAY_SCHEDULE,
InsertMode::NEW_ONLY,
)
.expect("insert() failed");
}
pinweaver.removeAll(LeafSet::WEAVER).expect("removeAll() failed");
assert_eq!(pinweaver.removeAll(LeafSet::WEAVER), Err(binder_error::leaf_not_found()));
}
#[test] fn pinweaver_log_replay_test() { // Start from a known state. let pinweaver: Strong<dyn IPinWeaver> =
connect_pinweaver().expect("connect_pinweaver() failed");
// Try Auth that succeeds.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &DEFAULT_LOW_ENTROPY_SECRET),
Ok(TryAuthResponse::HighEntropySecret(s)) if s == &DEFAULT_HIGH_ENTROPY_SECRET
);
// Back up the leaf contents to force storage out of sync. let start_request = StartOpRequest::TryAuth(api_to_storage::leaf_id(&DEFAULT_LEAF_ID)); let resp = storage_request(pinweaver.as_ref(), &StorageRequest::StartOp(start_request.clone()))
.expect("storage request failed"); let (new_leaf_hmac, new_leaf_contents) = iflet StorageResponse::StartOp(StartOpResponse {
op_data: StartOpResponseData::TryAuth(StartTryAuthResponseData { leaf_contents, .. }),
..
}) = resp
{ let hmac = gsc_to_storage::hmac(
&UnimportedLeafData::ref_from_bytes(leaf_contents.as_ref())
.expect("parsing leaf data failed")
.hmac,
);
(hmac, leaf_contents)
} else {
panic!("unexpected response: {:?}", resp);
}; // Try Auth that fails.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &[0u8; 32]),
Err(s) if s == &binder_error::low_entropy_auth_failed()
); // Roll back the try-auth with a fake operation. let _ = storage_request(pinweaver.as_ref(), &StorageRequest::StartOp(start_request.clone()))
.expect("storage request failed"); let _ = storage_request(
pinweaver.as_ref(),
&StorageRequest::CommitOp(CommitOpRequest {
start_request,
new_leaf_hmac,
new_leaf_contents,
}),
)
.expect("storage request failed");
// Test log-replay.
pinweaver.reconcile().expect("reconcile failed");
pinweaver
.insert(
&THIRD_LEAF_ID,
&OTHER_LOW_ENTROPY_SECRET,
&DEFAULT_HIGH_ENTROPY_SECRET,
&DEFAULT_RESET_SECRET,
&OTHER_DELAY_SCHEDULE,
InsertMode::NEW_ONLY,
)
.expect("insert() failed"); // Remove the THIRD_LEAF_ID to test replaying an insert. let start_request = StartOpRequest::Remove(api_to_storage::leaf_id(&THIRD_LEAF_ID)); let _ = storage_request(pinweaver.as_ref(), &StorageRequest::StartOp(start_request.clone()))
.expect("storage request failed"); let _ = storage_request(
pinweaver.as_ref(),
&StorageRequest::CommitOp(CommitOpRequest {
start_request,
new_leaf_hmac: EMPTY_TREE_HASH,
new_leaf_contents: SerdeVec::from_vec(Vec::new()),
}),
)
.expect("storage request failed");
// Test log-replay.
pinweaver.reconcile().expect("reconcile failed");
assert_matches!(
pinweaver.tryAuthenticate(&THIRD_LEAF_ID, &OTHER_LOW_ENTROPY_SECRET),
Err(err) if *err == binder_error::leaf_not_found()
);
// Back up the leaf contents to force storage out of sync. let resp = storage_request(
pinweaver.as_ref(),
&StorageRequest::StartOp(
StartOpRequest::TryAuth(api_to_storage::leaf_id(&OTHER_LEAF_ID)).clone(),
),
)
.expect("storage request failed"); let (path, new_leaf_hmac, new_leaf_contents) = iflet StorageResponse::StartOp(StartOpResponse {
path,
op_data: StartOpResponseData::TryAuth(StartTryAuthResponseData { leaf_contents, .. }),
..
}) = resp
{ let hmac = gsc_to_storage::hmac(
&UnimportedLeafData::ref_from_bytes(leaf_contents.as_ref())
.expect("parsing leaf data failed")
.hmac,
);
(path, hmac, leaf_contents)
} else {
panic!("unexpected response: {:?}", resp);
};
// Restore OTHER_LEAF_ID for the storage only. let start_request = StartOpRequest::LogReplay(path); let _ = storage_request(pinweaver.as_ref(), &StorageRequest::StartOp(start_request.clone()))
.expect("storage request failed"); let _ = storage_request(
pinweaver.as_ref(),
&StorageRequest::CommitOp(CommitOpRequest {
start_request,
new_leaf_hmac,
new_leaf_contents,
}),
)
.expect("storage request failed");
// Test log-replay.
pinweaver.reconcile().expect("reconcile failed");
assert_matches!(
pinweaver.tryAuthenticate(&OTHER_LEAF_ID, &OTHER_LOW_ENTROPY_SECRET),
Err(err) if *err == binder_error::leaf_not_found()
);
// Make sure the existing leaf still works.
assert_matches!(
pinweaver.tryAuthenticate(&DEFAULT_LEAF_ID, &DEFAULT_LOW_ENTROPY_SECRET),
Ok(TryAuthResponse::HighEntropySecret(s)) if s == &DEFAULT_HIGH_ENTROPY_SECRET
);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.