diff options
Diffstat (limited to 'toolkit/components/telemetry/dap')
7 files changed, 129 insertions, 89 deletions
diff --git a/toolkit/components/telemetry/dap/DAPTelemetrySender.sys.mjs b/toolkit/components/telemetry/dap/DAPTelemetrySender.sys.mjs index 9dcc949788..b948e80681 100644 --- a/toolkit/components/telemetry/dap/DAPTelemetrySender.sys.mjs +++ b/toolkit/components/telemetry/dap/DAPTelemetrySender.sys.mjs @@ -35,7 +35,12 @@ XPCOMUtils.defineLazyPreferenceGetter(lazy, "HELPER", PREF_HELPER, undefined); */ export const DAPTelemetrySender = new (class { - startup() { + async startup() { + await lazy.NimbusFeatures.dapTelemetry.ready(); + if (!lazy.NimbusFeatures.dapTelemetry.getVariable("enabled")) { + return; + } + lazy.logConsole.debug("Performing DAP startup"); if (lazy.NimbusFeatures.dapTelemetry.getVariable("visitCountingEnabled")) { diff --git a/toolkit/components/telemetry/dap/ffi-gtest/Cargo.toml b/toolkit/components/telemetry/dap/ffi-gtest/Cargo.toml index abad140b7d..3abbb9d60c 100644 --- a/toolkit/components/telemetry/dap/ffi-gtest/Cargo.toml +++ b/toolkit/components/telemetry/dap/ffi-gtest/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" [dependencies] dap_ffi = { path = "../ffi" } hex = { version = "0.4.3", features = ["serde"] } -prio = {version = "0.15.3", default-features = false } +prio = {version = "0.16.2", default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } thin-vec = { version = "0.2.1", features = ["gecko-ffi"] } diff --git a/toolkit/components/telemetry/dap/ffi-gtest/test.rs b/toolkit/components/telemetry/dap/ffi-gtest/test.rs index 3871965107..874e0e99a5 100644 --- a/toolkit/components/telemetry/dap/ffi-gtest/test.rs +++ b/toolkit/components/telemetry/dap/ffi-gtest/test.rs @@ -17,7 +17,7 @@ use prio::codec::{Decode, Encode}; pub extern "C" fn dap_test_encoding() { let r = Report::new_dummy(); let mut encoded = Vec::<u8>::new(); - Report::encode(&r, &mut encoded); + Report::encode(&r, &mut encoded).expect("Report encoding failed!"); let decoded = Report::decode(&mut Cursor::new(&encoded)).expect("Report decoding failed!"); if r != decoded { println!("Report:"); diff --git a/toolkit/components/telemetry/dap/ffi/Cargo.toml b/toolkit/components/telemetry/dap/ffi/Cargo.toml index dfb69e4821..5e94bf30a7 100644 --- a/toolkit/components/telemetry/dap/ffi/Cargo.toml +++ b/toolkit/components/telemetry/dap/ffi/Cargo.toml @@ -8,6 +8,7 @@ authors = [ license = "MPL-2.0" [dependencies] -prio = {version = "0.15.3", default-features = false } +prio = {version = "0.16.2", default-features = false } thin-vec = { version = "0.2.1", features = ["gecko-ffi"] } rand = "0.8" +log = "0.4" diff --git a/toolkit/components/telemetry/dap/ffi/src/lib.rs b/toolkit/components/telemetry/dap/ffi/src/lib.rs index 998c8af204..2d595c1a8f 100644 --- a/toolkit/components/telemetry/dap/ffi/src/lib.rs +++ b/toolkit/components/telemetry/dap/ffi/src/lib.rs @@ -5,6 +5,8 @@ use std::error::Error; use std::io::Cursor; +use log::{debug, warn}; + use prio::vdaf::prio3::Prio3Sum; use prio::vdaf::prio3::Prio3SumVec; use thin_vec::ThinVec; @@ -19,8 +21,6 @@ use types::Time; use prio::codec::Encode; use prio::codec::{decode_u16_items, encode_u32_items}; -use prio::flp::types::{Sum, SumVec}; -use prio::vdaf::prio3::Prio3; use prio::vdaf::Client; use prio::vdaf::VdafError; @@ -41,7 +41,7 @@ extern "C" { ) -> bool; } -pub fn new_prio_u8(num_aggregators: u8, bits: u32) -> Result<Prio3Sum, VdafError> { +pub fn new_prio_sum(num_aggregators: u8, bits: usize) -> Result<Prio3Sum, VdafError> { if bits > 64 { return Err(VdafError::Uncategorized(format!( "bit length ({}) exceeds limit for aggregate type (64)", @@ -49,17 +49,16 @@ pub fn new_prio_u8(num_aggregators: u8, bits: u32) -> Result<Prio3Sum, VdafError ))); } - Prio3::new(num_aggregators, Sum::new(bits as usize)?) + Prio3Sum::new_sum(num_aggregators, bits) } -pub fn new_prio_vecu8(num_aggregators: u8, len: usize) -> Result<Prio3SumVec, VdafError> { +pub fn new_prio_sumvec( + num_aggregators: u8, + len: usize, + bits: usize, +) -> Result<Prio3SumVec, VdafError> { let chunk_length = prio::vdaf::prio3::optimal_chunk_length(8 * len); - Prio3::new(num_aggregators, SumVec::new(8, len, chunk_length)?) -} - -pub fn new_prio_vecu16(num_aggregators: u8, len: usize) -> Result<Prio3SumVec, VdafError> { - let chunk_length = prio::vdaf::prio3::optimal_chunk_length(16 * len); - Prio3::new(num_aggregators, SumVec::new(16, len, chunk_length)?) + Prio3SumVec::new_sum_vec(num_aggregators, bits, len, chunk_length) } enum Role { @@ -112,14 +111,17 @@ impl Shardable for u8 { &self, nonce: &[u8; 16], ) -> Result<(Vec<u8>, Vec<Vec<u8>>), Box<dyn std::error::Error>> { - let prio = new_prio_u8(2, 2)?; + let prio = new_prio_sum(2, 8)?; let (public_share, input_shares) = prio.shard(&(*self as u128), nonce)?; debug_assert_eq!(input_shares.len(), 2); - let encoded_input_shares = input_shares.iter().map(|s| s.get_encoded()).collect(); - let encoded_public_share = public_share.get_encoded(); + let encoded_input_shares = input_shares + .iter() + .map(|s| s.get_encoded()) + .collect::<Result<Vec<_>, _>>()?; + let encoded_public_share = public_share.get_encoded()?; Ok((encoded_public_share, encoded_input_shares)) } } @@ -129,15 +131,18 @@ impl Shardable for ThinVec<u8> { &self, nonce: &[u8; 16], ) -> Result<(Vec<u8>, Vec<Vec<u8>>), Box<dyn std::error::Error>> { - let prio = new_prio_vecu8(2, self.len())?; + let prio = new_prio_sumvec(2, self.len(), 8)?; let measurement: Vec<u128> = self.iter().map(|e| (*e as u128)).collect(); let (public_share, input_shares) = prio.shard(&measurement, nonce)?; debug_assert_eq!(input_shares.len(), 2); - let encoded_input_shares = input_shares.iter().map(|s| s.get_encoded()).collect(); - let encoded_public_share = public_share.get_encoded(); + let encoded_input_shares = input_shares + .iter() + .map(|s| s.get_encoded()) + .collect::<Result<Vec<_>, _>>()?; + let encoded_public_share = public_share.get_encoded()?; Ok((encoded_public_share, encoded_input_shares)) } } @@ -147,15 +152,18 @@ impl Shardable for ThinVec<u16> { &self, nonce: &[u8; 16], ) -> Result<(Vec<u8>, Vec<Vec<u8>>), Box<dyn std::error::Error>> { - let prio = new_prio_vecu16(2, self.len())?; + let prio = new_prio_sumvec(2, self.len(), 16)?; let measurement: Vec<u128> = self.iter().map(|e| (*e as u128)).collect(); let (public_share, input_shares) = prio.shard(&measurement, nonce)?; debug_assert_eq!(input_shares.len(), 2); - let encoded_input_shares = input_shares.iter().map(|s| s.get_encoded()).collect(); - let encoded_public_share = public_share.get_encoded(); + let encoded_input_shares = input_shares + .iter() + .map(|s| s.get_encoded()) + .collect::<Result<Vec<_>, _>>()?; + let encoded_public_share = public_share.get_encoded()?; Ok((encoded_public_share, encoded_input_shares)) } } @@ -163,7 +171,7 @@ impl Shardable for ThinVec<u16> { /// Pre-fill the info part of the HPKE sealing with the constants from the standard. fn make_base_info() -> Vec<u8> { let mut info = Vec::<u8>::new(); - const START: &[u8] = "dap-07 input share".as_bytes(); + const START: &[u8] = "dap-09 input share".as_bytes(); info.extend(START); const FIXED: u8 = 1; info.push(FIXED); @@ -215,7 +223,8 @@ fn get_dap_report_internal<T: Shardable>( } .get_encoded() }) - .collect(); + .collect::<Result<Vec<_>, _>>()?; + debug!("Plaintext input shares computed."); let metadata = ReportMetadata { report_id, @@ -230,18 +239,20 @@ fn get_dap_report_internal<T: Shardable>( let mut info = make_base_info(); let mut aad = Vec::from(*task_id); - metadata.encode(&mut aad); - encode_u32_items(&mut aad, &(), &encoded_public_share); + metadata.encode(&mut aad)?; + encode_u32_items(&mut aad, &(), &encoded_public_share)?; info.push(Role::Leader as u8); let leader_payload = hpke_encrypt_wrapper(&plaintext_input_shares[0], &aad, &info, &leader_hpke_config)?; + debug!("Leader payload encrypted."); *info.last_mut().unwrap() = Role::Helper as u8; let helper_payload = hpke_encrypt_wrapper(&plaintext_input_shares[1], &aad, &info, &helper_hpke_config)?; + debug!("Helper payload encrypted."); Ok(Report { metadata, @@ -264,20 +275,22 @@ pub extern "C" fn dapGetReportU8( ) -> bool { assert_eq!(task_id.len(), 32); - if let Ok(report) = get_dap_report_internal::<u8>( + let Ok(report) = get_dap_report_internal::<u8>( leader_hpke_config_encoded, helper_hpke_config_encoded, &measurement, &task_id.as_slice().try_into().unwrap(), time_precision, - ) { - let encoded_report = report.get_encoded(); - out_report.extend(encoded_report); - - true - } else { - false - } + ) else { + warn!("Creating report failed!"); + return false; + }; + let Ok(encoded_report) = report.get_encoded() else { + warn!("Encoding report failed!"); + return false; + }; + out_report.extend(encoded_report); + true } #[no_mangle] @@ -291,20 +304,22 @@ pub extern "C" fn dapGetReportVecU8( ) -> bool { assert_eq!(task_id.len(), 32); - if let Ok(report) = get_dap_report_internal::<ThinVec<u8>>( + let Ok(report) = get_dap_report_internal::<ThinVec<u8>>( leader_hpke_config_encoded, helper_hpke_config_encoded, measurement, &task_id.as_slice().try_into().unwrap(), time_precision, - ) { - let encoded_report = report.get_encoded(); - out_report.extend(encoded_report); - - true - } else { - false - } + ) else { + warn!("Creating report failed!"); + return false; + }; + let Ok(encoded_report) = report.get_encoded() else { + warn!("Encoding report failed!"); + return false; + }; + out_report.extend(encoded_report); + true } #[no_mangle] @@ -318,18 +333,20 @@ pub extern "C" fn dapGetReportVecU16( ) -> bool { assert_eq!(task_id.len(), 32); - if let Ok(report) = get_dap_report_internal::<ThinVec<u16>>( + let Ok(report) = get_dap_report_internal::<ThinVec<u16>>( leader_hpke_config_encoded, helper_hpke_config_encoded, measurement, &task_id.as_slice().try_into().unwrap(), time_precision, - ) { - let encoded_report = report.get_encoded(); - out_report.extend(encoded_report); - - true - } else { - false - } + ) else { + warn!("Creating report failed!"); + return false; + }; + let Ok(encoded_report) = report.get_encoded() else { + warn!("Encoding report failed!"); + return false; + }; + out_report.extend(encoded_report); + true } diff --git a/toolkit/components/telemetry/dap/ffi/src/types.rs b/toolkit/components/telemetry/dap/ffi/src/types.rs index e8f6385dcd..c84cbf16bc 100644 --- a/toolkit/components/telemetry/dap/ffi/src/types.rs +++ b/toolkit/components/telemetry/dap/ffi/src/types.rs @@ -34,8 +34,9 @@ impl Decode for TaskID { } impl Encode for TaskID { - fn encode(&self, bytes: &mut Vec<u8>) { + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { bytes.extend_from_slice(&self.0); + Ok(()) } } @@ -52,8 +53,9 @@ impl Decode for Time { } impl Encode for Time { - fn encode(&self, bytes: &mut Vec<u8>) { - u64::encode(&self.0, bytes); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + u64::encode(&self.0, bytes)?; + Ok(()) } } @@ -93,9 +95,10 @@ impl Decode for Extension { } impl Encode for Extension { - fn encode(&self, bytes: &mut Vec<u8>) { - (self.extension_type as u16).encode(bytes); - encode_u16_items(bytes, &(), &self.extension_data); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + (self.extension_type as u16).encode(bytes)?; + encode_u16_items(bytes, &(), &self.extension_data)?; + Ok(()) } } @@ -131,9 +134,10 @@ pub struct PlaintextInputShare { } impl Encode for PlaintextInputShare { - fn encode(&self, bytes: &mut Vec<u8>) { - encode_u16_items(bytes, &(), &self.extensions); - encode_u32_items(bytes, &(), &self.payload); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + encode_u16_items(bytes, &(), &self.extensions)?; + encode_u32_items(bytes, &(), &self.payload)?; + Ok(()) } } @@ -150,8 +154,9 @@ impl Decode for HpkeConfigId { } impl Encode for HpkeConfigId { - fn encode(&self, bytes: &mut Vec<u8>) { - self.0.encode(bytes); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + self.0.encode(bytes)?; + Ok(()) } } @@ -189,12 +194,13 @@ impl Decode for HpkeConfig { } impl Encode for HpkeConfig { - fn encode(&self, bytes: &mut Vec<u8>) { - self.id.encode(bytes); - self.kem_id.encode(bytes); - self.kdf_id.encode(bytes); - self.aead_id.encode(bytes); - encode_u16_items(bytes, &(), &self.public_key); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + self.id.encode(bytes)?; + self.kem_id.encode(bytes)?; + self.kdf_id.encode(bytes)?; + self.aead_id.encode(bytes)?; + encode_u16_items(bytes, &(), &self.public_key)?; + Ok(()) } } @@ -227,10 +233,11 @@ impl Decode for HpkeCiphertext { } impl Encode for HpkeCiphertext { - fn encode(&self, bytes: &mut Vec<u8>) { - self.config_id.encode(bytes); - encode_u16_items(bytes, &(), &self.enc); - encode_u32_items(bytes, &(), &self.payload); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + self.config_id.encode(bytes)?; + encode_u16_items(bytes, &(), &self.enc)?; + encode_u32_items(bytes, &(), &self.payload)?; + Ok(()) } } @@ -248,8 +255,9 @@ impl Decode for ReportID { } impl Encode for ReportID { - fn encode(&self, bytes: &mut Vec<u8>) { + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { bytes.extend_from_slice(&self.0); + Ok(()) } } @@ -286,9 +294,10 @@ impl Decode for ReportMetadata { } impl Encode for ReportMetadata { - fn encode(&self, bytes: &mut Vec<u8>) { - self.report_id.encode(bytes); - self.time.encode(bytes); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + self.report_id.encode(bytes)?; + self.time.encode(bytes)?; + Ok(()) } } @@ -307,7 +316,6 @@ pub struct Report { pub helper_encrypted_input_share: HpkeCiphertext, } - impl Report { /// Creates a minimal report for use in tests. pub fn new_dummy() -> Self { @@ -321,8 +329,16 @@ impl Report { time: Time::generate(1), }, public_share: vec![], - leader_encrypted_input_share: HpkeCiphertext { config_id: HpkeConfigId(5), enc: vec![1, 2, 3, 4, 5], payload: vec![6, 7, 8, 9, 10] }, - helper_encrypted_input_share: HpkeCiphertext { config_id: HpkeConfigId(100), enc: enc.into(), payload: payload.into() }, + leader_encrypted_input_share: HpkeCiphertext { + config_id: HpkeConfigId(5), + enc: vec![1, 2, 3, 4, 5], + payload: vec![6, 7, 8, 9, 10], + }, + helper_encrypted_input_share: HpkeCiphertext { + config_id: HpkeConfigId(100), + enc: enc.into(), + payload: payload.into(), + }, } } } @@ -349,10 +365,11 @@ impl Decode for Report { } impl Encode for Report { - fn encode(&self, bytes: &mut Vec<u8>) { - self.metadata.encode(bytes); - encode_u32_items(bytes, &(), &self.public_share); - self.leader_encrypted_input_share.encode(bytes); - self.helper_encrypted_input_share.encode(bytes); + fn encode(&self, bytes: &mut Vec<u8>) -> Result<(), CodecError> { + self.metadata.encode(bytes)?; + encode_u32_items(bytes, &(), &self.public_share)?; + self.leader_encrypted_input_share.encode(bytes)?; + self.helper_encrypted_input_share.encode(bytes)?; + Ok(()) } } diff --git a/toolkit/components/telemetry/dap/tests/xpcshell/test_dap.js b/toolkit/components/telemetry/dap/tests/xpcshell/test_dap.js index deb68bafef..ba973c647f 100644 --- a/toolkit/components/telemetry/dap/tests/xpcshell/test_dap.js +++ b/toolkit/components/telemetry/dap/tests/xpcshell/test_dap.js @@ -91,7 +91,7 @@ function uploadHandler(request, response) { console.log(body.available()); Assert.equal( true, - body.available() == 406 || body.available() == 3654, + body.available() == 886 || body.available() == 3654, "Wrong request body size." ); received = true; |