From 8cda810ce19e77387af89aa9edda2d5481098432 Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Mon, 30 Sep 2024 17:05:02 +0000 Subject: [PATCH 1/7] Add Dilithium COSE algorithm IDs --- src/webauthn.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/webauthn.rs b/src/webauthn.rs index 48d4dc6..37c3f94 100644 --- a/src/webauthn.rs +++ b/src/webauthn.rs @@ -158,9 +158,13 @@ pub enum UnknownPKCredentialParam { pub const ES256: i32 = -7; /// EdDSA pub const ED_DSA: i32 = -8; +/// Dilithium2 +pub const DILITHIUM2: i32 = -87; +pub const DILITHIUM3: i32 = -88; +pub const DILITHIUM5: i32 = -89; -pub const COUNT_KNOWN_ALGS: usize = 2; -pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ES256, ED_DSA]; +pub const COUNT_KNOWN_ALGS: usize = 5; +pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ES256, ED_DSA, DILITHIUM2, DILITHIUM3, DILITHIUM5]; impl TryFrom for KnownPublicKeyCredentialParameters { type Error = UnknownPKCredentialParam; From b6f0c5a265f5b21711da3a63ae1afa5191753129 Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Tue, 1 Oct 2024 03:18:56 +0000 Subject: [PATCH 2/7] Add Dilithium algorithms --- Cargo.toml | 6 +++++- src/webauthn.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e3a43cf..e9b8b66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,9 +36,13 @@ get-info-full = [] large-blobs = [] third-party-payment = [] +backend-dilithium2 = [] +backend-dilithium3 = [] +backend-dilithium5 = [] + log-all = [] log-none = [] log-info = [] log-debug = [] log-warn = [] -log-error = [] +log-error = [] \ No newline at end of file diff --git a/src/webauthn.rs b/src/webauthn.rs index 37c3f94..072b929 100644 --- a/src/webauthn.rs +++ b/src/webauthn.rs @@ -159,12 +159,39 @@ pub const ES256: i32 = -7; /// EdDSA pub const ED_DSA: i32 = -8; /// Dilithium2 +#[cfg(feature = "backend-dilithium2")] pub const DILITHIUM2: i32 = -87; +#[cfg(feature = "backend-dilithium3")] pub const DILITHIUM3: i32 = -88; +#[cfg(feature = "backend-dilithium5")] pub const DILITHIUM5: i32 = -89; -pub const COUNT_KNOWN_ALGS: usize = 5; -pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ES256, ED_DSA, DILITHIUM2, DILITHIUM3, DILITHIUM5]; +// Dynamically calculate the number of different known algorithms +pub const COUNT_KNOWN_ALGS: usize = + 2 + (if cfg!(feature = "backend-dilithium2") { + 1 + } else { + 0 + }) + (if cfg!(feature = "backend-dilithium3") { + 1 + } else { + 0 + }) + (if cfg!(feature = "backend-dilithium5") { + 1 + } else { + 0 + }); + +pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ + ES256, + ED_DSA, + #[cfg(feature = "backend-dilithium2")] + DILITHIUM2, + #[cfg(feature = "backend-dilithium3")] + DILITHIUM3, + #[cfg(feature = "backend-dilithium5")] + DILITHIUM5, +]; impl TryFrom for KnownPublicKeyCredentialParameters { type Error = UnknownPKCredentialParam; From b7a4259d07bd2064c7eadb0aa985ecfac155c6b1 Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Sun, 27 Oct 2024 22:39:23 -0400 Subject: [PATCH 3/7] Update Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e9b8b66..629cb23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,4 +45,4 @@ log-none = [] log-info = [] log-debug = [] log-warn = [] -log-error = [] \ No newline at end of file +log-error = [] From 2fe6e1b75468b750554cb69faf37d9aa818b64db Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Mon, 4 Nov 2024 22:16:27 -0500 Subject: [PATCH 4/7] Use constants instead of hardcoded values --- Cargo.toml | 1 + src/ctap1.rs | 5 +++-- src/ctap2.rs | 3 ++- src/sizes.rs | 13 +++++++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 629cb23..70480db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/trussed-dev/ctap-types" arbitrary = { version = "1.3.2", features = ["derive"], optional = true } bitflags = "1.3" cbor-smol = { version = "0.5", features = ["heapless-bytes-v0-3"] } +cfg-if = "1.0" cosey = "0.3.1" delog = "0.1" heapless = { version = "0.7", default-features = false, features = ["serde"] } diff --git a/src/ctap1.rs b/src/ctap1.rs index 0fc6153..aefe095 100644 --- a/src/ctap1.rs +++ b/src/ctap1.rs @@ -30,6 +30,7 @@ pub mod authenticate { pub mod register { use super::Bytes; + use crate::sizes::MAX_MESSAGE_LENGTH; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Request<'a> { @@ -42,7 +43,7 @@ pub mod register { pub header_byte: u8, pub public_key: Bytes<65>, pub key_handle: Bytes<255>, - pub attestation_certificate: Bytes<1024>, + pub attestation_certificate: Bytes, pub signature: Bytes<72>, } @@ -52,7 +53,7 @@ pub mod register { public_key: &cosey::EcdhEsHkdf256PublicKey, key_handle: Bytes<255>, signature: Bytes<72>, - attestation_certificate: Bytes<1024>, + attestation_certificate: Bytes, ) -> Self { let mut public_key_bytes = Bytes::new(); public_key_bytes.push(0x04).unwrap(); diff --git a/src/ctap2.rs b/src/ctap2.rs index 8136be2..efc70d2 100644 --- a/src/ctap2.rs +++ b/src/ctap2.rs @@ -6,6 +6,7 @@ use bitflags::bitflags; use cbor_smol::cbor_deserialize; use serde::{Deserialize, Serialize}; +use crate::sizes::MAX_MESSAGE_LENGTH; use crate::{sizes::*, Bytes, TryFromStrError, Vec}; pub use crate::operation::{Operation, VendorOperation}; @@ -301,7 +302,7 @@ pub struct PackedAttestationStatement { pub alg: i32, pub sig: Bytes, #[serde(skip_serializing_if = "Option::is_none")] - pub x5c: Option, 1>>, + pub x5c: Option, 1>>, } #[derive(Clone, Debug, Default, Eq, PartialEq)] diff --git a/src/sizes.rs b/src/sizes.rs index 3f36595..43f51f4 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -30,3 +30,16 @@ pub const THEORETICAL_MAX_MESSAGE_SIZE: usize = PACKET_SIZE - 7 + 128 * (PACKET_ pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 0; #[cfg(feature = "large-blobs")] pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 3008; + +// TODO: update these, and grab them from a common crate? +cfg_if::cfg_if! { + if #[cfg(feature = "backend-dilithium5")] { + pub const MAX_MESSAGE_LENGTH: usize = 7523 + 57 + 30; + } else if #[cfg(feature = "backend-dilithium3")] { + pub const MAX_MESSAGE_LENGTH: usize = 6019 + 57 + 30; + } else if #[cfg(feature = "backend-dilithium2")] { + pub const MAX_MESSAGE_LENGTH: usize = 3907 + 57 + 30; + } else { + pub const MAX_MESSAGE_LENGTH: usize = 1024; + } +} From 09bb2e4d3f6591c703b6c340adec70eed4264a6b Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Mon, 4 Nov 2024 23:58:41 -0500 Subject: [PATCH 5/7] Update max credential ID length; update all max sizes --- src/ctap1.rs | 6 +++--- src/sizes.rs | 23 +++++++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/ctap1.rs b/src/ctap1.rs index aefe095..dd6216c 100644 --- a/src/ctap1.rs +++ b/src/ctap1.rs @@ -30,7 +30,7 @@ pub mod authenticate { pub mod register { use super::Bytes; - use crate::sizes::MAX_MESSAGE_LENGTH; + use crate::sizes::{MAX_CREDENTIAL_ID_LENGTH, MAX_MESSAGE_LENGTH}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Request<'a> { @@ -42,7 +42,7 @@ pub mod register { pub struct Response { pub header_byte: u8, pub public_key: Bytes<65>, - pub key_handle: Bytes<255>, + pub key_handle: Bytes, pub attestation_certificate: Bytes, pub signature: Bytes<72>, } @@ -51,7 +51,7 @@ pub mod register { pub fn new( header_byte: u8, public_key: &cosey::EcdhEsHkdf256PublicKey, - key_handle: Bytes<255>, + key_handle: Bytes, signature: Bytes<72>, attestation_certificate: Bytes, ) -> Self { diff --git a/src/sizes.rs b/src/sizes.rs index 43f51f4..68395dd 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -1,13 +1,10 @@ -pub const AUTHENTICATOR_DATA_LENGTH: usize = 676; // pub const AUTHENTICATOR_DATA_LENGTH_BYTES: usize = 512; -pub const ASN1_SIGNATURE_LENGTH: usize = 77; // pub const ASN1_SIGNATURE_LENGTH_BYTES: usize = 72; pub const COSE_KEY_LENGTH: usize = 256; // pub const COSE_KEY_LENGTH_BYTES: usize = 256; -pub const MAX_CREDENTIAL_ID_LENGTH: usize = 255; pub const MAX_CREDENTIAL_ID_LENGTH_PLUS_256: usize = 767; pub const MAX_CREDENTIAL_COUNT_IN_LIST: usize = 10; @@ -34,12 +31,26 @@ pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 3008; // TODO: update these, and grab them from a common crate? cfg_if::cfg_if! { if #[cfg(feature = "backend-dilithium5")] { - pub const MAX_MESSAGE_LENGTH: usize = 7523 + 57 + 30; + pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 7523 + 57 + 30 + 37; + pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this will have to be larger + pub const ASN1_SIGNATURE_LENGTH: usize = 4627; } else if #[cfg(feature = "backend-dilithium3")] { - pub const MAX_MESSAGE_LENGTH: usize = 6019 + 57 + 30; + pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 6019 + 57 + 30 + 37; + pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; + pub const ASN1_SIGNATURE_LENGTH: usize = 3309; } else if #[cfg(feature = "backend-dilithium2")] { - pub const MAX_MESSAGE_LENGTH: usize = 3907 + 57 + 30; + pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 3907 + 57 + 30 + 37; + pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this can be smaller + pub const ASN1_SIGNATURE_LENGTH: usize = 2420; } else { pub const MAX_MESSAGE_LENGTH: usize = 1024; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 255; + pub const AUTHENTICATOR_DATA_LENGTH: usize = 676; + pub const ASN1_SIGNATURE_LENGTH: usize = 77; } } + +pub const MAX_COMMITTMENT_LENGTH: usize = AUTHENTICATOR_DATA_LENGTH + 32; From 6db9125f1940d3f4e4400da062a4f321dc850a02 Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Thu, 20 Feb 2025 20:59:56 -0500 Subject: [PATCH 6/7] Switch to ML-DSA --- Cargo.toml | 6 +++--- src/sizes.rs | 6 +++--- src/webauthn.rs | 32 ++++++++++++++++---------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70480db..4bea8fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,9 +37,9 @@ get-info-full = [] large-blobs = [] third-party-payment = [] -backend-dilithium2 = [] -backend-dilithium3 = [] -backend-dilithium5 = [] +backend-mldsa-44 = [] +backend-mldsa-65 = [] +backend-mldsa-87 = [] log-all = [] log-none = [] diff --git a/src/sizes.rs b/src/sizes.rs index 68395dd..b529a17 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -30,17 +30,17 @@ pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 3008; // TODO: update these, and grab them from a common crate? cfg_if::cfg_if! { - if #[cfg(feature = "backend-dilithium5")] { + if #[cfg(feature = "backend-mldsa-87")] { pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; pub const MAX_CREDENTIAL_ID_LENGTH: usize = 7523 + 57 + 30 + 37; pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this will have to be larger pub const ASN1_SIGNATURE_LENGTH: usize = 4627; - } else if #[cfg(feature = "backend-dilithium3")] { + } else if #[cfg(feature = "backend-mldsa-65")] { pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; pub const MAX_CREDENTIAL_ID_LENGTH: usize = 6019 + 57 + 30 + 37; pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; pub const ASN1_SIGNATURE_LENGTH: usize = 3309; - } else if #[cfg(feature = "backend-dilithium2")] { + } else if #[cfg(feature = "backend-mldsa-44")] { pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; pub const MAX_CREDENTIAL_ID_LENGTH: usize = 3907 + 57 + 30 + 37; pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this can be smaller diff --git a/src/webauthn.rs b/src/webauthn.rs index 072b929..5e22f4a 100644 --- a/src/webauthn.rs +++ b/src/webauthn.rs @@ -158,25 +158,25 @@ pub enum UnknownPKCredentialParam { pub const ES256: i32 = -7; /// EdDSA pub const ED_DSA: i32 = -8; -/// Dilithium2 -#[cfg(feature = "backend-dilithium2")] -pub const DILITHIUM2: i32 = -87; -#[cfg(feature = "backend-dilithium3")] -pub const DILITHIUM3: i32 = -88; -#[cfg(feature = "backend-dilithium5")] -pub const DILITHIUM5: i32 = -89; +/// ML0DSA +#[cfg(feature = "backend-mldsa-44")] +pub const MLDSA44: i32 = -87; +#[cfg(feature = "backend-mldsa-65")] +pub const MLDSA65: i32 = -88; +#[cfg(feature = "backend-mldsa-87")] +pub const MLDSA87: i32 = -89; // Dynamically calculate the number of different known algorithms pub const COUNT_KNOWN_ALGS: usize = - 2 + (if cfg!(feature = "backend-dilithium2") { + 2 + (if cfg!(feature = "backend-mldsa-44") { 1 } else { 0 - }) + (if cfg!(feature = "backend-dilithium3") { + }) + (if cfg!(feature = "backend-mldsa-65") { 1 } else { 0 - }) + (if cfg!(feature = "backend-dilithium5") { + }) + (if cfg!(feature = "backend-mldsa-87") { 1 } else { 0 @@ -185,12 +185,12 @@ pub const COUNT_KNOWN_ALGS: usize = pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ ES256, ED_DSA, - #[cfg(feature = "backend-dilithium2")] - DILITHIUM2, - #[cfg(feature = "backend-dilithium3")] - DILITHIUM3, - #[cfg(feature = "backend-dilithium5")] - DILITHIUM5, + #[cfg(feature = "backend-mldsa-44")] + MLDSA44, + #[cfg(feature = "backend-mldsa-65")] + MLDSA65, + #[cfg(feature = "backend-mldsa-87")] + MLDSA87, ]; impl TryFrom for KnownPublicKeyCredentialParameters { From b9462b2e2dedc104d53aab688fc0e7bb33996256 Mon Sep 17 00:00:00 2001 From: Kyle Kotowick Date: Wed, 26 Feb 2025 16:00:44 -0500 Subject: [PATCH 7/7] Initial PQC edits to build with upstream updates --- Cargo.toml | 6 +++--- src/sizes.rs | 6 +++--- src/webauthn.rs | 30 ++++++++++-------------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4bea8fd..2c8fb09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,9 +37,9 @@ get-info-full = [] large-blobs = [] third-party-payment = [] -backend-mldsa-44 = [] -backend-mldsa-65 = [] -backend-mldsa-87 = [] +mldsa44 = [] +mldsa65 = [] +mldsa87 = [] log-all = [] log-none = [] diff --git a/src/sizes.rs b/src/sizes.rs index b529a17..8867b7e 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -30,17 +30,17 @@ pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 3008; // TODO: update these, and grab them from a common crate? cfg_if::cfg_if! { - if #[cfg(feature = "backend-mldsa-87")] { + if #[cfg(feature = "mldsa87")] { pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; pub const MAX_CREDENTIAL_ID_LENGTH: usize = 7523 + 57 + 30 + 37; pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this will have to be larger pub const ASN1_SIGNATURE_LENGTH: usize = 4627; - } else if #[cfg(feature = "backend-mldsa-65")] { + } else if #[cfg(feature = "mldsa65")] { pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; pub const MAX_CREDENTIAL_ID_LENGTH: usize = 6019 + 57 + 30 + 37; pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; pub const ASN1_SIGNATURE_LENGTH: usize = 3309; - } else if #[cfg(feature = "backend-mldsa-44")] { + } else if #[cfg(feature = "mldsa44")] { pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; pub const MAX_CREDENTIAL_ID_LENGTH: usize = 3907 + 57 + 30 + 37; pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this can be smaller diff --git a/src/webauthn.rs b/src/webauthn.rs index 5e22f4a..cb4e18c 100644 --- a/src/webauthn.rs +++ b/src/webauthn.rs @@ -159,37 +159,27 @@ pub const ES256: i32 = -7; /// EdDSA pub const ED_DSA: i32 = -8; /// ML0DSA -#[cfg(feature = "backend-mldsa-44")] +#[cfg(feature = "mldsa44")] pub const MLDSA44: i32 = -87; -#[cfg(feature = "backend-mldsa-65")] +#[cfg(feature = "mldsa65")] pub const MLDSA65: i32 = -88; -#[cfg(feature = "backend-mldsa-87")] +#[cfg(feature = "mldsa87")] pub const MLDSA87: i32 = -89; // Dynamically calculate the number of different known algorithms -pub const COUNT_KNOWN_ALGS: usize = - 2 + (if cfg!(feature = "backend-mldsa-44") { - 1 - } else { - 0 - }) + (if cfg!(feature = "backend-mldsa-65") { - 1 - } else { - 0 - }) + (if cfg!(feature = "backend-mldsa-87") { - 1 - } else { - 0 - }); +pub const COUNT_KNOWN_ALGS: usize = 2 + + (if cfg!(feature = "mldsa44") { 1 } else { 0 }) + + (if cfg!(feature = "mldsa65") { 1 } else { 0 }) + + (if cfg!(feature = "mldsa87") { 1 } else { 0 }); pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ ES256, ED_DSA, - #[cfg(feature = "backend-mldsa-44")] + #[cfg(feature = "mldsa44")] MLDSA44, - #[cfg(feature = "backend-mldsa-65")] + #[cfg(feature = "mldsa65")] MLDSA65, - #[cfg(feature = "backend-mldsa-87")] + #[cfg(feature = "mldsa87")] MLDSA87, ];