Add SGX KSS support
Signed-off-by: Zheng, Qi <huaiqing.zq@antgroup.com>
This commit is contained in:
parent
8cb08aac29
commit
7db9d9b955
@ -24,7 +24,16 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"product_id": 0,
|
"product_id": 0,
|
||||||
"version_number": 0,
|
"version_number": 0,
|
||||||
"debuggable": true
|
"debuggable": true,
|
||||||
|
"enable_kss": false,
|
||||||
|
"family_id": {
|
||||||
|
"high": "0x0",
|
||||||
|
"low": "0x0"
|
||||||
|
},
|
||||||
|
"ext_prod_id": {
|
||||||
|
"high": "0x0",
|
||||||
|
"low": "0x0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mount": [
|
"mount": [
|
||||||
{
|
{
|
||||||
|
68
src/pal/src/base64.c
Normal file
68
src/pal/src/base64.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Base64 encoding/decoding (RFC1341)
|
||||||
|
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
||||||
|
*
|
||||||
|
* This software may be distributed under the terms of the BSD license.
|
||||||
|
* See README for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pal_log.h"
|
||||||
|
#include "base64.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const unsigned char base64_table[65] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
static size_t base64_decode_len(const char *b64input) {
|
||||||
|
size_t len = strlen(b64input), padding = 0;
|
||||||
|
|
||||||
|
if (b64input[len - 1] == '=' && b64input[len - 2] == '=') { //last two chars are =
|
||||||
|
padding = 2;
|
||||||
|
} else if (b64input[len - 1] == '=') { //last char is =
|
||||||
|
padding = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len * 3) / 4 - padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base64_decode - Base64 decode
|
||||||
|
*/
|
||||||
|
void base64_decode(const char *b64input, unsigned char *dest, size_t dest_len) {
|
||||||
|
unsigned char dtable[256], *pos, block[4], tmp;
|
||||||
|
size_t i, count, olen;
|
||||||
|
size_t len = strlen(b64input);
|
||||||
|
|
||||||
|
memset(dtable, 0x80, 256);
|
||||||
|
for (i = 0; i < sizeof(base64_table) - 1; i++) {
|
||||||
|
dtable[base64_table[i]] = (unsigned char) i;
|
||||||
|
}
|
||||||
|
dtable['='] = 0;
|
||||||
|
|
||||||
|
olen = base64_decode_len(b64input);
|
||||||
|
if (olen > dest_len) {
|
||||||
|
PAL_WARN("Base64 encoded length %ld is biggeer than %ld\n", olen, dest_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = dest;
|
||||||
|
count = 0;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
tmp = dtable[(unsigned char)b64input[i]];
|
||||||
|
if (tmp == 0x80) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
block[count] = tmp;
|
||||||
|
count++;
|
||||||
|
if (count == 4) {
|
||||||
|
*pos++ = (block[0] << 2) | (block[1] >> 4);
|
||||||
|
*pos++ = (block[1] << 4) | (block[2] >> 2);
|
||||||
|
*pos++ = (block[2] << 6) | block[3];
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/pal/src/base64.h
Normal file
14
src/pal/src/base64.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __BASE64_H__
|
||||||
|
#define __BASE64_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void base64_decode(const char *b64input, unsigned char *dest, size_t dest_len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __BASE64_H__ */
|
@ -22,6 +22,7 @@
|
|||||||
#include "pal_enclave.h"
|
#include "pal_enclave.h"
|
||||||
#include "pal_error.h"
|
#include "pal_error.h"
|
||||||
#include "pal_log.h"
|
#include "pal_log.h"
|
||||||
|
#include "base64.h"
|
||||||
|
|
||||||
#define MAX_PATH FILENAME_MAX
|
#define MAX_PATH FILENAME_MAX
|
||||||
#define TOKEN_FILENAME "enclave.token"
|
#define TOKEN_FILENAME "enclave.token"
|
||||||
@ -43,6 +44,20 @@ static int get_enclave_debug_flag() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get enable kss flag according to env "OCCLUM_ENABLE_KSS" */
|
||||||
|
static int get_enable_kss_flag() {
|
||||||
|
const char *enable_kss_val = getenv("OCCLUM_ENABLE_KSS");
|
||||||
|
if (enable_kss_val) {
|
||||||
|
if (!strcmp(enable_kss_val, "1") ||
|
||||||
|
!strcasecmp(enable_kss_val, "y") ||
|
||||||
|
!strcasecmp(enable_kss_val, "yes") ||
|
||||||
|
!strcasecmp(enable_kss_val, "true")) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *get_enclave_absolute_path(const char *instance_dir) {
|
static const char *get_enclave_absolute_path(const char *instance_dir) {
|
||||||
static char enclave_path[MAX_PATH + 1] = {0};
|
static char enclave_path[MAX_PATH + 1] = {0};
|
||||||
strncat(enclave_path, instance_dir, MAX_PATH);
|
strncat(enclave_path, instance_dir, MAX_PATH);
|
||||||
@ -102,8 +117,36 @@ int pal_init_enclave(const char *instance_dir) {
|
|||||||
/* Debug Support: set 2nd parameter to 1 */
|
/* Debug Support: set 2nd parameter to 1 */
|
||||||
const char *enclave_path = get_enclave_absolute_path(instance_dir);
|
const char *enclave_path = get_enclave_absolute_path(instance_dir);
|
||||||
int sgx_debug_flag = get_enclave_debug_flag();
|
int sgx_debug_flag = get_enclave_debug_flag();
|
||||||
|
int sgx_enable_kss = get_enable_kss_flag();
|
||||||
|
|
||||||
|
/* If enable kss, use sgx_create_enclave_ex to create enclave */
|
||||||
|
if (sgx_enable_kss) {
|
||||||
|
sgx_kss_config_t kss_config = { 0 };
|
||||||
|
const void *enclave_ex_p[32] = { 0 };
|
||||||
|
const char *sgx_conf_id = getenv("OCCLUM_CONF_ID_BASE64");
|
||||||
|
const char *sgx_conf_svn = getenv("OCCLUM_CONF_SVN");
|
||||||
|
|
||||||
|
if (sgx_conf_id) {
|
||||||
|
base64_decode(sgx_conf_id, kss_config.config_id, SGX_CONFIGID_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sgx_conf_svn) {
|
||||||
|
unsigned long svn_val = strtoul(sgx_conf_svn, NULL, 0);
|
||||||
|
/* CONFIG SVN is 16 bits long */
|
||||||
|
if (svn_val > 0xFFFF) {
|
||||||
|
PAL_WARN("Invalid CONFIG SVN value: 0x%lx\n", svn_val);
|
||||||
|
} else {
|
||||||
|
kss_config.config_svn = svn_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enclave_ex_p[SGX_CREATE_ENCLAVE_EX_KSS_BIT_IDX] = (const void *)&kss_config;
|
||||||
|
ret = sgx_create_enclave_ex(enclave_path, sgx_debug_flag, &token, &updated, &global_eid,
|
||||||
|
NULL, SGX_CREATE_ENCLAVE_EX_KSS, enclave_ex_p);
|
||||||
|
} else {
|
||||||
ret = sgx_create_enclave(enclave_path, sgx_debug_flag, &token, &updated, &global_eid,
|
ret = sgx_create_enclave(enclave_path, sgx_debug_flag, &token, &updated, &global_eid,
|
||||||
NULL);
|
NULL);
|
||||||
|
}
|
||||||
if (ret != SGX_SUCCESS) {
|
if (ret != SGX_SUCCESS) {
|
||||||
const char *sgx_err_msg = pal_get_sgx_error_msg(ret);
|
const char *sgx_err_msg = pal_get_sgx_error_msg(ret);
|
||||||
PAL_ERROR("Failed to create enclave with error code 0x%x: %s", ret, sgx_err_msg);
|
PAL_ERROR("Failed to create enclave with error code 0x%x: %s", ret, sgx_err_msg);
|
||||||
|
@ -27,7 +27,16 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"product_id": 0,
|
"product_id": 0,
|
||||||
"version_number": 0,
|
"version_number": 0,
|
||||||
"debuggable": true
|
"debuggable": true,
|
||||||
|
"enable_kss": false,
|
||||||
|
"family_id": {
|
||||||
|
"high": "0x0",
|
||||||
|
"low": "0x0"
|
||||||
|
},
|
||||||
|
"ext_prod_id": {
|
||||||
|
"high": "0x0",
|
||||||
|
"low": "0x0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"mount": [
|
"mount": [
|
||||||
{
|
{
|
||||||
|
@ -155,6 +155,8 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let kss_tuple = parse_kss_conf(&occlum_config);
|
||||||
|
|
||||||
// Generate the enclave configuration
|
// Generate the enclave configuration
|
||||||
let sgx_enclave_configuration = EnclaveConfiguration {
|
let sgx_enclave_configuration = EnclaveConfiguration {
|
||||||
ProdID: occlum_config.metadata.product_id,
|
ProdID: occlum_config.metadata.product_id,
|
||||||
@ -175,6 +177,11 @@ fn main() {
|
|||||||
ReservedMemMinSize: user_space_size.unwrap() as u64,
|
ReservedMemMinSize: user_space_size.unwrap() as u64,
|
||||||
ReservedMemInitSize: user_space_size.unwrap() as u64,
|
ReservedMemInitSize: user_space_size.unwrap() as u64,
|
||||||
ReservedMemExecutable: 1,
|
ReservedMemExecutable: 1,
|
||||||
|
EnableKSS: kss_tuple.0,
|
||||||
|
ISVEXTPRODID_H: kss_tuple.1,
|
||||||
|
ISVEXTPRODID_L: kss_tuple.2,
|
||||||
|
ISVFAMILYID_H: kss_tuple.3,
|
||||||
|
ISVFAMILYID_L: kss_tuple.4,
|
||||||
};
|
};
|
||||||
let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap();
|
let enclave_config = serde_xml_rs::to_string(&sgx_enclave_configuration).unwrap();
|
||||||
debug!("The enclave config:{:?}", enclave_config);
|
debug!("The enclave config:{:?}", enclave_config);
|
||||||
@ -286,6 +293,30 @@ fn parse_memory_size(mem_str: &str) -> Result<usize, &str> {
|
|||||||
Ok(mem_val * unit_factor)
|
Ok(mem_val * unit_factor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_u64_id_high_and_low(id: &OcclumMetaID) -> (u64, u64) {
|
||||||
|
let id_high = u64::from_str_radix(id.high.trim_start_matches("0x"), 16)
|
||||||
|
.expect("64 bit hex string ID required, such as 0x1234567812345678");
|
||||||
|
let id_low = u64::from_str_radix(id.low.trim_start_matches("0x"), 16)
|
||||||
|
.expect("64 bit hex string ID required, such as 0x1234567812345678");
|
||||||
|
|
||||||
|
(id_high, id_low)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a tuple (EnableKSS, ISVEXTPRODID_H, ISVEXTPRODID_L, ISVFAMILYID_H, ISVFAMILYID_L)
|
||||||
|
fn parse_kss_conf(occlum_config: &OcclumConfiguration
|
||||||
|
) -> (u32, u64, u64, u64, u64)
|
||||||
|
{
|
||||||
|
match occlum_config.metadata.enable_kss {
|
||||||
|
true => {
|
||||||
|
let ext_prod_id = get_u64_id_high_and_low(&occlum_config.metadata.ext_prod_id);
|
||||||
|
let family_id = get_u64_id_high_and_low(&occlum_config.metadata.family_id);
|
||||||
|
|
||||||
|
(1, ext_prod_id.0, ext_prod_id.1, family_id.0, family_id.1)
|
||||||
|
},
|
||||||
|
false => (0, 0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn gen_user_mount_config(
|
fn gen_user_mount_config(
|
||||||
mount_conf: Vec<OcclumMount>,
|
mount_conf: Vec<OcclumMount>,
|
||||||
occlum_conf_user_fs_mac: String,
|
occlum_conf_user_fs_mac: String,
|
||||||
@ -385,11 +416,20 @@ struct OcclumProcess {
|
|||||||
default_mmap_size: String,
|
default_mmap_size: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
struct OcclumMetaID {
|
||||||
|
high: String,
|
||||||
|
low: String
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
struct OcclumMetadata {
|
struct OcclumMetadata {
|
||||||
product_id: u32,
|
product_id: u32,
|
||||||
version_number: u32,
|
version_number: u32,
|
||||||
debuggable: bool,
|
debuggable: bool,
|
||||||
|
enable_kss: bool,
|
||||||
|
family_id: OcclumMetaID,
|
||||||
|
ext_prod_id: OcclumMetaID
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
@ -443,6 +483,11 @@ struct EnclaveConfiguration {
|
|||||||
ReservedMemMinSize: u64,
|
ReservedMemMinSize: u64,
|
||||||
ReservedMemInitSize: u64,
|
ReservedMemInitSize: u64,
|
||||||
ReservedMemExecutable: u32,
|
ReservedMemExecutable: u32,
|
||||||
|
EnableKSS: u32,
|
||||||
|
ISVEXTPRODID_H: u64,
|
||||||
|
ISVEXTPRODID_L: u64,
|
||||||
|
ISVFAMILYID_H: u64,
|
||||||
|
ISVFAMILYID_L: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||||
|
34
tools/occlum
34
tools/occlum
@ -36,6 +36,10 @@ get_enclave_debuggable_flag() {
|
|||||||
jq '.metadata.debuggable' $instance_dir/Occlum.json
|
jq '.metadata.debuggable' $instance_dir/Occlum.json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_enclave_enable_kss_flag() {
|
||||||
|
jq '.metadata.enable_kss' $instance_dir/Occlum.json
|
||||||
|
}
|
||||||
|
|
||||||
exit_error() {
|
exit_error() {
|
||||||
echo "Error: $@" >&2
|
echo "Error: $@" >&2
|
||||||
exit 1
|
exit 1
|
||||||
@ -312,11 +316,21 @@ cmd_build() {
|
|||||||
echo "Built the Occlum image and enclave successfully"
|
echo "Built the Occlum image and enclave successfully"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cmd_run() {
|
cmd_run() {
|
||||||
check_has_built
|
check_has_built
|
||||||
check_has_run
|
check_has_run
|
||||||
check_aesm_service
|
check_aesm_service
|
||||||
|
|
||||||
|
loop=true
|
||||||
|
while [ -n "$1" ] && [ "$loop" = "true" ]; do
|
||||||
|
case "$1" in
|
||||||
|
--config-id) [ -n "$2" ] && export OCCLUM_CONF_ID_BASE64=$2 ; shift 2 || exit_error "Empty Base64 Encoded Occlum Config ID provided" ;;
|
||||||
|
--config-svn) [ -n "$2" ] && export OCCLUM_CONF_SVN=$2 ; shift 2 || exit_error "Empty Occlum Config SVN provided" ;;
|
||||||
|
*) loop=false ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
SGX_MODE=$(cat $instance_dir/.sgx_mode)
|
SGX_MODE=$(cat $instance_dir/.sgx_mode)
|
||||||
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
|
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
|
||||||
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
|
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
|
||||||
@ -329,6 +343,11 @@ cmd_run() {
|
|||||||
if [ "`get_enclave_debuggable_flag`" == "false" ]; then
|
if [ "`get_enclave_debuggable_flag`" == "false" ]; then
|
||||||
export OCCLUM_RELEASE_ENCLAVE=1
|
export OCCLUM_RELEASE_ENCLAVE=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "`get_enclave_enable_kss_flag`" == "true" ]; then
|
||||||
|
export OCCLUM_ENABLE_KSS=1
|
||||||
|
fi
|
||||||
|
|
||||||
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum-run" "$@"
|
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum-run" "$@"
|
||||||
|
|
||||||
echo "built" > $status_file
|
echo "built" > $status_file
|
||||||
@ -338,6 +357,15 @@ cmd_start() {
|
|||||||
check_has_built
|
check_has_built
|
||||||
check_aesm_service
|
check_aesm_service
|
||||||
|
|
||||||
|
loop=true
|
||||||
|
while [ -n "$1" ] && [ "$loop" = "true" ]; do
|
||||||
|
case "$1" in
|
||||||
|
--config-id) [ -n "$2" ] && export OCCLUM_CONF_ID_BASE64=$2 ; shift 2 || exit_error "Empty Base64 Encoded Occlum Config ID provided" ;;
|
||||||
|
--config-svn) [ -n "$2" ] && export OCCLUM_CONF_SVN=$2 ; shift 2 || exit_error "Empty Occlum Config SVN provided" ;;
|
||||||
|
*) loop=false ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
SGX_MODE=$(cat $instance_dir/.sgx_mode)
|
SGX_MODE=$(cat $instance_dir/.sgx_mode)
|
||||||
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
|
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
|
||||||
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
|
export LD_LIBRARY_PATH="$instance_dir/build/lib:$SGX_SDK/sdk_libs/"
|
||||||
@ -350,6 +378,10 @@ cmd_start() {
|
|||||||
if [ "`get_enclave_debuggable_flag`" == "false" ]; then
|
if [ "`get_enclave_debuggable_flag`" == "false" ]; then
|
||||||
export OCCLUM_RELEASE_ENCLAVE=1
|
export OCCLUM_RELEASE_ENCLAVE=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "`get_enclave_enable_kss_flag`" == "true" ]; then
|
||||||
|
export OCCLUM_ENABLE_KSS=1
|
||||||
|
fi
|
||||||
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum_exec_client" start
|
RUST_BACKTRACE=1 "$instance_dir/build/bin/occlum_exec_client" start
|
||||||
|
|
||||||
echo "built" > $status_file
|
echo "built" > $status_file
|
||||||
@ -565,7 +597,7 @@ case "$cmd" in
|
|||||||
cmd_run "${@:2}"
|
cmd_run "${@:2}"
|
||||||
;;
|
;;
|
||||||
start)
|
start)
|
||||||
cmd_start
|
cmd_start "${@:2}"
|
||||||
;;
|
;;
|
||||||
exec)
|
exec)
|
||||||
cmd_exec "${@:2}"
|
cmd_exec "${@:2}"
|
||||||
|
Loading…
Reference in New Issue
Block a user