From fe36f0f6fcf2f3d86d2eeb19de05a7ad6284a0bd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 19 Nov 2024 23:27:33 -0500 Subject: [PATCH] Reorganize EC code to its own directory Also fixes feature detection to be more straightforward Signed-off-by: Simo Sorce --- .github/workflows/build.yml | 4 +-- Cargo.toml | 7 ++-- src/{ => ec}/ecdh.rs | 2 +- src/{ecc.rs => ec/ecdsa.rs} | 9 +++-- src/{ => ec}/eddsa.rs | 2 +- src/{ecc_misc.rs => ec/mod.rs} | 20 +++++++++-- src/{ec_montgomery.rs => ec/montgomery.rs} | 5 +-- src/enabled.rs | 38 +++++++++----------- src/fips/indicators.rs | 2 +- src/ossl/common.rs | 18 +++++----- src/ossl/ecdh.rs | 6 ++-- src/ossl/{ecc.rs => ecdsa.rs} | 4 +-- src/ossl/eddsa.rs | 6 +--- src/ossl/mod.rs | 12 +++---- src/ossl/{ec_montgomery.rs => montgomery.rs} | 5 +-- src/tests/ecdh_vectors.rs | 10 +++--- src/tests/keys.rs | 2 +- src/tests/mod.rs | 10 +++--- src/tests/signatures.rs | 2 +- 19 files changed, 82 insertions(+), 82 deletions(-) rename src/{ => ec}/ecdh.rs (96%) rename src/{ecc.rs => ec/ecdsa.rs} (98%) rename src/{ => ec}/eddsa.rs (99%) rename src/{ecc_misc.rs => ec/mod.rs} (95%) rename src/{ec_montgomery.rs => ec/montgomery.rs} (97%) rename src/ossl/{ecc.rs => ecdsa.rs} (99%) rename src/ossl/{ec_montgomery.rs => montgomery.rs} (96%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e55dcf35..629ebeb1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,7 +78,7 @@ jobs: - name: Build run: | if [ "${{ matrix.name }}" = "fips" ]; then - cargo build -vv --features fips + cargo build -vv --no-default-features --features fips fi if [ "${{ matrix.name }}" = "ossl3" ]; then cargo build -vv @@ -93,7 +93,7 @@ jobs: - name: Test run: | if [ "${{ matrix.name }}" = "fips" ]; then - cargo test --features fips + cargo test --no-default-features --features fips fi if [ "${{ matrix.name }}" = "ossl3" ]; then cargo test diff --git a/Cargo.toml b/Cargo.toml index fe62d4ef..c38b6d87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,8 @@ zeroize = "1.6.0" [features] aes = [] -ecc = [] +ecdsa = [] +ecdh = [] eddsa = [] ec_montgomery = [] hash = [] @@ -70,9 +71,9 @@ basic = [ "aes", "hmac", "pbkdf2", "sqlitedb" ] #select everything by default # Use --no-default-features --features basic, xxx for custom selections -default = [ "basic", "ecc", "ec_montgomery", "eddsa", "hash", "hkdf", "rsa", "sp800_108", "sshkdf", "tlskdf"] +default = [ "basic", "ecdsa", "ec_montgomery", "eddsa", "ecdh", "hash", "hkdf", "rsa", "sp800_108", "sshkdf", "tlskdf"] -fips = [ "rusqlite/bundled", "basic", "ecc", "hash", "hkdf", "rsa", "sp800_108", "sshkdf", "tlskdf"] +fips = [ "rusqlite/bundled", "basic", "ecdsa", "ecdh", "hash", "hkdf", "rsa", "sp800_108", "sshkdf", "tlskdf"] dynamic = [ ] # Builds against system libcrypto.so diff --git a/src/ecdh.rs b/src/ec/ecdh.rs similarity index 96% rename from src/ecdh.rs rename to src/ec/ecdh.rs index bcdeee2f..3980afe9 100644 --- a/src/ecdh.rs +++ b/src/ec/ecdh.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; -use crate::ecc::*; +use crate::ec::ecdsa::{MAX_EC_SIZE_BITS, MIN_EC_SIZE_BITS}; use crate::error::Result; use crate::interface::*; use crate::mechanism::{Mechanism, Mechanisms, Operation}; diff --git a/src/ecc.rs b/src/ec/ecdsa.rs similarity index 98% rename from src/ecc.rs rename to src/ec/ecdsa.rs index 9ffca012..a45ea7a5 100644 --- a/src/ecc.rs +++ b/src/ec/ecdsa.rs @@ -4,20 +4,19 @@ use std::fmt::Debug; use crate::attribute::Attribute; -use crate::ecc_misc::*; +use crate::ec::*; use crate::error::Result; -use crate::interface::*; use crate::kasn1::PrivateKeyInfo; use crate::mechanism::*; use crate::object::*; -use crate::ossl::ecc::EccOperation; +use crate::ossl::ecdsa::EccOperation; use crate::{attr_element, bytes_attr_not_empty}; use asn1; use once_cell::sync::Lazy; -pub const MIN_EC_SIZE_BITS: usize = 256; -pub const MAX_EC_SIZE_BITS: usize = 521; +pub const MIN_EC_SIZE_BITS: usize = BITS_SECP256R1; +pub const MAX_EC_SIZE_BITS: usize = BITS_SECP521R1; #[derive(Debug)] pub struct ECCPubFactory { diff --git a/src/eddsa.rs b/src/ec/eddsa.rs similarity index 99% rename from src/eddsa.rs rename to src/ec/eddsa.rs index 12dd9c23..986bfa89 100644 --- a/src/eddsa.rs +++ b/src/ec/eddsa.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use crate::attribute::Attribute; -use crate::ecc_misc::*; +use crate::ec::{ec_key_check_import, BITS_ED25519, BITS_ED448}; use crate::error::Result; use crate::interface::*; use crate::mechanism::*; diff --git a/src/ecc_misc.rs b/src/ec/mod.rs similarity index 95% rename from src/ecc_misc.rs rename to src/ec/mod.rs index 92f20738..e19c6d15 100644 --- a/src/ecc_misc.rs +++ b/src/ec/mod.rs @@ -9,6 +9,18 @@ use crate::object::Object; use asn1; +#[cfg(feature = "ecdh")] +pub mod ecdh; + +#[cfg(feature = "ecdsa")] +pub mod ecdsa; + +#[cfg(feature = "eddsa")] +pub mod eddsa; + +#[cfg(feature = "ec_montgomery")] +pub mod montgomery; + type Version = u64; #[derive(asn1::Asn1Read, asn1::Asn1Write)] @@ -48,9 +60,10 @@ pub fn ec_key_check_import(obj: &mut Object) -> Result<()> { } // Bit sized for curves -const BITS_SECP256R1: usize = 256; -const BITS_SECP384R1: usize = 384; -const BITS_SECP521R1: usize = 521; +pub const BITS_SECP256R1: usize = 256; +#[allow(dead_code)] +pub const BITS_SECP384R1: usize = 384; +pub const BITS_SECP521R1: usize = 521; pub const BITS_ED25519: usize = 256; pub const BITS_ED448: usize = 448; pub const BITS_X25519: usize = 256; @@ -99,6 +112,7 @@ const NAME_X448: &[u8] = b"X448\0"; pub static EC_NAME: &[u8; 3] = b"EC\0"; +#[cfg(any(test, feature = "fips"))] pub fn curve_name_to_bits(name: &[u8]) -> Result { match name { NAME_SECP256R1 => Ok(BITS_SECP256R1), diff --git a/src/ec_montgomery.rs b/src/ec/montgomery.rs similarity index 97% rename from src/ec_montgomery.rs rename to src/ec/montgomery.rs index 3479c5b2..e609978c 100644 --- a/src/ec_montgomery.rs +++ b/src/ec/montgomery.rs @@ -4,12 +4,13 @@ use std::fmt::Debug; use crate::attribute::Attribute; -use crate::ecc_misc::*; +use crate::ec::montgomery::montgomery::ECMontgomeryOperation; +use crate::ec::{ec_key_check_import, BITS_X25519, BITS_X448}; use crate::error::Result; use crate::interface::*; use crate::mechanism::*; use crate::object::*; -use crate::ossl::ec_montgomery::*; +use crate::ossl::montgomery; use crate::{attr_element, bytes_attr_not_empty}; use once_cell::sync::Lazy; diff --git a/src/enabled.rs b/src/enabled.rs index c316866c..538b322f 100644 --- a/src/enabled.rs +++ b/src/enabled.rs @@ -4,23 +4,17 @@ #[cfg(all(feature = "dynamic", feature = "fips"))] compile_error!("Feature 'dynamic' and 'fips' are mutually exclusive and cannot be enabled together"); +#[cfg(all( + feature = "ecdh", + not(any(feature = "ecdsa", feature = "ec_montgomery")) +))] +compile_error!("Feature 'ecdh' requires either 'ecdsa' or 'ec_montgomery'"); + #[cfg(feature = "aes")] mod aes; -#[cfg(feature = "ecc")] -mod ecc; - -#[cfg(any(feature = "ecc", feature = "eddsa"))] -mod ecc_misc; - -#[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] -mod ec_montgomery; - -#[cfg(any(feature = "ec_montgomery", feature = "ecc"))] -mod ecdh; - -#[cfg(all(feature = "eddsa", not(feature = "fips")))] -mod eddsa; +#[cfg(any(feature = "ecdsa", feature = "eddsa", feature = "ec_montgomery"))] +mod ec; #[cfg(feature = "hash")] mod hash; @@ -55,17 +49,17 @@ pub fn register_all(mechs: &mut Mechanisms, ot: &mut ObjectFactories) { #[cfg(feature = "aes")] aes::register(mechs, ot); - #[cfg(feature = "ecc")] - ecc::register(mechs, ot); + #[cfg(feature = "ecdsa")] + ec::ecdsa::register(mechs, ot); - #[cfg(any(feature = "ec_montgomery", feature = "ecc"))] - ecdh::register(mechs, ot); + #[cfg(feature = "ecdh")] + ec::ecdh::register(mechs, ot); - #[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] - ec_montgomery::register(mechs, ot); + #[cfg(feature = "ec_montgomery")] + ec::montgomery::register(mechs, ot); - #[cfg(all(feature = "eddsa", not(feature = "fips")))] - eddsa::register(mechs, ot); + #[cfg(feature = "eddsa")] + ec::eddsa::register(mechs, ot); #[cfg(feature = "hash")] hash::register(mechs, ot); diff --git a/src/fips/indicators.rs b/src/fips/indicators.rs index ba1d85ec..ddcf4b4c 100644 --- a/src/fips/indicators.rs +++ b/src/fips/indicators.rs @@ -3,7 +3,7 @@ use crate::attr_element; use crate::attribute::Attribute; -use crate::ecc_misc::*; +use crate::ec::{curve_name_to_bits, get_ossl_name_from_obj}; use crate::error::Result; use crate::interface::*; use crate::object::{OAFlags, Object, ObjectAttr, ObjectFactory}; diff --git a/src/ossl/common.rs b/src/ossl/common.rs index 69b1df57..a6bdd1eb 100644 --- a/src/ossl/common.rs +++ b/src/ossl/common.rs @@ -11,12 +11,12 @@ use crate::ossl::bindings::*; use crate::ossl::get_libctx; use crate::{byte_ptr, void_ptr}; -#[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] -use crate::ossl::ec_montgomery as ecm; -#[cfg(feature = "ecc")] -use crate::ossl::ecc; -#[cfg(all(feature = "eddsa", not(feature = "fips")))] +#[cfg(feature = "ecdsa")] +use crate::ossl::ecdsa; +#[cfg(feature = "eddsa")] use crate::ossl::eddsa; +#[cfg(feature = "ec_montgomery")] +use crate::ossl::montgomery as ecm; #[cfg(feature = "rsa")] use crate::ossl::rsa; @@ -283,11 +283,11 @@ impl EvpPkey { }; let key_type = obj.get_attr_as_ulong(CKA_KEY_TYPE)?; let (name, params) = match key_type { - #[cfg(feature = "ecc")] - CKK_EC => ecc::ecc_object_to_params(obj, class)?, - #[cfg(all(feature = "eddsa", not(feature = "fips")))] + #[cfg(feature = "ecdsa")] + CKK_EC => ecdsa::ecc_object_to_params(obj, class)?, + #[cfg(feature = "eddsa")] CKK_EC_EDWARDS => eddsa::eddsa_object_to_params(obj, class)?, - #[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] + #[cfg(feature = "ec_montgomery")] CKK_EC_MONTGOMERY => ecm::ecm_object_to_params(obj, class)?, #[cfg(feature = "rsa")] CKK_RSA => rsa::rsa_object_to_params(obj, class)?, diff --git a/src/ossl/ecdh.rs b/src/ossl/ecdh.rs index 74b352ff..4629f5c4 100644 --- a/src/ossl/ecdh.rs +++ b/src/ossl/ecdh.rs @@ -6,7 +6,7 @@ use std::borrow::Cow; use crate::attribute::CkAttrs; use crate::bytes_to_vec; -use crate::ecc_misc::*; +use crate::ec::{get_ossl_name_from_obj, EC_NAME}; use crate::error::Result; use crate::interface::*; use crate::mechanism::*; @@ -34,7 +34,7 @@ fn make_peer_key(key: &Object, ec_point: &Vec) -> Result { params.zeroize = true; let name = match key.get_attr_as_ulong(CKA_KEY_TYPE)? { - #[cfg(feature = "ecc")] + #[cfg(feature = "ecdsa")] CKK_EC => { params.add_const_c_string( name_as_char(OSSL_PKEY_PARAM_GROUP_NAME), @@ -42,7 +42,7 @@ fn make_peer_key(key: &Object, ec_point: &Vec) -> Result { )?; EC_NAME } - #[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] + #[cfg(feature = "ec_montgomery")] CKK_EC_MONTGOMERY => get_ossl_name_from_obj(key)?, _ => return Err(CKR_KEY_TYPE_INCONSISTENT)?, }; diff --git a/src/ossl/ecc.rs b/src/ossl/ecdsa.rs similarity index 99% rename from src/ossl/ecc.rs rename to src/ossl/ecdsa.rs index 81f7a2fd..4c4211c7 100644 --- a/src/ossl/ecc.rs +++ b/src/ossl/ecdsa.rs @@ -4,8 +4,8 @@ use core::ffi::{c_char, c_int}; use crate::attribute::Attribute; -use crate::ecc::*; -use crate::ecc_misc::*; +use crate::ec::ecdsa::*; +use crate::ec::{get_ec_point_from_obj, get_ossl_name_from_obj, EC_NAME}; use crate::error::Result; use crate::interface::*; use crate::kasn1::DerEncBigUint; diff --git a/src/ossl/eddsa.rs b/src/ossl/eddsa.rs index 606ec8a2..29f429e5 100644 --- a/src/ossl/eddsa.rs +++ b/src/ossl/eddsa.rs @@ -4,7 +4,7 @@ use std::ffi::{c_char, c_int}; use crate::attribute::Attribute; -use crate::ecc_misc::*; +use crate::ec::{get_ec_point_from_obj, get_ossl_name_from_obj}; use crate::error::Result; use crate::interface::*; use crate::mechanism::*; @@ -19,10 +19,6 @@ use crate::ossl::fips::*; #[cfg(not(feature = "fips"))] use crate::ossl::get_libctx; -/* confusingly enough, this is not EC for FIPS-level operations */ -#[cfg(feature = "fips")] -static ECDSA_NAME: &[u8; 6] = b"EDDSA\0"; - pub const OUTLEN_ED25519: usize = 64; pub const OUTLEN_ED448: usize = 114; diff --git a/src/ossl/mod.rs b/src/ossl/mod.rs index e8058125..a87a020f 100644 --- a/src/ossl/mod.rs +++ b/src/ossl/mod.rs @@ -33,16 +33,16 @@ pub mod common; pub mod drbg; // the derive code for both ECDSA and Montgomery curves -#[cfg(any(feature = "ecc", feature = "ec_montgomery"))] +#[cfg(feature = "ecdh")] pub mod ecdh; -#[cfg(feature = "ecc")] -pub mod ecc; +#[cfg(feature = "ecdsa")] +pub mod ecdsa; -#[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] -pub mod ec_montgomery; +#[cfg(feature = "ec_montgomery")] +pub mod montgomery; -#[cfg(all(feature = "eddsa", not(feature = "fips")))] +#[cfg(feature = "eddsa")] pub mod eddsa; #[cfg(feature = "fips")] diff --git a/src/ossl/ec_montgomery.rs b/src/ossl/montgomery.rs similarity index 96% rename from src/ossl/ec_montgomery.rs rename to src/ossl/montgomery.rs index 1b04f647..221a19f5 100644 --- a/src/ossl/ec_montgomery.rs +++ b/src/ossl/montgomery.rs @@ -4,16 +4,13 @@ use std::ffi::{c_char, c_int}; use crate::attribute::Attribute; -use crate::ecc_misc::*; +use crate::ec::{get_ec_point_from_obj, get_ossl_name_from_obj}; use crate::error::Result; use crate::interface::*; use crate::object::Object; use crate::ossl::bindings::*; use crate::ossl::common::*; -#[cfg(feature = "fips")] -use crate::ossl::fips::*; - pub fn ecm_object_to_params( key: &Object, class: CK_OBJECT_CLASS, diff --git a/src/tests/ecdh_vectors.rs b/src/tests/ecdh_vectors.rs index 24a441b0..896864e6 100644 --- a/src/tests/ecdh_vectors.rs +++ b/src/tests/ecdh_vectors.rs @@ -5,7 +5,7 @@ use std::io; use std::io::BufRead; use std::str::from_utf8; -use crate::ecc_misc; +use crate::ec; use crate::tests::*; use serial_test::parallel; @@ -75,9 +75,7 @@ fn parse_ecdh_vector(filename: &str) -> Vec { tag = Some(line.clone()); curve = None; } else if line.starts_with(kw) { - curve = ecc_misc::map_curve_name( - &line[kw.len()..line.len() - 1], - ); + curve = ec::map_curve_name(&line[kw.len()..line.len() - 1]); if curve != None { println!( " : {} Matched", @@ -118,7 +116,7 @@ fn parse_ecdh_vector(filename: &str) -> Vec { from_utf8(curve_name).unwrap() ); let ec_params = - match ecc_misc::curve_name_to_ec_params(curve_name) { + match ec::curve_name_to_ec_params(curve_name) { Ok(p) => p, Err(_) => continue, /* skip unsupported */ }; @@ -196,7 +194,7 @@ fn test_to_ecc_point(key: &EccKey, curve_name: &'static [u8]) -> Vec { ec_point.push(0x04); /* The P-521 curve points are heavily zero padded so we need to make sure they are well * formatted for OpenSSL -- to the field length boundary */ - let field_len = match ecc_misc::curve_name_to_bits(curve_name) { + let field_len = match ec::curve_name_to_bits(curve_name) { Ok(l) => l, Err(_) => panic!("Unknown curve given"), }; diff --git a/src/tests/keys.rs b/src/tests/keys.rs index cc9fdd2a..bd8cd238 100644 --- a/src/tests/keys.rs +++ b/src/tests/keys.rs @@ -340,7 +340,7 @@ fn test_rsa_key() { testtokn.finalize(); } -#[cfg(feature = "ecc")] +#[cfg(feature = "ecdsa")] #[test] #[parallel] fn test_ecc_key() { diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 29e3a146..888980b5 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -250,19 +250,19 @@ mod rsa; mod session; -#[cfg(feature = "ecc")] +#[cfg(feature = "ecdsa")] mod ecc; -#[cfg(all(feature = "ec_montgomery", not(feature = "fips")))] +#[cfg(feature = "ec_montgomery")] mod ec_montgomery; -#[cfg(feature = "ecc")] +#[cfg(feature = "ecdh")] mod ecdh; -#[cfg(feature = "ecc")] +#[cfg(feature = "ecdh")] mod ecdh_vectors; -#[cfg(all(feature = "eddsa", not(feature = "fips")))] +#[cfg(feature = "eddsa")] mod eddsa; #[cfg(feature = "hash")] diff --git a/src/tests/signatures.rs b/src/tests/signatures.rs index 73b4b001..447ce3a7 100644 --- a/src/tests/signatures.rs +++ b/src/tests/signatures.rs @@ -126,7 +126,7 @@ fn test_rsa_signatures() { testtokn.finalize(); } -#[cfg(feature = "ecc")] +#[cfg(feature = "ecdsa")] #[test] #[parallel] fn test_ecc_signatures() {