Skip to content

Commit

Permalink
Add new method for curve initialization that can be better optimized …
Browse files Browse the repository at this point in the history
…by the compiler to remove unused constants
  • Loading branch information
sosthene-nitrokey committed Apr 10, 2024
1 parent 4a63dc1 commit 2cd31b8
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 16 deletions.
50 changes: 34 additions & 16 deletions src/se05x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,56 +188,74 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se05X<Twi, D> {
)
}

pub fn create_and_set_curve(&mut self, curve: EcCurve) -> Result<(), Error> {
/// Prior to being used with the se05x, the curve constants need to be configured for the secure element
///
/// This method configures the secure element to be able to use the given curve.
///
/// The values for the `data` parameter can be found in the [`constants`]() module
pub fn create_and_set_curve_params(
&mut self,
data: &constants::CurveInitializer,
) -> Result<(), Error> {
let response_buf = &mut [0; 2];
let Some(params) = curve.params() else {
// Curve doesn't need configuring params
return Ok(());
};
self.run_command(&CreateEcCurve { curve }, response_buf)?;
self.run_command(&CreateEcCurve { curve: data.curve }, response_buf)?;
self.run_command(
&SetEcCurveParam {
curve,
curve: data.curve,
param: EcCurveParam::ParamA,
value: params.a,
value: data.constants.a,
},
response_buf,
)?;
self.run_command(
&SetEcCurveParam {
curve,
curve: data.curve,
param: EcCurveParam::ParamB,
value: params.b,
value: data.constants.b,
},
response_buf,
)?;
self.run_command(
&SetEcCurveParam {
curve,
curve: data.curve,
param: EcCurveParam::ParamG,
value: params.g,
value: data.constants.g,
},
response_buf,
)?;
self.run_command(
&SetEcCurveParam {
curve,
curve: data.curve,
param: EcCurveParam::ParamN,
value: params.order,
value: data.constants.order,
},
response_buf,
)?;
self.run_command(
&SetEcCurveParam {
curve,
curve: data.curve,
param: EcCurveParam::ParamPrime,
value: params.prime,
value: data.constants.prime,
},
response_buf,
)?;
Ok(())
}

/// Prior to being used with the se05x, the curve constants need to be configured for the secure element
///
/// This method configures the secure element to be able to use the given curve.
///
/// Since the commands are hard-coded, the constants can be quite large. If only a subset of the curves are used,
/// it is recommended to instead use [`create_and_set_curve_params`]()
pub fn create_and_set_curve(&mut self, curve: EcCurve) -> Result<(), Error> {
let Some(constants) = curve.params() else {
// Curve doesn't need configuring params
return Ok(());
};
self.create_and_set_curve_params(&constants::CurveInitializer { constants, curve })
}

#[cfg(feature = "aes-session")]
pub fn authenticate_aes128_session<R: rand::CryptoRng + rand::RngCore>(
&mut self,
Expand Down
76 changes: 76 additions & 0 deletions src/se05x/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

use hex_literal::hex;

use super::EcCurve;

/// Curve constants as sent to `SetCurveParameter`
pub struct CurveConstants {
pub prime: &'static [u8],
Expand All @@ -17,6 +19,80 @@ pub struct CurveConstants {
pub order: &'static [u8],
}

pub struct CurveInitializer {
pub constants: CurveConstants,
pub curve: EcCurve,
}

pub const PRIME192V1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::NistP192,
constants: PRIME192V1,
};
pub const SECP224R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::NistP224,
constants: SECP224R1,
};
pub const PRIME256V1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::NistP256,
constants: PRIME256V1,
};
pub const SECP384R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::NistP384,
constants: SECP384R1,
};
pub const SECP521R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::NistP521,
constants: SECP521R1,
};
pub const BRAINPOOL_P160R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool160,
constants: BRAINPOOL_P160R1,
};
pub const BRAINPOOL_P192R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool192,
constants: BRAINPOOL_P192R1,
};
pub const BRAINPOOL_P224R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool224,
constants: BRAINPOOL_P224R1,
};
pub const BRAINPOOL_P256R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool256,
constants: BRAINPOOL_P256R1,
};
pub const BRAINPOOL_P320R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool320,
constants: BRAINPOOL_P320R1,
};
pub const BRAINPOOL_P384R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool384,
constants: BRAINPOOL_P384R1,
};
pub const BRAINPOOL_P512R1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Brainpool512,
constants: BRAINPOOL_P512R1,
};
pub const SECP160K1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Secp160k1,
constants: SECP160K1,
};
pub const SECP192K1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Secp192k1,
constants: SECP192K1,
};
pub const SECP224K1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Secp224k1,
constants: SECP224K1,
};
pub const SECP256K1_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::Secp256k1,
constants: SECP256K1,
};
pub const TPM_BN_P256_INITIALIZER: CurveInitializer = CurveInitializer {
curve: EcCurve::TpmEccBnP256,
constants: TPM_BN_P256,
};

/// secp112r1 : SECG/WTLS curve over a 112 bit prime field
pub const SECP112R1: CurveConstants = CurveConstants {
prime: &hex!("DB7C2ABF62E35E668076BEAD208B"),
Expand Down

0 comments on commit 2cd31b8

Please sign in to comment.