-
-
Notifications
You must be signed in to change notification settings - Fork 779
RFC: AES Encryption HIL Updates + Virtualizers #4609
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
base: master
Are you sure you want to change the base?
Conversation
Refactoring and update of AES encryption HIL to: - remove GCM / CCM clients in favor of a standard AES client - update CCM / GCM traits to correspond to HW ops. The current implementation is inconsistent with HIL and encodes properties beyond what is necessary for an interface with hardware. - update crypt to use `Result` pattern rather than nested `Option`
This updates the nrf5x aes implementation to use the refactored aes symmetric encryption HIL. Additionally, this removes the software implementation of CTR/CCM modes in the HIL. These should not be implemented within the chips directory as they are not related to the hardware.
Provide opinionated interface as traits for each aes mode (e.g. specify if a given mode requires iv and the length of said iv).
Add aes hw virtualizer that exposes generic interface for all aes modes.
Provides a fully SW aes ctr implementation using RustCrypto aes ctr crate in addition to a aes ctr implementation built upon hw ecb support.
Rewrite aes userspace driver for new interface.
(for demonstration purposes only)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple comments. I think this in the right direction.
[dependencies] | ||
kernel = { path = "../../kernel" } | ||
capsules-core = { path = "../core"} | ||
enum_primitive = { path = "../../libraries/enum_primitive" } | ||
tickv = { path = "../../libraries/tickv" } | ||
ctr = "0.9.2" | ||
aes = "0.8.4" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[dependencies] | |
kernel = { path = "../../kernel" } | |
capsules-core = { path = "../core"} | |
enum_primitive = { path = "../../libraries/enum_primitive" } | |
tickv = { path = "../../libraries/tickv" } | |
ctr = "0.9.2" | |
aes = "0.8.4" | |
[dependencies] | |
kernel = { path = "../../kernel" } | |
capsules-core = { path = "../core"} | |
ctr = "0.9.2" | |
aes = "0.8.4" |
?
/// Implement this trait and use `set_client()` in order to receive callbacks from an `AES128` | ||
/// instance. | ||
/// instance. This returns the provided source. The `dest` contains the result of the operation | ||
/// and in both cases the `SubSliceMut` provided to `crypt()` will be returned. | ||
pub trait Client<'a> { | ||
fn crypt_done(&'a self, source: Option<&'static mut [u8]>, dest: &'static mut [u8]); | ||
fn crypt_done( | ||
&'a self, | ||
source: Option<SubSliceMut<'static, u8>>, | ||
dest: Result<SubSliceMut<'static, u8>, (ErrorCode, SubSliceMut<'static, u8>)>, | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, what are source
and dest
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
source
and dest
are the buffers provided to the crypto function. source
is optional, and in the absence of source
, dest
is used as the input to the crypto and overwritten as the output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok what I don't understand is how dest is a result. The result should just be separate.
pub struct AesOperators<'a, ECB: Aes128Ecb<'a>, CTR: Aes128Ctr<'a>> { | ||
ecb: &'a ECB, | ||
ctr: &'a CTR, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No we do not, this was used by a prior version of something that was removed.
impl<'a, ECB: Aes128Ecb<'a>, CTR: Aes128Ctr<'a>> AesDriver<'a, ECB, CTR> { | ||
pub fn new( | ||
aes: &'static A, | ||
source_buffer: &'static mut [u8], | ||
dest_buffer: &'static mut [u8], | ||
aes_ecb: &'a ECB, | ||
aes_ctr: &'a CTR, | ||
grant: Grant< | ||
App, | ||
UpcallCount<1>, | ||
UpcallCount<{ upcall::COUNT }>, | ||
AllowRoCount<{ ro_allow::COUNT }>, | ||
AllowRwCount<{ rw_allow::COUNT }>, | ||
>, | ||
) -> AesDriver<'static, A> { | ||
kernel_dest_buf: &'static mut [u8], | ||
kernel_src_buf: &'static mut [u8], | ||
) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if aes_ecb
and aes_ctr
are the same reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a lot of files called "aes". This makes it really hard to tell what is actually using what.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. We should try to come up with some other names for the files at the different layers. I'll think some more about this.
aes: &'static capsules_extra::symmetric_encryption::aes::AesDriver< | ||
'static, | ||
capsules_core::virtualizers::virtual_aes::AesVirtualHw< | ||
'static, | ||
nrf52840::aes::AesECB<'static>, | ||
>, | ||
capsules_aes_ctr::aes_ctr::Aes128CtrEcbBase< | ||
'static, | ||
capsules_core::virtualizers::virtual_aes::AesVirtualHw< | ||
'static, | ||
nrf52840::aes::AesECB<'static>, | ||
>, | ||
>, | ||
>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make a type AesDriver =
for this.
let aes_driver = static_init!( | ||
capsules_extra::symmetric_encryption::aes::AesDriver< | ||
'static, | ||
capsules_core::virtualizers::virtual_aes::AesVirtualHw< | ||
'static, | ||
nrf52840::aes::AesECB<'static>, | ||
>, | ||
capsules_aes_ctr::aes_ctr::Aes128CtrEcbBase< | ||
'static, | ||
capsules_core::virtualizers::virtual_aes::AesVirtualHw< | ||
'static, | ||
nrf52840::aes::AesECB<'static>, | ||
>, | ||
>, | ||
>, | ||
capsules_extra::symmetric_encryption::aes::AesDriver::new( | ||
virtual_aes_ecb, | ||
sw_ctr, | ||
grant, | ||
crypt_dest_buf, | ||
crypt_src_buf, | ||
) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have an aes component?
// (todo) likely want to remove enable / disable per discussion on | ||
// https://github.com/tock/tock/pull/4500 | ||
fn enable(&self); | ||
fn disable(&self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should clarify when secrets are deleted (I'm assuming when disable()
is called), but it's worth being really clear
// https://github.com/tock/tock/pull/4500 | ||
fn enable(&self); | ||
fn disable(&self); | ||
fn configure(&self, typer: Self::T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs
Pull Request Overview
This pull request introduces updates to the AES Symmetric Encryption HIL, adds traits that specify the semantics for each AES encryption mode, and adds a generic AES HW encryption virtualizer. This PR demonstrates these changes across the
Nrf5x
AES crypto engine andnRF52840dk
board file. Importantly, this is currently untested and remains a draft. The primary purpose of this PR is to solicit feedback before spending additional time finalizing / testing / incorporating these changes for the other AES crypto hardware.The current AES stack uses a combination of virtualizers / overloaded traits to provide the needed crypto interfaces (e.g. ECB, CTR, CCM, GCM, CBC are required for the userspace symmetric encryption capsule, but the kernel 15.4 stack also requires CCM). The current design does not scale well and struggles when building higher level crypto modes (e.g. GCM) from HW supported ECB. This design attempts to provide a single generic AES HW virtualizer (to avoid each mode needing to implement a virtualizer).
Key Changes:
capsule
level to encapsulate the behavior of each crypto mode. This allows us to statically enforce requirements for each crypto mode.Testing Strategy
N/A, testing will follow based on RFC discussion.
TODO or Help Wanted
This pull request still needs...
Documentation Updated
/docs
, or no updates are required.Formatting
make prepush
.