mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "Sk VTS: Policy gating & Out of Seq req rejection" into main am: c6cf62d113
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2904307 Change-Id: I489abe98380ae626cad2257f026e3345f524a63e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -113,8 +113,8 @@ impl SkClient {
|
|||||||
|
|
||||||
/// This method is wrapper that use `SkSession::secret_management_request` which handles
|
/// This method is wrapper that use `SkSession::secret_management_request` which handles
|
||||||
/// encryption and decryption.
|
/// encryption and decryption.
|
||||||
fn secret_management_request(&mut self, req_data: &[u8]) -> Vec<u8> {
|
fn secret_management_request(&mut self, req_data: &[u8]) -> Result<Vec<u8>, Error> {
|
||||||
self.session.secret_management_request(req_data).unwrap()
|
Ok(self.session.secret_management_request(req_data)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlike the method [`secret_management_request`], this method directly uses
|
/// Unlike the method [`secret_management_request`], this method directly uses
|
||||||
@@ -125,7 +125,7 @@ impl SkClient {
|
|||||||
req_data: &[u8],
|
req_data: &[u8],
|
||||||
req_aad: &[u8],
|
req_aad: &[u8],
|
||||||
expected_res_aad: &[u8],
|
expected_res_aad: &[u8],
|
||||||
) -> Vec<u8> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
let aes_gcm = boring::BoringAes;
|
let aes_gcm = boring::BoringAes;
|
||||||
let rng = boring::BoringRng;
|
let rng = boring::BoringRng;
|
||||||
let request_bytes = cipher::encrypt_message(
|
let request_bytes = cipher::encrypt_message(
|
||||||
@@ -136,53 +136,54 @@ impl SkClient {
|
|||||||
&req_data,
|
&req_data,
|
||||||
req_aad,
|
req_aad,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.map_err(|e| secretkeeper_client::Error::CipherError(e))?;
|
||||||
|
|
||||||
// Binder call!
|
// Binder call!
|
||||||
let response_bytes = self.sk.processSecretManagementRequest(&request_bytes).unwrap();
|
let response_bytes = self.sk.processSecretManagementRequest(&request_bytes)?;
|
||||||
|
|
||||||
let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes).unwrap();
|
let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes)?;
|
||||||
cipher::decrypt_message(
|
Ok(cipher::decrypt_message(
|
||||||
&aes_gcm,
|
&aes_gcm,
|
||||||
self.session.decryption_key(),
|
self.session.decryption_key(),
|
||||||
&response_encrypt0,
|
&response_encrypt0,
|
||||||
expected_res_aad,
|
expected_res_aad,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.map_err(|e| secretkeeper_client::Error::CipherError(e))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method to store a secret. This uses the default compatible sealing_policy on
|
/// Helper method to store a secret. This uses the default compatible sealing_policy on
|
||||||
/// dice_chain.
|
/// dice_chain.
|
||||||
fn store(&mut self, id: &Id, secret: &Secret) {
|
fn store(&mut self, id: &Id, secret: &Secret) -> Result<(), Error> {
|
||||||
let sealing_policy = sealing_policy(self.dice_artifacts.explicit_key_dice_chain().unwrap());
|
let sealing_policy = sealing_policy(
|
||||||
|
self.dice_artifacts.explicit_key_dice_chain().ok_or(Error::UnexpectedError)?,
|
||||||
|
);
|
||||||
let store_request =
|
let store_request =
|
||||||
StoreSecretRequest { id: id.clone(), secret: secret.clone(), sealing_policy };
|
StoreSecretRequest { id: id.clone(), secret: secret.clone(), sealing_policy };
|
||||||
let store_request = store_request.serialize_to_packet().to_vec().unwrap();
|
let store_request = store_request.serialize_to_packet().to_vec()?;
|
||||||
|
|
||||||
let store_response = self.secret_management_request(&store_request);
|
let store_response = self.secret_management_request(&store_request)?;
|
||||||
let store_response = ResponsePacket::from_slice(&store_response).unwrap();
|
let store_response = ResponsePacket::from_slice(&store_response)?;
|
||||||
|
|
||||||
assert_eq!(store_response.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(store_response.response_type()?, ResponseType::Success);
|
||||||
// Really just checking that the response is indeed StoreSecretResponse
|
// Really just checking that the response is indeed StoreSecretResponse
|
||||||
let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
|
let _ = StoreSecretResponse::deserialize_from_packet(store_response)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method to get a secret.
|
/// Helper method to get a secret.
|
||||||
fn get(&mut self, id: &Id) -> Option<Secret> {
|
fn get(&mut self, id: &Id) -> Result<Secret, Error> {
|
||||||
let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None };
|
let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None };
|
||||||
let get_request = get_request.serialize_to_packet().to_vec().unwrap();
|
let get_request = get_request.serialize_to_packet().to_vec()?;
|
||||||
|
|
||||||
let get_response = self.secret_management_request(&get_request);
|
let get_response = self.secret_management_request(&get_request)?;
|
||||||
let get_response = ResponsePacket::from_slice(&get_response).unwrap();
|
let get_response = ResponsePacket::from_slice(&get_response)?;
|
||||||
|
|
||||||
if get_response.response_type().unwrap() == ResponseType::Success {
|
if get_response.response_type()? == ResponseType::Success {
|
||||||
let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
|
let get_response = *GetSecretResponse::deserialize_from_packet(get_response)?;
|
||||||
Some(Secret(get_response.secret.0))
|
Ok(Secret(get_response.secret.0))
|
||||||
} else {
|
} else {
|
||||||
// Only expect a not-found failure.
|
let err = *SecretkeeperError::deserialize_from_packet(get_response)?;
|
||||||
let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
|
Err(Error::SecretkeeperError(err))
|
||||||
assert_eq!(err, SecretkeeperError::EntryNotFound);
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +199,50 @@ impl SkClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Error {
|
||||||
|
// Errors from Secretkeeper API errors. These are thrown by core SecretManagement and
|
||||||
|
// not visible without decryption.
|
||||||
|
SecretkeeperError(SecretkeeperError),
|
||||||
|
InfraError(secretkeeper_client::Error),
|
||||||
|
UnexpectedError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<secretkeeper_client::Error> for Error {
|
||||||
|
fn from(e: secretkeeper_client::Error) -> Self {
|
||||||
|
Self::InfraError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SecretkeeperError> for Error {
|
||||||
|
fn from(e: SecretkeeperError) -> Self {
|
||||||
|
Self::SecretkeeperError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<coset::CoseError> for Error {
|
||||||
|
fn from(e: coset::CoseError) -> Self {
|
||||||
|
Self::InfraError(secretkeeper_client::Error::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<binder::Status> for Error {
|
||||||
|
fn from(s: binder::Status) -> Self {
|
||||||
|
Self::InfraError(secretkeeper_client::Error::from(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<secretkeeper_comm::data_types::error::Error> for Error {
|
||||||
|
fn from(e: secretkeeper_comm::data_types::error::Error) -> Self {
|
||||||
|
Self::InfraError(secretkeeper_client::Error::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that the error is EntryNotFound
|
||||||
|
fn assert_entry_not_found(res: Result<Secret, Error>) {
|
||||||
|
assert!(matches!(res.unwrap_err(), Error::SecretkeeperError(SecretkeeperError::EntryNotFound)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct a sealing policy on the dice chain. This method uses the following set of
|
/// Construct a sealing policy on the dice chain. This method uses the following set of
|
||||||
/// constraints which are compatible with sample DICE chains used in VTS.
|
/// constraints which are compatible with sample DICE chains used in VTS.
|
||||||
/// 1. ExactMatch on AUTHORITY_HASH (non-optional).
|
/// 1. ExactMatch on AUTHORITY_HASH (non-optional).
|
||||||
@@ -272,7 +317,7 @@ fn secret_management_get_version(instance: String) {
|
|||||||
let request_packet = request.serialize_to_packet();
|
let request_packet = request.serialize_to_packet();
|
||||||
let request_bytes = request_packet.to_vec().unwrap();
|
let request_bytes = request_packet.to_vec().unwrap();
|
||||||
|
|
||||||
let response_bytes = sk_client.secret_management_request(&request_bytes);
|
let response_bytes = sk_client.secret_management_request(&request_bytes).unwrap();
|
||||||
|
|
||||||
let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
|
let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
|
||||||
assert_eq!(response_packet.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(response_packet.response_type().unwrap(), ResponseType::Success);
|
||||||
@@ -292,7 +337,7 @@ fn secret_management_malformed_request(instance: String) {
|
|||||||
// Deform the request
|
// Deform the request
|
||||||
request_bytes[0] = !request_bytes[0];
|
request_bytes[0] = !request_bytes[0];
|
||||||
|
|
||||||
let response_bytes = sk_client.secret_management_request(&request_bytes);
|
let response_bytes = sk_client.secret_management_request(&request_bytes).unwrap();
|
||||||
|
|
||||||
let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
|
let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
|
||||||
assert_eq!(response_packet.response_type().unwrap(), ResponseType::Error);
|
assert_eq!(response_packet.response_type().unwrap(), ResponseType::Error);
|
||||||
@@ -304,10 +349,10 @@ fn secret_management_malformed_request(instance: String) {
|
|||||||
fn secret_management_store_get_secret_found(instance: String) {
|
fn secret_management_store_get_secret_found(instance: String) {
|
||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
|
|
||||||
// Get the secret that was just stored
|
// Get the secret that was just stored
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
|
assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rdroidtest(get_instances())]
|
#[rdroidtest(get_instances())]
|
||||||
@@ -315,64 +360,63 @@ fn secret_management_store_get_secret_not_found(instance: String) {
|
|||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
// Store a secret (corresponding to an id).
|
// Store a secret (corresponding to an id).
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
|
|
||||||
// Get the secret that was never stored
|
// Get the secret that was never stored
|
||||||
assert_eq!(sk_client.get(&ID_NOT_STORED), None);
|
assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rdroidtest(get_instances())]
|
#[rdroidtest(get_instances())]
|
||||||
fn secretkeeper_store_delete_ids(instance: String) {
|
fn secretkeeper_store_delete_ids(instance: String) {
|
||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.delete(&[&ID_EXAMPLE]);
|
sk_client.delete(&[&ID_EXAMPLE]);
|
||||||
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), None);
|
assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
|
|
||||||
|
|
||||||
sk_client.delete(&[&ID_EXAMPLE_2]);
|
sk_client.delete(&[&ID_EXAMPLE_2]);
|
||||||
|
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rdroidtest(get_instances())]
|
#[rdroidtest(get_instances())]
|
||||||
fn secretkeeper_store_delete_multiple_ids(instance: String) {
|
fn secretkeeper_store_delete_multiple_ids(instance: String) {
|
||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
|
sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
|
||||||
|
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
|
||||||
}
|
}
|
||||||
#[rdroidtest(get_instances())]
|
#[rdroidtest(get_instances())]
|
||||||
fn secretkeeper_store_delete_duplicate_ids(instance: String) {
|
fn secretkeeper_store_delete_duplicate_ids(instance: String) {
|
||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
|
||||||
// Delete the same secret twice.
|
// Delete the same secret twice.
|
||||||
sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE]);
|
sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE]);
|
||||||
|
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
|
assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rdroidtest(get_instances())]
|
#[rdroidtest(get_instances())]
|
||||||
fn secretkeeper_store_delete_nonexistent(instance: String) {
|
fn secretkeeper_store_delete_nonexistent(instance: String) {
|
||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.delete(&[&ID_NOT_STORED]);
|
sk_client.delete(&[&ID_NOT_STORED]);
|
||||||
|
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
|
assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
|
assert_eq!(sk_client.get(&ID_EXAMPLE_2).unwrap(), SECRET_EXAMPLE);
|
||||||
assert_eq!(sk_client.get(&ID_NOT_STORED), None);
|
assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't run deleteAll() on a secure device, as it might affect real secrets.
|
// Don't run deleteAll() on a secure device, as it might affect real secrets.
|
||||||
@@ -381,22 +425,22 @@ fn secretkeeper_store_delete_nonexistent(instance: String) {
|
|||||||
fn secretkeeper_store_delete_all(instance: String) {
|
fn secretkeeper_store_delete_all(instance: String) {
|
||||||
let mut sk_client = SkClient::new(&instance);
|
let mut sk_client = SkClient::new(&instance);
|
||||||
|
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE).unwrap();
|
||||||
|
|
||||||
sk_client.delete_all();
|
sk_client.delete_all();
|
||||||
|
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE));
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
|
assert_entry_not_found(sk_client.get(&ID_EXAMPLE_2));
|
||||||
|
|
||||||
// Store a new secret (corresponding to an id).
|
// Store a new secret (corresponding to an id).
|
||||||
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
|
|
||||||
// Get the restored secret.
|
// Get the restored secret.
|
||||||
assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
|
assert_eq!(sk_client.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
|
||||||
|
|
||||||
// (Try to) Get the secret that was never stored
|
// (Try to) Get the secret that was never stored
|
||||||
assert_eq!(sk_client.get(&ID_NOT_STORED), None);
|
assert_entry_not_found(sk_client.get(&ID_NOT_STORED));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test checks that Secretkeeper uses the expected [`RequestSeqNum`] as aad while
|
// This test checks that Secretkeeper uses the expected [`RequestSeqNum`] as aad while
|
||||||
@@ -416,21 +460,21 @@ fn secret_management_replay_protection_seq_num(instance: String) {
|
|||||||
|
|
||||||
// Check first request/response is successful
|
// Check first request/response is successful
|
||||||
let res = ResponsePacket::from_slice(
|
let res = ResponsePacket::from_slice(
|
||||||
&sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
|
&sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
||||||
|
|
||||||
// Check 2nd request/response is successful
|
// Check 2nd request/response is successful
|
||||||
let res = ResponsePacket::from_slice(
|
let res = ResponsePacket::from_slice(
|
||||||
&sk_client.secret_management_request_custom_aad(&req_2, &seq_1, &seq_1),
|
&sk_client.secret_management_request_custom_aad(&req_2, &seq_1, &seq_1).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
||||||
|
|
||||||
// Check 3rd request/response is successful
|
// Check 3rd request/response is successful
|
||||||
let res = ResponsePacket::from_slice(
|
let res = ResponsePacket::from_slice(
|
||||||
&sk_client.secret_management_request_custom_aad(&req_3, &seq_2, &seq_2),
|
&sk_client.secret_management_request_custom_aad(&req_3, &seq_2, &seq_2).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
||||||
@@ -452,7 +496,7 @@ fn secret_management_replay_protection_seq_num_per_session(instance: String) {
|
|||||||
let seq_0 = seq_a.get_then_increment().unwrap();
|
let seq_0 = seq_a.get_then_increment().unwrap();
|
||||||
// Check first request/response is successful
|
// Check first request/response is successful
|
||||||
let res = ResponsePacket::from_slice(
|
let res = ResponsePacket::from_slice(
|
||||||
&sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
|
&sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
||||||
@@ -461,7 +505,7 @@ fn secret_management_replay_protection_seq_num_per_session(instance: String) {
|
|||||||
let sk_client_diff = SkClient::new(&instance);
|
let sk_client_diff = SkClient::new(&instance);
|
||||||
// Check first request/response is with seq_0 is successful
|
// Check first request/response is with seq_0 is successful
|
||||||
let res = ResponsePacket::from_slice(
|
let res = ResponsePacket::from_slice(
|
||||||
&sk_client_diff.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
|
&sk_client_diff.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
assert_eq!(res.response_type().unwrap(), ResponseType::Success);
|
||||||
@@ -470,7 +514,6 @@ fn secret_management_replay_protection_seq_num_per_session(instance: String) {
|
|||||||
// This test checks that Secretkeeper rejects requests with out of order [`RequestSeqNum`]
|
// This test checks that Secretkeeper rejects requests with out of order [`RequestSeqNum`]
|
||||||
// TODO(b/317416663): This test fails, when HAL is not present in the device. Refactor to fix this.
|
// TODO(b/317416663): This test fails, when HAL is not present in the device. Refactor to fix this.
|
||||||
#[rdroidtest(get_instances())]
|
#[rdroidtest(get_instances())]
|
||||||
#[ignore]
|
|
||||||
fn secret_management_replay_protection_out_of_seq_req_not_accepted(instance: String) {
|
fn secret_management_replay_protection_out_of_seq_req_not_accepted(instance: String) {
|
||||||
let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
|
let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 5);
|
||||||
let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
|
let sealing_policy = sealing_policy(dice_chain.explicit_key_dice_chain().unwrap());
|
||||||
@@ -484,11 +527,36 @@ fn secret_management_replay_protection_out_of_seq_req_not_accepted(instance: Str
|
|||||||
let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
|
let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
|
||||||
|
|
||||||
// Assume First request/response is successful
|
// Assume First request/response is successful
|
||||||
sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0);
|
sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0).unwrap();
|
||||||
|
|
||||||
// Check 2nd request/response with skipped seq_num in request is a binder error
|
// Check 2nd request/response with skipped seq_num in request is a binder error
|
||||||
// This should panic!
|
let res = sk_client
|
||||||
sk_client.secret_management_request_custom_aad(&req_2, /*Skipping seq_1*/ &seq_2, &seq_1);
|
.secret_management_request_custom_aad(&req_2, /*Skipping seq_1*/ &seq_2, &seq_1);
|
||||||
|
let err = res.expect_err("Out of Seq messages accepted!");
|
||||||
|
// Incorrect sequence numbers lead to failed decryption. The resultant error should be
|
||||||
|
// thrown in clear text & wrapped in Binder errors.
|
||||||
|
assert!(matches!(err, Error::InfraError(secretkeeper_client::Error::BinderStatus(_e))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test checks DICE policy based access control of Secretkeeper.
|
||||||
|
#[rdroidtest(get_instances())]
|
||||||
|
fn secret_management_policy_gate(instance: String) {
|
||||||
|
let dice_chain = make_explicit_owned_dice(/*Security version in a node */ 100);
|
||||||
|
let mut sk_client = SkClient::with_identity(&instance, dice_chain);
|
||||||
|
sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE).unwrap();
|
||||||
|
|
||||||
|
// Start a session with higher security_version & get the stored secret.
|
||||||
|
let dice_chain_upgraded = make_explicit_owned_dice(/*Security version in a node */ 101);
|
||||||
|
let mut sk_client_upgraded = SkClient::with_identity(&instance, dice_chain_upgraded);
|
||||||
|
assert_eq!(sk_client_upgraded.get(&ID_EXAMPLE).unwrap(), SECRET_EXAMPLE);
|
||||||
|
|
||||||
|
// Start a session with lower security_version (This should be denied access to the secret).
|
||||||
|
let dice_chain_downgraded = make_explicit_owned_dice(/*Security version in a node */ 99);
|
||||||
|
let mut sk_client_downgraded = SkClient::with_identity(&instance, dice_chain_downgraded);
|
||||||
|
assert!(matches!(
|
||||||
|
sk_client_downgraded.get(&ID_EXAMPLE).unwrap_err(),
|
||||||
|
Error::SecretkeeperError(SecretkeeperError::DicePolicyError)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method that constructs 3 SecretManagement requests. Callers would usually not care about
|
// Helper method that constructs 3 SecretManagement requests. Callers would usually not care about
|
||||||
|
|||||||
Reference in New Issue
Block a user