-
Notifications
You must be signed in to change notification settings - Fork 59
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
Add U and V key handlers, and decrypt + run payload #197
Conversation
src/keys_handler.rs
Outdated
let (iv, rest) = payload.split_at(AES_BLOCK_SIZE); | ||
let (ciphertext, tag) = rest.split_at(rest.len() - AES_BLOCK_SIZE); | ||
|
||
// note: it's unclear in the python codebase whether this is AES 128, but 128 seems |
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.
So, you could just automatically derive the Cipher
value.
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.
Since I'm pretty sure that for cryptography
, the default depends on the length of the key.
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.
(Also, given the fact that ukey
, vkey
and sym_key
are 32 bytes, that means that this is 256 bit AES.)
src/keys_handler.rs
Outdated
// to be the default | ||
// https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#symmetric-encryption-modes | ||
decrypt_aead( | ||
Cipher::aes_128_gcm(), |
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.
Cipher::aes_128_gcm(), | |
match symm_key.len() { | |
16 => Cipher::aes_128_gcm(), | |
32 => Cipher::aes_256_gcm(), | |
_ => return Err(....), | |
} |
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.
Terrific idea.
src/keys_handler.rs
Outdated
|
||
use crate::{error::Error, QuoteData}; | ||
|
||
// This value comes from and must match the Python codebase |
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 think a better reference for this constant could be FIPS 197, Introduction: This standard specifies the Rijndael algorithm ([3] and [4]), a symmetric block cipher that can process data blocks of 128 bits, ...
. (128 bits / 8 bits-per-byte gives you 16)
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
src/keys_handler.rs
Outdated
Cipher::aes_128_gcm(), | ||
symm_key, | ||
Some(iv), | ||
&[0u8], // todo: check that we don't need additional auth data here? |
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 is no additional data: that would be a call like encryptor.authenticate_additional_data(associated_data)
in the encrypt
function, or decryptor.authenticate_additional_data(authenticated_data)
in decrypt
.
src/keys_handler.rs
Outdated
) | ||
} | ||
|
||
pub(crate) unsafe fn try_combine_keys() -> bool { |
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.
All the unsafe
stuff makes me feel a bit worried. Would it be a possibility to put this data as a fully locked struct
field in the overall HTTP state?
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.
Good point, I've put this in the app_data now.
a22749d
to
44cd92c
Compare
46b48d4
to
121185c
Compare
@puiterwijk @lukehinds @ashcrow This is updated, I'm able to run a small script with it. Still having the problem referenced in #202 but that is the fail point right now after the payload script runs. |
dbe7019
to
e6af73a
Compare
I can also split these commits out into their own PRs if that makes it easier to review; just let me know. |
3ab0bb5
to
56a32bd
Compare
Happy to say #202 is fixed now in this PR. To use the revocation feature and ensure that the revocation certificate is sent correctly, you must run the tenant with the following command (example directory and script shown here):
... where
I'll include this in some documentation. |
Signed-off-by: Lily Sturmann <[email protected]>
The Python code manually forces the IMA PCR (PCR 10) to be added from the SHA1 bank, even when that is not the bank used for the other PCRs. Because of the way it builds up the list of PCRs to check, we must also do this the same way. Signed-off-by: Lily Sturmann <[email protected]> Co-authored-by: Patrick Uiterwijk <[email protected]>
Signed-off-by: Lily Sturmann <[email protected]>
src/main.rs
Outdated
let zipped_payload = config_get("cloud_agent", "dec_payload_file")?; | ||
info!("Unzipping payload {} to {}", zipped_payload, unzipped); | ||
|
||
let mut status = Command::new("unzip") |
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 is nothing wrong with this, though I do want to ask: Why use the system command instead of a library?
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.
@ashcrow I tried a library, but it was a bit more fiddly than I expected and this just worked. I suppose we could always update it on a second pass if we want to make some enhancements.
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.
The zip_rs is not nice I agree, check out compress tools, I find it a lot simpler https://crates.io/crates/compress-tools
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.
@lukehinds Sure will do, I can push a new version of that commit if I get that working.
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.
The library seems straightforward, but I keep getting
INFO keylime_agent > Unzipping payload decrypted_payload.zip to /tmp/secure/unzipped
Error: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" })
Despite
[keylime-ima@localhost rust-keylime]$ ls /tmp/secure/unzipped/
decrypted_payload.zip derived_tci_key
[keylime-ima@localhost rust-keylime]$ file /tmp/secure/unzipped/decrypted_payload.zip
/tmp/secure/unzipped/decrypted_payload.zip: Zip archive data, at least v2.0 to extract
[keylime-ima@localhost rust-keylime]$ ls -la /tmp/secure/unzipped/decrypted_payload.zip
-rw-r--r--. 1 root root 8738 Jul 12 14:02 /tmp/secure/unzipped/decrypted_payload.zip
The code:
let zipped_payload = config_get("cloud_agent", "dec_payload_file")?;
info!("Unzipping payload {} to {}", &zipped_payload, &unzipped);
let mut source = fs::File::open(&zipped_payload)?;
assert!(Path::new(&zipped_payload).exists());
let dest = Path::new(&unzipped);
assert!(Path::new(&dest).exists());
let file_list = list_archive_files(&mut source).expect("failed to list files");
info!("File list: {:?}", file_list);
uncompress_archive(&mut source, &dest, Ownership::Ignore).expect("failed to unzip");
Still debugging...
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.
Okay, it worked with a test example so it should be doable here shortly.
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.
It says it succeeds, but then the unzipped files aren't there. All I can think of is maybe it isn't opening with the correct permissions, as it's apparently r
only. This should be easy to update but for some reason is not.
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 figured out the error... apparently compress_tools::list_archive_files
mutates the src
archive you give it so that there are no files left afterwards. Bizarre!
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.
One question but overall 👍
This LGTM, would you like me to test again first thing tomorrow @lkatalin ? |
Thanks @ashcrow and @lukehinds ! @lukehinds Thanks for the offer - if you test again with this branch, you will get the same intermittent quote error we saw at the end of last week. I bypassed that to test the U/V key handling behavior by setting the Python |
996683c
to
3f97775
Compare
@ashcrow @lukehinds Updated to use a zip library! |
Signed-off-by: Lily Sturmann <[email protected]>
Signed-off-by: Lily Sturmann <[email protected]>
Signed-off-by: Lily Sturmann <[email protected]>
in order for CI to pass as these are unstable features. The former should be easy, the latter maybe not so much.
The decrypted payload appears to be the excludes list; there is noautorun.sh
sent.Resolves #97
Resolves #203
Resolves #221
Resolves #226
Resolves #202
Resolves #99