diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs index 11c0ef1..b88660a 100644 --- a/src/key_exchange/traits.rs +++ b/src/key_exchange/traits.rs @@ -35,7 +35,6 @@ pub trait KeyExchange { server_s_sk: KeyFormat::Repr, id_u: Vec, id_s: Vec, - info: Vec, e_info: Vec, ) -> Result<(Vec, Self::KE2State, Self::KE2Message), ProtocolError>; @@ -48,15 +47,13 @@ pub trait KeyExchange { client_s_sk: KeyFormat::Repr, id_u: Vec, id_s: Vec, - info: Vec, - e_info: Vec, - ) -> Result<(Vec, Vec, Vec, Self::KE3Message), ProtocolError>; + ) -> Result<(Vec, Vec, Self::KE3Message), ProtocolError>; #[allow(clippy::type_complexity)] fn finish_ke( ke3_message: Self::KE3Message, ke2_state: &Self::KE2State, - ) -> Result<(Vec, Vec, Vec), ProtocolError>; + ) -> Result, ProtocolError>; fn ke1_state_size() -> usize; diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs index 1acc052..183de32 100644 --- a/src/key_exchange/tripledh.rs +++ b/src/key_exchange/tripledh.rs @@ -35,6 +35,8 @@ static STR_3DH: &[u8] = b"3DH keys"; static STR_CLIENT_MAC: &[u8] = b"client mac"; static STR_HANDSHAKE_SECRET: &[u8] = b"handshake secret"; static STR_SERVER_MAC: &[u8] = b"server mac"; +static STR_SERVER_ENC: &[u8] = b"server enc"; +static STR_ENCRYPTION_PAD: &[u8] = b"encryption pad"; static STR_SESSION_SECRET: &[u8] = b"session secret"; static STR_OPAQUE: &[u8] = b"OPAQUE "; @@ -91,7 +93,6 @@ impl KeyExchange for TripleDH { server_s_sk: KeyFormat::Repr, id_u: Vec, id_s: Vec, - info: Vec, e_info: Vec, ) -> Result<(Vec, Self::KE2State, Self::KE2Message), ProtocolError> { let server_e_kp = KeyFormat::generate_random(rng)?; @@ -101,7 +102,7 @@ impl KeyExchange for TripleDH { server_nonce_bytes.into() }; - let (session_secret, km2, km3) = derive_3dh_keys::( + let (session_secret, km2, ke2, km3) = derive_3dh_keys::( TripleDHComponents { pk1: ke1_message.client_e_pk.clone(), sk1: server_e_kp.private().clone(), @@ -116,6 +117,17 @@ impl KeyExchange for TripleDH { &id_s, )?; + // Compute encryption of e_info + let h = Hkdf::::new(None, &ke2); + let mut encryption_pad = vec![0u8; e_info.len()]; + h.expand(STR_ENCRYPTION_PAD, &mut encryption_pad) + .map_err(|_| InternalPakeError::HkdfError)?; + let ciphertext: Vec = encryption_pad + .iter() + .zip(e_info.iter()) + .map(|(&x1, &x2)| x1 ^ x2) + .collect(); + let mut hasher = D::new(); hasher.update(&l1_bytes); let hashed_l1 = hasher.finalize(); @@ -124,9 +136,8 @@ impl KeyExchange for TripleDH { &hashed_l1[..], &l2_bytes[..], &server_nonce[..], - &serialize(&info, 2), &server_e_kp.public().to_arr(), - &serialize(&e_info, 2), + &serialize(&ciphertext, 2), ] .concat(); @@ -153,9 +164,8 @@ impl KeyExchange for TripleDH { }, KE2Message { server_nonce, - info, server_e_pk: server_e_kp.public().clone(), - e_info, + e_info: ciphertext, mac, }, )) @@ -170,10 +180,8 @@ impl KeyExchange for TripleDH { client_s_sk: KeyFormat::Repr, id_u: Vec, id_s: Vec, - info: Vec, - e_info: Vec, - ) -> Result<(Vec, Vec, Vec, Self::KE3Message), ProtocolError> { - let (session_secret, km2, km3) = derive_3dh_keys::( + ) -> Result<(Vec, Vec, Self::KE3Message), ProtocolError> { + let (session_secret, km2, ke2, km3) = derive_3dh_keys::( TripleDHComponents { pk1: ke2_message.server_e_pk.clone(), sk1: ke1_state.client_e_sk.clone(), @@ -214,24 +222,25 @@ impl KeyExchange for TripleDH { hasher2.update(ke2_message.mac.to_vec()); let hashed_transcript = hasher2.finalize(); - let transcript_with_ke3 = [ - hashed_transcript.to_vec(), - serialize(&info, 2), - serialize(&e_info, 2), - ] - .concat(); - let mut client_mac = Hmac::::new_varkey(&km3).map_err(|_| InternalPakeError::HmacError)?; - client_mac.update(&transcript_with_ke3); + client_mac.update(&hashed_transcript); + + // Compute decryption of e_info + let h = Hkdf::::new(None, &ke2); + let mut encryption_pad = vec![0u8; ke2_message.e_info.len()]; + h.expand(STR_ENCRYPTION_PAD, &mut encryption_pad) + .map_err(|_| InternalPakeError::HkdfError)?; + let plaintext: Vec = encryption_pad + .iter() + .zip(ke2_message.e_info.iter()) + .map(|(&x1, &x2)| x1 ^ x2) + .collect(); Ok(( - ke2_message.info, - ke2_message.e_info, // TODO: need to decrypt + plaintext, session_secret.to_vec(), KE3Message { - info, - e_info, mac: client_mac.finalize().into_bytes(), }, )) @@ -241,15 +250,10 @@ impl KeyExchange for TripleDH { fn finish_ke( ke3_message: Self::KE3Message, ke2_state: &Self::KE2State, - ) -> Result<(Vec, Vec, Vec), ProtocolError> { - let transcript_with_ke3 = [ - ke2_state.hashed_transcript.to_vec(), - ke3_message.to_bytes_without_mac(), - ] - .concat(); + ) -> Result, ProtocolError> { let mut client_mac = Hmac::::new_varkey(&ke2_state.km3).map_err(|_| InternalPakeError::HmacError)?; - client_mac.update(&transcript_with_ke3); + client_mac.update(&ke2_state.hashed_transcript); if ke3_message.mac != client_mac.finalize().into_bytes() { return Err(ProtocolError::VerificationError( @@ -257,11 +261,7 @@ impl KeyExchange for TripleDH { )); } - Ok(( - ke3_message.info, - ke3_message.e_info, // TODO: need to decrypt - ke2_state.session_secret.to_vec(), - )) + Ok(ke2_state.session_secret.to_vec()) } fn ke1_state_size() -> usize { @@ -360,7 +360,6 @@ pub struct KE2State> { /// The second key exchange message pub struct KE2Message, KeyFormat: KeyPair> { server_nonce: GenericArray, - info: Vec, server_e_pk: KeyFormat::Repr, e_info: Vec, mac: GenericArray, @@ -401,7 +400,6 @@ impl, KeyFormat: KeyPair> KE2Message Vec { [ &self.server_nonce[..], - &serialize(&self.info, 2), &self.server_e_pk.to_arr(), &serialize(&self.e_info, 2), ] @@ -416,15 +414,16 @@ impl, KeyFormat: KeyPair> TryFrom<&[u8]> fn try_from(input: &[u8]) -> Result { let checked_nonce = check_slice_size_atleast(input, NONCE_LEN, "ke2_message nonce")?; - let (info, remainder) = tokenize(&checked_nonce[NONCE_LEN..], 2)?; - let checked_server_e_pk = - check_slice_size_atleast(&remainder, KEY_LEN, "ke2_message server_e_pk")?; + let checked_server_e_pk = check_slice_size_atleast( + &checked_nonce[NONCE_LEN..], + KEY_LEN, + "ke2_message server_e_pk", + )?; let (e_info, remainder) = tokenize(&checked_server_e_pk[KEY_LEN..], 2)?; let checked_mac = check_slice_size(&remainder, HashLen::to_usize(), "ke1_message mac")?; Ok(Self { server_nonce: GenericArray::clone_from_slice(&checked_nonce[..NONCE_LEN]), - info, server_e_pk: KeyFormat::Repr::from_bytes(&checked_server_e_pk[..KEY_LEN])?, e_info, mac: GenericArray::clone_from_slice(&checked_mac), @@ -442,29 +441,22 @@ struct TripleDHComponents { sk3: KeyFormat::Repr, } -// Consists of a shared secret, followed by two mac keys: (session_secret, km2, km3) +// Consists of a shared secret, followed by two mac keys and an encryption key: (session_secret, km2, ke2, km3) type TripleDHDerivationResult = ( GenericArray::OutputSize>, GenericArray::OutputSize>, GenericArray::OutputSize>, + GenericArray::OutputSize>, ); /// The third key exchange message pub struct KE3Message> { - info: Vec, - e_info: Vec, mac: GenericArray, } impl> ToBytes for KE3Message { fn to_bytes(&self) -> Vec { - [self.to_bytes_without_mac(), self.mac.to_vec()].concat() - } -} - -impl> KE3Message { - fn to_bytes_without_mac(&self) -> Vec { - [serialize(&self.info, 2), serialize(&self.e_info, 2)].concat() + self.mac.to_vec() } } @@ -472,13 +464,9 @@ impl> TryFrom<&[u8]> for KE3Message { type Error = PakeError; fn try_from(bytes: &[u8]) -> Result { - let (info, remainder) = tokenize(&bytes, 2)?; - let (e_info, remainder) = tokenize(&remainder, 2)?; - let checked_bytes = check_slice_size(&remainder, KEY_LEN, "ke3_message")?; + let checked_bytes = check_slice_size(&bytes, KEY_LEN, "ke3_message")?; Ok(Self { - info, - e_info, mac: GenericArray::clone_from_slice(&checked_bytes), }) } @@ -520,6 +508,12 @@ fn derive_3dh_keys( b"", ::OutputSize::to_usize(), )?; + let ke2 = hkdf_expand_label::( + &handshake_secret, + &STR_SERVER_ENC, + b"", + ::OutputSize::to_usize(), + )?; let km3 = hkdf_expand_label::( &handshake_secret, &STR_CLIENT_MAC, @@ -530,6 +524,7 @@ fn derive_3dh_keys( Ok(( GenericArray::clone_from_slice(&session_secret), GenericArray::clone_from_slice(&km2), + GenericArray::clone_from_slice(&ke2), GenericArray::clone_from_slice(&km3), )) } diff --git a/src/lib.rs b/src/lib.rs index 9bc2d76..3ea14a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,8 +15,9 @@ //! * a finite cyclic group along with a point representation, //! * a keypair type, //! * a key exchange protocol, -//! * a hashing function, and -//! * a slow hashing function. +//! * a hashing function, +//! * a slow hashing function, and +//! * an authenticated encryption algorithm. //! //! We will use the following choices in this example: //! ``` @@ -721,18 +722,16 @@ //! //! A key exchange protocol typically supports the passing of data between the two parties before the exchange is complete, so as to bind the integrity //! and/or confidentiality of application-specific data to the security of the key exchange. During the login phase, the client and server can pass -//! additional data alongside the first three messages of the protocol, with confidential data being supported for the second and third messages. +//! additional data alongside the first two messages of the protocol, with confidential data being supported for the second message. //! //! The following three messages support passing of additional data: //! - The first login message, where the client can populate [ClientLoginStartParameters::WithInfo] with plaintext additional data, and //! the server can retrieve using the `plain_info` field of [ServerLoginStartResult]. -//! - The second login message, where the server can populate [ServerLoginStartParameters::WithInfo] with plaintext and confidential additional data, -//! and the client can retrieve using the `plain_info` and `confidential_info` fields of [ClientLoginFinishResult]. -//! - The third login message, where the client can populate [ClientLoginFinishParameters::WithInfo] with plaintext and confidential -//! additional info, and the server can retrieve using the `plain_info` and `confidential_info` fields of [ServerLoginFinishResult]. +//! - The second login message, where the server can populate [ServerLoginStartParameters::WithInfo] with confidential additional data, +//! and the client can retrieve using the `confidential_info` field of [ClientLoginFinishResult]. //! -//! The `WithInfoAndIdentifiers` variant of each of these enums representing optional parameters can be used to specify these fields in addition to -//! [custom identifiers](#custom-identifiers), with the ordering of the fields as `WithInfoAndIdentifiers(plain_info, confidential_info, username, server_name)`. +//! For the second login message, the `WithInfoAndIdentifiers` variant can be used to specify these fields in addition to +//! [custom identifiers](#custom-identifiers), with the ordering of the fields as `WithInfoAndIdentifiers(confidential_info, username, server_name)`. //! //! diff --git a/src/opaque.rs b/src/opaque.rs index 3964e0d..8275d10 100644 --- a/src/opaque.rs +++ b/src/opaque.rs @@ -503,14 +503,8 @@ pub struct ClientLoginStartResult { /// Optional parameters for client login finish pub enum ClientLoginFinishParameters { - /// Specifying a plaintext info and confidential info field that will be sent to the server - WithInfo(Vec, Vec), /// Specifying a user identifier and server identifier that will be matched against the client WithIdentifiers(Vec, Vec), - /// Specifying a plaintext info and confidential info that will be sent to the server, - /// along with a user identifier and and server identifier that will be matched against the server - /// (in that order) - WithInfoAndIdentifiers(Vec, Vec, Vec, Vec), /// No info and no custom identifiers Default, } @@ -531,8 +525,6 @@ pub struct ClientLoginFinishResult { pub export_key: GenericArray, /// The server's static public key pub server_s_pk: ::Repr, - /// The plaintext info sent by the client - pub plain_info: Vec, /// The confidential info sent by the client pub confidential_info: Vec, } @@ -628,15 +620,9 @@ impl ClientLogin { l2: CredentialResponse, params: ClientLoginFinishParameters, ) -> Result, ProtocolError> { - let (info, e_info, optional_ids) = match params { - ClientLoginFinishParameters::Default => (Vec::new(), Vec::new(), None), - ClientLoginFinishParameters::WithInfo(info, e_info) => (info, e_info, None), - ClientLoginFinishParameters::WithIdentifiers(id_u, id_s) => { - (Vec::new(), Vec::new(), Some((id_u, id_s))) - } - ClientLoginFinishParameters::WithInfoAndIdentifiers(info, e_info, id_u, id_s) => { - (info, e_info, Some((id_u, id_s))) - } + let optional_ids = match params { + ClientLoginFinishParameters::Default => None, + ClientLoginFinishParameters::WithIdentifiers(id_u, id_s) => Some((id_u, id_s)), }; let l2_beta_bytes = &l2.beta.to_arr()[..]; @@ -673,21 +659,17 @@ impl ClientLogin { ] .concat(); - let (plain_info, confidential_info, shared_secret, ke3_message) = - CS::KeyExchange::generate_ke3( - l2_bytes, - l2.ke2_message, - &self.ke1_state, - l2.server_s_pk.clone(), - client_s_sk, - id_u, - id_s, - info, - e_info, - )?; + let (confidential_info, shared_secret, ke3_message) = CS::KeyExchange::generate_ke3( + l2_bytes, + l2.ke2_message, + &self.ke1_state, + l2.server_s_pk.clone(), + client_s_sk, + id_u, + id_s, + )?; Ok(ClientLoginFinishResult { - plain_info, confidential_info, message: CredentialFinalization { ke3_message }, shared_secret, @@ -718,19 +700,19 @@ impl TryFrom<&[u8]> for ServerLogin { /// Optional parameters for server login start pub enum ServerLoginStartParameters { - /// Specifying a plaintext info and confidential info field that will be sent to the client - WithInfo(Vec, Vec), + /// Specifying a confidential info field that will be sent to the client + WithInfo(Vec), /// Specifying a user identifier and server identifier that will be matched against the client WithIdentifiers(Vec, Vec), - /// Specifying a plaintext info and confidential info that will be sent to the client, + /// Specifying a confidential info field that will be sent to the client, /// along with a user identifier and and server identifier that will be matched against the client /// (in that order) - WithInfoAndIdentifiers(Vec, Vec, Vec, Vec), + WithInfoAndIdentifiers(Vec, Vec, Vec), } impl Default for ServerLoginStartParameters { fn default() -> Self { - Self::WithInfo(Vec::new(), Vec::new()) + Self::WithInfo(Vec::new()) } } @@ -748,10 +730,6 @@ pub struct ServerLoginStartResult { pub struct ServerLoginFinishResult { /// The shared session secret between client and server pub shared_secret: Vec, - /// The plaintext info sent by the client - pub plain_info: Vec, - /// The confidential info sent by the client - pub confidential_info: Vec, } impl ServerLogin { @@ -805,13 +783,13 @@ impl ServerLogin { .client_s_pk .ok_or(InternalPakeError::SealError)?; - let (info, e_info, optional_ids) = match params { - ServerLoginStartParameters::WithInfo(info, e_info) => (info, e_info, None), + let (e_info, optional_ids) = match params { + ServerLoginStartParameters::WithInfo(e_info) => (e_info, None), ServerLoginStartParameters::WithIdentifiers(id_u, id_s) => { - (Vec::new(), Vec::new(), Some((id_u, id_s))) + (Vec::new(), Some((id_u, id_s))) } - ServerLoginStartParameters::WithInfoAndIdentifiers(info, e_info, id_u, id_s) => { - (info, e_info, Some((id_u, id_s))) + ServerLoginStartParameters::WithInfoAndIdentifiers(e_info, id_u, id_s) => { + (e_info, Some((id_u, id_s))) } }; @@ -851,7 +829,6 @@ impl ServerLogin { server_s_sk.clone(), id_u, id_s, - info, e_info, )?; @@ -912,23 +889,18 @@ impl ServerLogin { &self, message: CredentialFinalization, ) -> Result { - let (plain_info, confidential_info, shared_secret) = - >::finish_ke( - message.ke3_message, - &self.ke2_state, - ) - .map_err(|e| match e { - ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => { - ProtocolError::VerificationError(PakeError::InvalidLoginError) - } - err => err, - })?; + let shared_secret = >::finish_ke( + message.ke3_message, + &self.ke2_state, + ) + .map_err(|e| match e { + ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => { + ProtocolError::VerificationError(PakeError::InvalidLoginError) + } + err => err, + })?; - Ok(ServerLoginFinishResult { - plain_info, - confidential_info, - shared_secret, - }) + Ok(ServerLoginFinishResult { shared_secret }) } } diff --git a/src/serialization/tests.rs b/src/serialization/tests.rs index c179e2a..7132398 100644 --- a/src/serialization/tests.rs +++ b/src/serialization/tests.rs @@ -233,14 +233,11 @@ fn login_second_message_roundtrip() { let mut server_nonce = [0u8; NONCE_LEN]; rng.fill_bytes(&mut server_nonce); - let mut info = [0u8; MAX_INFO_LENGTH]; - rng.fill_bytes(&mut info); let mut e_info = [0u8; MAX_INFO_LENGTH]; rng.fill_bytes(&mut e_info); let ke2m: Vec = [ &server_nonce[..], - &serialize(&info.to_vec(), 2), &server_e_kp.public(), &serialize(&e_info.to_vec(), 2), &mac[..], @@ -263,19 +260,10 @@ fn login_second_message_roundtrip() { #[test] fn login_third_message_roundtrip() { let mut rng = OsRng; - let mut info = [0u8; MAX_INFO_LENGTH]; - rng.fill_bytes(&mut info); - let mut e_info = [0u8; MAX_INFO_LENGTH]; - rng.fill_bytes(&mut e_info); let mut mac = [0u8; 32]; rng.fill_bytes(&mut mac); - let input: Vec = [ - &serialize(&info.to_vec(), 2), - &serialize(&e_info.to_vec(), 2), - &mac[..], - ] - .concat(); + let input: Vec = [&mac[..]].concat(); let l3 = CredentialFinalization::::deserialize(&input).unwrap(); let l3_bytes = l3.serialize(); @@ -328,8 +316,11 @@ fn ke1_message_roundtrip() { &client_e_kp.public(), ] .concat(); - let reg = - >::KE1Message::try_from(&ke1m[..]).unwrap(); + let reg = >::KE1Message::try_from(&ke1m[..]) + .unwrap(); let reg_bytes = reg.to_bytes(); assert_eq!(reg_bytes, ke1m); } @@ -343,22 +334,22 @@ fn ke2_message_roundtrip() { rng.fill_bytes(&mut mac); let mut server_nonce = [0u8; NONCE_LEN]; rng.fill_bytes(&mut server_nonce); - let mut info = [0u8; MAX_INFO_LENGTH]; - rng.fill_bytes(&mut info); let mut e_info = [0u8; MAX_INFO_LENGTH]; rng.fill_bytes(&mut e_info); let ke2m: Vec = [ &server_nonce[..], - &serialize(&info.to_vec(), 2), &server_e_kp.public(), &serialize(&e_info.to_vec(), 2), &mac[..], ] .concat(); - let reg = - >::KE2Message::try_from(&ke2m[..]).unwrap(); + let reg = >::KE2Message::try_from(&ke2m[..]) + .unwrap(); let reg_bytes = reg.to_bytes(); assert_eq!(reg_bytes, ke2m); } @@ -366,22 +357,16 @@ fn ke2_message_roundtrip() { #[test] fn ke3_message_roundtrip() { let mut rng = OsRng; - let mut info = [0u8; MAX_INFO_LENGTH]; - rng.fill_bytes(&mut info); - let mut e_info = [0u8; MAX_INFO_LENGTH]; - rng.fill_bytes(&mut e_info); let mut mac = [0u8; 32]; rng.fill_bytes(&mut mac); - let ke3m: Vec = [ - &serialize(&info.to_vec(), 2), - &serialize(&e_info.to_vec(), 2), - &mac[..], - ] - .concat(); + let ke3m: Vec = [&mac[..]].concat(); - let reg = - >::KE3Message::try_from(&ke3m[..]).unwrap(); + let reg = >::KE3Message::try_from(&ke3m[..]) + .unwrap(); let reg_bytes = reg.to_bytes(); assert_eq!(reg_bytes, ke3m); } diff --git a/src/tests/opaque_ke_test.rs b/src/tests/opaque_ke_test.rs index 824639b..e8d7b26 100644 --- a/src/tests/opaque_ke_test.rs +++ b/src/tests/opaque_ke_test.rs @@ -51,10 +51,7 @@ pub struct TestVectorParameters { pub client_nonce: Vec, pub server_nonce: Vec, pub info1: Vec, - pub info2: Vec, pub einfo2: Vec, - pub info3: Vec, - pub einfo3: Vec, pub registration_request: Vec, pub registration_response: Vec, pub registration_upload: Vec, @@ -72,40 +69,37 @@ pub struct TestVectorParameters { static TEST_VECTOR: &str = r#" { - "client_s_pk": "037ffc2cece49ab487448c9b52debee00bfcc72f00c78668f9b160466cc5b25a", - "client_s_sk": "e09f8a22c083743c60a2eb41640dc7174edd8863bb1a7482c12a02f08914db60", - "client_e_pk": "61422d4437b43abca17d2297a3b519fc37b24e20cb45d14a91ffcb1bc2107a5c", - "client_e_sk": "c831faece522d77c10625d1b0ea5592fb4ee45b042b4af4218d5702b087b136e", - "server_s_pk": "2cd221b189b472badcc2d4984dba174fd2e016bcc2bc8110527a11f28cd4f54f", - "server_s_sk": "986f09786edea821e346bd961cc0d727d5af77f88acda9bf2f95235716535f7c", - "server_e_pk": "b282307ada534fbb7e91253e8a807d3a0c5adb0cbcfb39fe5bae5bfd407abf17", - "server_e_sk": "f0d994f344f79aab474637090d6aeb6319c0a8123e21a18774fb4b21496a9963", + "client_s_pk": "d762053e2da32c990b1edb22408138369282462feeaa68fc0acfd157c2745740", + "client_s_sk": "b06303fb12bde8fb2875ffc052c0c0cdb4bbef7b6a32ec9bb4a00a3a56fb9545", + "client_e_pk": "0375e9aa445b859a02e9ccacd45772758e560f8640ee067319a86374cd93a435", + "client_e_sk": "c835f5854f1651c8551e24aee6ab1b81bf44e4cb906d0ac9fcf1aaa26ef3b872", + "server_s_pk": "b7d6d756fb2b3972125245f53c042c53c8b3bf5e9d2b576809548c5510f33136", + "server_s_sk": "b81e81698a315f4ee817e5c9bd4426db1bf8dd9fec2e6fc82639d08d90509e6f", + "server_e_pk": "6ce63bc56b7b2141680b4fc4c8d3b4d09b903c5a2d657fc79432c586d0e9bd64", + "server_e_sk": "a0f3efd594b41deaba4480cae066c658529b90754f5109f9b0b61d42266f234e", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", - "blinding_factor": "26f30696f7a0d47fe3c5a08e2962880f413e805c013b59dde187df0d1667b003", - "oprf_key": "b1126f88aa2377b1b56a81227c9f72c015dd6f94e1f8d88e4cb983016da50804", - "envelope_nonce": "66ea20d6a122e7cb9872fd141f338c8009655963f8ba925ca801182c63921ce6", - "client_nonce": "85320d740dc2d1b4e78e3c4d6e6ce474b3f2f5abe3c0e314555e310e9f5b7dde", - "server_nonce": "2e1d659f03ad117e51acad7e8b8519472237aa0c7e9c35482185cefdaa972607", + "blinding_factor": "78b54192e145ff02458385f8540fdf54e94c2a20f0a7f8f98944bc17af795e04", + "oprf_key": "98a9232ccfda91d14ea305e5cfb4e552ab8aa972ac6c79befe15ccf9f4f2970a", + "envelope_nonce": "46c395bdc879bfebae229024f0004721448e713643a341146310d50c84cef011", + "client_nonce": "197b1147bb214fafde9f5ce6f5e903d69be0ca006c51ac8f949ce7ab73a828ed", + "server_nonce": "73a56c702168d9d534429fd45c37390ed6f55b6ea79f2025e4584a04d35aa229", "info1": "696e666f31", - "info2": "696e666f32", "einfo2": "65696e666f32", - "info3": "696e666f33", - "einfo3": "65696e666f33", - "registration_request": "00205cebd79b362cbb48eab435801125e4646c4e56c9f19d720f1b7cdbca4c300ea8", - "registration_response": "002075dfc31fff8a44bde1ed1fd8c9295b7516bce1fe7559692883ada956a423fa9c00202cd221b189b472badcc2d4984dba174fd2e016bcc2bc8110527a11f28cd4f54f", - "registration_upload": "0166ea20d6a122e7cb9872fd141f338c8009655963f8ba925ca801182c63921ce600223c2deccbf09b5506d628137bd661b6de943a92fe762fd2b872c6adabc1e4c10ca2fb002c00202cd221b189b472badcc2d4984dba174fd2e016bcc2bc8110527a11f28cd4f54f000369645500036964530020dd6e96af9578ad04ef758070afdbb34ac695d2be131fed185ce746537cd02de60020037ffc2cece49ab487448c9b52debee00bfcc72f00c78668f9b160466cc5b25a", - "credential_request": "00205cebd79b362cbb48eab435801125e4646c4e56c9f19d720f1b7cdbca4c300ea885320d740dc2d1b4e78e3c4d6e6ce474b3f2f5abe3c0e314555e310e9f5b7dde0005696e666f3161422d4437b43abca17d2297a3b519fc37b24e20cb45d14a91ffcb1bc2107a5c", - "credential_response": "002075dfc31fff8a44bde1ed1fd8c9295b7516bce1fe7559692883ada956a423fa9c00202cd221b189b472badcc2d4984dba174fd2e016bcc2bc8110527a11f28cd4f54f0166ea20d6a122e7cb9872fd141f338c8009655963f8ba925ca801182c63921ce600223c2deccbf09b5506d628137bd661b6de943a92fe762fd2b872c6adabc1e4c10ca2fb002c00202cd221b189b472badcc2d4984dba174fd2e016bcc2bc8110527a11f28cd4f54f000369645500036964530020dd6e96af9578ad04ef758070afdbb34ac695d2be131fed185ce746537cd02de6f0d994f344f79aab474637090d6aeb6319c0a8123e21a18774fb4b21496a99630005696e666f32b282307ada534fbb7e91253e8a807d3a0c5adb0cbcfb39fe5bae5bfd407abf17000665696e666f32fb98272619ab5c17b860c2a59f194b88203080f641b96c278d10d69be004d2dd", - "key_exchange": "0005696e666f33000665696e666f33a13c4265ac30d7e079e975a550571ee95e74149cdc83b8683ac12d3764ed779a", - "client_registration_state": "26f30696f7a0d47fe3c5a08e2962880f413e805c013b59dde187df0d1667b00370617373776f7264", - "client_login_state": "26f30696f7a0d47fe3c5a08e2962880f413e805c013b59dde187df0d1667b003c831faece522d77c10625d1b0ea5592fb4ee45b042b4af4218d5702b087b136e85320d740dc2d1b4e78e3c4d6e6ce474b3f2f5abe3c0e314555e310e9f5b7dde518be4c0634f9829245f95c3ead10fafa41c29be9c6ca976bff9a1a22a61895e70617373776f7264", - "server_registration_state": "b1126f88aa2377b1b56a81227c9f72c015dd6f94e1f8d88e4cb983016da50804", - "server_login_state": "cb5e5021406dab84937ee7964c288e2ea176f7533ef12c2f7836dfc0a034c0387088884ba8e2ed9703ebf185a91511426d4dff480bd7282057e49b0b0fc38d6fa58f4c40f986833c2773696694d51a0a36d9ee85b0aacfc9cdad34dd9ad90d61", - "password_file": "b1126f88aa2377b1b56a81227c9f72c015dd6f94e1f8d88e4cb983016da50804037ffc2cece49ab487448c9b52debee00bfcc72f00c78668f9b160466cc5b25a0166ea20d6a122e7cb9872fd141f338c8009655963f8ba925ca801182c63921ce600223c2deccbf09b5506d628137bd661b6de943a92fe762fd2b872c6adabc1e4c10ca2fb002c00202cd221b189b472badcc2d4984dba174fd2e016bcc2bc8110527a11f28cd4f54f000369645500036964530020dd6e96af9578ad04ef758070afdbb34ac695d2be131fed185ce746537cd02de6", - "export_key": "776947002cb41ad575506e82778313bb8d2767dd9d7ed3fd55f875071d833a2e", - "shared_secret": "a58f4c40f986833c2773696694d51a0a36d9ee85b0aacfc9cdad34dd9ad90d61" + "registration_request": "0020ed5ca18ae23e622694611af62744f21c70f68d495ce36ae17784f03d225b573c", + "registration_response": "002078b592b789e7239481637419438333cbdcd3dd909534ac28e5473683d023719d0020b7d6d756fb2b3972125245f53c042c53c8b3bf5e9d2b576809548c5510f33136", + "registration_upload": "0146c395bdc879bfebae229024f0004721448e713643a341146310d50c84cef0110022f6906b64d3d45c4d77dd8c002b841749f716efc9e3e2cff762004b4878e75c0a7abe002c0020b7d6d756fb2b3972125245f53c042c53c8b3bf5e9d2b576809548c5510f33136000369645500036964530020e4444a287fc0bc8921d0c6423d36948fa176f68671196592cb947984b082bacd0020d762053e2da32c990b1edb22408138369282462feeaa68fc0acfd157c2745740", + "credential_request": "0020ed5ca18ae23e622694611af62744f21c70f68d495ce36ae17784f03d225b573c197b1147bb214fafde9f5ce6f5e903d69be0ca006c51ac8f949ce7ab73a828ed0005696e666f310375e9aa445b859a02e9ccacd45772758e560f8640ee067319a86374cd93a435", + "credential_response": "002078b592b789e7239481637419438333cbdcd3dd909534ac28e5473683d023719d0020b7d6d756fb2b3972125245f53c042c53c8b3bf5e9d2b576809548c5510f331360146c395bdc879bfebae229024f0004721448e713643a341146310d50c84cef0110022f6906b64d3d45c4d77dd8c002b841749f716efc9e3e2cff762004b4878e75c0a7abe002c0020b7d6d756fb2b3972125245f53c042c53c8b3bf5e9d2b576809548c5510f33136000369645500036964530020e4444a287fc0bc8921d0c6423d36948fa176f68671196592cb947984b082bacda0f3efd594b41deaba4480cae066c658529b90754f5109f9b0b61d42266f234e6ce63bc56b7b2141680b4fc4c8d3b4d09b903c5a2d657fc79432c586d0e9bd6400061e51f6093a7669db4e4a493137440cada18dcff631462e349de1d043a14a7a1de77b85638fbd", + "key_exchange": "11d1a3f15b490c059bfa06f7d0fae9cde9ff6af80270f3327161a362ec84570e", + "client_registration_state": "78b54192e145ff02458385f8540fdf54e94c2a20f0a7f8f98944bc17af795e0470617373776f7264", + "client_login_state": "78b54192e145ff02458385f8540fdf54e94c2a20f0a7f8f98944bc17af795e04c835f5854f1651c8551e24aee6ab1b81bf44e4cb906d0ac9fcf1aaa26ef3b872197b1147bb214fafde9f5ce6f5e903d69be0ca006c51ac8f949ce7ab73a828ed3a139e3e250129a1d3e7633052f853006a501e24b1d3c6ba6403aeb9cca7eda170617373776f7264", + "server_registration_state": "98a9232ccfda91d14ea305e5cfb4e552ab8aa972ac6c79befe15ccf9f4f2970a", + "server_login_state": "8be81bab99a1ce566adb4f33d14b012a8583f0ecf8b467bad1930a6adbf7178dcc8daa2de4be476dde1d8193f9fe7786601d7db0af7302c19501b516ad5e53329706a48a68a6bbf3dea894447a53b423fc5b5e561c9c3fa9b1b278d6790bbb74", + "password_file": "98a9232ccfda91d14ea305e5cfb4e552ab8aa972ac6c79befe15ccf9f4f2970ad762053e2da32c990b1edb22408138369282462feeaa68fc0acfd157c27457400146c395bdc879bfebae229024f0004721448e713643a341146310d50c84cef0110022f6906b64d3d45c4d77dd8c002b841749f716efc9e3e2cff762004b4878e75c0a7abe002c0020b7d6d756fb2b3972125245f53c042c53c8b3bf5e9d2b576809548c5510f33136000369645500036964530020e4444a287fc0bc8921d0c6423d36948fa176f68671196592cb947984b082bacd", + "export_key": "3cdf9ad930b46fad7855faab02a7f2e28282cc73f82fdd411f1a7f6c300c8ab1", + "shared_secret": "9706a48a68a6bbf3dea894447a53b423fc5b5e561c9c3fa9b1b278d6790bbb74" } "#; @@ -134,10 +128,7 @@ fn populate_test_vectors(values: &Value) -> TestVectorParameters { client_nonce: decode(&values, "client_nonce").unwrap(), server_nonce: decode(&values, "server_nonce").unwrap(), info1: decode(&values, "info1").unwrap(), - info2: decode(&values, "info2").unwrap(), einfo2: decode(&values, "einfo2").unwrap(), - info3: decode(&values, "info3").unwrap(), - einfo3: decode(&values, "einfo3").unwrap(), registration_request: decode(&values, "registration_request").unwrap(), registration_response: decode(&values, "registration_response").unwrap(), registration_upload: decode(&values, "registration_upload").unwrap(), @@ -186,10 +177,7 @@ fn stringify_test_vectors(p: &TestVectorParameters) -> String { s.push_str(format!("\"client_nonce\": \"{}\",\n", hex::encode(&p.client_nonce)).as_str()); s.push_str(format!("\"server_nonce\": \"{}\",\n", hex::encode(&p.server_nonce)).as_str()); s.push_str(format!("\"info1\": \"{}\",\n", hex::encode(&p.info1)).as_str()); - s.push_str(format!("\"info2\": \"{}\",\n", hex::encode(&p.info2)).as_str()); s.push_str(format!("\"einfo2\": \"{}\",\n", hex::encode(&p.einfo2)).as_str()); - s.push_str(format!("\"info3\": \"{}\",\n", hex::encode(&p.info3)).as_str()); - s.push_str(format!("\"einfo3\": \"{}\",\n", hex::encode(&p.einfo3)).as_str()); s.push_str( format!( "\"registration_request\": \"{}\",\n", @@ -301,10 +289,7 @@ where rng.fill_bytes(&mut server_nonce); let info1 = b"info1"; - let info2 = b"info2"; let einfo2 = b"einfo2"; - let info3 = b"info3"; - let einfo3 = b"einfo3"; let mut blinding_factor_registration_rng = CycleRng::new(blinding_factor_raw.to_vec()); let client_registration_start_result = ClientRegistration::::start( @@ -383,7 +368,6 @@ where server_s_kp.private(), client_login_start_result.message, ServerLoginStartParameters::WithInfoAndIdentifiers( - info2.to_vec(), einfo2.to_vec(), id_u.to_vec(), id_s.to_vec(), @@ -397,12 +381,7 @@ where .state .finish( server_login_start_result.message, - ClientLoginFinishParameters::WithInfoAndIdentifiers( - info3.to_vec(), - einfo3.to_vec(), - id_u.to_vec(), - id_s.to_vec(), - ), + ClientLoginFinishParameters::WithIdentifiers(id_u.to_vec(), id_s.to_vec()), ) .unwrap(); let key_exchange_bytes = client_login_finish_result.message.to_bytes().to_vec(); @@ -425,10 +404,7 @@ where client_nonce: client_nonce.to_vec(), server_nonce: server_nonce.to_vec(), info1: info1.to_vec(), - info2: info2.to_vec(), einfo2: einfo2.to_vec(), - info3: info3.to_vec(), - einfo3: einfo3.to_vec(), registration_request: registration_request_bytes, registration_response: registration_response_bytes, registration_upload: registration_upload_bytes, @@ -582,7 +558,6 @@ fn test_credential_response() -> Result<(), ProtocolError> { CredentialRequest::::deserialize(¶meters.credential_request[..]) .unwrap(), ServerLoginStartParameters::WithInfoAndIdentifiers( - parameters.info2.to_vec(), parameters.einfo2.to_vec(), parameters.id_u, parameters.id_s, @@ -614,18 +589,9 @@ fn test_key_exchange() -> Result<(), ProtocolError> { CredentialResponse::::deserialize( ¶meters.credential_response[..], )?, - ClientLoginFinishParameters::WithInfoAndIdentifiers( - parameters.info3.to_vec(), - parameters.einfo3.to_vec(), - parameters.id_u, - parameters.id_s, - ), + ClientLoginFinishParameters::WithIdentifiers(parameters.id_u, parameters.id_s), )?; - assert_eq!( - hex::encode(¶meters.info2), - hex::encode(&client_login_finish_result.plain_info) - ); assert_eq!( hex::encode(¶meters.einfo2), hex::encode(&client_login_finish_result.confidential_info) @@ -659,14 +625,6 @@ fn test_server_login_finish() -> Result<(), ProtocolError> { CredentialFinalization::try_from(¶meters.key_exchange[..])?, )?; - assert_eq!( - hex::encode(parameters.info3), - hex::encode(server_login_result.plain_info) - ); - assert_eq!( - hex::encode(parameters.einfo3), - hex::encode(server_login_result.confidential_info) - ); assert_eq!( hex::encode(parameters.shared_secret), hex::encode(server_login_result.shared_secret)