Skip to content

Commit

Permalink
KBS: Update KBS protocol to 0.2.0 to fix JWE
Browse files Browse the repository at this point in the history
Fixes #583.

Due to RFC 7516, the JWE AEAD Auth Tag should be expcilitly be included
inside the `tag` part. Before this commit, the tag is actually included
as the suffix of the `ciphertest`. Although this is also secure, it's
not standard.

We fix this by expcilitly extract the tag and include it into the jwe
body. Also, we use an AAD `CoCo` to do AEAD. This should be align with
the guest-components side.

This change will make the kbs_client not able to connect to the KBS.
Thus we update the KBS protocol version from 0.1.1 to 0.2.0.

Signed-off-by: Xynnn007 <xynnn@linux.alibaba.com>
  • Loading branch information
Xynnn007 committed Nov 26, 2024
1 parent 423e208 commit 57d5ea2
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
5 changes: 5 additions & 0 deletions kbs/docs/kbs_attestation_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ The encrypted symmetric key is used to encrypt `ciphertext`.
This key is encrypted with the HW-TEE's public key, using the algorithm defined
in `alg`.

- `tag`

The authentication tag is used to authenticate the ciphertext. If the algorithm
described by `enc` used does not need it, this field is left blank.

## Key Format

### Public Key
Expand Down
4 changes: 2 additions & 2 deletions kbs/src/attestation/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use super::{
};

static KBS_MAJOR_VERSION: u64 = 0;
static KBS_MINOR_VERSION: u64 = 1;
static KBS_PATCH_VERSION: u64 = 1;
static KBS_MINOR_VERSION: u64 = 2;
static KBS_PATCH_VERSION: u64 = 0;

lazy_static! {
static ref VERSION_REQ: VersionReq = {
Expand Down
15 changes: 8 additions & 7 deletions kbs/src/jwe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit, Nonce};
use aes_gcm::{aead::AeadMutInPlace, Aes256Gcm, KeyInit, Nonce};
use anyhow::{anyhow, bail, Context, Result};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
use kbs_types::{Response, TeePubKey};
Expand All @@ -12,8 +12,9 @@ use serde_json::json;

const RSA_ALGORITHM: &str = "RSA1_5";
const AES_GCM_256_ALGORITHM: &str = "A256GCM";
const AEAD_AAD: &[u8] = b"CoCo";

pub fn jwe(tee_pub_key: TeePubKey, payload_data: Vec<u8>) -> Result<Response> {
pub fn jwe(tee_pub_key: TeePubKey, mut payload_data: Vec<u8>) -> Result<Response> {
let TeePubKey::RSA { alg, k_mod, k_exp } = tee_pub_key else {
bail!("Only RSA key is support for TEE pub key")
};
Expand All @@ -25,11 +26,11 @@ pub fn jwe(tee_pub_key: TeePubKey, payload_data: Vec<u8>) -> Result<Response> {
let mut rng = rand::thread_rng();

let aes_sym_key = Aes256Gcm::generate_key(&mut OsRng);
let cipher = Aes256Gcm::new(&aes_sym_key);
let mut cipher = Aes256Gcm::new(&aes_sym_key);
let iv = rng.gen::<[u8; 12]>();
let nonce = Nonce::from_slice(&iv);
let encrypted_payload_data = cipher
.encrypt(nonce, payload_data.as_slice())
let tag = cipher
.encrypt_in_place_detached(nonce, AEAD_AAD, &mut payload_data)
.map_err(|e| anyhow!("AES encrypt Resource payload failed: {e}"))?;

let k_mod = URL_SAFE_NO_PAD
Expand Down Expand Up @@ -59,7 +60,7 @@ pub fn jwe(tee_pub_key: TeePubKey, payload_data: Vec<u8>) -> Result<Response> {
.context("serde protected_header failed")?,
encrypted_key: URL_SAFE_NO_PAD.encode(wrapped_sym_key),
iv: URL_SAFE_NO_PAD.encode(iv),
ciphertext: URL_SAFE_NO_PAD.encode(encrypted_payload_data),
tag: "".to_string(),
ciphertext: URL_SAFE_NO_PAD.encode(payload_data),
tag: URL_SAFE_NO_PAD.encode(tag),
})
}

0 comments on commit 57d5ea2

Please sign in to comment.