Skip to content

Commit 20ad96a

Browse files
haowqsjyao1
authored andcommitted
td-payload: Migrate staging branch td-payload to main branch
Description: A sample TD module/driver for TDX hardware platforms Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Liu Jiang <gerry@linux.alibaba.com> Signed-off-by: haowei <WeiX.Hao@intel.com>
1 parent f32cde4 commit 20ad96a

File tree

10 files changed

+562
-0
lines changed

10 files changed

+562
-0
lines changed

td-payload/Cargo.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[package]
2+
name = "td-payload"
3+
version = "0.1.0"
4+
description = "A sample TD module/driver for TDX hardware platforms"
5+
repository = "https://github.com/confidential-containers/td-shim"
6+
homepage = "https://github.com/confidential-containers"
7+
license = "BSD-2-Clause-Patent"
8+
edition = "2018"
9+
10+
[dependencies]
11+
chrono = { version = "0.4.19", default-features = false, features = ["serde"]}
12+
linked_list_allocator = "0.9.0"
13+
log = "0.4.13"
14+
r-efi = "3.2.0"
15+
serde = { version = "1.0", default-features = false, features = ["derive"]}
16+
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
17+
td-layout = { path = "../td-layout" }
18+
td-logger = { path = "../td-logger" }
19+
uefi-pi = { path = "../uefi-pi" }
20+
21+
td-benchmark = { path = "../devtools/td-benchmark", optional = true }
22+
tdx-tdcall = { path = "../tdx-tdcall", optional = true }
23+
24+
[features]
25+
default = []
26+
cet-ss = []
27+
benches = ["td-benchmark"]
28+
tdx = ["tdx-tdcall", "td-logger/tdx"]
29+
main = []

td-payload/src/asm/cet_ss_test.asm

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright (c) 2021 Intel Corporation
2+
# SPDX-License-Identifier: BSD-2-Clause-Patent
3+
4+
.section .text
5+
6+
# cet_ss_test(
7+
# loop: usize, // rcx
8+
# );
9+
.global cet_ss_test
10+
cet_ss_test:
11+
mov rdx, rsp
12+
rcx_test:
13+
cmp rcx, 0x1000
14+
jnz rcx_test
15+
write_stack:
16+
mov byte ptr [rdx], 100
17+
add rdx, 1
18+
dec rcx
19+
jnz write_stack
20+
21+
ret

td-payload/src/asm/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2021 Intel Corporation
2+
//
3+
// SPDX-License-Identifier: BSD-2-Clause-Patent
4+
5+
global_asm!(include_str!("stack_guard_test.asm"));
6+
#[cfg(feature = "cet-ss")]
7+
global_asm!(include_str!("cet_ss_test.asm"));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2021 Intel Corporation
2+
# SPDX-License-Identifier: BSD-2-Clause-Patent
3+
4+
.section .text
5+
# stack_guard_test(
6+
# );
7+
.global stack_guard_test
8+
stack_guard_test:
9+
10+
loop:
11+
push rax
12+
jmp loop

td-payload/src/json.rs

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// Copyright © 2019 Intel Corporation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use alloc::string::String;
16+
use chrono::{serde::ts_seconds, DateTime, FixedOffset, TimeZone, Utc};
17+
use r_efi::efi::Guid;
18+
use serde::{Deserialize, Serialize};
19+
20+
#[derive(Debug, PartialEq, Serialize, Deserialize)]
21+
struct SerdeJsonTest {
22+
#[serde(with = "guid")]
23+
test_guid: Guid,
24+
#[serde(with = "range")]
25+
test_range_inclu: range::Range,
26+
#[serde(with = "range")]
27+
test_range_exclu: range::Range,
28+
#[serde(with = "range")]
29+
test_range_hex: range::Range,
30+
#[serde(with = "hex")]
31+
test_u32: u32,
32+
test_bool: bool,
33+
test_u16: u16,
34+
test_string: String,
35+
test_array: [u32; 5],
36+
//Default rfc3339 for chrono serde.
37+
test_time: DateTime<FixedOffset>,
38+
#[serde(with = "ts_seconds")]
39+
test_time_stamp: DateTime<Utc>,
40+
}
41+
42+
pub fn json_test() {
43+
let zero = SerdeJsonTest {
44+
//{B0BAE802-534F-4974-942D-2EDE15BC1AE8}
45+
test_guid: Guid::from_fields(
46+
0xB0BAE802,
47+
0x534F,
48+
0x4974,
49+
0x94,
50+
0x2D,
51+
&[0x2E, 0xDE, 0x15, 0xBC, 0x1A, 0xE8],
52+
),
53+
test_range_inclu: range::new(false, 2, true, i64::MAX),
54+
test_range_exclu: range::new(true, -2, true, 5),
55+
test_range_hex: range::new(true, 16, false, 32),
56+
test_u32: 0x00001000,
57+
test_bool: true,
58+
test_u16: 256,
59+
test_string: String::from("A test"),
60+
test_array: [1, 2, 3, 4, 5],
61+
test_time: DateTime::parse_from_rfc3339("1996-12-19T16:39:57-08:00").unwrap(),
62+
test_time_stamp: Utc.ymd(2015, 5, 15).and_hms(10, 0, 0),
63+
};
64+
65+
let config = r#"
66+
{
67+
"test_guid":"B0BAE802-534F-4974-942D-2EDE15BC1AE8",
68+
"test_range_inclu":"[2..inf)",
69+
"test_range_exclu":"(-2..5)",
70+
"test_range_hex":"(0x10..0x20]",
71+
"test_u32": "0x00001000",
72+
"test_bool": true,
73+
"test_u16": 256,
74+
"test_string": "A test",
75+
"test_array": [1, 2, 3, 4, 5],
76+
"test_time":"1996-12-19T16:39:57-08:00",
77+
"test_time_stamp":1431684000
78+
}
79+
"#;
80+
let bytes_config = config.as_bytes();
81+
82+
let one: SerdeJsonTest =
83+
serde_json::from_slice(bytes_config).expect("It is not a successful JSON test.");
84+
assert_eq!(zero, one);
85+
}
86+
87+
mod guid {
88+
use r_efi::efi::Guid;
89+
use serde::{de::Error, Deserialize, Deserializer, Serializer};
90+
pub fn serialize<S>(guid: &Guid, serialize: S) -> Result<S::Ok, S::Error>
91+
where
92+
S: Serializer,
93+
{
94+
let (time_low, time_mid, time_hi_and_version, clk_seq_hi_res, clk_seq_low, node) =
95+
guid.as_fields();
96+
let str = format!(
97+
"{:08X?}-{:04X?}-{:04X?}-{:02X?}{:02X?}-{:02X?}{:02X?}{:02X?}{:02X?}{:02X?}{:02X?}",
98+
time_low,
99+
time_mid,
100+
time_hi_and_version,
101+
clk_seq_hi_res,
102+
clk_seq_low,
103+
node[0],
104+
node[1],
105+
node[2],
106+
node[3],
107+
node[4],
108+
node[5]
109+
);
110+
serialize.serialize_str(&str)
111+
}
112+
113+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Guid, D::Error>
114+
where
115+
D: Deserializer<'de>,
116+
{
117+
let s: &str = Deserialize::deserialize(deserializer)?;
118+
Ok(Guid::from_fields(
119+
u32::from_str_radix(&s[0..8], 16).map_err(D::Error::custom)?,
120+
u16::from_str_radix(&s[9..13], 16).map_err(D::Error::custom)?,
121+
u16::from_str_radix(&s[14..18], 16).map_err(D::Error::custom)?,
122+
u8::from_str_radix(&s[19..21], 16).map_err(D::Error::custom)?,
123+
u8::from_str_radix(&s[21..23], 16).map_err(D::Error::custom)?,
124+
&[
125+
u8::from_str_radix(&s[24..26], 16).map_err(D::Error::custom)?,
126+
u8::from_str_radix(&s[26..28], 16).map_err(D::Error::custom)?,
127+
u8::from_str_radix(&s[28..30], 16).map_err(D::Error::custom)?,
128+
u8::from_str_radix(&s[30..32], 16).map_err(D::Error::custom)?,
129+
u8::from_str_radix(&s[32..34], 16).map_err(D::Error::custom)?,
130+
u8::from_str_radix(&s[34..36], 16).map_err(D::Error::custom)?,
131+
],
132+
))
133+
}
134+
}
135+
136+
mod range {
137+
use alloc::string::ToString;
138+
use serde::{Deserialize, Deserializer, Serializer};
139+
140+
pub fn new(exclusive_min: bool, min: i64, exclusive_max: bool, max: i64) -> Range {
141+
Range {
142+
exclusive_min,
143+
min,
144+
exclusive_max,
145+
max,
146+
}
147+
}
148+
149+
#[derive(Debug, PartialEq)]
150+
pub struct Range {
151+
exclusive_min: bool,
152+
min: i64,
153+
exclusive_max: bool,
154+
max: i64,
155+
}
156+
157+
pub fn serialize<S>(range: &Range, serialize: S) -> Result<S::Ok, S::Error>
158+
where
159+
S: Serializer,
160+
{
161+
let str = format!(
162+
"{}{}..{}{}",
163+
if range.exclusive_min { '(' } else { '[' },
164+
if range.min == i64::MIN {
165+
"-inf".to_string()
166+
} else {
167+
range.min.to_string()
168+
},
169+
if range.max == i64::MAX {
170+
"inf".to_string()
171+
} else {
172+
range.max.to_string()
173+
},
174+
if range.exclusive_max { ')' } else { ']' },
175+
);
176+
serialize.serialize_str(&str)
177+
}
178+
179+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Range, D::Error>
180+
where
181+
D: Deserializer<'de>,
182+
{
183+
let s: &str = Deserialize::deserialize(deserializer)?;
184+
let len = s.len();
185+
let exclu_max = b')' == s.as_bytes()[len - 1];
186+
let exclu_min = b'(' == s.as_bytes()[0];
187+
let dot_dot = s.find("..").unwrap();
188+
fn str_to_int64(s: &str) -> i64 {
189+
match s {
190+
"-inf" => i64::MIN,
191+
"inf" => i64::MAX,
192+
_ => {
193+
if s.len() > 2 && (&s[..2] == "0x" || &s[..2] == "0X") {
194+
i64::from_str_radix(&s[2..], 16).unwrap()
195+
} else {
196+
s.parse::<i64>().unwrap()
197+
}
198+
}
199+
}
200+
}
201+
let min = str_to_int64(&s[1..dot_dot]);
202+
let max = str_to_int64(&s[dot_dot + 2..len - 1]);
203+
Ok(Range {
204+
exclusive_max: exclu_max,
205+
exclusive_min: exclu_min,
206+
min: min,
207+
max: max,
208+
})
209+
}
210+
}
211+
212+
mod hex {
213+
use serde::{de::Error, Deserialize, Deserializer, Serializer};
214+
pub fn serialize<S>(num: &u32, serialize: S) -> Result<S::Ok, S::Error>
215+
where
216+
S: Serializer,
217+
{
218+
let str = format!("0x{:x}", num);
219+
serialize.serialize_str(&str)
220+
}
221+
222+
pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
223+
where
224+
D: Deserializer<'de>,
225+
{
226+
let s: &str = Deserialize::deserialize(deserializer)?;
227+
if s.len() > 2 && (&s[..2] == "0x" || &s[..2] == "0X") {
228+
u32::from_str_radix(&s[2..], 16).map_err(D::Error::custom)
229+
} else {
230+
s.parse::<u32>().map_err(D::Error::custom)
231+
}
232+
}
233+
}

td-payload/src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright © 2019 Intel Corporation
2+
// Copyright (c) 2022 Alibaba Cloud
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#![no_std]
17+
#![feature(alloc_error_handler)]
18+
19+
#[macro_use]
20+
extern crate alloc;
21+
22+
#[cfg(not(test))]
23+
#[alloc_error_handler]
24+
#[allow(clippy::empty_loop)]
25+
fn alloc_error(_info: core::alloc::Layout) -> ! {
26+
log::info!("alloc_error ... {:?}\n", _info);
27+
panic!("deadloop");
28+
}
29+
30+
mod json;
31+
pub use json::json_test;

0 commit comments

Comments
 (0)