From 1fd257e8abb1aff7e10e3b6af584413b78d33dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Wed, 13 Sep 2023 11:58:34 +0200 Subject: [PATCH] Put RSA behind a feature flag --- Cargo.toml | 4 +++- Makefile | 2 +- src/container.rs | 11 ++++++++--- src/lib.rs | 1 + src/piv_types.rs | 17 +++++++++++++++-- src/virt.rs | 5 +++++ tests/pivy.rs | 28 +++++++++++++++++++--------- 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dba74f5..c380070 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ vpicc = { version = "0.1.0", optional = true } log = "0.4" heapless-bytes = "0.3.0" subtle = { version = "2", default-features = false } -trussed-rsa-alloc = { version = "0.1.0", features = ["raw"] } +trussed-rsa-alloc = { version = "0.1.0", features = ["raw"], optional = true } trussed-staging = { version = "0.1.0", features = ["chunked", "encrypted-chunked"]} [dev-dependencies] @@ -66,6 +66,8 @@ vpicc = ["std", "dep:vpicc", "virt"] virt = ["std", "trussed/virt"] pivy-tests = [] opensc-tests = [] +alloc = [] +rsa = ["trussed-rsa-alloc", "alloc"] log-all = [] log-none = [] diff --git a/Makefile b/Makefile index 146c00b..16a9048 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ .NOTPARALLEL: export RUST_LOG ?= info,cargo_tarpaulin=off -TEST_FEATURES ?=vpicc,pivy-tests,opensc-tests +TEST_FEATURES ?=vpicc,pivy-tests,opensc-tests,rsa .PHONY: build-cortex-m4 build-cortex-m4: diff --git a/src/container.rs b/src/container.rs index b917c55..fc61edb 100644 --- a/src/container.rs +++ b/src/container.rs @@ -10,7 +10,7 @@ macro_rules! enum_subset { $(#[$outer:meta])* $vis:vis enum $name:ident: $sup:ident { - $($var:ident),+ + $($(#[cfg($inner:meta)])? $var:ident),+ $(,)* } ) => { @@ -19,6 +19,7 @@ macro_rules! enum_subset { #[derive(Clone, Copy)] $vis enum $name { $( + $(#[cfg($inner)])? $var, )* } @@ -29,6 +30,7 @@ macro_rules! enum_subset { fn try_from(val: $sup) -> ::core::result::Result { match val { $( + $(#[cfg($inner)])? $sup::$var => Ok($name::$var), )* _ => Err(::iso7816::Status::KeyReferenceNotFound) @@ -41,6 +43,7 @@ macro_rules! enum_subset { fn from(v: $name) -> $sup { match v { $( + $(#[cfg($inner)])? $name::$var => $sup::$var, )* } @@ -51,8 +54,9 @@ macro_rules! enum_subset { fn eq(&self, other: &T) -> bool { match (self,(*other).into()) { $( - | ($name::$var, $sup::$var) - )* => true, + $(#[cfg($inner)])? + ($name::$var, $sup::$var) => true, + )* _ => false } } @@ -66,6 +70,7 @@ macro_rules! enum_subset { let v: $sup = tag.try_into()?; match v { $( + $(#[cfg($inner)])? $sup::$var => Ok($name::$var), )* _ => Err(::iso7816::Status::KeyReferenceNotFound) diff --git a/src/lib.rs b/src/lib.rs index 73ac897..b50f50d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -877,6 +877,7 @@ impl<'a, T: Client> LoadedAuthenticator<'a, T> { reply.expand(&serialized_key)?; reply.prepend_len(offset)?; } + #[cfg(feature = "rsa")] AsymmetricAlgorithms::Rsa2048 | AsymmetricAlgorithms::Rsa4096 => { use trussed_rsa_alloc::RsaPublicParts; reply.expand(&[0x7F, 0x49])?; diff --git a/src/piv_types.rs b/src/piv_types.rs index 996bb5c..037bd85 100644 --- a/src/piv_types.rs +++ b/src/piv_types.rs @@ -123,7 +123,9 @@ enum_u8! { crate::container::enum_subset! { #[derive(Debug,Deserialize,Serialize)] pub enum AsymmetricAlgorithms: Algorithms { + #[cfg(feature = "rsa")] Rsa2048, + #[cfg(feature = "rsa")] Rsa4096, P256, @@ -148,7 +150,9 @@ crate::container::enum_subset! { impl AsymmetricAlgorithms { pub fn key_mechanism(self) -> Mechanism { match self { + #[cfg(feature = "rsa")] Self::Rsa2048 => Mechanism::Rsa2048Raw, + #[cfg(feature = "rsa")] Self::Rsa4096 => Mechanism::Rsa4096Raw, Self::P256 => Mechanism::P256, } @@ -159,13 +163,16 @@ impl AsymmetricAlgorithms { match self { P256 => Some(Mechanism::P256), /* P384 | P521 | X25519 | X448 */ + #[allow(unreachable_patterns)] _ => None, } } pub fn sign_mechanism(self) -> Mechanism { match self { + #[cfg(feature = "rsa")] Self::Rsa2048 => Mechanism::Rsa2048Raw, + #[cfg(feature = "rsa")] Self::Rsa4096 => Mechanism::Rsa4096Raw, Self::P256 => Mechanism::P256Prehashed, } @@ -173,14 +180,20 @@ impl AsymmetricAlgorithms { pub fn sign_serialization(self) -> SignatureSerialization { match self { + #[cfg(feature = "rsa")] Self::Rsa2048 | Self::Rsa4096 => SignatureSerialization::Raw, Self::P256 => SignatureSerialization::Asn1Der, } } pub fn is_rsa(self) -> bool { - use AsymmetricAlgorithms::*; - matches!(self, Rsa2048 | Rsa4096) + #[cfg(feature = "rsa")] + return matches!( + self, + AsymmetricAlgorithms::Rsa2048 | AsymmetricAlgorithms::Rsa4096 + ); + #[cfg(not(feature = "rsa"))] + return false; } } diff --git a/src/virt.rs b/src/virt.rs index 5cf735b..d08db71 100644 --- a/src/virt.rs +++ b/src/virt.rs @@ -15,6 +15,7 @@ pub mod dispatch { types::{Bytes, Context, Location}, }; use trussed_auth::{AuthBackend, AuthContext, AuthExtension, MAX_HW_KEY_LEN}; + #[cfg(feature = "rsa")] use trussed_rsa_alloc::SoftwareRsa; use trussed_staging::{streaming::ChunkedExtension, StagingBackend, StagingContext}; @@ -22,6 +23,7 @@ pub mod dispatch { pub const BACKENDS: &[BackendId] = &[ BackendId::Custom(Backend::Staging), BackendId::Custom(Backend::Auth), + #[cfg(feature = "rsa")] BackendId::Custom(Backend::Rsa), BackendId::Core, ]; @@ -29,6 +31,7 @@ pub mod dispatch { #[derive(Debug, Clone, Copy)] pub enum Backend { Auth, + #[cfg(feature = "rsa")] Rsa, Staging, } @@ -119,6 +122,7 @@ pub mod dispatch { request, resources, ), + #[cfg(feature = "rsa")] Backend::Rsa => SoftwareRsa.request(&mut ctx.core, &mut (), request, resources), } } @@ -153,6 +157,7 @@ pub mod dispatch { } Extension::Auth => Err(Error::RequestNotAvailable), } + #[cfg(feature = "rsa")] Backend::Rsa => Err(Error::RequestNotAvailable), } } diff --git a/tests/pivy.rs b/tests/pivy.rs index 98decfd..0f8f50a 100644 --- a/tests/pivy.rs +++ b/tests/pivy.rs @@ -43,17 +43,20 @@ fn generate() { with_vsc(WITH_UUID, test); with_vsc(WITHOUT_UUID, test); - let test = || { - let mut p = spawn("pivy-tool -A 3des -K 010203040506070801020304050607080102030405060708 generate 9A -a rsa2048 -P 123456").unwrap(); - p.expect(Regex( + #[cfg(feature = "rsa")] + { + let test = || { + let mut p = spawn("pivy-tool -A 3des -K 010203040506070801020304050607080102030405060708 generate 9A -a rsa2048 -P 123456").unwrap(); + p.expect(Regex( "ssh-rsa (?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)? PIV_slot_9A@[A-F0-9]{20}", )) .unwrap(); - p.expect(Eof).unwrap(); - assert_eq!(p.wait().unwrap(), WaitStatus::Exited(p.pid(), 0)); - }; - with_vsc(WITH_UUID, test); - with_vsc(WITHOUT_UUID, test); + p.expect(Eof).unwrap(); + assert_eq!(p.wait().unwrap(), WaitStatus::Exited(p.pid(), 0)); + }; + with_vsc(WITH_UUID, test); + with_vsc(WITHOUT_UUID, test); + } } #[test_log::test] @@ -88,6 +91,7 @@ fn ecdh() { #[test_log::test] fn sign() { + #[cfg(feature = "rsa")] let test_rsa = || { let mut p = spawn("pivy-tool -A 3des -K 010203040506070801020304050607080102030405060708 generate 9A -a rsa2048 -P 123456").unwrap(); p.expect(Regex("ssh-rsa (?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)? PIV_slot_9A@[A-F0-9]{20}")).unwrap(); @@ -139,7 +143,13 @@ fn sign() { assert_eq!(p.wait().unwrap().code(), Some(0)); }; - let test = || (test_rsa(), test_p256()); + let test = || { + ( + test_p256(), + #[cfg(feature = "rsa")] + test_rsa(), + ) + }; with_vsc(WITH_UUID, test); with_vsc(WITHOUT_UUID, test);