8000 IEEE802.15.4 RxClient Encrypted Receive by tyler-potyondy · Pull Request #3940 · tock/tock · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

IEEE802.15.4 RxClient Encrypted Receive #3940

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 12, 2024
Merged

Conversation

tyler-potyondy
Copy link
Contributor

Pull Request Overview

This pull request fixes the bug described in #3923. This provides a minimal change to the RxClient receive method to allow the RxClient to know if a packet remains encrypted and subsequently filter the packet if needed. Additional context for these changes can be found in the linked issue.

Testing Strategy

This pull request was tested using the libtock-c openthread implementation.

TODO or Help Wanted

N/A

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make prepush.

@github-actions github-actions bot added the WG-Network In the purview of the Network working group. label Mar 28, 2024
@bradjc
Copy link
Contributor
bradjc commented Mar 28, 2024
  1. Why pass encrypted packets to the 6lowpan layer? I assume that will never work/be useful.
  2. Man, even with Rust we run into the same issues every ~10 years: tinyos/tinyos-main@c042820
  3. Seems like we need a separate trait for raw receive. One, the comments for the current receive are very clear that everything passed through is unencrypted. Two, it lets the type system enforce the check rather than using a bool.

@tyler-potyondy
Copy link
Contributor Author

Why pass encrypted packets to the 6lowpan layer? I assume that will never work/be useful.

There is no good reason to do this. This is an artifact of our current stack / trait design. Having a new trait as you suggested would fix this.

Man, even with Rust we run into the same issues every ~10 years: tinyos/tinyos-main@c042820

Crazy to hear this popped up in TinyOS too...

Seems like we need a separate trait for raw receive. One, the comments for the current receive are very clear that everything passed through is unencrypted. Two, it lets the type system enforce the check rather than using a bool.

I am very much in favor of this. The only complicating factor (which I think we can work around) is the fact that the driver for all userspace processes using 15.4 is one RxClient (making multiple traits difficult).

@tyler-potyondy
Copy link
Contributor Author

I updated the MacDevice trait to now include the ability to register a RawRxClient in addition to the RxClient. For MacDevices wishing to receive raw packets (i.e. packets that have not been decrypted) the MacDevice can now now be subscribed as a RawRxClient. This allows a mechanism to only pass unencrypted packets to devices expecting unencrypted packets.

I have included below diagrams of the prior design and the new design to help in understanding these changes.

Prior Design:

Proposed Design:

@bradjc
Copy link
Contributor
bradjc commented Mar 30, 2024

I think this is a reasonable approach.

@tyler-potyondy
Copy link
Contributor Author

@bradjc if others are in favor of these changes and once we merge this, I'll go ahead and update the tock book documentation we have on the network stack to incorporate the new trait.

brghena
brghena previously approved these changes Apr 2, 2024
Copy link
Contributor
@brghena brghena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I'd appreciate a comment if you wouldn't mind, but otherwise good to go.

@@ -135,3 +137,13 @@ pub trait RxClient {
/// - `data_len`: Length of the data payload
fn receive<'a>(&self, buf: &'a [u8], header: Header<'a>, data_offset: usize, data_len: usize);
}

pub trait RawRxClient {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment here explaining that the fields here will match the explanation of RxClient would be nice. Also the comment should explain what differs from a normal RxClient (i.e., what "raw" actually means here)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brghena I just pushed changes adding these comments. (good catch on the missing documentation)

While I was adding this, I also softened the language to "potentially" including extra bytes for the PHY layer in the buf argument comment. This is to reflect #3933 removing the PSDU offset passed to RxClients that are "higher" in the stack.

Copy link
Member
@ppannuto ppannuto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really want to block the critical path to working demo, but I'm a bit confused on semantics here.

My instinct from the naming is that ReceiveRaw would get every packet, and Receive would only get 'processed' (in this context, unencrypted) packets.

If understand what happens around https://github.com/tock/tock/pull/3940/files#diff-85e0d54f818678f55fd9b21778b576635e2fdfb6e2fe633fd3e1fdc312dcbaa3R492 correctly, it seems that what happens is every packet will flow up either Receive or ReceiveRaw. In that sense, are these better named ReceiveDecrypted and ReceiveEncrypted?

Perhaps more importantly, are there layers above this that realistically want both? Wouldn't the layer above either be expected packets in the clear or expecting to encrypt? i.e., should the rx_client be a union enum for one of Receive[De/En]crypted?

Hmm.. maybe answering my own question, is the issue that link/security establishment for something capable of doing encryption needs access to both?

Even in that case, I still get hung up on something called ReceiveRaw not simply giving every packet to its client. Could we stick with the receiver enum, but the ReceiveRaw trait include a bool/flag which indicates whether the packet is encrypted? (re-read thread re: Brad's comment on type-checked enforcement) trait have two functions, receive_encrypted and receive_decrypted?

@bradjc
Copy link
Contributor
bradjc commented Apr 3, 2024

Even in that case, I still get hung up on something called ReceiveRaw not simply giving every packet to its client.

I agree with this.

receive_encrypted and receive_decrypted?

This I'm not sure about. Is a packet that was never encrypted "decrypted"? I would say no.

I end up at: we need something that works for now, and what the interfaces are seems like it should be a more holistic analysis. Is it a problem to just pass every packet to receive raw?

@tyler-potyondy
Copy link
Contributor Author

Circling back to @ppannuto and @bradjc comments now...

If I am understanding your concerns correctly, the issue is naming something ReceiveRaw that is only called in the instance of passing upwards a secured frame that is not decrypted in framer.rs (https://github.com/tock/tock/pull/3940/files#diff-85e0d54f818678f55fd9b21778b576635e2fdfb6e2fe633fd3e1fdc312dcbaa3R503).

Would perhaps a better way of doing this be to change RxClient to receive secured and unsecured packets and then have a RxDecryptClient (or some better name). This seems like it may resolve some of the confusion with semantics and naming? This would be a trivial change and would only involve changing framer.rs and updating the documentation comments for RxClient (currently states that it only passes upwards unsecured frames).

@bradjc
Copy link
Contributor
bradjc commented Apr 5, 2024

Why not just pass everything to raw?

@tyler-potyondy
Copy link
Contributor Author

So we would then have two traits: RawRxClient and ParseRxClient? It seems if we pass everything to raw, it would be misleading to have a trait named RxClient for unsecured frames so we would want to rename this (e.g. ParseRxClient).

@bradjc
Copy link
Contributor
bradjc commented Apr 5, 2024

I think it is common to have two paths in a networking stack "raw", which on the RX side just passes everything, and on the TX side just sends packets without worrying about headers/structure, and the conventional path, which parses and checks headers.

I think adding a raw interface, without any if statements (ie checking for encryption), makes this an easy change.

@tyler-potyondy
Copy link
Contributor Author

@bradjc this sounds very reasonable to me but I am getting a little lost with our next steps to implement this.

Would moving RawRxClient in framer.rs outside the logic checking encryption provide a more clear use? This seems to satisfy:

I think adding a raw interface, without any if statements (ie checking for encryption), makes this an easy change.

In actuality, the only location the receive paths (raw / standard) diverge is in framer.rs. It is unfortunate we need to add another generic device trait that is only used here (this I think is a major source of confusion to this design as Pat noted).

At the end of the day and after a while thinking about all of this, it seems that no one solution will perfectly fit into the existing stack design. The original stack was designed around having a generic RxClient trait that each layer would implement. The "lower" 15.4 layers that serve as the virtualizer only possess one path through the stack. The standard / raw paths only diverge at the framer level upwards. Having to implement two type enforced paths through the stack does not map cleanly upon the original design that assumes only one path through the stack.

@tyler-potyondy
Copy link
Contributor Author

I changed the naming of the trait to a verbose name. I think this should provide more clarity as to what this trait is (and isn't) used for. @ppannuto does this resolve your earlier concerns with "raw" being in the trait name?

ppannuto
ppannuto previously approved these changes Apr 10, 2024
Copy link
Member
@ppannuto ppannuto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in an ideal world, we'd pull raw out of all the function names too, but there's a point where it's just becoming busy-work for an ultimately temporary change to the networking stack.

I'm in favor of merging this and moving on, with the understanding that the more real re-write of the networking stack interfaces is on the short-term, post-tutorial priority list

@tyler-potyondy
Copy link
Contributor Author

@ppannuto I quickly went through and removed the function names and comments with raw. It wasn't too much work and will hopefully avoid any confusion between now and the rewrite.

bradjc
bradjc previously approved these changes Apr 10, 2024
ppannuto
ppannuto previously approved these changes Apr 10, 2024
@brghena
Copy link
Contributor
brghena commented Apr 12, 2024

@tyler-potyondy It looks like this is back in your court due to a conflict.

There now are 2 potential RxClients a MacDevice implements. With this
design, a mac device can decide if it wishes to receive raw or parsed
(i.e. decrypted) packets. Furthermore, a mac device can subscribe to
both clients to receive both raw and parsed packets.
This implements the needed changes for passing received packets to
correct clients and subsequently to the userprocess.
Using the verbose name `SecuredFrameNoDecryptRxClient`. This should be
removed with the redesign.
@tyler-potyondy
Copy link
Contributor Author

Rebased and should be good to go. I also updated the framer method to match Pat's suggested naming to remove raw.

@ppannuto ppannuto added this pull request to the merge queue Apr 12, 2024
Merged via the queue into tock:master with commit 86abc90 Apr 12, 2024
@tyler-potyondy tyler-potyondy deleted the 6LoWPAN branch April 22, 2024 18:58
bradjc added a commit that referenced this pull request May 20, 2024
This reverts commit 86abc90, reversing
changes made to 34352f7.
bradjc added a commit that referenced this pull request May 20, 2024
This reverts commit 86abc90, reversing
changes made to 34352f7.
bradjc added a commit that referenced this pull request May 28, 2024
This reverts commit 86abc90, reversing
changes made to 34352f7.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component WG-Network In the purview of the Network working group.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0