-
Notifications
You must be signed in to change notification settings - Fork 49
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
[PM-5693] CryptoService using memfd_secret on Linux #979
Closed
Closed
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
d7c7c3e
Initial CryptoService impl
dani-garcia 6068e84
More work
dani-garcia 50dc1b4
Refactor keystore to also handle resizes
dani-garcia 216eb25
Merge branch 'main' into ps/secure-crypto-service
dani-garcia 4b846ed
Fix
dani-garcia 7a01168
Paralelization plus alternative to locatekey
dani-garcia c649bf0
WASM support
dani-garcia b901ef7
Merge branch 'main' into ps/secure-crypto-service
dani-garcia e2129ad
Remove unnecessary trait
dani-garcia f708fcc
Inline cryptoengine
dani-garcia 30854f7
Impl KeyStore in Slice struct directly
dani-garcia bed894a
Reset the values to None after munlock has zeroized them
dani-garcia 709dfce
Merge branch 'main' into ps/secure-crypto-service
dani-garcia f7eda88
Fmt
dani-garcia ce2343e
Add benchmark
dani-garcia bcd712f
Respect no-memory-hardening flag
dani-garcia 38343d2
Fix cfg flags, silence warnings
dani-garcia f34ce02
Export memfd correctly
dani-garcia cc27320
Fix memtest
dani-garcia 281619d
Merge branch 'main' into ps/secure-crypto-service
dani-garcia 32d298f
Try fat LTO to fix windows
dani-garcia c43aa08
Disable memsec on windows to fix it
dani-garcia dd37d1d
Incorrect optional dep
dani-garcia 45f3d32
Try updating windows in memsec
dani-garcia 1f70169
Remove unnecessary bound
dani-garcia 22a8b17
Move store impl around a bit
dani-garcia c63f656
Make KeyStore pub
dani-garcia db3f8d4
Merge branch 'main' into ps/secure-crypto-service-impl
dani-garcia eb81684
Some renames/simplifications
dani-garcia d279626
Add some missing implementations
dani-garcia d5f1ede
Rename
dani-garcia 8652d79
Introduce mutable context
dani-garcia fdb0263
Refactor keyref/encryptable locations
dani-garcia 6ea6267
Some additions needed to migrate the code
dani-garcia 32088c7
Merge branch 'main' into ps/secure-crypto-service
dani-garcia f882fb2
Remove bench
dani-garcia bec4786
Remove using
dani-garcia c2ffea6
Fix TODO
dani-garcia c0d2b63
Comment
dani-garcia cacf4db
Merge branch 'main' into ps/secure-crypto-service
dani-garcia f4ca816
Fmt
dani-garcia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,10 @@ pub enum CryptoError { | |
MissingKey(Uuid), | ||
#[error("The item was missing a required field: {0}")] | ||
MissingField(&'static str), | ||
#[error("Missing Key for Ref. {0}")] | ||
MissingKey2(String), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't change the |
||
#[error("Crypto store is read-only")] | ||
ReadOnlyCryptoStore, | ||
|
||
#[error("Insufficient KDF parameters")] | ||
InsufficientKdfParameters, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
use super::key_ref::{AsymmetricKeyRef, KeyRef, SymmetricKeyRef}; | ||
use crate::{service::CryptoServiceContext, AsymmetricEncString, CryptoError, EncString}; | ||
|
||
/// This trait should be implemented by any struct capable of knowing which key it needs | ||
/// to encrypt or decrypt itself. | ||
pub trait UsesKey<Key: KeyRef> { | ||
fn uses_key(&self) -> Key; | ||
} | ||
|
||
pub trait Encryptable< | ||
SymmKeyRef: SymmetricKeyRef, | ||
AsymmKeyRef: AsymmetricKeyRef, | ||
Key: KeyRef, | ||
Output, | ||
> | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: Key, | ||
) -> Result<Output, crate::CryptoError>; | ||
} | ||
|
||
pub trait Decryptable< | ||
SymmKeyRef: SymmetricKeyRef, | ||
AsymmKeyRef: AsymmetricKeyRef, | ||
Key: KeyRef, | ||
Output, | ||
> | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: Key, | ||
) -> Result<Output, crate::CryptoError>; | ||
} | ||
|
||
// Basic Encryptable/Decryptable implementations to and from bytes | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Decryptable<SymmKeyRef, AsymmKeyRef, SymmKeyRef, Vec<u8>> for EncString | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: SymmKeyRef, | ||
) -> Result<Vec<u8>, crate::CryptoError> { | ||
ctx.decrypt_data_with_symmetric_key(key, self) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Decryptable<SymmKeyRef, AsymmKeyRef, AsymmKeyRef, Vec<u8>> for AsymmetricEncString | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: AsymmKeyRef, | ||
) -> Result<Vec<u8>, crate::CryptoError> { | ||
ctx.decrypt_data_with_asymmetric_key(key, self) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Encryptable<SymmKeyRef, AsymmKeyRef, SymmKeyRef, EncString> for &[u8] | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: SymmKeyRef, | ||
) -> Result<EncString, crate::CryptoError> { | ||
ctx.encrypt_data_with_symmetric_key(key, self) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Encryptable<SymmKeyRef, AsymmKeyRef, AsymmKeyRef, AsymmetricEncString> for &[u8] | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: AsymmKeyRef, | ||
) -> Result<AsymmetricEncString, crate::CryptoError> { | ||
ctx.encrypt_data_with_asymmetric_key(key, self) | ||
} | ||
} | ||
|
||
// Encryptable/Decryptable implementations to and from strings | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Decryptable<SymmKeyRef, AsymmKeyRef, SymmKeyRef, String> for EncString | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: SymmKeyRef, | ||
) -> Result<String, crate::CryptoError> { | ||
let bytes: Vec<u8> = self.decrypt(ctx, key)?; | ||
String::from_utf8(bytes).map_err(|_| CryptoError::InvalidUtf8String) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Decryptable<SymmKeyRef, AsymmKeyRef, AsymmKeyRef, String> for AsymmetricEncString | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: AsymmKeyRef, | ||
) -> Result<String, crate::CryptoError> { | ||
let bytes: Vec<u8> = self.decrypt(ctx, key)?; | ||
String::from_utf8(bytes).map_err(|_| CryptoError::InvalidUtf8String) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Encryptable<SymmKeyRef, AsymmKeyRef, SymmKeyRef, EncString> for &str | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: SymmKeyRef, | ||
) -> Result<EncString, crate::CryptoError> { | ||
self.as_bytes().encrypt(ctx, key) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Encryptable<SymmKeyRef, AsymmKeyRef, AsymmKeyRef, AsymmetricEncString> for &str | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: AsymmKeyRef, | ||
) -> Result<AsymmetricEncString, crate::CryptoError> { | ||
self.as_bytes().encrypt(ctx, key) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Encryptable<SymmKeyRef, AsymmKeyRef, SymmKeyRef, EncString> for String | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: SymmKeyRef, | ||
) -> Result<EncString, crate::CryptoError> { | ||
self.as_bytes().encrypt(ctx, key) | ||
} | ||
} | ||
|
||
impl<SymmKeyRef: SymmetricKeyRef, AsymmKeyRef: AsymmetricKeyRef> | ||
Encryptable<SymmKeyRef, AsymmKeyRef, AsymmKeyRef, AsymmetricEncString> for String | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: AsymmKeyRef, | ||
) -> Result<AsymmetricEncString, crate::CryptoError> { | ||
self.as_bytes().encrypt(ctx, key) | ||
} | ||
} | ||
|
||
// Generic implementations for Optional values | ||
|
||
impl< | ||
SymmKeyRef: SymmetricKeyRef, | ||
AsymmKeyRef: AsymmetricKeyRef, | ||
Key: KeyRef, | ||
T: Encryptable<SymmKeyRef, AsymmKeyRef, Key, Output>, | ||
Output, | ||
> Encryptable<SymmKeyRef, AsymmKeyRef, Key, Option<Output>> for Option<T> | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: Key, | ||
) -> Result<Option<Output>, crate::CryptoError> { | ||
self.as_ref() | ||
.map(|value| value.encrypt(ctx, key)) | ||
.transpose() | ||
} | ||
} | ||
|
||
impl< | ||
SymmKeyRef: SymmetricKeyRef, | ||
AsymmKeyRef: AsymmetricKeyRef, | ||
Key: KeyRef, | ||
T: Decryptable<SymmKeyRef, AsymmKeyRef, Key, Output>, | ||
Output, | ||
> Decryptable<SymmKeyRef, AsymmKeyRef, Key, Option<Output>> for Option<T> | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: Key, | ||
) -> Result<Option<Output>, crate::CryptoError> { | ||
self.as_ref() | ||
.map(|value| value.decrypt(ctx, key)) | ||
.transpose() | ||
} | ||
} | ||
|
||
// Generic implementations for Vec values | ||
|
||
impl< | ||
SymmKeyRef: SymmetricKeyRef, | ||
AsymmKeyRef: AsymmetricKeyRef, | ||
Key: KeyRef, | ||
T: Encryptable<SymmKeyRef, AsymmKeyRef, Key, Output>, | ||
Output, | ||
> Encryptable<SymmKeyRef, AsymmKeyRef, Key, Vec<Output>> for Vec<T> | ||
{ | ||
fn encrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: Key, | ||
) -> Result<Vec<Output>, crate::CryptoError> { | ||
self.iter().map(|value| value.encrypt(ctx, key)).collect() | ||
} | ||
} | ||
|
||
impl< | ||
SymmKeyRef: SymmetricKeyRef, | ||
AsymmKeyRef: AsymmetricKeyRef, | ||
Key: KeyRef, | ||
T: Decryptable<SymmKeyRef, AsymmKeyRef, Key, Output>, | ||
Output, | ||
> Decryptable<SymmKeyRef, AsymmKeyRef, Key, Vec<Output>> for Vec<T> | ||
{ | ||
fn decrypt( | ||
&self, | ||
ctx: &mut CryptoServiceContext<SymmKeyRef, AsymmKeyRef>, | ||
key: Key, | ||
) -> Result<Vec<Output>, crate::CryptoError> { | ||
self.iter().map(|value| value.decrypt(ctx, key)).collect() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
use crate::{AsymmetricCryptoKey, SymmetricCryptoKey}; | ||
|
||
// Hide the `KeyRef` trait from the public API, to avoid confusion | ||
// the trait itself needs to be public to reference it in the macro, so wrap it in a hidden module | ||
#[doc(hidden)] | ||
pub mod __internal { | ||
use std::{fmt::Debug, hash::Hash}; | ||
|
||
use zeroize::ZeroizeOnDrop; | ||
|
||
use crate::CryptoKey; | ||
|
||
/// This trait represents a key reference that can be used to identify cryptographic keys in the | ||
/// key store. It is used to abstract over the different types of keys that can be used in | ||
/// the system, an end user would not implement this trait directly, and would instead use | ||
/// the `SymmetricKeyRef` and `AsymmetricKeyRef` traits. | ||
pub trait KeyRef: | ||
Debug + Clone + Copy + Hash + Eq + PartialEq + Ord + PartialOrd + Send + Sync + 'static | ||
{ | ||
type KeyValue: CryptoKey + Send + Sync + ZeroizeOnDrop; | ||
|
||
/// Returns whether the key is local to the current context or shared globally by the | ||
/// service. | ||
fn is_local(&self) -> bool; | ||
coroiu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
pub(crate) use __internal::KeyRef; | ||
|
||
// These traits below are just basic aliases of the `KeyRef` trait, but they allow us to have two | ||
// separate trait bounds | ||
|
||
pub trait SymmetricKeyRef: KeyRef<KeyValue = SymmetricCryptoKey> {} | ||
pub trait AsymmetricKeyRef: KeyRef<KeyValue = AsymmetricCryptoKey> {} | ||
|
||
// Just a small derive_like macro that can be used to generate the key reference enums. | ||
// Example usage: | ||
// ```rust | ||
// key_refs! { | ||
// #[symmetric] | ||
// pub enum KeyRef { | ||
// User, | ||
// Org(Uuid), | ||
// #[local] | ||
// Local(String), | ||
// } | ||
// } | ||
#[macro_export] | ||
macro_rules! key_refs { | ||
( $( | ||
#[$meta_type:tt] | ||
$(pub)? enum $name:ident { | ||
$( | ||
$( #[$variant_tag:tt] )? | ||
$variant:ident $( ( $inner:ty ) )? | ||
,)+ | ||
} | ||
)+ ) => { $( | ||
#[derive(std::fmt::Debug, Clone, Copy, std::hash::Hash, Eq, PartialEq, Ord, PartialOrd)] | ||
pub enum $name { $( | ||
$variant $( ($inner) )? | ||
,)+ } | ||
|
||
impl $crate::key_ref::__internal::KeyRef for $name { | ||
type KeyValue = key_refs!(@key_type $meta_type); | ||
|
||
fn is_local(&self) -> bool { | ||
use $name::*; | ||
match self { $( | ||
key_refs!(@variant_match $variant $( ( $inner ) )?) => | ||
key_refs!(@variant_tag $( $variant_tag )? ), | ||
)+ } | ||
} | ||
} | ||
|
||
key_refs!(@key_trait $meta_type $name); | ||
)+ }; | ||
|
||
( @key_type symmetric ) => { $crate::SymmetricCryptoKey }; | ||
( @key_type asymmetric ) => { $crate::AsymmetricCryptoKey }; | ||
|
||
( @key_trait symmetric $name:ident ) => { impl $crate::key_ref::SymmetricKeyRef for $name {} }; | ||
( @key_trait asymmetric $name:ident ) => { impl $crate::key_ref::AsymmetricKeyRef for $name {} }; | ||
|
||
( @variant_match $variant:ident ( $inner:ty ) ) => { $variant (_) }; | ||
( @variant_match $variant:ident ) => { $variant }; | ||
|
||
( @variant_tag local ) => { true }; | ||
( @variant_tag ) => { false }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
memsec
is usingwindows-sys
0.45, which was causing build errors similar to the ones fixed by #1053.Using the latest
windows-sys
0.59 seems to solve the problem for me. TODO: Open a PR upstream?