Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor and Centralize ECC helpers #116

Merged
merged 6 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ jobs:
cargo build -vv --features fips
fi
if [ "${{ matrix.name }}" = "ossl3" ]; then
cargo build -vv
cargo build -vv --features standard
fi
if [ "${{ matrix.name }}" = "release" ]; then
cargo build -vv --release
cargo build -vv --release --features standard
fi
if [ "${{ matrix.name }}" = "dynamic" ]; then
cargo build -vv --release --features dynamic
cargo build -vv --release --features standard,dynamic
fi

- name: Test
Expand All @@ -96,16 +96,16 @@ jobs:
cargo test --features fips
fi
if [ "${{ matrix.name }}" = "ossl3" ]; then
cargo test
cargo test --features standard
fi
if [ "${{ matrix.name }}" = "release" ]; then
cargo test --release
cargo test --release --features standard
fi
if [ "${{ matrix.name }}" = "dynamic" ]; then
cargo test --release --features dynamic
cargo test --release --features standard,dynamic
fi
if [ "${{ matrix.name }}" = "i686" ]; then
cargo test --target i686-unknown-linux-gnu --features dynamic
cargo test --target i686-unknown-linux-gnu --features standard,dynamic
fi

- uses: actions/upload-artifact@v3
Expand Down
11 changes: 5 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ zeroize = "1.6.0"

[features]
aes = []
ecc = []
ecdsa = []
ecdh = []
eddsa = []
ec_montgomery = []
hash = []
Expand All @@ -66,13 +67,11 @@ memorydb = []
sqlitedb = ["dep:rusqlite"]

# these are always required, so easier to specify this way
basic = [ "aes", "hmac", "pbkdf2", "sqlitedb" ]
default = [ "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"]
standard = [ "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", "ecdsa", "ecdh", "hash", "hkdf", "rsa", "sp800_108", "sshkdf", "tlskdf"]

dynamic = [ ] # Builds against system libcrypto.so

Expand Down
12 changes: 6 additions & 6 deletions packaging/kryoptic.spec
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ A PKCS #11 software token written in Rust.}
%cargo_prep

%generate_buildrequires
%cargo_generate_buildrequires -f dynamic
%cargo_generate_buildrequires -f standard,dynamic

%build
CONFDIR=%{_sysconfdir} %cargo_build -f dynamic
%{cargo_license_summary -f dynamic}
%{cargo_license -f dynamic} > LICENSE.dependencies
CONFDIR=%{_sysconfdir} %cargo_build -f standard,dynamic
%{cargo_license_summary -f standard,dynamic}
%{cargo_license -f standard,dynamic} > LICENSE.dependencies

%install
%cargo_install -f dynamic
%cargo_install -f standard,dynamic
install -Dp target/rpm/libkryoptic_pkcs11.so $RPM_BUILD_ROOT/%{_libdir}/libkryoptic_pkcs11.so

%if %{with check}
%check
%cargo_test -f dynamic
%cargo_test -f standard,dynamic
%endif

%files
Expand Down
2 changes: 1 addition & 1 deletion src/ecdh.rs → src/ec/ecdh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
131 changes: 4 additions & 127 deletions src/ecc.rs → src/ec/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,127 +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;

// ASN.1 encoding of the OID
const OID_SECP256R1: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 10045, 3, 1, 7);
const OID_SECP384R1: asn1::ObjectIdentifier = asn1::oid!(1, 3, 132, 0, 34);
const OID_SECP521R1: asn1::ObjectIdentifier = asn1::oid!(1, 3, 132, 0, 35);

// ASN.1 encoding of the curve name
const STRING_SECP256R1: &[u8] = &[
0x13, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x65, 0x32, 0x35, 0x36, 0x76, 0x31,
];
const STRING_SECP384R1: &[u8] = &[
0x13, 0x09, 0x73, 0x65, 0x63, 0x70, 0x33, 0x38, 0x34, 0x72, 0x31,
];
const STRING_SECP521R1: &[u8] = &[
0x13, 0x09, 0x73, 0x65, 0x63, 0x70, 0x35, 0x32, 0x31, 0x72, 0x31,
];

pub const NAME_SECP256R1: &str = "prime256v1";
pub const NAME_SECP384R1: &str = "secp384r1";
pub const NAME_SECP521R1: &str = "secp521r1";

const BITS_SECP256R1: usize = 256;
const BITS_SECP384R1: usize = 384;
const BITS_SECP521R1: usize = 521;

pub fn oid_to_curve_name(oid: asn1::ObjectIdentifier) -> Result<&'static str> {
match oid {
OID_SECP256R1 => Ok(NAME_SECP256R1),
OID_SECP384R1 => Ok(NAME_SECP384R1),
OID_SECP521R1 => Ok(NAME_SECP521R1),
_ => Err(CKR_GENERAL_ERROR)?,
}
}

#[cfg(test)]
pub fn curve_name_to_ec_params(name: &'static str) -> Result<&'static [u8]> {
match name {
NAME_SECP256R1 => Ok(STRING_SECP256R1),
NAME_SECP384R1 => Ok(STRING_SECP384R1),
NAME_SECP521R1 => Ok(STRING_SECP521R1),
_ => Err(CKR_GENERAL_ERROR)?,
}
}

#[cfg(test)]
pub fn name_to_bits(name: &'static str) -> Result<usize> {
match name {
NAME_SECP256R1 => Ok(BITS_SECP256R1),
NAME_SECP384R1 => Ok(BITS_SECP384R1),
NAME_SECP521R1 => Ok(BITS_SECP521R1),
_ => Err(CKR_GENERAL_ERROR)?,
}
}

pub fn oid_to_bits(oid: asn1::ObjectIdentifier) -> Result<usize> {
match oid {
OID_SECP256R1 => Ok(BITS_SECP256R1),
OID_SECP384R1 => Ok(BITS_SECP384R1),
OID_SECP521R1 => Ok(BITS_SECP521R1),
_ => Err(CKR_GENERAL_ERROR)?,
}
}

pub fn curve_name_to_bits(name: asn1::PrintableString) -> Result<usize> {
let asn1_name = match asn1::write_single(&name) {
Ok(r) => r,
Err(_) => return Err(CKR_GENERAL_ERROR)?,
};
match asn1_name.as_slice() {
STRING_SECP256R1 => Ok(BITS_SECP256R1),
STRING_SECP384R1 => Ok(BITS_SECP384R1),
STRING_SECP521R1 => Ok(BITS_SECP521R1),
_ => Err(CKR_GENERAL_ERROR)?,
}
}

pub fn curve_name_to_oid(
name: asn1::PrintableString,
) -> Result<asn1::ObjectIdentifier> {
let asn1_name = match asn1::write_single(&name) {
Ok(r) => r,
Err(_) => return Err(CKR_GENERAL_ERROR)?,
};
Ok(match asn1_name.as_slice() {
STRING_SECP256R1 => OID_SECP256R1,
STRING_SECP384R1 => OID_SECP384R1,
STRING_SECP521R1 => OID_SECP521R1,
_ => return Err(CKR_GENERAL_ERROR)?,
})
}

#[cfg(feature = "fips")]
pub fn ec_key_curve_size(key: &Object) -> Result<usize> {
let x = match key.get_attr_as_bytes(CKA_EC_PARAMS) {
Ok(b) => b,
Err(_) => return Err(CKR_GENERAL_ERROR)?,
};
match asn1::parse_single::<ECParameters>(x) {
Ok(a) => match a {
ECParameters::OId(o) => oid_to_bits(o),
ECParameters::CurveName(c) => curve_name_to_bits(c),
_ => return Err(CKR_GENERAL_ERROR)?,
},
Err(_) => return Err(CKR_GENERAL_ERROR)?,
}
}
pub const MIN_EC_SIZE_BITS: usize = BITS_SECP256R1;
pub const MAX_EC_SIZE_BITS: usize = BITS_SECP521R1;

#[derive(Debug)]
pub struct ECCPubFactory {
Expand Down Expand Up @@ -234,21 +126,6 @@ impl ObjectFactory for ECCPrivFactory {
}
}

fn get_oid_from_obj(key: &Object) -> Result<asn1::ObjectIdentifier> {
let x = match key.get_attr_as_bytes(CKA_EC_PARAMS) {
Ok(b) => b,
Err(_) => return Err(CKR_GENERAL_ERROR)?,
};
match asn1::parse_single::<ECParameters>(x) {
Ok(a) => match a {
ECParameters::OId(o) => Ok(o),
ECParameters::CurveName(c) => curve_name_to_oid(c),
_ => return Err(CKR_GENERAL_ERROR)?,
},
Err(_) => return Err(CKR_GENERAL_ERROR)?,
}
}

impl CommonKeyFactory for ECCPrivFactory {}

impl PrivKeyFactory for ECCPrivFactory {
Expand Down
2 changes: 1 addition & 1 deletion src/eddsa.rs → src/ec/eddsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down
Loading