diff --git a/src/agreement.rs b/src/agreement.rs index d116c8faab..390c2cdbdc 100644 --- a/src/agreement.rs +++ b/src/agreement.rs @@ -149,6 +149,106 @@ impl EphemeralPrivateKey { } } +/// A static key pair that can be used for multiple exchanges +pub struct StaticKeyPair { + private_key: ec::Seed, + public_key: PublicKey, + algorithm: &'static Algorithm, +} + +derive_debug_via_field!(StaticKeyPair, stringify!(StaticKeyPair), algorithm); + +impl StaticKeyPair { + /// Generate a new static key pair for the given algorithm. + pub fn generate( + alg: &'static Algorithm, + rng: &dyn rand::SecureRandom, + ) -> Result { + let cpu_features = cpu::features(); + + // Generate the private key + let private_key = ec::Seed::generate(&alg.curve, rng, cpu_features)?; + + // Return the keypair + Self::from_private_key(alg, private_key) + } + + /// Constructs a static key pair from the private key `private_key` and its + /// public key `public_key`. + /// + /// The private and public keys will be verified to be consistent with each + /// other. This helps avoid misuse of the key (e.g. accidentally swapping + /// the private key and public key, or using the wrong private key for the + /// public key). This also detects any corruption of the public or private + /// key. + pub fn from_private_and_public_key( + alg: &'static Algorithm, + private_key: &[u8], + public_key: &[u8], + ) -> Result { + let pair = Self::from_private_key_unchecked(alg, private_key)?; + + let pair_public_key: &[u8] = pair.public_key().as_ref(); + if public_key == pair_public_key { + Ok(pair) + } else { + Err(error::Unspecified) + } + } + + /// Constructs a key pair from the private key `private_key`. + /// + /// Since the public key is not given, the public key will be computed from + /// the private key. It is not possible to detect misuse or corruption of + /// the private key since the public key isn't given as input. + pub fn from_private_key_unchecked( + alg: &'static Algorithm, + private_key: &[u8], + ) -> Result { + let cpu_features = cpu::features(); + + // Wrap the byte sequence + let private_key = ec::Seed::from_bytes(&alg.curve, private_key.into(), cpu_features)?; + + // Return the keypair + Self::from_private_key(alg, private_key) + } + + pub(crate) fn from_private_key( + alg: &'static Algorithm, + private_key: ec::Seed, + ) -> Result { + // Derive the public key + let public_key = private_key + .compute_public_key() + .map(|public_key| PublicKey { + algorithm: alg, + bytes: public_key, + })?; + + Ok(Self { + private_key, + public_key, + algorithm: alg, + }) + } + + /// The algorithm for this key pair. + pub fn algorithm(&self) -> &'static Algorithm { + self.algorithm + } + + /// Get the public key + pub fn public_key(&self) -> &PublicKey { + &self.public_key + } + + /// Get the private key + pub fn private_key(&self) -> &[u8] { + self.private_key.bytes_less_safe() + } +} + /// A public key for key agreement. #[derive(Clone)] pub struct PublicKey { @@ -265,11 +365,61 @@ where algorithm: peer_public_key.algorithm, bytes: peer_public_key.bytes.as_ref(), }; - agree_ephemeral_(my_private_key, peer_public_key, error_value, kdf) + agree_( + &my_private_key.private_key, + &my_private_key.algorithm, + peer_public_key, + error_value, + kdf, + ) } -fn agree_ephemeral_( - my_private_key: EphemeralPrivateKey, +/// Performs a key agreement with a static key pair and a peer's public key +/// +/// `my_key_pair` is the static key pair containing the private key to use. In +/// constrast to `EphemeralPrivateKey` a `StaticKeyPair` can be used multiple +/// times. +/// +/// `peer_public_key` is the peer's public key. `agree_static` will return +/// `Err(error_value)` if it does not match `my_key_pair's` algorithm/curve. +/// `agree_static` verifies that it is encoded in the standard form for the +/// algorithm and that the key is *valid*; see the algorithm's documentation for +/// details on how keys are to be encoded and what constitutes a valid key for +/// that algorithm. +/// +/// `error_value` is the value to return if an error occurs before `kdf` is +/// called, e.g. when decoding of the peer's public key fails or when the public +/// key is otherwise invalid. +/// +/// After the key agreement is done, `agree_ephemeral` calls `kdf` with the raw +/// key material from the key agreement operation and then returns what `kdf` +/// returns. +#[inline] +pub fn agree_static, F, R, E>( + my_key_pair: &StaticKeyPair, + peer_public_key: &UnparsedPublicKey, + error_value: E, + kdf: F, +) -> Result +where + F: FnOnce(&[u8]) -> Result, +{ + let peer_public_key = UnparsedPublicKey { + algorithm: peer_public_key.algorithm, + bytes: peer_public_key.bytes.as_ref(), + }; + agree_( + &my_key_pair.private_key, + &my_key_pair.algorithm, + peer_public_key, + error_value, + kdf, + ) +} + +fn agree_( + my_private_key: &ec::Seed, + alg: &Algorithm, peer_public_key: UnparsedPublicKey<&[u8]>, error_value: E, kdf: F, @@ -282,12 +432,10 @@ where // The domain parameters are hard-coded. This check verifies that the // peer's public key's domain parameters match the domain parameters of // this private key. - if peer_public_key.algorithm != my_private_key.algorithm { + if peer_public_key.algorithm != alg { return Err(error_value); } - let alg = &my_private_key.algorithm; - // NSA Guide Prerequisite 2, regarding which KDFs are allowed, is delegated // to the caller. @@ -307,7 +455,7 @@ where // that doesn't meet the NSA requirement to "zeroize." (alg.ecdh)( shared_key, - &my_private_key.private_key, + &my_private_key, untrusted::Input::from(peer_public_key.bytes), ) .map_err(|_| error_value)?; diff --git a/tests/agreement_tests.rs b/tests/agreement_tests.rs index 4162015378..365c8efa47 100644 --- a/tests/agreement_tests.rs +++ b/tests/agreement_tests.rs @@ -60,9 +60,93 @@ fn agreement_traits() { } #[test] -fn agreement_agree_ephemeral() { +fn agreement_public_key() { let rng = rand::SystemRandom::new(); + test::run( + test_file!("agreement_tests_pubkey.txt"), + |section, test_case| { + assert_eq!(section, ""); + + let curve_name = test_case.consume_string("Curve"); + let alg = alg_from_curve_name(&curve_name); + let peer_public = + agreement::UnparsedPublicKey::new(alg, test_case.consume_bytes("PeerQ")); + let _error = test_case.consume_string("Error"); + + // In the no-heap mode, some algorithms aren't supported so + // we have to skip those algorithms' test cases. + let dummy_private_key = agreement::EphemeralPrivateKey::generate(alg, &rng)?; + fn kdf_not_called(_: &[u8]) -> Result<(), ()> { + panic!( + "The KDF was called during ECDH when the peer's \ + public key is invalid." + ); + } + assert!(agreement::agree_ephemeral( + dummy_private_key, + &peer_public, + (), + kdf_not_called + ) + .is_err()); + + Ok(()) + }, + ); +} + +#[test] +fn agreement_private_key() { + test::run( + test_file!("agreement_tests_privkey.txt"), + |section, test_case| { + assert_eq!(section, ""); + + let curve_name = test_case.consume_string("Curve"); + let alg = alg_from_curve_name(&curve_name); + let private_key = test_case.consume_bytes("D"); + let _error = test_case.consume_string("Error"); + + let pair = agreement::StaticKeyPair::from_private_key_unchecked(&alg, &private_key[..]); + assert!(pair.is_err()); + + Ok(()) + }, + ); +} + +#[test] +fn agreement_static_key_pair() { + static ALGORITHMS: [&agreement::Algorithm; 3] = [ + &agreement::ECDH_P256, + &agreement::ECDH_P384, + &agreement::X25519, + ]; + + let rng = rand::SystemRandom::new(); + + for alg in ALGORITHMS.iter() { + let pair1 = agreement::StaticKeyPair::generate(alg, &rng).unwrap(); + let pk1: &[u8] = pair1.public_key().as_ref(); + let sk1: &[u8] = pair1.private_key(); + + let pair2 = agreement::StaticKeyPair::from_private_key_unchecked(alg, sk1).unwrap(); + let pk2: &[u8] = pair2.public_key().as_ref(); + let sk2: &[u8] = pair2.private_key(); + assert_eq!(pk2, pk1); + assert_eq!(sk2, sk1); + + let pair3 = agreement::StaticKeyPair::from_private_and_public_key(alg, sk1, pk1).unwrap(); + let pk3: &[u8] = pair3.public_key().as_ref(); + let sk3: &[u8] = pair3.private_key(); + assert_eq!(pk3, pk1); + assert_eq!(sk3, sk1); + } +} + +#[test] +fn agreement_agree_ephemeral() { test::run(test_file!("agreement_tests.txt"), |section, test_case| { assert_eq!(section, ""); @@ -70,50 +154,56 @@ fn agreement_agree_ephemeral() { let alg = alg_from_curve_name(&curve_name); let peer_public = agreement::UnparsedPublicKey::new(alg, test_case.consume_bytes("PeerQ")); - match test_case.consume_optional_string("Error") { - None => { - let my_private = test_case.consume_bytes("D"); - let my_private = { - let rng = test::rand::FixedSliceRandom { bytes: &my_private }; - agreement::EphemeralPrivateKey::generate(alg, &rng)? - }; - let my_public = test_case.consume_bytes("MyQ"); - let output = test_case.consume_bytes("Output"); - - assert_eq!(my_private.algorithm(), alg); - - let computed_public = my_private.compute_public_key().unwrap(); - assert_eq!(computed_public.as_ref(), &my_public[..]); - - assert_eq!(my_private.algorithm(), alg); - - let result = - agreement::agree_ephemeral(my_private, &peer_public, (), |key_material| { - assert_eq!(key_material, &output[..]); - Ok(()) - }); - assert_eq!(result, Ok(())); - } + let my_private = test_case.consume_bytes("D"); + let my_private = { + let rng = test::rand::FixedSliceRandom { bytes: &my_private }; + agreement::EphemeralPrivateKey::generate(alg, &rng)? + }; + let my_public = test_case.consume_bytes("MyQ"); + let output = test_case.consume_bytes("Output"); - Some(_) => { - // In the no-heap mode, some algorithms aren't supported so - // we have to skip those algorithms' test cases. - let dummy_private_key = agreement::EphemeralPrivateKey::generate(alg, &rng)?; - fn kdf_not_called(_: &[u8]) -> Result<(), ()> { - panic!( - "The KDF was called during ECDH when the peer's \ - public key is invalid." - ); - } - assert!(agreement::agree_ephemeral( - dummy_private_key, - &peer_public, - (), - kdf_not_called - ) - .is_err()); - } - } + assert_eq!(my_private.algorithm(), alg); + + let computed_public = my_private.compute_public_key().unwrap(); + assert_eq!(computed_public.as_ref(), &my_public[..]); + + assert_eq!(my_private.algorithm(), alg); + + let result = agreement::agree_ephemeral(my_private, &peer_public, (), |key_material| { + assert_eq!(key_material, &output[..]); + Ok(()) + }); + assert_eq!(result, Ok(())); + + Ok(()) + }); +} + +#[test] +fn agreement_agree_static() { + test::run(test_file!("agreement_tests.txt"), |section, test_case| { + assert_eq!(section, ""); + + let curve_name = test_case.consume_string("Curve"); + let alg = alg_from_curve_name(&curve_name); + let peer_public = agreement::UnparsedPublicKey::new(alg, test_case.consume_bytes("PeerQ")); + + let my_private = test_case.consume_bytes("D"); + let my_pair = + agreement::StaticKeyPair::from_private_key_unchecked(&alg, &my_private).unwrap(); + let my_public = test_case.consume_bytes("MyQ"); + let output = test_case.consume_bytes("Output"); + + assert_eq!(my_pair.algorithm(), alg); + + let computed_public = my_pair.public_key(); + assert_eq!(computed_public.as_ref(), &my_public[..]); + + let result = agreement::agree_static(&my_pair, &peer_public, (), |key_material| { + assert_eq!(key_material, &output[..]); + Ok(()) + }); + assert_eq!(result, Ok(())); Ok(()) }); diff --git a/tests/agreement_tests.txt b/tests/agreement_tests.txt index 354d8ae709..f733f5bc6e 100644 --- a/tests/agreement_tests.txt +++ b/tests/agreement_tests.txt @@ -17,30 +17,6 @@ D = 4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d MyQ = ff63fe57bfbf43fa3f563628b149af704d3db625369c49983650347a6a71e00e Output = 95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957 - -# Additional X25519 Test Vectors - -Curve = X25519 -PeerQ = "" -Error = Peer public key is empty. - -Curve = X25519 -PeerQ = 00 -Error = Peer public key is too short. - -Curve = X25519 -PeerQ = e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a4 -Error = Peer public key is too short. - -Curve = X25519 -PeerQ = e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a49300 -Error = Peer public key is too long (zero appended). - -Curve = X25519 -PeerQ = 00e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493 -Error = Peer public key is too long (zero prepended). - - # RFC 5903 (IKE and IKEv2 ECDH) Test Vectors # # PeerQ is (grx, gry) in uncompressed encoding. @@ -60,147 +36,6 @@ D = 099F3C7034D4A2C699884D73A375A67F7624EF7C6B3C0F160647B67414DCE655E35B538041E6 MyQ = 04667842D7D180AC2CDE6F74F37551F55755C7645C20EF73E31634FE72B4C55EE6DE3AC808ACB4BDB4C88732AEE95F41AA9482ED1FC0EEB9CAFC4984625CCFC23F65032149E0E144ADA024181535A0F38EEB9FCFF3C2C947DAE69B4C634573A81C Output = 11187331C279962D93D604243FD592CB9D0A926F422E47187521287E7156C5C4D603135569B9E9D09CF5D4A270F59746 - -# Tweaks of the RFC 5903 vectors for testing malformed (syntactically) public -# keys - -Curve = P-256 -PeerQ = "" -Error = Peer public key is empty. - -Curve = P-384 -PeerQ = "" -Error = Peer public key is empty. - -Curve = P-256 -PeerQ = 00 -Error = Peer public key is the special encoding of the point at infinity. - -Curve = P-384 -PeerQ = 00 -Error = Peer public key is the special encoding of the point at infinity. - -Curve = P-256 -PeerQ = 01 -Error = Peer public key consists of (only) an invalid encoding indicator. - -Curve = P-384 -PeerQ = 01 -Error = Peer public key consists of (only) an invalid encoding indicator. - -Curve = P-256 -PeerQ = 02 -Error = Peer public key consists of (only) a compressed encoding indicator (0x02). - -Curve = P-384 -PeerQ = 02 -Error = Peer public key consists of (only) a compressed encoding indicator (0x02). - -Curve = P-256 -PeerQ = 03 -Error = Peer public key consists of (only) a compressed encoding indicator (0x03). - -Curve = P-384 -PeerQ = 03 -Error = Peer public key consists of (only) a compressed encoding indicator (0x03). - -Curve = P-256 -PeerQ = 04 -Error = Peer public key consists of (only) a uncompressed encoding indicator. - -Curve = P-384 -PeerQ = 04 -Error = Peer public key consists of (only) a compressed encoding indicator. - -Curve = P-256 -PeerQ = 04 -Error = Peer public key consists of (only) an invalid encoding indicator (0x05). - -Curve = P-384 -PeerQ = 04 -Error = Peer public key consists of (only) an invalid encoding indicator (0x05). - -Curve = P-256 -PeerQ = 01D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB -Error = Peer public key starts with a completely invalid encoding indicator byte (0x01). - -Curve = P-384 -PeerQ = 01E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C -Error = Peer public key starts with a completely invalid encoding indicator byte (0x01). - -Curve = P-256 -PeerQ = 02D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB -Error = Peer public key encoding's first byte is 0x02, should be 0x04. - -Curve = P-384 -PeerQ = 02E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C -Error = Peer public key encoding's first byte is 0x02, should be 0x04. - -Curve = P-256 -PeerQ = 03D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB -Error = Peer public key encoding's first byte is 0x03, should be 0x04. - -Curve = P-384 -PeerQ = 03E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C -Error = Peer public key encoding's first byte is 0x03, should be 0x04. - -Curve = P-256 -PeerQ = 05D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB -Error = Peer public key starts with a completely invalid encoding indicator byte (0x05). - -Curve = P-384 -PeerQ = 05E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C -Error = Peer public key starts with a completely invalid encoding indicator byte (0x05). - -Curve = P-256 -PeerQ = FFD12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB -Error = Peer public key starts with a completely invalid encoding indicator byte (0xff). - -Curve = P-384 -PeerQ = FFE558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C -Error = Peer public key starts with a completely invalid encoding indicator byte (0xff). - -Curve = P-256 -PeerQ = D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB -Error = Peer public key is missing the encoding indicator byte. - -Curve = P-384 -PeerQ = E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C -Error = Peer public key is missing the encoding indicator byte. - -Curve = P-256 -PeerQ = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872 -Error = Peer public key has the last byte truncated. - -Curve = P-384 -PeerQ = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E638 -Error = Peer public key has the last byte truncated. - -Curve = P-256 -PeerQ = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63 -Error = Peer public key is missing the Y coordinate completely. - -Curve = P-384 -PeerQ = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571 -Error = Peer public key is missing the Y coordinate completely. - -Curve = P-256 -PeerQ = 02D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63 -Error = Peer public key is in compressed form (0x02). - -Curve = P-384 -PeerQ = 02E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571 -Error = Peer public key is in compressed form (0x02). - -Curve = P-256 -PeerQ = 03D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63 -Error = Peer public key is in compressed form (0x03). - -Curve = P-384 -PeerQ = 03E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571 -Error = Peer public key is in compressed form (0x03). - - # NIST vectors from # http://csrc.nist.gov/groups/STM/cavp/documents/components/ecccdhtestvectors.zip # @@ -516,126 +351,3 @@ PeerQ = 0429d8a36d22200a75b7aea1bb47cdfcb1b7fd66de967041434728ab5d533a060df73213 D = 74ad8386c1cb2ca0fcdeb31e0869bb3f48c036afe2ef110ca302bc8b910f621c9fcc54cec32bb89ec7caa84c7b8e54a8 MyQ = 0427a3e83cfb9d5122e73129d801615857da7cc089cccc9c54ab3032a19e0a0a9f677346e37f08a0b3ed8da6e5dd6910638d60e44aa5e0fd30c918456796af37f0e41957901645e5c596c6d989f5859b03a0bd7d1f4e77936fff3c74d204e5388e Output = 81e1e71575bb4505498de097350186430a6242fa6c57b85a5f984a23371123d2d1424eefbf804258392bc723e4ef1e35 - - -# Test vectors from NIST where the peer's public key validation fails. -# -# These vectors were taken from the file -# KASValidityTest_ECCEphemeralUnified_KDFConcat_NOKC_init.fax in -# http://csrc.nist.gov/groups/STM/cavp/documents/keymgmt/KASTestVectorsECC2014.zip -# accessible via -# http://csrc.nist.gov/groups/STM/cavp/key-establishment.html#test-vectors. -# -# Only the test vectors where the test fails because the peer's public key is -# invalid are included here. Supporting the other vectors would require -# implementing an entire key exchange protocol; since the omitted test vectors -# don't seem to stress any *edge cases* of the *ECDH* step of the key exchange -# protocol, they don't seem valuable. -# -# PeerQ = (QeCAVSx, QeCAVSy) in uncompressed encoding. -# Error is the error text from the Result field. The errors reference -# "PKV 5.6.2.5" which is section 5.6.2.5 of -# http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf -# which is section 5.6.2.3.2/5.6.2.3.3 of -# http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf - -# [EC - SHA-256, COUNT = 4] -Curve = P-256 -PeerQ = 04eec6ea7be0362fa496af12e551982a7d9c06b5ef735fadc37990c78ab9be87f4f45058db687e98326036c88eb846476a05385d7bda1d6dd6ca600499b7cc613f -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [EC - SHA-256, COUNT = 12] -Curve = P-256 -PeerQ = 0439883b3aadd78b044dadbd9be6a2cc8360da8df4241a4d11665a14e1ce17d19296d5cc675c252d902da5118245e738d57442ca042add79f1d07752bb98a7b805 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [EC - SHA-256, COUNT = 12] -Curve = P-256 -PeerQ = 0462ff2c3f5e165afa8dc919b7d705c862855d87869b8440c8d98db2ccb6144e3634a0335ebf64d77dc1c90fd5a5957c0d062593e8891d339f4b3616eb05018103 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [EC - SHA-256, COUNT = 20] -Curve = P-256 -PeerQ = 04eaa4b595bd200d3197a35fad5afbee310ac2da532237d5623e1285bdcaa2422177735e831623cd5d67b45e9ca947a48055bdc5f3cca81f75ab124c92ea62091c -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [EC - SHA384, COUNT = 3] -Curve = P-256 -PeerQ = 0482022f7a7507a5fdf191b7474d8503f1c2f31ef654096f28d046ff0b1f07d59406b2c2ff0fdcc2d913d6f3fbe02fded8543cd6aff9304213acc9cfd8f4d52803 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [EC - SHA384, COUNT = 9] -Curve = P-256 -PeerQ = 045ce1fd24f150bb8714c7c12ed1d85fb8bd597f6e4a8c27eaabd3348903abf91261941a5cd8978c1cfaf6b0f67441dcc5a3686adc7dd1e157f138c9ce48634019 -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [EC - SHA384, COUNT = 24] -Curve = P-256 -PeerQ = 04d441c98190cf34cff0ba0dbafbade26c4cadcd5438bb5324e136851b09c009ac14c355a01189339a5a9a4f8a8ed57d7f6537ed161882c1e6912f8e3512faad0f -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [EC - SHA384, COUNT = 25] -Curve = P-256 -PeerQ = 048dfc7063c55a1fe8684ff6675ad4b53dab503e409c12058ab602c40c143ef84cbe0fce323492ee123e2a543b26b327139f234a08355dd60e2fc2c0babf1a10e3 -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [EC - SHA512, COUNT = 0] -Curve = P-256 -PeerQ = 04eb65aaefab96a190a67e566978a179826cf4e04634013f7fe1547a749f3cf6e91d89dfdf23dc14fca68c7c138e90a0d9ee7bcdded8d80e6e409c7f0041d50b80 -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [EC - SHA512, COUNT = 5] -Curve = P-256 -PeerQ = 040d0d6e855cd97a1b5a5e52593b8ceac553be06a19090c5442e521731c08e7fc5efa166e25741659bfa5b257a23f36e7d9f08e084610be8dfd8c6844d0ea860b9 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [EC - SHA512, COUNT = 26] -Curve = P-256 -PeerQ = 047417e66bbf708b258079648e1a9500d969f2d3860bd606054b611bc853228a324aade59d9ffb73cec6083887f5887c0306deb68e6aa984bbdad141635d078e79 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [EC - SHA512, COUNT = 29] -Curve = P-256 -PeerQ = 04d9313d9b7c9abebba2d4cb3c05e3393bd5da667efa74c9d4cc33d2e54446d8d9904240a61c8d7f5ff2028041a81e1408451f4c0e0a18fcf33557546dfc380a06 -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - - -# [ED - SHA384, COUNT = 1] -Curve = P-384 -PeerQ = 04eed1bfbefb4c3b568ba187893d0d66f0a266928e57f5903213690cfe55660ce86d7eccf9ad1503932c31ab23917bc759a6e69055c5b84ccd92a414b84283bf89ebb85a850f03e02016a12ff22a4af6f80dd3900f68153b81e02c3f0c3d045d69 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [ED - SHA384, COUNT = 2] -Curve = P-384 -PeerQ = 04f081e7e14fcfbf38e3780f57822e8255452e96c673e4b49ebda246b0a5dbca279935e5b31f94eff8ac753aecc810f5ac4dd779b89b0fb7460fe0c50d90006fc5ad7a7a31fe6b827ec059c3b22b40611dbad54c75e653bbdb408fe2e5e24246ae -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [ED - SHA384, COUNT = 19] -Curve = P-384 -PeerQ = 0412159e7a89210ff0a5f723904a10c2425a13cfe9016b65cdb48285ec27912b66e415079ced48c94e707963bf5af66cd6ca8c934a135d8d3607f5792b63f127056e715eb4deabd501e6d3e3cfb6eb554c684c10c4a2b31df16fb8d9082131fa09 -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [ED - SHA384, COUNT = 28] -Curve = P-384 -PeerQ = 04a308a4cadf229c47fd74de1d1b6e07722ed87fa7506a0ddb8eb2060ca0f93ced5973a76d9e622b7519142ec41969a825fbb34034f8a6ead96a600281a01306b1a8d9a3148e4fb2e9727a4cec6a62b16690f3480a96a5f42dee895a2d456eb0f2 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [ED - SHA512, COUNT = 11] -Curve = P-384 -PeerQ = 04ca8e02c55ea6756f5f65d213649c400296a6961d37947025f9d448042ed9c1f3da4e88842f64c1e8a5c2215d57e16cb0697b0923dc80e38fca5381b9a9d59c6f29337adcc7ff183cbb42f267956d130b0b53cb51ba459731001a39093b97db8c -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 - -# [ED - SHA512, COUNT = 13] -Curve = P-384 -PeerQ = 045cb621e4a2186b552961cb7fa8e8191d21335c8fbf2eff27cc44f27a3ae5aa4d000c146279979cbe2cd901ee1619494abd0f8333b8ad65f621271c30386cb455bd66fde88705c57490638c3a6b73c27c4982eba177b0fb867d253d4fccac2361 -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [ED - SHA512, COUNT = 20] -Curve = P-384 -PeerQ = 04fd2a7437151a1df4949386fccec7509d731c36dc7ceae03c1ecd9b2b2a413853f5fe2066b4a52082a0a538b0536f6df670132a719f37a02a8fa12ed714876b17fe4d923abe50e7dd371172293336921229fcd44376dd52a2969f459c4a95f11f -Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 - -# [ED - SHA512, COUNT = 28] -Curve = P-384 -PeerQ = 0432d3118ba89149e3f75623098a258d5df0706730a256ee257e04b0a39cf8dfb631c4e31f476d40e538798048dc641138081f05d14000f9dcf2c98245951b6ab55ab9b4687eb36e3aae5391c3c3a0aefff41aebebc6bf027d268aa3153a017bd6 -Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 diff --git a/tests/agreement_tests_privkey.txt b/tests/agreement_tests_privkey.txt new file mode 100644 index 0000000000..11bddd7a07 --- /dev/null +++ b/tests/agreement_tests_privkey.txt @@ -0,0 +1,65 @@ +# X25519 Private Key Test Vectors (derived from RFC 7748 test vectors) + +Curve = X25519 +D = "" +Error = Private key is empty. + +Curve = X25519 +D = 00 +Error = Private key is too short. + +Curve = X25519 +D = a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a +Error = Private key is too short. + +Curve = X25519 +D = a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac400 +Error = Private key is too long (zero appendend). + +Curve = X25519 +D = 00a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4 +Error = Private key is too long (zero prepended). + + +# Tweaks of the RFC 5903 vectors for testing malformed (syntactically) private +# keys + +Curve = P-256 +D = "" +Error = Private key is empty. + +Curve = P-256 +D = 00 +Error = Private key is too short. + +Curve = P-256 +D = C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D14 +Error = Private key is too short. + +Curve = P-256 +D = C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D143300 +Error = Private key is too long (zero appendend). + +Curve = P-256 +D = 00C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433 +Error = Private key is too long (zero prepended). + +Curve = P-384 +D = "" +Error = Private key is empty. + +Curve = P-384 +D = 00 +Error = Private key is too short. + +Curve = P-384 +D = 099F3C7034D4A2C699884D73A375A67F7624EF7C6B3C0F160647B67414DCE655E35B538041E649EE3FAEF896783AB1 +Error = Private key is too short. + +Curve = P-384 +D = 099F3C7034D4A2C699884D73A375A67F7624EF7C6B3C0F160647B67414DCE655E35B538041E649EE3FAEF896783AB19400 +Error = Private key is too long (zero appendend). + +Curve = P-384 +D = 00099F3C7034D4A2C699884D73A375A67F7624EF7C6B3C0F160647B67414DCE655E35B538041E649EE3FAEF896783AB194 +Error = Private key is too long (zero prepended). diff --git a/tests/agreement_tests_pubkey.txt b/tests/agreement_tests_pubkey.txt new file mode 100644 index 0000000000..3c7e40ac82 --- /dev/null +++ b/tests/agreement_tests_pubkey.txt @@ -0,0 +1,284 @@ +# X25519 Public Key Test Vectors (derived from RFC 7748 test vectors) + +Curve = X25519 +PeerQ = "" +Error = Peer public key is empty. + +Curve = X25519 +PeerQ = 00 +Error = Peer public key is too short. + +Curve = X25519 +PeerQ = e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a4 +Error = Peer public key is too short. + +Curve = X25519 +PeerQ = e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a49300 +Error = Peer public key is too long (zero appended). + +Curve = X25519 +PeerQ = 00e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493 +Error = Peer public key is too long (zero prepended). + + +# Tweaks of the RFC 5903 vectors for testing malformed (syntactically) public +# keys + +Curve = P-256 +PeerQ = "" +Error = Peer public key is empty. + +Curve = P-384 +PeerQ = "" +Error = Peer public key is empty. + +Curve = P-256 +PeerQ = 00 +Error = Peer public key is the special encoding of the point at infinity. + +Curve = P-384 +PeerQ = 00 +Error = Peer public key is the special encoding of the point at infinity. + +Curve = P-256 +PeerQ = 01 +Error = Peer public key consists of (only) an invalid encoding indicator. + +Curve = P-384 +PeerQ = 01 +Error = Peer public key consists of (only) an invalid encoding indicator. + +Curve = P-256 +PeerQ = 02 +Error = Peer public key consists of (only) a compressed encoding indicator (0x02). + +Curve = P-384 +PeerQ = 02 +Error = Peer public key consists of (only) a compressed encoding indicator (0x02). + +Curve = P-256 +PeerQ = 03 +Error = Peer public key consists of (only) a compressed encoding indicator (0x03). + +Curve = P-384 +PeerQ = 03 +Error = Peer public key consists of (only) a compressed encoding indicator (0x03). + +Curve = P-256 +PeerQ = 04 +Error = Peer public key consists of (only) a uncompressed encoding indicator. + +Curve = P-384 +PeerQ = 04 +Error = Peer public key consists of (only) a compressed encoding indicator. + +Curve = P-256 +PeerQ = 04 +Error = Peer public key consists of (only) an invalid encoding indicator (0x05). + +Curve = P-384 +PeerQ = 04 +Error = Peer public key consists of (only) an invalid encoding indicator (0x05). + +Curve = P-256 +PeerQ = 01D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB +Error = Peer public key starts with a completely invalid encoding indicator byte (0x01). + +Curve = P-384 +PeerQ = 01E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C +Error = Peer public key starts with a completely invalid encoding indicator byte (0x01). + +Curve = P-256 +PeerQ = 02D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB +Error = Peer public key encoding's first byte is 0x02, should be 0x04. + +Curve = P-384 +PeerQ = 02E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C +Error = Peer public key encoding's first byte is 0x02, should be 0x04. + +Curve = P-256 +PeerQ = 03D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB +Error = Peer public key encoding's first byte is 0x03, should be 0x04. + +Curve = P-384 +PeerQ = 03E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C +Error = Peer public key encoding's first byte is 0x03, should be 0x04. + +Curve = P-256 +PeerQ = 05D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB +Error = Peer public key starts with a completely invalid encoding indicator byte (0x05). + +Curve = P-384 +PeerQ = 05E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C +Error = Peer public key starts with a completely invalid encoding indicator byte (0x05). + +Curve = P-256 +PeerQ = FFD12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB +Error = Peer public key starts with a completely invalid encoding indicator byte (0xff). + +Curve = P-384 +PeerQ = FFE558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C +Error = Peer public key starts with a completely invalid encoding indicator byte (0xff). + +Curve = P-256 +PeerQ = D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB +Error = Peer public key is missing the encoding indicator byte. + +Curve = P-384 +PeerQ = E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E6386C +Error = Peer public key is missing the encoding indicator byte. + +Curve = P-256 +PeerQ = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF6356FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872 +Error = Peer public key has the last byte truncated. + +Curve = P-384 +PeerQ = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571DCFBEC7AACF3196472169E838430367F66EEBE3C6E70C416DD5F0C68759DD1FFF83FA40142209DFF5EAAD96DB9E638 +Error = Peer public key has the last byte truncated. + +Curve = P-256 +PeerQ = 04D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63 +Error = Peer public key is missing the Y coordinate completely. + +Curve = P-384 +PeerQ = 04E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571 +Error = Peer public key is missing the Y coordinate completely. + +Curve = P-256 +PeerQ = 02D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63 +Error = Peer public key is in compressed form (0x02). + +Curve = P-384 +PeerQ = 02E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571 +Error = Peer public key is in compressed form (0x02). + +Curve = P-256 +PeerQ = 03D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63 +Error = Peer public key is in compressed form (0x03). + +Curve = P-384 +PeerQ = 03E558DBEF53EECDE3D3FCCFC1AEA08A89A987475D12FD950D83CFA41732BC509D0D1AC43A0336DEF96FDA41D0774A3571 +Error = Peer public key is in compressed form (0x03). + + +# Test vectors from NIST where the peer's public key validation fails. +# +# These vectors were taken from the file +# KASValidityTest_ECCEphemeralUnified_KDFConcat_NOKC_init.fax in +# http://csrc.nist.gov/groups/STM/cavp/documents/keymgmt/KASTestVectorsECC2014.zip +# accessible via +# http://csrc.nist.gov/groups/STM/cavp/key-establishment.html#test-vectors. +# +# Only the test vectors where the test fails because the peer's public key is +# invalid are included here. Supporting the other vectors would require +# implementing an entire key exchange protocol; since the omitted test vectors +# don't seem to stress any *edge cases* of the *ECDH* step of the key exchange +# protocol, they don't seem valuable. +# +# PeerQ = (QeCAVSx, QeCAVSy) in uncompressed encoding. +# Error is the error text from the Result field. The errors reference +# "PKV 5.6.2.5" which is section 5.6.2.5 of +# http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf +# which is section 5.6.2.3.2/5.6.2.3.3 of +# http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf + +# [EC - SHA-256, COUNT = 4] +Curve = P-256 +PeerQ = 04eec6ea7be0362fa496af12e551982a7d9c06b5ef735fadc37990c78ab9be87f4f45058db687e98326036c88eb846476a05385d7bda1d6dd6ca600499b7cc613f +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [EC - SHA-256, COUNT = 12] +Curve = P-256 +PeerQ = 0439883b3aadd78b044dadbd9be6a2cc8360da8df4241a4d11665a14e1ce17d19296d5cc675c252d902da5118245e738d57442ca042add79f1d07752bb98a7b805 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [EC - SHA-256, COUNT = 12] +Curve = P-256 +PeerQ = 0462ff2c3f5e165afa8dc919b7d705c862855d87869b8440c8d98db2ccb6144e3634a0335ebf64d77dc1c90fd5a5957c0d062593e8891d339f4b3616eb05018103 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [EC - SHA-256, COUNT = 20] +Curve = P-256 +PeerQ = 04eaa4b595bd200d3197a35fad5afbee310ac2da532237d5623e1285bdcaa2422177735e831623cd5d67b45e9ca947a48055bdc5f3cca81f75ab124c92ea62091c +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [EC - SHA384, COUNT = 3] +Curve = P-256 +PeerQ = 0482022f7a7507a5fdf191b7474d8503f1c2f31ef654096f28d046ff0b1f07d59406b2c2ff0fdcc2d913d6f3fbe02fded8543cd6aff9304213acc9cfd8f4d52803 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [EC - SHA384, COUNT = 9] +Curve = P-256 +PeerQ = 045ce1fd24f150bb8714c7c12ed1d85fb8bd597f6e4a8c27eaabd3348903abf91261941a5cd8978c1cfaf6b0f67441dcc5a3686adc7dd1e157f138c9ce48634019 +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [EC - SHA384, COUNT = 24] +Curve = P-256 +PeerQ = 04d441c98190cf34cff0ba0dbafbade26c4cadcd5438bb5324e136851b09c009ac14c355a01189339a5a9a4f8a8ed57d7f6537ed161882c1e6912f8e3512faad0f +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [EC - SHA384, COUNT = 25] +Curve = P-256 +PeerQ = 048dfc7063c55a1fe8684ff6675ad4b53dab503e409c12058ab602c40c143ef84cbe0fce323492ee123e2a543b26b327139f234a08355dd60e2fc2c0babf1a10e3 +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [EC - SHA512, COUNT = 0] +Curve = P-256 +PeerQ = 04eb65aaefab96a190a67e566978a179826cf4e04634013f7fe1547a749f3cf6e91d89dfdf23dc14fca68c7c138e90a0d9ee7bcdded8d80e6e409c7f0041d50b80 +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [EC - SHA512, COUNT = 5] +Curve = P-256 +PeerQ = 040d0d6e855cd97a1b5a5e52593b8ceac553be06a19090c5442e521731c08e7fc5efa166e25741659bfa5b257a23f36e7d9f08e084610be8dfd8c6844d0ea860b9 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [EC - SHA512, COUNT = 26] +Curve = P-256 +PeerQ = 047417e66bbf708b258079648e1a9500d969f2d3860bd606054b611bc853228a324aade59d9ffb73cec6083887f5887c0306deb68e6aa984bbdad141635d078e79 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [EC - SHA512, COUNT = 29] +Curve = P-256 +PeerQ = 04d9313d9b7c9abebba2d4cb3c05e3393bd5da667efa74c9d4cc33d2e54446d8d9904240a61c8d7f5ff2028041a81e1408451f4c0e0a18fcf33557546dfc380a06 +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + + +# [ED - SHA384, COUNT = 1] +Curve = P-384 +PeerQ = 04eed1bfbefb4c3b568ba187893d0d66f0a266928e57f5903213690cfe55660ce86d7eccf9ad1503932c31ab23917bc759a6e69055c5b84ccd92a414b84283bf89ebb85a850f03e02016a12ff22a4af6f80dd3900f68153b81e02c3f0c3d045d69 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [ED - SHA384, COUNT = 2] +Curve = P-384 +PeerQ = 04f081e7e14fcfbf38e3780f57822e8255452e96c673e4b49ebda246b0a5dbca279935e5b31f94eff8ac753aecc810f5ac4dd779b89b0fb7460fe0c50d90006fc5ad7a7a31fe6b827ec059c3b22b40611dbad54c75e653bbdb408fe2e5e24246ae +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [ED - SHA384, COUNT = 19] +Curve = P-384 +PeerQ = 0412159e7a89210ff0a5f723904a10c2425a13cfe9016b65cdb48285ec27912b66e415079ced48c94e707963bf5af66cd6ca8c934a135d8d3607f5792b63f127056e715eb4deabd501e6d3e3cfb6eb554c684c10c4a2b31df16fb8d9082131fa09 +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [ED - SHA384, COUNT = 28] +Curve = P-384 +PeerQ = 04a308a4cadf229c47fd74de1d1b6e07722ed87fa7506a0ddb8eb2060ca0f93ced5973a76d9e622b7519142ec41969a825fbb34034f8a6ead96a600281a01306b1a8d9a3148e4fb2e9727a4cec6a62b16690f3480a96a5f42dee895a2d456eb0f2 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [ED - SHA512, COUNT = 11] +Curve = P-384 +PeerQ = 04ca8e02c55ea6756f5f65d213649c400296a6961d37947025f9d448042ed9c1f3da4e88842f64c1e8a5c2215d57e16cb0697b0923dc80e38fca5381b9a9d59c6f29337adcc7ff183cbb42f267956d130b0b53cb51ba459731001a39093b97db8c +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5 + +# [ED - SHA512, COUNT = 13] +Curve = P-384 +PeerQ = 045cb621e4a2186b552961cb7fa8e8191d21335c8fbf2eff27cc44f27a3ae5aa4d000c146279979cbe2cd901ee1619494abd0f8333b8ad65f621271c30386cb455bd66fde88705c57490638c3a6b73c27c4982eba177b0fb867d253d4fccac2361 +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [ED - SHA512, COUNT = 20] +Curve = P-384 +PeerQ = 04fd2a7437151a1df4949386fccec7509d731c36dc7ceae03c1ecd9b2b2a413853f5fe2066b4a52082a0a538b0536f6df670132a719f37a02a8fa12ed714876b17fe4d923abe50e7dd371172293336921229fcd44376dd52a2969f459c4a95f11f +Error = 4 - CAVS's Ephemeral public key Y fails PKV 5.6.2.5 + +# [ED - SHA512, COUNT = 28] +Curve = P-384 +PeerQ = 0432d3118ba89149e3f75623098a258d5df0706730a256ee257e04b0a39cf8dfb631c4e31f476d40e538798048dc641138081f05d14000f9dcf2c98245951b6ab55ab9b4687eb36e3aae5391c3c3a0aefff41aebebc6bf027d268aa3153a017bd6 +Error = 3 - CAVS's Ephemeral public key X fails PKV 5.6.2.5