Skip to content

Commit c84c7b4

Browse files
committed
Use separate keys for payload mechanism and mTLS
This allows other algorithms to be used for mTLS. The payload encryption mechanism requires an RSA key pair, so always generate an RSA key for the payload mechanism. Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
1 parent ef83ed2 commit c84c7b4

File tree

3 files changed

+34
-22
lines changed

3 files changed

+34
-22
lines changed

keylime-agent/src/keys_handler.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ async fn u_key(
166166
// https://github.com/keylime/keylime/blob/f3c31b411dd3dd971fd9d614a39a150655c6797c/ \
167167
// keylime/crypto.py#L118
168168
let decrypted_key = match crypto::rsa_oaep_decrypt(
169-
&quote_data.priv_key,
169+
&quote_data.payload_priv_key,
170170
&encrypted_key,
171171
)
172172
.map_err(Error::from)
@@ -278,7 +278,7 @@ async fn v_key(
278278
// https://github.com/keylime/keylime/blob/f3c31b411dd3dd971fd9d614a39a150655c6797c/ \
279279
// keylime/crypto.py#L118
280280
let decrypted_key = match crypto::rsa_oaep_decrypt(
281-
&quote_data.priv_key,
281+
&quote_data.payload_priv_key,
282282
&encrypted_key,
283283
)
284284
.map_err(Error::from)
@@ -323,7 +323,7 @@ async fn pubkey(
323323
req: HttpRequest,
324324
data: web::Data<QuoteData<'_>>,
325325
) -> impl Responder {
326-
match crypto::pkey_pub_to_pem(&data.pub_key) {
326+
match crypto::pkey_pub_to_pem(&data.payload_pub_key) {
327327
Ok(pubkey) => {
328328
let response = JsonWrapper::success(KeylimePubkey { pubkey });
329329
info!("GET pubkey returning 200 response.");
@@ -902,7 +902,7 @@ mod tests {
902902
fixture.keys_tx = keys_tx.clone();
903903

904904
let quotedata = web::Data::new(fixture);
905-
let pubkey = quotedata.pub_key.clone();
905+
let pubkey = quotedata.payload_pub_key.clone();
906906

907907
// Run server
908908
let mut app = test::init_service(
@@ -968,7 +968,7 @@ mod tests {
968968
})));
969969

970970
let encrypted_key =
971-
rsa_oaep_encrypt(&quotedata.pub_key, u.as_ref()).unwrap(); //#[allow_ci]
971+
rsa_oaep_encrypt(&quotedata.payload_pub_key, u.as_ref()).unwrap(); //#[allow_ci]
972972

973973
let ukey = KeylimeUKey {
974974
encrypted_key: general_purpose::STANDARD.encode(&encrypted_key),
@@ -985,7 +985,7 @@ mod tests {
985985
assert!(resp.status().is_success());
986986

987987
let encrypted_key =
988-
rsa_oaep_encrypt(&quotedata.pub_key, v.as_ref()).unwrap(); //#[allow_ci]
988+
rsa_oaep_encrypt(&quotedata.payload_pub_key, v.as_ref()).unwrap(); //#[allow_ci]
989989

990990
let vkey = KeylimeVKey {
991991
encrypted_key: general_purpose::STANDARD.encode(&encrypted_key),
@@ -1110,7 +1110,7 @@ mod tests {
11101110
test::read_body_json(resp).await;
11111111
assert!(pkey_pub_from_pem(&result.results.pubkey)
11121112
.unwrap() //#[allow_ci]
1113-
.public_eq(&quotedata.pub_key));
1113+
.public_eq(&quotedata.payload_pub_key));
11141114

11151115
// Explicitly drop QuoteData to cleanup keys
11161116
drop(quotedata);

keylime-agent/src/main.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ pub struct QuoteData<'a> {
114114
)>,
115115
measuredboot_ml_file: Option<Mutex<fs::File>>,
116116
payload_tx: mpsc::Sender<payloads::PayloadMessage>,
117+
payload_priv_key: PKey<Private>,
118+
payload_pub_key: PKey<Public>,
117119
priv_key: PKey<Private>,
118120
pub_key: PKey<Public>,
119121
revocation_tx: mpsc::Sender<revocation::RevocationMessage>,
@@ -488,35 +490,36 @@ async fn main() -> Result<()> {
488490
(None, None)
489491
};
490492

491-
// Generate key pair for secure transmission of u, v keys. The u, v
492-
// keys are two halves of the key used to decrypt the workload after
493+
// Generate ephemeral RSA key pair for secure transmission of u, v keys.
494+
// The u, v keys are two halves of the key used to decrypt the workload after
493495
// the Identity and Integrity Quotes sent by the agent are validated
494496
// by the Tenant and Cloud Verifier, respectively.
495-
//
496-
// Since we store the u key in memory, discarding this key, which
497-
// safeguards u and v keys in transit, is not part of the threat model.
497+
debug!("Generating ephemeral RSA key pair for payload mechanism");
498+
let (payload_pub_key, payload_priv_key) =
499+
crypto::rsa_generate_pair(2048)?;
498500

501+
// Generate mTLS key pair (separate from payload keys)
499502
let (nk_pub, nk_priv) = match config.server_key.as_ref() {
500503
"" => {
501504
debug!(
502505
"The server_key option was not set in the configuration file"
503506
);
504-
debug!("Generating new key pair");
507+
debug!("Generating new mTLS key pair");
505508
crypto::rsa_generate_pair(2048)?
506509
}
507510
path => {
508511
let key_path = Path::new(&path);
509512
if key_path.exists() {
510513
debug!(
511-
"Loading existing key pair from {}",
514+
"Loading existing mTLS key pair from {}",
512515
key_path.display()
513516
);
514517
crypto::load_key_pair(
515518
key_path,
516519
Some(config.server_key_password.as_ref()),
517520
)?
518521
} else {
519-
debug!("Generating new key pair");
522+
debug!("Generating new mTLS key pair");
520523
let (public, private) = crypto::rsa_generate_pair(2048)?;
521524
// Write the generated key to the file
522525
crypto::write_key_pair(
@@ -694,6 +697,8 @@ async fn main() -> Result<()> {
694697
keys_tx: keys_tx.clone(),
695698
measuredboot_ml_file,
696699
payload_tx: payload_tx.clone(),
700+
payload_priv_key,
701+
payload_pub_key,
697702
priv_key: nk_priv,
698703
pub_key: nk_pub,
699704
revocation_tx: revocation_tx.clone(),
@@ -993,7 +998,11 @@ mod testing {
993998
.join("test-rsa.pem");
994999

9951000
let (nk_pub, nk_priv) =
996-
crypto::testing::rsa_import_pair(rsa_key_path)?;
1001+
crypto::testing::rsa_import_pair(rsa_key_path.clone())?;
1002+
1003+
// Generate separate ephemeral payload keys for testing
1004+
let (payload_pub_key, payload_priv_key) =
1005+
crypto::rsa_generate_pair(2048)?;
9971006

9981007
let (mut payload_tx, mut payload_rx) =
9991008
mpsc::channel::<payloads::PayloadMessage>(1);
@@ -1046,6 +1055,8 @@ mod testing {
10461055
QuoteData {
10471056
api_versions,
10481057
tpmcontext: Mutex::new(ctx),
1058+
payload_priv_key,
1059+
payload_pub_key,
10491060
priv_key: nk_priv,
10501061
pub_key: nk_pub,
10511062
ak_handle,

keylime-agent/src/quotes_handler.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ async fn identity(
6767
let tpm_quote = match context.quote(
6868
param.nonce.as_bytes(),
6969
0,
70-
&data.pub_key,
70+
&data.payload_pub_key,
7171
data.ak_handle,
7272
data.hash_alg,
7373
data.sign_alg,
@@ -92,7 +92,7 @@ async fn identity(
9292
..Default::default()
9393
};
9494

95-
match crypto::pkey_pub_to_pem(&data.pub_key) {
95+
match crypto::pkey_pub_to_pem(&data.payload_pub_key) {
9696
Ok(pubkey) => quote.pubkey = Some(pubkey),
9797
Err(e) => {
9898
debug!("Unable to retrieve public key for quote: {e:?}");
@@ -169,7 +169,8 @@ async fn integrity(
169169
// If partial="0", include the public key in the quote
170170
let pubkey = match &param.partial[..] {
171171
"0" => {
172-
let pubkey = match crypto::pkey_pub_to_pem(&data.pub_key) {
172+
let pubkey = match crypto::pkey_pub_to_pem(&data.payload_pub_key)
173+
{
173174
Ok(pubkey) => pubkey,
174175
Err(e) => {
175176
debug!("Unable to retrieve public key: {e:?}");
@@ -214,7 +215,7 @@ async fn integrity(
214215
let tpm_quote = match context.quote(
215216
param.nonce.as_bytes(),
216217
mask,
217-
&data.pub_key,
218+
&data.payload_pub_key,
218219
data.ak_handle,
219220
data.hash_alg,
220221
data.sign_alg,
@@ -389,7 +390,7 @@ mod tests {
389390
assert!(
390391
pkey_pub_from_pem(&result.results.pubkey.unwrap()) //#[allow_ci]
391392
.unwrap() //#[allow_ci]
392-
.public_eq(&quotedata.pub_key)
393+
.public_eq(&quotedata.payload_pub_key)
393394
);
394395
assert!(result.results.quote.starts_with('r'));
395396

@@ -435,7 +436,7 @@ mod tests {
435436
assert!(
436437
pkey_pub_from_pem(&result.results.pubkey.unwrap()) //#[allow_ci]
437438
.unwrap() //#[allow_ci]
438-
.public_eq(&quotedata.pub_key)
439+
.public_eq(&quotedata.payload_pub_key)
439440
);
440441

441442
if let Some(ima_mutex) = &quotedata.ima_ml_file {

0 commit comments

Comments
 (0)