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