Skip to content

Commit e14320b

Browse files
authored
feat: add quote generator assistant (#45)
* feat: add quote-generator assistant * feat: install latest rust version * feat: add building of quote-generator in dockerfile * fix: correct the placement of quote-generator * fix: correct dockerfile issues * fix: add missing dependencies and remove unreachable chineese mirror * chore: add logging environment * chore: apply cargo fmt * fix: update tdx-attest-rs dependency to point to github-based crate * fix: remove unnecessary download of dependency * fix: update cargo edition to 2024 * chore: encode size variables with const type * chore: add rust building folder in gitignore * fix: apply cargo fmt * chore: replace remaining magical numbers with their constants * fix: add exit after fatal errors * chore: encapsulate code into funtions * rafactor: factorize code into functions * docs: document functions * docs: improve comments * fix: add carriage return in gitignore * fix: support at most 64 bytes report_data
1 parent 7fa63b7 commit e14320b

File tree

4 files changed

+189
-4
lines changed

4 files changed

+189
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
apploader/conf/local.yml
2+
cvmassistants/quote-generator/target

Dockerfile

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ FROM ubuntu:24.04 AS build
33
RUN apt-get update \
44
&& env DEBIAN_FRONTEND=noninteractive apt-get install -y \
55
wget \
6+
curl \
67
pkg-config \
78
unzip \
89
build-essential
@@ -15,6 +16,10 @@ COPY . /cvm-agent
1516
RUN wget --no-proxy --progress=bar:force -c https://dl.google.com/go/go1.24.9.linux-amd64.tar.gz -O - | tar -xz -C /usr/local
1617
ENV PATH=$PATH:/usr/local/go/bin
1718

19+
# Install latest Rust from official source
20+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
21+
ENV PATH=/root/.cargo/bin:$PATH
22+
1823
RUN cd /cvm-agent/apploader \
1924
&& go build -ldflags "-w -s -X apploader/version.version=${VERSION}" -o apploader
2025

@@ -27,11 +32,11 @@ RUN apt-get install -y \
2732
make \
2833
cmake \
2934
gcc \
30-
cargo \
3135
libssl-dev \
3236
software-properties-common \
3337
libcurl4-openssl-dev \
34-
libcbor-dev
38+
libcbor-dev \
39+
libclang-dev
3540

3641
# RA-TLS DCAP libraries
3742
# https://download.01.org/intel-sgx/sgx_repo/ubuntu/dists/noble/main/binary-amd64/Packages
@@ -45,8 +50,6 @@ RUN echo 'deb [signed-by=/etc/apt/keyrings/intel-sgx-keyring.asc arch=amd64] htt
4550
libtdx-attest-dev \
4651
libsgx-dcap-default-qpl-dev
4752

48-
RUN mkdir -p $HOME/.cargo/ && echo '[source.crates-io] \n registry = "git://mirrors.ustc.edu.cn/crates.io-index"' >> $HOME/.cargo/config
49-
5053
## todovm-cal 1005.1
5154
RUN git clone https://github.com/inclavare-containers/rats-tls.git /rats-tls\
5255
&& cd /rats-tls \
@@ -63,6 +66,10 @@ RUN cd /cvm-agent/cvmassistants/keyprovider/key-provider-agent \
6366
RUN cd /cvm-agent/cvmassistants/secretprovider/secret-provider-agent \
6467
&& make all
6568

69+
# Build quote-generator
70+
RUN cd /cvm-agent/cvmassistants/quote-generator \
71+
&& cargo build --release
72+
6673
# Final image
6774
FROM ubuntu:24.04
6875

@@ -127,6 +134,10 @@ COPY --from=build /usr/local/lib/rats-tls/ /usr/local/lib/rats-tls/
127134
RUN mkdir -p /workplace/cvm-agent/cvmassistants/secretprovider
128135
COPY --from=build /cvm-agent/cvmassistants/secretprovider/secret-provider-agent/secret_provider_agent /workplace/cvm-agent/cvmassistants/secretprovider
129136

137+
#get quote-generator
138+
RUN mkdir -p /workplace/cvm-agent/cvmassistants/quote-generator
139+
COPY --from=build /cvm-agent/cvmassistants/quote-generator/target/release/quote-generator /workplace/cvm-agent/cvmassistants/quote-generator
140+
130141
#config supervisord
131142
RUN apt-get update \
132143
&& env DEBIAN_FRONTEND=noninteractive apt-get install -y \
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "quote-generator"
3+
version = "1.0.0"
4+
edition = "2024"
5+
6+
7+
[dependencies]
8+
tdx-attest-rs = {git = "https://github.com/intel/confidential-computing.tee.dcap", tag = "DCAP_1.23"}
9+
log = "0.4"
10+
env_logger = "0.11"
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
* Copyright (C) 2011-2022 Intel Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in
12+
* the documentation and/or other materials provided with the
13+
* distribution.
14+
* * Neither the name of Intel Corporation nor the names of its
15+
* contributors may be used to endorse or promote products derived
16+
* from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*
30+
*/
31+
32+
use log::{debug, error, info};
33+
use std::env;
34+
use std::fs;
35+
use std::process;
36+
use tdx_attest_rs;
37+
38+
const REPORT_DATA_SIZE: usize = 64;
39+
const REPORT_SIZE: usize = 1024;
40+
const TDX_UUID_SIZE: usize = 16;
41+
const QUOTE_FILE_NAME: &str = "quote.dat";
42+
43+
/// Creates a TDX report data structure from input bytes.
44+
///
45+
/// # Arguments
46+
///
47+
/// * `input_bytes` - A byte slice that **must be exactly `REPORT_DATA_SIZE` bytes long**.
48+
/// In this binary, `main` guarantees this by copying/padding the user input into
49+
/// a fixed-size `REPORT_DATA_SIZE` buffer before calling this function.
50+
///
51+
/// # Returns
52+
///
53+
/// A `tdx_report_data_t` structure containing the input bytes.
54+
///
55+
/// # Panics
56+
///
57+
/// Panics if `input_bytes` length doesn't match `REPORT_DATA_SIZE` (due to `try_into().unwrap()`).
58+
fn create_report_data(input_bytes: &[u8]) -> tdx_attest_rs::tdx_report_data_t {
59+
let report_data = tdx_attest_rs::tdx_report_data_t {
60+
d: input_bytes.try_into().unwrap(),
61+
};
62+
debug!("TDX report data: {:?}", report_data.d);
63+
64+
report_data
65+
}
66+
67+
/// Generates and displays a TDX report for the given report data.
68+
///
69+
/// This function creates a TDX report and logs it at debug level.
70+
/// The report is only visible when the logger is configured to show debug messages.
71+
///
72+
/// # Arguments
73+
///
74+
/// * `report_data` - The report data to use for generating the TDX report
75+
///
76+
/// # Exits
77+
///
78+
/// Exits with status code 1 if the report generation fails
79+
fn display_tdx_report(report_data: &tdx_attest_rs::tdx_report_data_t) {
80+
let mut tdx_report = tdx_attest_rs::tdx_report_t {
81+
d: [0; REPORT_SIZE],
82+
};
83+
let result = tdx_attest_rs::tdx_att_get_report(Some(report_data), &mut tdx_report);
84+
if result != tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS {
85+
error!("Failed to get the report");
86+
process::exit(1);
87+
}
88+
debug!("TDX report: {:?}", tdx_report.d);
89+
}
90+
91+
/// Creates a TDX attestation quote from the given report data.
92+
///
93+
/// This function generates a cryptographic quote that can be used to verify
94+
/// the integrity and authenticity of the TDX environment.
95+
///
96+
/// # Arguments
97+
///
98+
/// * `report_data` - The report data to include in the quote
99+
///
100+
/// # Returns
101+
///
102+
/// A `Vec<u8>` containing the generated quote data
103+
///
104+
/// # Exits
105+
///
106+
/// Exits with status code 1 if quote generation fails
107+
fn create_quote(report_data: &tdx_attest_rs::tdx_report_data_t) -> Vec<u8> {
108+
let mut selected_att_key_id = tdx_attest_rs::tdx_uuid_t {
109+
d: [0; TDX_UUID_SIZE],
110+
};
111+
let (result, quote) = tdx_attest_rs::tdx_att_get_quote(
112+
Some(report_data),
113+
None,
114+
Some(&mut selected_att_key_id),
115+
0,
116+
);
117+
if result != tdx_attest_rs::tdx_attest_error_t::TDX_ATTEST_SUCCESS {
118+
error!("Failed to get the quote");
119+
process::exit(1);
120+
}
121+
match quote {
122+
Some(q) => {
123+
debug!("Successfully generated TDX quote with {} bytes", q.len());
124+
debug!("Quote: {:?}", q);
125+
q
126+
}
127+
None => {
128+
error!("Failed to get the quote");
129+
process::exit(1);
130+
}
131+
}
132+
}
133+
134+
fn main() {
135+
// Initialize the logger (defaults to INFO level, override with RUST_LOG env var)
136+
env_logger::init();
137+
138+
let args: Vec<String> = env::args().collect();
139+
if args.len() != 2 {
140+
error!("Usage: {} <{}-byte-report-data>", args[0], REPORT_DATA_SIZE);
141+
process::exit(1);
142+
}
143+
144+
let input = &args[1];
145+
let input_bytes = input.as_bytes();
146+
if input_bytes.len() > REPORT_DATA_SIZE {
147+
error!(
148+
"report_data must be at most {} bytes, got {} bytes",
149+
REPORT_DATA_SIZE,
150+
input_bytes.len()
151+
);
152+
process::exit(1);
153+
}
154+
155+
let mut report_bytes = [0u8; REPORT_DATA_SIZE];
156+
report_bytes[..input_bytes.len()].copy_from_slice(input_bytes);
157+
158+
let report_data = create_report_data(&report_bytes);
159+
display_tdx_report(&report_data); // Report is only displayed on debug mode - this function is optional
160+
let quote = create_quote(&report_data);
161+
fs::write(QUOTE_FILE_NAME, quote).expect("Unable to write quote file");
162+
info!("Quote successfully written to {}", QUOTE_FILE_NAME);
163+
}

0 commit comments

Comments
 (0)