Snap for 11510257 from 067e8481614cc3fec93b7051a388a3299346ad3b to simpleperf-release
Change-Id: I98b751d5c5465ebbdb5a94f9076a114b8594999f
diff --git a/README.md b/README.md
index 5851e6b..c436f62 100644
--- a/README.md
+++ b/README.md
@@ -254,8 +254,8 @@
[generateCertificateRequestV2.cddl][pubkeycddl].
Microdroid expects the public key to be present in the Linux device tree as the
-value of the `secretkeeper-key` property of the `/avf` node - exposed to
-userspace at `/sys/firmware/devicetree/base/avf/secretkeeper-key`.
+value of the `secretkeeper_public_key` property of the `/avf` node - exposed to
+userspace at `/proc/device-tree/avf/secretkeeper_public_key`.
When a protected VM is started, AVF populates this property in the VM DT `/avf`
node from the corresponding property in the `/avf/reference/avf` node in the
diff --git a/client/Android.bp b/client/Android.bp
index 5b48063..8397c0b 100644
--- a/client/Android.bp
+++ b/client/Android.bp
@@ -34,6 +34,7 @@
"libbinder_rs",
"libciborium",
"libcoset",
+ "libhex",
"libdiced_open_dice",
// TODO(b/315464358): Use the std version
"libsecretkeeper_comm_nostd",
diff --git a/client/src/authgraph_dev.rs b/client/src/authgraph_dev.rs
index e0a39a9..3784048 100644
--- a/client/src/authgraph_dev.rs
+++ b/client/src/authgraph_dev.rs
@@ -26,15 +26,15 @@
use authgraph_core::error::Error as AgError;
use authgraph_core::error::Error;
use authgraph_core::key::{
- AesKey, CertChain, EcSignKey, Identity, IdentityVerificationDecision, CURVE25519_PRIV_KEY_LEN,
- IDENTITY_VERSION,
+ AesKey, CertChain, EcSignKey, EcVerifyKey, Identity, IdentityVerificationDecision,
+ CURVE25519_PRIV_KEY_LEN, IDENTITY_VERSION,
};
use authgraph_core::traits;
use authgraph_core::traits::AG_KEY_EXCHANGE_PROTOCOL_VERSION_1;
-use authgraph_core::traits::{AesGcm, Device};
+use authgraph_core::traits::{AesGcm, Device, EcDsa};
use authgraph_wire::{ErrorCode, SESSION_ID_LEN};
-use coset::iana;
use coset::CborSerializable;
+use coset::{iana, CoseKey};
use diced_open_dice::derive_cdi_leaf_priv;
/// Implementation of `authgraph_core::traits::Device` required for configuring the local
@@ -42,12 +42,16 @@
pub struct AgDevice {
per_boot_key: AesKey,
identity: (EcSignKey, Identity),
+ expected_peer_key: Option<CoseKey>,
}
impl AgDevice {
const AG_KE_VERSION: i32 = AG_KEY_EXCHANGE_PROTOCOL_VERSION_1;
/// Create a new `AgDevice`, using dice_artifacts for `Identity`.
- pub fn new(dice_artifacts: &OwnedDiceArtifactsWithExplicitKey) -> Result<Self, AgError> {
+ pub fn new(
+ dice_artifacts: &OwnedDiceArtifactsWithExplicitKey,
+ expected_peer_key: Option<CoseKey>,
+ ) -> Result<Self, AgError> {
let cdi_leaf_priv = derive_cdi_leaf_priv(dice_artifacts)
.map_err(|_| ag_err!(InternalError, "Failed to get private key"))?;
let identity = Identity {
@@ -80,6 +84,7 @@
),
identity,
),
+ expected_peer_key,
})
}
}
@@ -140,15 +145,37 @@
Ok(())
}
+ fn validate_peer_identity(
+ &self,
+ identity: &Identity,
+ ecdsa: &dyn EcDsa,
+ ) -> Result<EcVerifyKey, Error> {
+ if identity.cert_chain.dice_cert_chain.is_some() {
+ return Err(ag_err!(InvalidPeerKeKey, "Expected peer's DICE chain to be None"));
+ }
+ let root_key = identity.validate(ecdsa)?;
+
+ if let Some(expected_key) = &self.expected_peer_key {
+ // Do bit by bit comparison of the keys. This assumes the 2 keys are equivalently
+ // canonicalized
+ if root_key.get_key_ref() != expected_key {
+ return Err(ag_err!(
+ InvalidPeerKeKey,
+ "Peer identity did not match the expected identity"
+ ));
+ }
+ }
+ Ok(root_key)
+ }
+
fn validate_shared_sessions(
&self,
_peer_identity: &Identity,
_session_id: &[u8; SESSION_ID_LEN],
_shared_keys: &[Vec<u8>],
_sha256: &dyn traits::Sha256,
- ) -> Result<(), AgError> {
- // TODO(b/291232226): Ensure the peer is "real" Secretkeeper, by validating the identity
- // against a trusted source.
+ ) -> Result<(), Error> {
+ // Currently, there is no use of validation of shared session to application protocol.
Ok(())
}
}
diff --git a/client/src/dice.rs b/client/src/dice.rs
index 8f4ead3..c45e49a 100644
--- a/client/src/dice.rs
+++ b/client/src/dice.rs
@@ -20,6 +20,7 @@
use ciborium::Value;
use coset::{AsCborValue, CborOrdering, CborSerializable, CoseKey};
use diced_open_dice::{DiceArtifacts, OwnedDiceArtifacts, CDI_SIZE};
+use std::fmt;
const EXPLICIT_KEY_DICE_CERT_CHAIN_VERSION: u64 = 1;
@@ -54,6 +55,12 @@
}
}
+impl fmt::Debug for OwnedDiceArtifactsWithExplicitKey {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Sensitive information omitted")
+ }
+}
+
impl DiceArtifacts for OwnedDiceArtifactsWithExplicitKey {
fn cdi_attest(&self) -> &[u8; CDI_SIZE] {
self.artifacts.cdi_attest()
diff --git a/client/src/lib.rs b/client/src/lib.rs
index 81de959..ee8a31b 100644
--- a/client/src/lib.rs
+++ b/client/src/lib.rs
@@ -32,11 +32,12 @@
IAuthGraphKeyExchange::IAuthGraphKeyExchange, PlainPubKey::PlainPubKey, PubKey::PubKey,
SessionIdSignature::SessionIdSignature, Identity::Identity,
};
-use coset::{CborSerializable, CoseEncrypt0};
+use coset::{CoseKey, CborSerializable, CoseEncrypt0};
use secretkeeper_core::cipher;
use secretkeeper_comm::data_types::SeqNum;
use secretkeeper_comm::wire::ApiError;
use std::cell::RefCell;
+use std::fmt;
use std::rc::Rc;
/// A Secretkeeper session that can be used by client, this encapsulates the Authgraph Key exchange
@@ -56,11 +57,20 @@
impl SkSession {
/// Create a new Secretkeeper session. This triggers an AuthgraphKeyExchange protocol with a
/// local `source` and remote `sink`.
+ ///
+ /// # Arguments
+ /// `sk`: Secretkeeper instance
+ ///
+ /// `dice`: DiceArtifacts of the caller (i.e, Sk client)
+ ///
+ /// `expected_sk_key`: Expected Identity of Secretkeeper. If set, the claimed peer identity is
+ /// matched against this and in cases of mismatch, error is returned.
pub fn new(
sk: binder::Strong<dyn ISecretkeeper>,
dice: &OwnedDiceArtifactsWithExplicitKey,
+ expected_sk_key: Option<CoseKey>,
) -> Result<Self, Error> {
- let ag_dev = Rc::new(RefCell::new(AgDevice::new(dice)?));
+ let ag_dev = Rc::new(RefCell::new(AgDevice::new(dice, expected_sk_key)?));
let ([encryption_key, decryption_key], session_id) =
authgraph_key_exchange(sk.clone(), ag_dev.clone())?;
Ok(Self {
@@ -122,6 +132,12 @@
}
}
+impl fmt::Debug for SkSession {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("SkSession").field("session_id", &hex::encode(&self.session_id)).finish()
+ }
+}
+
/// Errors thrown by this SkSession.
#[derive(Debug)]
pub enum Error {
diff --git a/comm/src/data_types/request.rs b/comm/src/data_types/request.rs
index 0d54bcd..e415454 100644
--- a/comm/src/data_types/request.rs
+++ b/comm/src/data_types/request.rs
@@ -59,7 +59,7 @@
/// Construct the [`Request`] struct from given [`RequestPacket`].
fn deserialize_from_packet(packet: RequestPacket) -> Result<Box<Self>, Error> {
let mut req = packet.into_inner();
- if req.get(0) != Some(&Value::from(Self::OPCODE as u16)) {
+ if req.first() != Some(&Value::from(Self::OPCODE as u16)) {
return Err(Error::RequestMalformed);
}
req.remove(0);