use core::mem; use sys::*; use tipc::{Deserialize, Handle, Serialize, Serializer}; use trusty_std::alloc::{TryAllocFrom, Vec};
/// The command sent to the hwwsk service. pubenum HwWskCmd { /// Generate (or import) a persistent storage key. /// /// Result is wrapped using a device-unique key.
Generate(GenerateKeyReq), /// Re-wrap a non-ephemeral wrapped key with ephemeral storage key. /// /// Result is a key that is only good for the current session.
Export(ExportKeyReq),
}
/// A request to the hwwsk service. pubstruct HwWskReq {
hdr: hwwsk_req_hdr, /// The command that is requested. pub req: HwWskCmd,
}
impl Deserialize for HwWskReq { type Error = HwWskError; const MAX_SERIALIZED_SIZE: usize = HWWSK_MAX_MSG_SIZE as usize;
fn deserialize(bytes: &[u8], handles: &mut [Option<Handle>]) -> Result<Self, Self::Error> { let header_size = mem::size_of::<hwwsk_req_hdr>(); if bytes.len() < header_size {
log::error!("response too small"); return Err(HwWskError::BadLen);
} // SAFETY: We have validated that the buffer contains enough data to // represent a hwwsk_req_hdr. The constructed lifetime here does not // outlive the function and thus cannot outlive the lifetime of the // buffer. let hdr = unsafe { &*(bytes.as_ptr() as *const hwwsk_req_hdr) };
/// Request to generate a persistent storage key. If the supplied key is empty, /// a new key will be generated. Otherwise, the provided data will be /// imported as a raw key. pubstruct GenerateKeyReq {
req: hwwsk_generate_key_req,
raw_key: Vec<u8>,
}
impl<'s> Serialize<'s> for GenerateKeyReq { fn serialize<'a: 's, S: Serializer<'s>>(
&'a self,
serializer: &mut S,
) -> Result<S::Ok, S::Error> { // SAFETY: // All serialized attributes are trivial types with // corresponding C representations unsafe {
serializer.serialize_as_bytes(&self.req.key_size)?;
serializer.serialize_as_bytes(&self.req.key_flags)?;
}
serializer.serialize_bytes(&self.raw_key)
}
}
impl Deserialize for GenerateKeyReq { type Error = HwWskError; const MAX_SERIALIZED_SIZE: usize = HWWSK_MAX_MSG_SIZE as usize;
fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, Self::Error> { let header_size = mem::size_of::<hwwsk_generate_key_req>(); if bytes.len() < header_size {
log::error!("response too small"); return Err(HwWskError::BadLen);
} // SAFETY: We have validated that the buffer contains enough data to // represent a hwwsk_generate_key_req. The constructed lifetime here does not // outlive the function and thus cannot outlive the lifetime of the // buffer. let hwwsk_generate_key_req { key_size, key_flags } = unsafe { &*(bytes.as_ptr() as *const hwwsk_generate_key_req) };
/// A request to re-wrap a non-ephemeral key using an ephemeral storage key. /// The resulting key is only good for the current session. pubstruct ExportKeyReq {
key_blob: Vec<u8>,
}
/// Response from hwwsk service. pubstruct HwWskResponse { /// Sent command, acknowledged by service if successful.
cmd: u32, /// Status of command result.
status: u32, /// Response data.
payload: Vec<u8>,
}
impl<'s> Serialize<'s> for HwWskResponse { fn serialize<'a: 's, S: Serializer<'s>>(
&'a self,
serializer: &mut S,
) -> Result<S::Ok, S::Error> { // SAFETY: // All serialized attributes are trivial types with // corresponding C representations unsafe {
serializer.serialize_as_bytes(&self.cmd)?;
serializer.serialize_as_bytes(&self.status)?;
}
serializer.serialize_bytes(&self.payload)
}
}
impl Deserialize for HwWskResponse { type Error = HwWskError; const MAX_SERIALIZED_SIZE: usize = HWWSK_MAX_MSG_SIZE as usize;
fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> Result<Self, Self::Error> { // response must at least contain cmd and status let header_size = mem::size_of::<u32>() * 2; if bytes.len() < header_size {
log::error!("response too small"); return Err(HwWskError::BadLen);
} let (cmd_bytes, rest) = bytes.split_at(mem::size_of::<u32>()); let (status_bytes, payload_bytes) = rest.split_at(mem::size_of::<u32>());
let status = u32::from_ne_bytes(status_bytes.try_into()?); let cmd = u32::from_ne_bytes(cmd_bytes.try_into()?);
/// Indicates that the resulting key must be rollback resistant. pubfn rollback_resistance(mutself) -> Self { self.flags |= hwwsk_key_flags_HWWSK_FLAGS_ROLLBACK_RESISTANCE as u32; self
}
}
/// Creates a new persistent key from provided raw key material. /// /// This routine creates a new hardware wrapped storage key by /// either importing raw key material that's specified by the caller. /// The resulting key is persistent and reusable across device reset. /// /// # Arguments /// /// * `session` - IPC channel to HWWSK service /// * `buf` - buffer to store resulting key blob /// * `key_size` - key size in bits /// * `key_flags` - a combination of [`KeyFlags`] to specify any additional /// properties of the generated key /// * `raw_key` - the buffer containing raw key data for import operation /// /// # Returns /// /// A truncated view into `buf` where the wrapped key data was populated. /// pubfn import_key<'a>(
session: &Handle,
buf: &'a mut [u8],
key_size: usize,
key_flags: KeyFlags,
raw_key: &[u8],
) -> Result<&'a [u8], HwWskError> { if raw_key.is_empty() { return Err(HwWskError::BadLen);
}
create_key(session, buf, key_size, key_flags, raw_key)
}
/// Creates a new persistent key. /// /// This routine creates a new hardware wrapped storage key by /// generating a new random key The resulting key is persistent and /// reusable across device reset. /// /// # Arguments /// /// * `session` - IPC channel to HWWSK service /// * `buf` - buffer to store resulting key blob /// * `key_size` - key size in bits /// * `key_flags` - a combination of [`KeyFlags`] to specify any additional /// properties of the generated key /// /// # Returns /// /// A truncated view into `buf` where the wrapped key data was populated. /// pubfn generate_key<'a>(
session: &Handle,
buf: &'a mut [u8],
key_size: usize,
key_flags: KeyFlags,
) -> Result<&'a [u8], HwWskError> {
create_key(session, buf, key_size, key_flags, &[])
}
if buf.len() < response.payload.len() {
log::error!("response payload is too large to fit into the buffer"); return Err(HwWskError::BadLen);
}
let res_buffer = &mut buf[..response.payload.len()];
res_buffer.copy_from_slice(&response.payload);
Ok(res_buffer)
}
/// Rewrap specified SK key with ESK. /// /// This routine rewraps a specified persistent SK key with an ephemeral /// storage key (ESK). The resulting key is only good for the current /// session. /// /// # Arguments /// /// * `session` - IPC channel to HWWSK service /// * `buf` - buffer to store the resulting key blob /// * `key_blob` - the key blob to unwrap /// /// # Returns /// /// A truncated view into `buf` where the rewrrapped key data was populated. /// pubfn export_key<'a>(
session: &Handle,
buf: &'a mut [u8],
key_blob: &[u8],
) -> Result<&'a [u8], HwWskError> { let cmd = hwwsk_cmd_HWWSK_CMD_EXPORT_KEY as u32; let req = HwWskReq {
hdr: hwwsk_req_hdr { cmd, flags: 0 },
req: HwWskCmd::Export(ExportKeyReq { key_blob: Vec::try_alloc_from(key_blob)? }),
};
session.send(&req)?;
let resp_buf = &mut [0; HWWSK_MAX_MSG_SIZE as usize]; let response: HwWskResponse = session.recv(resp_buf)?;
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.