From 07066768c8f0cb0a03f10e25bef90435512a2092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 2 Feb 2023 16:29:19 +0100 Subject: [PATCH 1/3] Add RSA mechanisms and key serialization --- src/mechanisms/p256.rs | 1 + src/types.rs | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/mechanisms/p256.rs b/src/mechanisms/p256.rs index f862886e4eb..9b3f1169329 100644 --- a/src/mechanisms/p256.rs +++ b/src/mechanisms/p256.rs @@ -240,6 +240,7 @@ impl SerializeKey for super::P256 { .map_err(|_| Error::InternalError)?; serialized_key } + _ => return Err(Error::InvalidSerializationFormat), }; Ok(reply::SerializeKey { serialized_key }) diff --git a/src/types.rs b/src/types.rs index 50ab8acf354..fac83acdcd1 100644 --- a/src/types.rs +++ b/src/types.rs @@ -568,6 +568,9 @@ pub enum Mechanism { X255, /// Used to serialize the output of a diffie-hellman SharedSecret, + Rsa2048Pkcs1v15, + Rsa3072Pkcs1v15, + Rsa4096Pkcs1v15, } pub type LongData = Bytes; @@ -584,6 +587,12 @@ pub enum KeySerialization { EcdhEsHkdf256, Raw, Sec1, + /// Used by backends implementing RSA. + /// + /// Since RSA keys have multiple parts, and that the [`SerializeKey`](crate::api::Reply::SerializeKey) and + /// [`UnsafeInjectKey`](crate::api::Request::UnsafeInjectKey) have only transfer one byte array, the RSA key is serialized with postcard + RsaParts, + Pkcs8Der, } pub type Signature = Bytes; From 7fa9d074b136aeee27b340b8ce067fb425b9998b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 3 Feb 2023 11:34:44 +0100 Subject: [PATCH 2/3] Add RSA key kinds --- src/key.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/key.rs b/src/key.rs index 64910971a7f..5d0906548d8 100644 --- a/src/key.rs +++ b/src/key.rs @@ -63,6 +63,9 @@ pub enum Kind { Symmetric(usize), /// 32B symmetric key + nonce, the parameter is the length of the nonce in bytes Symmetric32Nonce(usize), + Rsa2048, + Rsa3072, + Rsa4096, Ed255, P256, X255, @@ -150,6 +153,9 @@ impl Kind { Kind::Ed255 => 4, Kind::P256 => 5, Kind::X255 => 6, + Kind::Rsa2048 => 7, + Kind::Rsa3072 => 8, + Kind::Rsa4096 => 9, } } From b732ec3dd1f0a14bcc45514446676a4a27249bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 6 Feb 2023 09:42:21 +0100 Subject: [PATCH 3/3] Fix key serialization length to accomodate RSA --- src/api.rs | 6 +++--- src/client.rs | 4 ++-- src/config.rs | 12 ++++++++---- src/key.rs | 3 +++ src/mechanisms/ed255.rs | 2 +- src/mechanisms/p256.rs | 4 ++-- src/mechanisms/shared_secret.rs | 2 +- src/mechanisms/x255.rs | 2 +- src/store/keystore.rs | 3 ++- src/types.rs | 1 + 10 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/api.rs b/src/api.rs index 234615c4a8f..42064d92083 100644 --- a/src/api.rs +++ b/src/api.rs @@ -174,7 +174,7 @@ pub mod request { DeserializeKey: - mechanism: Mechanism - - serialized_key: Message + - serialized_key: SerializedKey - format: KeySerialization - attributes: StorageAttributes @@ -282,7 +282,7 @@ pub mod request { UnsafeInjectKey: - mechanism: Mechanism // -> implies key type - - raw_key: ShortData + - raw_key: SerializedKey - attributes: StorageAttributes - format: KeySerialization @@ -443,7 +443,7 @@ pub mod reply { - bytes: Message SerializeKey: - - serialized_key: Message + - serialized_key: SerializedKey Sign: - signature: Signature diff --git a/src/client.rs b/src/client.rs index 1214656e920..abe4d1a1215 100644 --- a/src/client.rs +++ b/src/client.rs @@ -353,7 +353,7 @@ pub trait CryptoClient: PollClient { attributes: StorageAttributes, ) -> ClientResult<'c, reply::DeserializeKey, Self> { let serialized_key = - Message::from_slice(serialized_key).map_err(|_| ClientError::DataTooLarge)?; + SerializedKey::from_slice(serialized_key).map_err(|_| ClientError::DataTooLarge)?; self.request(request::DeserializeKey { mechanism, serialized_key, @@ -478,7 +478,7 @@ pub trait CryptoClient: PollClient { ) -> ClientResult<'_, reply::UnsafeInjectKey, Self> { self.request(request::UnsafeInjectKey { mechanism, - raw_key: ShortData::from_slice(raw_key).unwrap(), + raw_key: SerializedKey::from_slice(raw_key).unwrap(), attributes: StorageAttributes::new().set_persistence(persistence), format, }) diff --git a/src/config.rs b/src/config.rs index 4e92fd23093..189d6376c6c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,9 +13,6 @@ pub type MAX_OBJECT_HANDLES = consts::U16; pub type MAX_LABEL_LENGTH = consts::U256; pub const MAX_MEDIUM_DATA_LENGTH: usize = 256; pub type MAX_PATH_LENGTH = consts::U256; -pub const MAX_KEY_MATERIAL_LENGTH: usize = 128; -// must be above + 4 -pub const MAX_SERIALIZED_KEY_LENGTH: usize = 132; cfg_if::cfg_if! { if #[cfg(feature = "clients-12")] { pub type MAX_SERVICE_CLIENTS = consts::U12; @@ -44,7 +41,14 @@ cfg_if::cfg_if! { } } pub const MAX_SHORT_DATA_LENGTH: usize = 128; -pub const MAX_SIGNATURE_LENGTH: usize = 72; + +pub const MAX_SIGNATURE_LENGTH: usize = 512 * 2; +// FIXME: Value from https://stackoverflow.com/questions/5403808/private-key-length-bytes for Rsa2048 Private key +pub const MAX_KEY_MATERIAL_LENGTH: usize = 1160 * 2 + 72; + +// must be MAX_KEY_MATERIAL_LENGTH + 4 +pub const MAX_SERIALIZED_KEY_LENGTH: usize = MAX_KEY_MATERIAL_LENGTH + 4; + pub const MAX_USER_ATTRIBUTE_LENGTH: usize = 256; pub const USER_ATTRIBUTE_NUMBER: u8 = 37; diff --git a/src/key.rs b/src/key.rs index 5d0906548d8..ccda75c204a 100644 --- a/src/key.rs +++ b/src/key.rs @@ -167,6 +167,9 @@ impl Kind { 4 => Self::Ed255, 5 => Self::P256, 6 => Self::X255, + 7 => Kind::Rsa2048, + 8 => Kind::Rsa3072, + 9 => Kind::Rsa4096, _ => return Err(Error::InvalidSerializedKey), }) } diff --git a/src/mechanisms/ed255.rs b/src/mechanisms/ed255.rs index 0cf47adf1c9..6d3325d0873 100644 --- a/src/mechanisms/ed255.rs +++ b/src/mechanisms/ed255.rs @@ -142,7 +142,7 @@ impl SerializeKey for super::Ed255 { } KeySerialization::Raw => { - let mut serialized_key = Message::new(); + let mut serialized_key = SerializedKey::new(); serialized_key .extend_from_slice(public_key.as_bytes()) .map_err(|_| Error::InternalError)?; diff --git a/src/mechanisms/p256.rs b/src/mechanisms/p256.rs index 9b3f1169329..24b056698d4 100644 --- a/src/mechanisms/p256.rs +++ b/src/mechanisms/p256.rs @@ -224,7 +224,7 @@ impl SerializeKey for super::P256 { crate::cbor_serialize_bytes(&cose_pk).map_err(|_| Error::CborError)? } KeySerialization::Raw => { - let mut serialized_key = Message::new(); + let mut serialized_key = SerializedKey::new(); serialized_key .extend_from_slice(&public_key.x()) .map_err(|_| Error::InternalError)?; @@ -234,7 +234,7 @@ impl SerializeKey for super::P256 { serialized_key } KeySerialization::Sec1 => { - let mut serialized_key = Message::new(); + let mut serialized_key = SerializedKey::new(); serialized_key .extend_from_slice(&public_key.to_compressed_sec1_bytes()) .map_err(|_| Error::InternalError)?; diff --git a/src/mechanisms/shared_secret.rs b/src/mechanisms/shared_secret.rs index 7c42b0f684b..b33a1bdddec 100644 --- a/src/mechanisms/shared_secret.rs +++ b/src/mechanisms/shared_secret.rs @@ -22,7 +22,7 @@ impl SerializeKey for super::SharedSecret { if !key.flags.contains(key::Flags::SERIALIZABLE) { return Err(Error::InvalidSerializedKey); }; - let mut serialized_key = Message::new(); + let mut serialized_key = SerializedKey::new(); serialized_key.extend_from_slice(&key.material).unwrap(); Ok(reply::SerializeKey { serialized_key }) diff --git a/src/mechanisms/x255.rs b/src/mechanisms/x255.rs index 4178c15a758..c646c89f72d 100644 --- a/src/mechanisms/x255.rs +++ b/src/mechanisms/x255.rs @@ -149,7 +149,7 @@ impl SerializeKey for super::X255 { let key_id = request.key; let public_key = load_public_key(keystore, &key_id)?; - let mut serialized_key = Message::new(); + let mut serialized_key = SerializedKey::new(); match request.format { KeySerialization::Raw => { serialized_key diff --git a/src/store/keystore.rs b/src/store/keystore.rs index aea1c6b6c01..fae30af842f 100644 --- a/src/store/keystore.rs +++ b/src/store/keystore.rs @@ -2,6 +2,7 @@ use chacha20::ChaCha8Rng; use littlefs2::path::PathBuf; use crate::{ + config::MAX_KEY_MATERIAL_LENGTH, error::{Error, Result}, key, store::{self, Store}, @@ -172,7 +173,7 @@ impl Keystore for ClientKeystore { let location = self.location(secrecy, id).ok_or(Error::NoSuchKey)?; - let bytes: Bytes<128> = store::read(self.store, location, &path)?; + let bytes: Bytes<{ MAX_KEY_MATERIAL_LENGTH }> = store::read(self.store, location, &path)?; let key = key::Key::try_deserialize(&bytes)?; diff --git a/src/types.rs b/src/types.rs index fac83acdcd1..a584a403a9d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -578,6 +578,7 @@ pub type MediumData = Bytes; pub type ShortData = Bytes; pub type Message = Bytes; +pub type SerializedKey = Bytes; #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] pub enum KeySerialization {