Implement exponentiation

This commit is contained in:
Sosthène Guédon
2022-12-16 11:34:45 +01:00
parent 5180c6b161
commit 6dfbbb788d
3 changed files with 80 additions and 5 deletions
+1
View File
@@ -250,6 +250,7 @@ enum_subset! {
Retired20,
}
}
impl_use_security_condition!(
AttestKeyReference,
AsymmetricKeyReference,
+65 -5
View File
@@ -37,7 +37,7 @@ use core::convert::TryInto;
use flexiber::EncodableHeapless;
use heapless_bytes::Bytes;
use iso7816::{Data, Status};
use trussed::types::{Location, StorageAttributes};
use trussed::types::{KeySerialization, Location, StorageAttributes};
use trussed::{client, syscall, try_syscall};
use constants::*;
@@ -507,12 +507,72 @@ impl<'a, T: trussed::Client + trussed::client::Ed255> LoadedAuthenticator<'a, T>
pub fn exponentiation<const R: usize>(
&mut self,
_auth: GeneralAuthenticate,
_data: derp::Input<'_>,
_reply: Reply<'_, R>,
auth: GeneralAuthenticate,
data: derp::Input<'_>,
mut reply: Reply<'_, R>,
) -> Result {
info!("Request for exponentiation");
todo!()
let key_reference = auth.key_reference.try_into().map_err(|_| {
warn!(
"Attempt to use non asymetric key for exponentiation: {:?}",
auth.key_reference
);
Status::IncorrectP1OrP2Parameter
})?;
let Some(KeyWithAlg { alg, id }) = self.state.persistent.keys.asymetric_for_reference(key_reference) else {
warn!("Attempt to use unset key");
return Err(Status::ConditionsOfUseNotSatisfied);
};
if *alg != auth.algorithm {
warn!("Attempt to exponentiate with incorrect algorithm");
return Err(Status::IncorrectP1OrP2Parameter);
}
let Some(mechanism) = alg.ecdh_mechanism() else {
warn!("Attempt to exponentiate with non ECDH algorithm");
return Err(Status::ConditionsOfUseNotSatisfied);
};
let data = data.as_slice_less_safe();
if data.first() != Some(&0x04) {
warn!("Bad data format for ECDH");
return Err(Status::IncorrectDataParameter);
}
let public_key = try_syscall!(self.trussed.deserialize_key(
mechanism,
&data[1..],
KeySerialization::Raw,
StorageAttributes::default().set_persistence(Location::Volatile)
))
.map_err(|_err| {
warn!("Failed to load public key: {:?}", _err);
Status::IncorrectDataParameter
})?
.key;
let shared_secret = syscall!(self.trussed.agree(
mechanism,
*id,
public_key,
StorageAttributes::default()
.set_persistence(Location::Volatile)
.set_serializable(true)
))
.shared_secret;
let serialized_secret = syscall!(self.trussed.serialize_key(
trussed::types::Mechanism::SharedSecret,
shared_secret,
KeySerialization::Raw
))
.serialized_key;
syscall!(self.trussed.delete(public_key));
syscall!(self.trussed.delete(shared_secret));
reply.expand(&[0x82])?;
reply.append_len(serialized_secret.len())?;
reply.expand(&serialized_secret)
}
pub fn challenge<const R: usize>(
+14
View File
@@ -142,6 +142,15 @@ impl AsymmetricAlgorithms {
}
}
pub fn ecdh_mechanism(self) -> Option<Mechanism> {
use AsymmetricAlgorithms::*;
match self {
P256 => Some(Mechanism::P256),
/* P384 | P521 | X25519 | X448 */
_ => None,
}
}
pub fn sign_mechanism(self) -> Mechanism {
match self {
Self::Rsa2048 => Mechanism::Rsa2048Pkcs,
@@ -149,6 +158,11 @@ impl AsymmetricAlgorithms {
Self::P256 => Mechanism::P256Prehashed,
}
}
pub fn is_rsa(self) -> bool {
use AsymmetricAlgorithms::*;
matches!(self, Rsa2048 | Rsa4096)
}
}
/// TODO: