summaryrefslogtreecommitdiffstats
path: root/toolkit/components/telemetry/dap
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/telemetry/dap')
-rw-r--r--toolkit/components/telemetry/dap/DAPTelemetrySender.sys.mjs7
-rw-r--r--toolkit/components/telemetry/dap/ffi-gtest/Cargo.toml2
-rw-r--r--toolkit/components/telemetry/dap/ffi-gtest/test.rs2
-rw-r--r--toolkit/components/telemetry/dap/ffi/Cargo.toml3
-rw-r--r--toolkit/components/telemetry/dap/ffi/src/lib.rs119
-rw-r--r--toolkit/components/telemetry/dap/ffi/src/types.rs83
-rw-r--r--toolkit/components/telemetry/dap/tests/xpcshell/test_dap.js2
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;