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

Add support for secp256k1 #213

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ log-error = []

[patch.crates-io]
p256-cortex-m4 = { git = "https://github.com/Nitrokey/p256-cortex-m4", tag = "v0.1.0-alpha.6-nitrokey-1" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "046478b7a4f6e2315acf9112d98308379c2e3eee" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "316a96f66335eab8b4195e900cda1a768ed1b99e" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", rev = "c030b82ad3441f337af09afe3a69e8a6da5785ea"}
trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "chunked-v0.1.0" }
trussed-manage = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "manage-v0.1.0" }
Expand Down
4 changes: 4 additions & 0 deletions src/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ bitflags! {
const BRAINPOOL_P384R1 = 1 << 9;
/// BRAINPOOL_P521R1 Brainpool curve
const BRAINPOOL_P512R1 = 1 << 10;
/// SECP256k1 (bitcoin curve)
const SECP256K1 = 1 << 11;
}
}

Expand All @@ -202,6 +204,7 @@ impl AllowedAlgorithms {
Self::RSA_4096,
Self::X_25519,
Self::ED_25519,
Self::SECP256K1,
]
.into_iter()
.fold(Self::empty(), |acc, value| acc | value)
Expand All @@ -219,6 +222,7 @@ impl AllowedAlgorithms {
Self::RSA_4096,
Self::X_25519,
Self::ED_25519,
Self::SECP256K1,
]
.into_iter()
.fold(Self::empty(), |acc, value| acc | value)
Expand Down
22 changes: 21 additions & 1 deletion src/command/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ fn serialize_pub<const R: usize, T: crate::card::Client>(
| CurveAlgo::EcDsaBrainpoolP384R1
| CurveAlgo::EcDhBrainpoolP384R1
| CurveAlgo::EcDsaBrainpoolP512R1
| CurveAlgo::EcDhBrainpoolP512R1 => serialize_nist_curve(ctx, public_key),
| CurveAlgo::EcDhBrainpoolP512R1
| CurveAlgo::EcDhSecp256k1
| CurveAlgo::EcDsaSecp256k1 => serialize_nist_curve(ctx, public_key),
CurveAlgo::X255 | CurveAlgo::Ed255 => serialize_25519(ctx, public_key),
}
}
Expand Down Expand Up @@ -66,6 +68,9 @@ pub fn sign<const R: usize, T: crate::card::Client>(
SignatureAlgorithm::EcDsaBrainpoolP512R1 => {
gen_ec_key(ctx.lend(), KeyType::Sign, CurveAlgo::EcDsaBrainpoolP512R1)
}
SignatureAlgorithm::EcDsaSecp256k1 => {
gen_ec_key(ctx.lend(), KeyType::Sign, CurveAlgo::EcDsaSecp256k1)
}
SignatureAlgorithm::Rsa2048 => {
gen_rsa_key(ctx.lend(), KeyType::Sign, Mechanism::Rsa2048Pkcs1v15)
}
Expand Down Expand Up @@ -101,6 +106,9 @@ pub fn dec<const R: usize, T: crate::card::Client>(
DecryptionAlgorithm::EcDhBrainpoolP512R1 => {
gen_ec_key(ctx.lend(), KeyType::Dec, CurveAlgo::EcDhBrainpoolP512R1)
}
DecryptionAlgorithm::EcDhSecp256k1 => {
gen_ec_key(ctx.lend(), KeyType::Dec, CurveAlgo::EcDhSecp256k1)
}
DecryptionAlgorithm::Rsa2048 => {
gen_rsa_key(ctx.lend(), KeyType::Dec, Mechanism::Rsa2048Pkcs1v15)
}
Expand Down Expand Up @@ -142,6 +150,9 @@ pub fn aut<const R: usize, T: crate::card::Client>(
AuthenticationAlgorithm::EcDsaBrainpoolP512R1 => {
gen_ec_key(ctx.lend(), KeyType::Aut, CurveAlgo::EcDsaBrainpoolP512R1)
}
AuthenticationAlgorithm::EcDsaSecp256k1 => {
gen_ec_key(ctx.lend(), KeyType::Aut, CurveAlgo::EcDsaSecp256k1)
}
AuthenticationAlgorithm::Rsa2048 => {
gen_rsa_key(ctx.lend(), KeyType::Aut, Mechanism::Rsa2048Pkcs1v15)
}
Expand Down Expand Up @@ -263,6 +274,9 @@ pub fn read_sign<const R: usize, T: crate::card::Client>(
SignatureAlgorithm::EcDsaBrainpoolP512R1 => {
read_ec_key(ctx.lend(), key_id, CurveAlgo::EcDsaBrainpoolP512R1)
}
SignatureAlgorithm::EcDsaSecp256k1 => {
read_ec_key(ctx.lend(), key_id, CurveAlgo::EcDsaSecp256k1)
}
SignatureAlgorithm::Rsa2048 => read_rsa_key(ctx.lend(), key_id, Mechanism::Rsa2048Pkcs1v15),
SignatureAlgorithm::Rsa3072 => read_rsa_key(ctx.lend(), key_id, Mechanism::Rsa3072Pkcs1v15),
SignatureAlgorithm::Rsa4096 => read_rsa_key(ctx.lend(), key_id, Mechanism::Rsa4096Pkcs1v15),
Expand Down Expand Up @@ -293,6 +307,9 @@ pub fn read_dec<const R: usize, T: crate::card::Client>(
DecryptionAlgorithm::EcDhBrainpoolP512R1 => {
read_ec_key(ctx.lend(), key_id, CurveAlgo::EcDhBrainpoolP512R1)
}
DecryptionAlgorithm::EcDhSecp256k1 => {
read_ec_key(ctx.lend(), key_id, CurveAlgo::EcDhSecp256k1)
}
DecryptionAlgorithm::Rsa2048 => {
read_rsa_key(ctx.lend(), key_id, Mechanism::Rsa2048Pkcs1v15)
}
Expand Down Expand Up @@ -329,6 +346,9 @@ pub fn read_aut<const R: usize, T: crate::card::Client>(
AuthenticationAlgorithm::EcDsaBrainpoolP512R1 => {
read_ec_key(ctx.lend(), key_id, CurveAlgo::EcDsaBrainpoolP512R1)
}
AuthenticationAlgorithm::EcDsaSecp256k1 => {
read_ec_key(ctx.lend(), key_id, CurveAlgo::EcDsaSecp256k1)
}
AuthenticationAlgorithm::Rsa2048 => {
read_rsa_key(ctx.lend(), key_id, Mechanism::Rsa2048Pkcs1v15)
}
Expand Down
3 changes: 3 additions & 0 deletions src/command/private_key_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn put_sign<const R: usize, T: crate::card::Client>(
SignatureAlgorithm::EcDsaBrainpoolP512R1 => {
put_ec(ctx.lend(), CurveAlgo::EcDsaBrainpoolP512R1)?
}
SignatureAlgorithm::EcDsaSecp256k1 => put_ec(ctx.lend(), CurveAlgo::EcDsaSecp256k1)?,
SignatureAlgorithm::Ed255 => put_ec(ctx.lend(), CurveAlgo::Ed255)?,
SignatureAlgorithm::Rsa2048 => put_rsa(ctx.lend(), Mechanism::Rsa2048Pkcs1v15)?,
SignatureAlgorithm::Rsa3072 => put_rsa(ctx.lend(), Mechanism::Rsa3072Pkcs1v15)?,
Expand Down Expand Up @@ -99,6 +100,7 @@ pub fn put_dec<const R: usize, T: crate::card::Client>(
DecryptionAlgorithm::EcDhBrainpoolP512R1 => {
put_ec(ctx.lend(), CurveAlgo::EcDhBrainpoolP512R1)?
}
DecryptionAlgorithm::EcDhSecp256k1 => put_ec(ctx.lend(), CurveAlgo::EcDhSecp256k1)?,
DecryptionAlgorithm::X255 => put_ec(ctx.lend(), CurveAlgo::X255)?,
DecryptionAlgorithm::Rsa2048 => put_rsa(ctx.lend(), Mechanism::Rsa2048Pkcs1v15)?,
DecryptionAlgorithm::Rsa3072 => put_rsa(ctx.lend(), Mechanism::Rsa3072Pkcs1v15)?,
Expand Down Expand Up @@ -140,6 +142,7 @@ pub fn put_aut<const R: usize, T: crate::card::Client>(
AuthenticationAlgorithm::EcDsaBrainpoolP512R1 => {
put_ec(ctx.lend(), CurveAlgo::EcDsaBrainpoolP512R1)?
}
AuthenticationAlgorithm::EcDsaSecp256k1 => put_ec(ctx.lend(), CurveAlgo::EcDsaSecp256k1)?,
AuthenticationAlgorithm::Ed255 => put_ec(ctx.lend(), CurveAlgo::Ed255)?,
AuthenticationAlgorithm::Rsa2048 => put_rsa(ctx.lend(), Mechanism::Rsa2048Pkcs1v15)?,
AuthenticationAlgorithm::Rsa3072 => put_rsa(ctx.lend(), Mechanism::Rsa3072Pkcs1v15)?,
Expand Down
14 changes: 14 additions & 0 deletions src/command/pso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ pub fn sign<const R: usize, T: crate::card::Client>(
}
sign_ec(ctx.lend(), key_id, Mechanism::BrainpoolP512R1Prehashed)
}
SignatureAlgorithm::EcDsaSecp256k1 => {
if ctx.data.len() != 32 {
return Err(Status::ConditionsOfUseNotSatisfied);
}
sign_ec(ctx.lend(), key_id, Mechanism::Secp256k1Prehashed)
}
SignatureAlgorithm::Rsa2048 => sign_rsa(ctx.lend(), key_id, Mechanism::Rsa2048Pkcs1v15),
SignatureAlgorithm::Rsa3072 => sign_rsa(ctx.lend(), key_id, Mechanism::Rsa3072Pkcs1v15),
SignatureAlgorithm::Rsa4096 => sign_rsa(ctx.lend(), key_id, Mechanism::Rsa4096Pkcs1v15),
Expand Down Expand Up @@ -172,6 +178,9 @@ fn int_aut_key_mecha_uif<const R: usize, T: crate::card::Client>(
AuthenticationAlgorithm::EcDsaBrainpoolP512R1 => {
(Mechanism::BrainpoolP512R1Prehashed, RsaOrEcc::Ecc)
}
AuthenticationAlgorithm::EcDsaSecp256k1 => {
(Mechanism::Secp256k1Prehashed, RsaOrEcc::Ecc)
}
AuthenticationAlgorithm::Ed255 => (Mechanism::Ed255, RsaOrEcc::Ecc),

AuthenticationAlgorithm::Rsa2048 => (Mechanism::Rsa2048Pkcs1v15, RsaOrEcc::Rsa),
Expand All @@ -198,6 +207,9 @@ fn int_aut_key_mecha_uif<const R: usize, T: crate::card::Client>(
DecryptionAlgorithm::EcDhBrainpoolP512R1 => {
(Mechanism::BrainpoolP512R1Prehashed, RsaOrEcc::Ecc)
}
DecryptionAlgorithm::EcDhSecp256k1 => {
(Mechanism::Secp256k1Prehashed, RsaOrEcc::Ecc)
}
DecryptionAlgorithm::Rsa2048 => (Mechanism::Rsa2048Pkcs1v15, RsaOrEcc::Rsa),
DecryptionAlgorithm::Rsa3072 => (Mechanism::Rsa3072Pkcs1v15, RsaOrEcc::Rsa),
DecryptionAlgorithm::Rsa4096 => (Mechanism::Rsa4096Pkcs1v15, RsaOrEcc::Rsa),
Expand Down Expand Up @@ -271,6 +283,7 @@ fn decipher_key_mecha_uif<const R: usize, T: crate::card::Client>(
DecryptionAlgorithm::EcDhBrainpoolP512R1 => {
(Mechanism::BrainpoolP512R1, RsaOrEcc::Ecc)
}
DecryptionAlgorithm::EcDhSecp256k1 => (Mechanism::Secp256k1, RsaOrEcc::Ecc),
DecryptionAlgorithm::Rsa2048 => (Mechanism::Rsa2048Pkcs1v15, RsaOrEcc::Rsa),
DecryptionAlgorithm::Rsa3072 => (Mechanism::Rsa3072Pkcs1v15, RsaOrEcc::Rsa),
DecryptionAlgorithm::Rsa4096 => (Mechanism::Rsa4096Pkcs1v15, RsaOrEcc::Rsa),
Expand All @@ -291,6 +304,7 @@ fn decipher_key_mecha_uif<const R: usize, T: crate::card::Client>(
AuthenticationAlgorithm::EcDsaBrainpoolP512R1 => {
(Mechanism::BrainpoolP512R1, RsaOrEcc::Ecc)
}
AuthenticationAlgorithm::EcDsaSecp256k1 => (Mechanism::Secp256k1, RsaOrEcc::Ecc),
AuthenticationAlgorithm::Ed255 => {
warn!("Attempt to decipher with Ed255 key");
return Err(Status::ConditionsOfUseNotSatisfied);
Expand Down
31 changes: 25 additions & 6 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,30 @@ macro_rules! iterable_sub_enum {
}
}

const ED255_ATTRIBUTES: &[u8] = hex!("16 2B 06 01 04 01 DA 47 0F 01").as_slice();
const ED255_ATTRIBUTES_PK: &[u8] = hex!("16 2B 06 01 04 01 DA 47 0F 01 FF").as_slice();
const ECDSA_P256_ATTRIBUTES: &[u8] = hex!("13 2A 86 48 CE 3D 03 01 07").as_slice();
const ED255_ATTRIBUTES: &[u8] = hex!("162B06010401DA470F01").as_slice();
const ED255_ATTRIBUTES_PK: &[u8] = hex!("162B06010401DA470F01 FF").as_slice();
const ECDSA_P256_ATTRIBUTES: &[u8] = hex!("132A8648CE3D030107").as_slice();
const ECDSA_P384_ATTRIBUTES: &[u8] = hex!("132b81040022").as_slice();
const ECDSA_P521_ATTRIBUTES: &[u8] = hex!("132b81040023").as_slice();
const ECDSA_P256_ATTRIBUTES_PK: &[u8] = hex!("13 2A 86 48 CE 3D 03 01 07 FF").as_slice();
const ECDSA_P256_ATTRIBUTES_PK: &[u8] = hex!("132A8648CE3D030107 FF").as_slice();
const ECDSA_P384_ATTRIBUTES_PK: &[u8] = hex!("132b81040022 FF").as_slice();
const ECDSA_P521_ATTRIBUTES_PK: &[u8] = hex!("132b81040023 FF").as_slice();
const ECDSA_SECP256K1_ATTRIBUTES: &[u8] = hex!("132B8104000A").as_slice();
const ECDSA_SECP256K1_ATTRIBUTES_PK: &[u8] = hex!("132B8104000A FF").as_slice();
const ECDSA_BRAINPOOL_P256R1_ATTRIBUTES: &[u8] = hex!("132b2403030208010107").as_slice();
const ECDSA_BRAINPOOL_P384R1_ATTRIBUTES: &[u8] = hex!("132b240303020801010b").as_slice();
const ECDSA_BRAINPOOL_P512R1_ATTRIBUTES: &[u8] = hex!("132b240303020801010d").as_slice();
const ECDSA_BRAINPOOL_P256R1_ATTRIBUTES_PK: &[u8] = hex!("132b2403030208010107 FF").as_slice();
const ECDSA_BRAINPOOL_P384R1_ATTRIBUTES_PK: &[u8] = hex!("132b240303020801010b FF").as_slice();
const ECDSA_BRAINPOOL_P512R1_ATTRIBUTES_PK: &[u8] = hex!("132b240303020801010d FF").as_slice();
const ECDH_P256_ATTRIBUTES: &[u8] = hex!("12 2A 86 48 CE 3D 03 01 07").as_slice();
const ECDH_P256_ATTRIBUTES: &[u8] = hex!("122A8648CE3D030107").as_slice();
const ECDH_P384_ATTRIBUTES: &[u8] = hex!("122b81040022").as_slice();
const ECDH_P521_ATTRIBUTES: &[u8] = hex!("122b81040023").as_slice();
const ECDH_P256_ATTRIBUTES_PK: &[u8] = hex!("12 2A 86 48 CE 3D 03 01 07 FF").as_slice();
const ECDH_P256_ATTRIBUTES_PK: &[u8] = hex!("122A8648CE3D030107 FF").as_slice();
const ECDH_P384_ATTRIBUTES_PK: &[u8] = hex!("122b81040022 FF").as_slice();
const ECDH_P521_ATTRIBUTES_PK: &[u8] = hex!("122b81040023 FF").as_slice();
const ECDH_SECP256K1_ATTRIBUTES: &[u8] = hex!("122B8104000A").as_slice();
const ECDH_SECP256K1_ATTRIBUTES_PK: &[u8] = hex!("122B8104000A FF").as_slice();
const ECDH_BRAINPOOL_P256R1_ATTRIBUTES: &[u8] = hex!("122b2403030208010107").as_slice();
const ECDH_BRAINPOOL_P384R1_ATTRIBUTES: &[u8] = hex!("122b240303020801010b").as_slice();
const ECDH_BRAINPOOL_P512R1_ATTRIBUTES: &[u8] = hex!("122b240303020801010d").as_slice();
Expand Down Expand Up @@ -180,6 +184,8 @@ iterable_enum! {
EcDsaP384,
EcDhP521,
EcDsaP521,
EcDhSecp256k1,
EcDsaSecp256k1,
EcDhBrainpoolP256R1,
EcDsaBrainpoolP256R1,
EcDhBrainpoolP384R1,
Expand All @@ -202,6 +208,8 @@ impl TryFrom<&[u8]> for Algorithm {
ECDSA_P384_ATTRIBUTES | ECDSA_P384_ATTRIBUTES_PK => Ok(Self::EcDsaP384),
ECDH_P521_ATTRIBUTES | ECDH_P521_ATTRIBUTES_PK => Ok(Self::EcDhP521),
ECDSA_P521_ATTRIBUTES | ECDSA_P521_ATTRIBUTES_PK => Ok(Self::EcDsaP521),
ECDSA_SECP256K1_ATTRIBUTES | ECDSA_SECP256K1_ATTRIBUTES_PK => Ok(Self::EcDsaSecp256k1),
ECDH_SECP256K1_ATTRIBUTES | ECDH_SECP256K1_ATTRIBUTES_PK => Ok(Self::EcDhSecp256k1),
ECDH_BRAINPOOL_P256R1_ATTRIBUTES | ECDH_BRAINPOOL_P256R1_ATTRIBUTES_PK => {
Ok(Self::EcDhBrainpoolP256R1)
}
Expand Down Expand Up @@ -247,6 +255,8 @@ impl Algorithm {
Self::EcDsaP384 => ECDSA_P384_ATTRIBUTES_PK,
Self::EcDhP521 => ECDH_P521_ATTRIBUTES_PK,
Self::EcDsaP521 => ECDSA_P521_ATTRIBUTES_PK,
Self::EcDhSecp256k1 => ECDH_SECP256K1_ATTRIBUTES_PK,
Self::EcDsaSecp256k1 => ECDSA_SECP256K1_ATTRIBUTES_PK,
Self::EcDhBrainpoolP256R1 => ECDH_BRAINPOOL_P256R1_ATTRIBUTES_PK,
Self::EcDsaBrainpoolP256R1 => ECDSA_BRAINPOOL_P256R1_ATTRIBUTES_PK,
Self::EcDhBrainpoolP384R1 => ECDH_BRAINPOOL_P384R1_ATTRIBUTES_PK,
Expand All @@ -273,6 +283,8 @@ impl Algorithm {
Self::EcDsaP384 => allowed.contains(AllowedAlgorithms::P_384),
Self::EcDhP521 => allowed.contains(AllowedAlgorithms::P_521),
Self::EcDsaP521 => allowed.contains(AllowedAlgorithms::P_521),
Self::EcDsaSecp256k1 => allowed.contains(AllowedAlgorithms::SECP256K1),
Self::EcDhSecp256k1 => allowed.contains(AllowedAlgorithms::SECP256K1),
Self::EcDhBrainpoolP256R1 => allowed.contains(AllowedAlgorithms::BRAINPOOL_P256R1),
Self::EcDsaBrainpoolP256R1 => allowed.contains(AllowedAlgorithms::BRAINPOOL_P256R1),
Self::EcDhBrainpoolP384R1 => allowed.contains(AllowedAlgorithms::BRAINPOOL_P384R1),
Expand Down Expand Up @@ -301,6 +313,7 @@ iterable_sub_enum! {
EcDsaBrainpoolP256R1,
EcDsaBrainpoolP384R1,
EcDsaBrainpoolP512R1,
EcDsaSecp256k1,
}
}

Expand Down Expand Up @@ -360,6 +373,7 @@ iterable_sub_enum! {
EcDhBrainpoolP256R1,
EcDhBrainpoolP384R1,
EcDhBrainpoolP512R1,
EcDhSecp256k1,
}
}

Expand Down Expand Up @@ -419,6 +433,7 @@ iterable_sub_enum! {
EcDsaBrainpoolP256R1,
EcDsaBrainpoolP384R1,
EcDsaBrainpoolP512R1,
EcDsaSecp256k1,
}
}

Expand Down Expand Up @@ -594,6 +609,8 @@ pub enum CurveAlgo {
EcDsaBrainpoolP384R1,
EcDhBrainpoolP512R1,
EcDsaBrainpoolP512R1,
EcDsaSecp256k1,
EcDhSecp256k1,
X255,
Ed255,
}
Expand All @@ -609,6 +626,7 @@ impl CurveAlgo {
Self::EcDsaBrainpoolP512R1 | Self::EcDhBrainpoolP512R1 => Mechanism::BrainpoolP512R1,
Self::X255 => Mechanism::X255,
Self::Ed255 => Mechanism::Ed255,
Self::EcDsaSecp256k1 | Self::EcDhSecp256k1 => Mechanism::Secp256k1,
}
}

Expand All @@ -620,6 +638,7 @@ impl CurveAlgo {
Self::EcDsaBrainpoolP256R1 | Self::EcDhBrainpoolP256R1 => 0x04,
Self::EcDsaBrainpoolP384R1 | Self::EcDhBrainpoolP384R1 => 0x04,
Self::EcDsaBrainpoolP512R1 | Self::EcDhBrainpoolP512R1 => 0x04,
Self::EcDsaSecp256k1 | Self::EcDhSecp256k1 => 0x04,
Self::X255 | Self::Ed255 => 0x40,
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/brainpool-p512r1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ mod gpg;
use test_log::test;

#[test]
fn p521_gpg_hardware() {
fn brainpool512_gpg_hardware() {
gpg::gpg_test(gpg::KeyAlgo::BrainpoolP512R1);
}
Loading