Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,7 @@ dependencies = [
"hex",
"openssl",
"openssl_kdf",
"rsa",
"symcrypt",
"thiserror 2.0.16",
"wchar",
Expand Down Expand Up @@ -6167,9 +6168,9 @@ dependencies = [

[[package]]
name = "pkcs8"
version = "0.11.0-rc.11"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577"
checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7"
dependencies = [
"der",
"spki",
Expand Down Expand Up @@ -6539,9 +6540,9 @@ checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"

[[package]]
name = "rsa"
version = "0.10.0-rc.17"
version = "0.10.0-rc.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ed3e93fc7e473e464b9726f4759659e72bc8665e4b8ea227547024f416d905"
checksum = "30b2aa4ba0d89f73d1e332df05be0eeab8840351c36ca5654341dfdb57bb3caf"
dependencies = [
"const-oid",
"crypto-bigint",
Expand Down
23 changes: 10 additions & 13 deletions openhcl/underhill_attestation/src/jwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub(crate) enum JwtError {
#[error("failed to validate certificate chain")]
CertificateChainValidation(#[from] CertificateChainValidationError),
#[error("failed to verify JWT signature")]
JwtSignatureVerification(#[from] JwtSignatureVerificationError),
JwtSignatureVerification(#[source] JwtSignatureVerificationError),
}

#[derive(Debug, Error)]
Expand Down Expand Up @@ -167,11 +167,8 @@ impl<B: DeserializeOwned> JwtHelper<B> {
pub fn verify_signature(&self) -> Result<bool, JwtError> {
let alg = &self.jwt.header.alg;
let pkey = validate_cert_chain(&self.cert_chain()?)?;

let result =
verify_jwt_signature(alg, &pkey, self.payload.as_bytes(), &self.jwt.signature)?;

Ok(result)
verify_jwt_signature(alg, &pkey, self.payload.as_bytes(), &self.jwt.signature)
.map_err(JwtError::JwtSignatureVerification)
}
}

Expand Down Expand Up @@ -222,13 +219,11 @@ fn verify_jwt_signature(
payload: &[u8],
signature: &[u8],
) -> Result<bool, JwtSignatureVerificationError> {
let result = match alg {
match alg {
JwtAlgorithm::RS256 => pkey
.verify_pkcs1_sha256(payload, signature)
.map_err(JwtSignatureVerificationError::VerifySignature)?,
};

Ok(result)
.pkcs1_verify(payload, signature, crypto::rsa::HashAlgorithm::Sha256)
.map_err(JwtSignatureVerificationError::VerifySignature),
}
}

/// Helper function for x509 certificate chain validation.
Expand Down Expand Up @@ -396,7 +391,9 @@ mod tests {
let rsa_key = RsaKeyPair::generate(2048).unwrap();

let payload = "test";
let signature = rsa_key.sign_pkcs1_sha256(payload.as_bytes()).unwrap();
let signature = rsa_key
.pkcs1_sign(payload.as_bytes(), crypto::rsa::HashAlgorithm::Sha256)
.unwrap();

let cert = crate::test_helpers::generate_x509(&rsa_key);
let public = cert.public_key().unwrap();
Expand Down
24 changes: 12 additions & 12 deletions openhcl/underhill_attestation/src/key_protector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! Implementation of the key retrieval logic for the [`KeyProtector`].

use crate::Keys;
use crypto::rsa::OaepHashAlgorithm;
use crypto::rsa::HashAlgorithm;
use crypto::rsa::RsaKeyPair;
use cvm_tracing::CVM_ALLOWED;
use cvm_tracing::CVM_CONFIDENTIAL;
Expand Down Expand Up @@ -132,7 +132,7 @@ impl KeyProtectorExt for KeyProtector {
}

ingress_kek
.oaep_decrypt(&wrapped_des_key[..modulus_size], OaepHashAlgorithm::Sha256)
.oaep_decrypt(&wrapped_des_key[..modulus_size], HashAlgorithm::Sha256)
.map_err(GetKeysFromKeyProtectorError::DesKeyRsaUnwrap)?
} else {
// The DEK buffer should contain an RSA-wrapped key.
Expand All @@ -141,7 +141,7 @@ impl KeyProtectorExt for KeyProtector {
ingress_kek
.oaep_decrypt(
&self.dek[ingress_idx].dek_buffer[..modulus_size],
OaepHashAlgorithm::Sha256,
HashAlgorithm::Sha256,
)
.map_err(GetKeysFromKeyProtectorError::IngressDekRsaUnwrap)?
};
Expand Down Expand Up @@ -217,7 +217,7 @@ impl KeyProtectorExt for KeyProtector {
} else {
// The DEK buffer should contain an RSA-wrapped key.
ingress_kek
.oaep_decrypt(&dek_buffer[..modulus_size], OaepHashAlgorithm::Sha256)
.oaep_decrypt(&dek_buffer[..modulus_size], HashAlgorithm::Sha256)
.map_err(GetKeysFromKeyProtectorError::EgressDekRsaUnwrap)?
};
let mut key = [0u8; AES_GCM_KEY_LENGTH];
Expand All @@ -241,7 +241,7 @@ impl KeyProtectorExt for KeyProtector {
} else {
// Create an RSA wrapped key
ingress_kek
.oaep_encrypt(&encrypt_egress_key, OaepHashAlgorithm::Sha256)
.oaep_encrypt(&encrypt_egress_key, HashAlgorithm::Sha256)
.map_err(GetKeysFromKeyProtectorError::EgressKeyRsaWrap)?
};

Expand Down Expand Up @@ -295,7 +295,7 @@ mod tests {
let dek = generate_aes_256();

// Test DEK wrapped by the test RSA KEK
let result = kek.oaep_encrypt(&dek, OaepHashAlgorithm::Sha256);
let result = kek.oaep_encrypt(&dek, HashAlgorithm::Sha256);
assert!(result.is_ok());
let rsa_wrapped_dek = result.unwrap();

Expand Down Expand Up @@ -346,7 +346,7 @@ mod tests {

let result = kek.oaep_decrypt(
&key_protector.dek[egress_index].dek_buffer[..kek.modulus_size()],
OaepHashAlgorithm::Sha256,
HashAlgorithm::Sha256,
);
assert!(result.is_ok());
let plaintext = result.unwrap();
Expand Down Expand Up @@ -379,7 +379,7 @@ mod tests {

let result = kek.oaep_decrypt(
&key_protector.dek[egress_index].dek_buffer[..kek.modulus_size()],
OaepHashAlgorithm::Sha256,
HashAlgorithm::Sha256,
);
assert!(result.is_ok());
let plaintext = result.unwrap();
Expand All @@ -402,7 +402,7 @@ mod tests {
let aes_wrapped_dek = result.unwrap();

// Test DES key wrapped by the test RSA KEK
let result = kek.oaep_encrypt(&des, OaepHashAlgorithm::Sha256);
let result = kek.oaep_encrypt(&des, HashAlgorithm::Sha256);
assert!(result.is_ok());
let rsa_wrapped_des = result.unwrap();

Expand Down Expand Up @@ -457,7 +457,7 @@ mod tests {
false
);

let result = kek.oaep_decrypt(&rsa_wrapped_des, OaepHashAlgorithm::Sha256);
let result = kek.oaep_decrypt(&rsa_wrapped_des, HashAlgorithm::Sha256);
assert!(result.is_ok());
let des_key = result.unwrap();

Expand Down Expand Up @@ -499,7 +499,7 @@ mod tests {
false
);

let result = kek.oaep_decrypt(&rsa_wrapped_des, OaepHashAlgorithm::Sha256);
let result = kek.oaep_decrypt(&rsa_wrapped_des, HashAlgorithm::Sha256);
assert!(result.is_ok());
let des_key = result.unwrap();

Expand Down Expand Up @@ -528,7 +528,7 @@ mod tests {
let mut aes_wrapped_dek = result.unwrap();

// Test DES key wrapped by the test RSA KEK
let result = kek.oaep_encrypt(&des, OaepHashAlgorithm::Sha256);
let result = kek.oaep_encrypt(&des, HashAlgorithm::Sha256);
assert!(result.is_ok());
let rsa_wrapped_des = result.unwrap();

Expand Down
11 changes: 5 additions & 6 deletions openhcl/underhill_attestation/src/secure_key_release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn pkcs11_rsa_aes_key_unwrap(
unwrapping_rsa_key: &RsaKeyPair,
wrapped_key_blob: &[u8],
) -> Result<RsaKeyPair, Pkcs11RsaAesKeyUnwrapError> {
use crypto::rsa::OaepHashAlgorithm;
use crypto::rsa::HashAlgorithm;

let modulus_size = unwrapping_rsa_key.modulus_size();

Expand All @@ -92,7 +92,7 @@ fn pkcs11_rsa_aes_key_unwrap(
}

let unwrapped_aes_key = unwrapping_rsa_key
.oaep_decrypt(wrapped_aes_key, OaepHashAlgorithm::Sha1)
.oaep_decrypt(wrapped_aes_key, HashAlgorithm::Sha1)
.map_err(Pkcs11RsaAesKeyUnwrapError::RsaUnwrap)?;
let unwrapped_rsa_key = crypto::aes_key_wrap::AesKeyWrap::new(&unwrapped_aes_key)
.and_then(|kw| kw.unwrapper()?.unwrap(wrapped_rsa_key))
Expand Down Expand Up @@ -385,7 +385,6 @@ async fn make_igvm_attest_requests(
#[cfg(test)]
mod tests {
use super::*;
use crypto::rsa::OaepHashAlgorithm;

#[test]
fn fail_to_unwrap_pkcs11_rsa_aes_with_undersized_wrapped_key_blob() {
Expand Down Expand Up @@ -420,7 +419,7 @@ mod tests {

let wrapping_rsa_key = RsaKeyPair::generate(2048).unwrap();
let wrapped_aes_key = wrapping_rsa_key
.oaep_encrypt(&wrapping_aes_key, OaepHashAlgorithm::Sha1)
.oaep_encrypt(&wrapping_aes_key, crypto::rsa::HashAlgorithm::Sha1)
.unwrap();
let wrapped_target_key = crypto::aes_key_wrap::AesKeyWrap::new(&wrapping_aes_key)
.unwrap()
Expand All @@ -432,8 +431,8 @@ mod tests {
let unwrapped_target_key =
pkcs11_rsa_aes_key_unwrap(&wrapping_rsa_key, wrapped_key_blob.as_slice()).unwrap();
assert_eq!(
unwrapped_target_key.to_private_key_der().unwrap(),
target_key.to_private_key_der().unwrap()
unwrapped_target_key.to_pkcs8_der().unwrap(),
target_key.to_pkcs8_der().unwrap()
);
}
}
4 changes: 3 additions & 1 deletion openhcl/underhill_attestation/src/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ pub fn generate_base64_encoded_jwt_components(key_pair: &RsaKeyPair) -> (String,

// The signature is generated by signing the concatenation of base64_header and base64_body
let message = format!("{}.{}", base64_header, base64_body);
let signature = key_pair.sign_pkcs1_sha256(message.as_bytes()).unwrap();
let signature = key_pair
.pkcs1_sign(message.as_bytes(), crypto::rsa::HashAlgorithm::Sha256)
.unwrap();
let base64_signature = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(&signature);

(base64_header, base64_body, base64_signature)
Expand Down
8 changes: 6 additions & 2 deletions support/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,23 @@ openssl = ["dep:openssl", "dep:openssl_kdf"]
# Use Symcrypt instead of any native backend.
# Note that the symcrypt backend does not support vendoring, enabling both
# `symcrypt` and `vendored` will trigger a compile error
symcrypt = ["dep:symcrypt", "symcrypt/sha1"]
symcrypt = ["dep:symcrypt", "symcrypt/sha1", "dep:rsa"]

[dependencies]
openssl_kdf = { workspace = true, optional = true }
openssl = { workspace = true, optional = true }

symcrypt = { workspace = true, optional = true }
rsa = { workspace = true, optional = true, features = ["std", "encoding"] }

thiserror.workspace = true

[target.'cfg(windows)'.dependencies]
wchar.workspace = true
windows = { workspace = true, features = ["Win32_Foundation","Win32_Security_Cryptography"] }
windows = { workspace = true, features = [
"Win32_Foundation",
"Win32_Security_Cryptography",
] }
windows-result.workspace = true
zerocopy.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion support/crypto/src/aes_256_cbc/symcrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct Aes256CbcDecCtxInner<'a> {
}

fn err(e: ::symcrypt::errors::SymCryptError, op: &'static str) -> Aes256CbcError {
Aes256CbcError(crate::BackendError(e, op))
Aes256CbcError(crate::BackendError::SymCryptError(e, op))
}

impl Aes256CbcInner {
Expand Down
2 changes: 1 addition & 1 deletion support/crypto/src/aes_256_gcm/symcrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct Aes256GcmDecCtxInner<'a> {
}

fn err(e: ::symcrypt::errors::SymCryptError, op: &'static str) -> Aes256GcmError {
Aes256GcmError(crate::BackendError(e, op))
Aes256GcmError(crate::BackendError::SymCryptError(e, op))
}

impl Aes256GcmInner {
Expand Down
2 changes: 1 addition & 1 deletion support/crypto/src/hmac_sha_256/symcrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ::symcrypt::errors::SymCryptError;
use ::symcrypt::hmac::hmac_sha256;

fn err(e: SymCryptError, op: &'static str) -> HmacSha256Error {
HmacSha256Error(crate::BackendError(e, op))
HmacSha256Error(crate::BackendError::SymCryptError(e, op))
}

pub fn hmac_sha_256(key: &[u8], data: &[u8]) -> Result<[u8; 32], HmacSha256Error> {
Expand Down
9 changes: 7 additions & 2 deletions support/crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,13 @@ pub struct BackendError(#[source] windows_result::Error, &'static str);
/// operation being performed when the error occurred.
#[cfg(symcrypt)]
#[derive(Clone, Debug, thiserror::Error)]
#[error("symcrypt error during {1}")]
pub struct BackendError(#[source] symcrypt::errors::SymCryptError, &'static str);
#[error("symcrypt backend error during {1}")]
pub enum BackendError {
/// An error from the SymCrypt library, with the operation being performed when the error occurred.
SymCryptError(#[source] symcrypt::errors::SymCryptError, &'static str),
/// An error from encoding or decoding PKCS#8, with the operation being performed when the error occurred.
Pkcs8EncodingError(#[source] ::rsa::pkcs8::Error, &'static str),
}

#[cfg(all(native, target_os = "macos"))]
pub use mac::BackendError;
4 changes: 1 addition & 3 deletions support/crypto/src/pkcs7/ossl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ impl Pkcs7SignedDataInner {
key_pair: &crate::rsa::RsaKeyPair,
data: &[u8],
) -> Result<Self, Pkcs7Error> {
let pkey = openssl::pkey::PKey::from_rsa(key_pair.0.rsa.clone())
.map_err(|e| err(e, "converting RSA key for pkcs7 signing"))?;
let certs =
openssl::stack::Stack::new().map_err(|e| err(e, "creating empty certificate stack"))?;
let pkcs7 = openssl::pkcs7::Pkcs7::sign(
&cert.0.cert,
&pkey,
&key_pair.0.0,
&certs,
data,
openssl::pkcs7::Pkcs7Flags::empty(),
Expand Down
Loading
Loading