Skip to content

Commit

Permalink
osnma: refactor handling of chain in force in key storage
Browse files Browse the repository at this point in the history
This uses a different approach to keeping track of the key in force
in the key storage. The new approach fixes failures in the OSNMA
test vector Chain Revocation Step 2.

Instead of keeping track of which is the key of the chain in force,
we keep track of what is the CID of the chain in force. This simplifies
keeping track of the start of applicability, as we can simply set
it whenever the CID changes value. It also handles the case in
Chain Revocation Step 2, when the DSM-PKR is transmitting a KROOT
for a chain that will be in force. In that case, the receiver never
gets a KROOT from the first chain, and so it would never set the
start of applicability for the key of the new chain correctly.
  • Loading branch information
daniestevez committed Jan 26, 2024
1 parent aa1f277 commit 2ed7680
Showing 1 changed file with 30 additions and 41 deletions.
71 changes: 30 additions & 41 deletions src/osnma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,14 @@ struct PubkeyStore {
#[derive(Debug, Clone)]
struct KeyStore {
keys: [Option<Key<Validated>>; 2],
in_force: Option<KeyInForce>,
chain_in_force: Option<ChainInForce>,
}

#[derive(Debug, Clone)]
struct KeyInForce {
index: bool, // false for the 1st position, true for then 2nd position

// This is None if we haven't seen the key entering through a chain renewal
// or revocation, in which case we don't know when the key starts being
// applicable (and don't care, since we don't have the previous key).
struct ChainInForce {
cid: u8,
// This is None if the current CID has never replaced a previous different
// CID. Otherwise, it is set to the Gst in which the replacement happened.
start_applicability: Option<Gst>,
}

Expand Down Expand Up @@ -664,7 +662,7 @@ impl KeyStore {
fn empty() -> KeyStore {
KeyStore {
keys: [None; 2],
in_force: None,
chain_in_force: None,
}
}

Expand Down Expand Up @@ -699,32 +697,17 @@ impl KeyStore {
}
}
}
// update self.in_force
match (&self.keys[0], &self.keys[1]) {
(Some(k), _) if k.chain().chain_id() == cid => {
let index = false;
let start_applicability = match &self.in_force {
Some(in_force) if in_force.index != index => Some(gst),
_ => None,
};
self.in_force = Some(KeyInForce {
index,
start_applicability,
});
}
(_, Some(k)) if k.chain().chain_id() == cid => {
let index = true;
let start_applicability = match &self.in_force {
Some(in_force) if in_force.index != index => Some(gst),
_ => None,
};
self.in_force = Some(KeyInForce {
index,
start_applicability,
});
}
_ => self.in_force = None,
}
// update chain in force
self.chain_in_force = Some(ChainInForce {
cid,
start_applicability: self.chain_in_force.as_ref().and_then(|cif| {
if cif.cid != cid {
Some(gst)
} else {
None
}
}),
});
}

fn store_key(&mut self, key: Key<Validated>) {
Expand All @@ -742,24 +725,30 @@ impl KeyStore {
}

fn current_key(&self) -> Option<&Key<Validated>> {
self.in_force
.as_ref()
.and_then(|in_force| self.keys[usize::from(in_force.index)].as_ref())
self.chain_in_force.as_ref().and_then(|cif| {
self.keys
.iter()
.flatten()
.find(|&&k| k.chain().chain_id() == cif.cid)
})
}

// Similar to current_key but returns a key from the other chain if the
// requested GST is before the start of applicability of the current
// chain. This is used to get the key for MACK validation for Slow MAC.
fn key_past_chain(&self, gst: Gst) -> Option<&Key<Validated>> {
self.in_force
self.chain_in_force
.as_ref()
.and_then(|in_force| match in_force.start_applicability {
.and_then(|cif| match cif.start_applicability {
Some(gst0) if gst0 > gst => {
// Requested time is before the start of the applicability.
// Get the key from the other slot (if occupied).
self.keys[usize::from(!in_force.index)].as_ref()
self.keys
.iter()
.flatten()
.find(|&&k| k.chain().chain_id() != cif.cid)
}
_ => self.keys[usize::from(in_force.index)].as_ref(),
_ => self.current_key(),
})
}

Expand Down

0 comments on commit 2ed7680

Please sign in to comment.