From e4af99705b611e702216a58a8ddf90254f8b1977 Mon Sep 17 00:00:00 2001
From: houmingyong <houmingyong@huawei.com>
Date: Sat, 27 May 2023 14:26:56 +0800
Subject: [PATCH 2/2] secure channel support authentication by remote
 attestation

---
 component/secure_channel/Readme.md            |   6 +-
 .../secure_channel/client/CMakeLists.txt      |  13 +-
 .../client/secure_channel_client.c            | 362 +++++++++++++++---
 .../client/secure_channel_client.h            |   1 +
 .../secure_channel/enclave/CMakeLists.txt     |   8 +-
 .../enclave/secure_channel_enclave.c          |  79 +++-
 .../enclave/secure_channel_enclave.h          |   2 +
 component/secure_channel/host/CMakeLists.txt  |  14 +-
 .../secure_channel/host/secure_channel_host.c | 106 ++++-
 component/secure_channel/secure_channel.edl   |   2 +
 .../secure_channel/secure_channel_common.c    |  36 +-
 .../secure_channel/secure_channel_common.h    |  22 +-
 examples/secure_channel/CMakeLists.txt        |  25 +-
 examples/secure_channel/Readme.md             |   2 +-
 examples/secure_channel/client/CMakeLists.txt |   4 +-
 examples/secure_channel/client/client.c       |   3 +-
 .../secure_channel/enclave/CMakeLists.txt     |  14 +-
 .../secure_channel/enclave/config_cloud.ini   |  70 ++--
 examples/secure_channel/host/CMakeLists.txt   |  10 +-
 examples/secure_channel/host/server.c         |   2 +-
 20 files changed, 614 insertions(+), 167 deletions(-)

diff --git a/component/secure_channel/Readme.md b/component/secure_channel/Readme.md
index 84ef98b..ea6201f 100644
--- a/component/secure_channel/Readme.md
+++ b/component/secure_channel/Readme.md
@@ -11,7 +11,7 @@
 |------------|--------------------------|-----------------------|---------|
 | 客户端        | secure_channel_client.h  | libcsecure_channel.so | openssl |
 | 服务端host    | secure_channel_host.h    | libusecure_channel.so | openssl |
-| 服务端enclave | secure_channel_enclave.h | libtsecure_channel.so | TEE及TEE软件栈     |
+| 服务端enclave | secure_channel_enclave.h | libtsecure_channel.a| TEE及TEE软件栈     |
 
 ### 接口
 | 接口名                                                                                                                                          | 所属头文件、库                   | 功能           | 备注 |
@@ -25,8 +25,8 @@
 |  cc_sec_chl_svr_init                                                                                                                                            |  secure_channel_host.h  libusecure_channel.so                    |  安全通道服务端初始化            | 调用前需初始化ctx中enclave_ctx   |
 |  cc_sec_chl_svr_fini                                                                                                                                            |   secure_channel_host.h  libusecure_channel.so                    |  安全通道服务端销毁            |  销毁安全通道服务端以及所有客户端信息  |
 |  cc_sec_chl_svr_callback                                                                                                                                            |  secure_channel_host.h  libusecure_channel.so                     |  安全通道协商消息处理函数            | 处理安全通道协商过程中，客户端发送给服务端的消息。在服务端消息接收处调用，调用前需初始化与客户端的网络连接和发送消息函数，详见[样例](https://gitee.com/openeuler/secGear/blob/master/examples/secure_channel/host/server.c#:~:text=conn_ctx.conn_kit.send)。   |
-| cc_sec_chl_enclave_encrypt                                                                                                                                             |    secure_channel_enclave.h libtsecure_channel.so                   | 安全通道enclave中的加密接口             |  无  |
-|   cc_sec_chl_enclave_decrypt                                                                                                                                           |   secure_channel_enclave.h libtsecure_channel.so                    | 安全通道enclave中的解密接口             |  无  |
+| cc_sec_chl_enclave_encrypt                                                                                                                                             |    secure_channel_enclave.h libtsecure_channel.a                   | 安全通道enclave中的加密接口             |  无  |
+|   cc_sec_chl_enclave_decrypt                                                                                                                                           |   secure_channel_enclave.h libtsecure_channel.a                    | 安全通道enclave中的解密接口             |  无  |
 
 ### 注意事项
 安全通道仅封装密钥协商过程、加解密接口，不建立网络连接，协商过程复用业务的网络连接。其中客户端和服务端的网络连接由业务建立和维护，在安全通道客户端和服务端初始化时传入消息发送钩子函数和网络连接指针，详见[安全通道样例](https://gitee.com/openeuler/secGear/tree/master/examples/secure_channel)。
diff --git a/component/secure_channel/client/CMakeLists.txt b/component/secure_channel/client/CMakeLists.txt
index 31c2ce9..e544312 100644
--- a/component/secure_channel/client/CMakeLists.txt
+++ b/component/secure_channel/client/CMakeLists.txt
@@ -13,6 +13,9 @@ project(secure_channel_client C)
 set(PREFIX secure_channel)
 set(SOURCE_FILE secure_channel_client.c ${CMAKE_CURRENT_SOURCE_DIR}/../secure_channel_common.c)
 
+aux_source_directory(${LOCAL_ROOT_PATH}/thirdparty/cjson/ CJSON_SRC)
+FILE (GLOB_RECURSE BASE64_SRC "${LOCAL_ROOT_PATH}/thirdparty/base64url/*.c")
+
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
 
 if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
@@ -24,16 +27,18 @@ include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     ${LOCAL_ROOT_PATH}/inc/host_inc
     ${LOCAL_ROOT_PATH}/component/secure_channel
+    ${LOCAL_ROOT_PATH}/component/remote_attest/
+    ${LOCAL_ROOT_PATH}/component/remote_attest/ra_verify
+    ${LOCAL_ROOT_PATH}/thirdparty/cjson
+    ${LOCAL_ROOT_PATH}/thirdparty/base64url
 )
-add_library(c${PREFIX} SHARED ${SOURCE_FILE})
+add_library(c${PREFIX} SHARED ${SOURCE_FILE} ${CJSON_SRC} ${BASE64_SRC})
 
 if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
     target_link_directories(c${PREFIX} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
 endif()
 
-target_link_libraries(c${PREFIX} ssl crypto)
-
-set(LIBRARY_INSTALL ${LOCAL_ROOT_PATH_INSTALL}/usr/lib64)
+target_link_libraries(c${PREFIX} ssl crypto secgear_verify)
 
 install(TARGETS c${PREFIX} 
         LIBRARY
diff --git a/component/secure_channel/client/secure_channel_client.c b/component/secure_channel/client/secure_channel_client.c
index 4ea4c43..27b0812 100644
--- a/component/secure_channel/client/secure_channel_client.c
+++ b/component/secure_channel/client/secure_channel_client.c
@@ -14,31 +14,35 @@
 #include <string.h>
 #include <pthread.h>
 #include <unistd.h>
+#include <openssl/rand.h>
+#include <openssl/pem.h>
 
 #include "status.h"
 #include "enclave_log.h"
 #include "secure_channel_common.h"
+#include "sg_ra_report_verify.h"
+#include "cJSON.h"
+#include "base64url.h"
 
-#define SEC_CHL_RECV_BUF_MAX_LEN 1024
 
+#define SEC_CHL_RECV_BUF_MAX_LEN REPORT_OUT_LEN
 struct cc_sec_chl_handle {
     sec_chl_ecdh_ctx_t *ecdh_ctx;   // key exchange context
     pthread_mutex_t lock;           // proctect recv_buf and recv_buf_len
     uint8_t recv_buf[SEC_CHL_RECV_BUF_MAX_LEN];  // secure channel init msg max len
     size_t  recv_buf_len;                        // secure channel init msg real len
-    uint8_t *svr_pubkey;
-    size_t   svr_pubkey_len;
     cc_sec_chl_algo_t algo;
+    sec_chl_ra_req_t ra_req;
+    char *b64_enc_key;
+    RSA *rsa_svr_pubkey;
 };
 
 typedef enum {
     STATE_ORIGIN = 0,
     STATE_WAIT_SVRPUBKEY,
     STATE_SVRPUBKEY_READY,
-    STATE_WAIT_RA_REPORT,
-    STATE_RA_REPORT_READY,
-    STATE_VERIFY_RA_SUCCESS,
-    STATE_VERIFY_SVRPUBKEY_SUCCESS,
+    STATE_WAIT_SET_ENC_KEY,
+    STATE_SET_ENC_KEY_SUCCESS,
     STATE_WAIT_SVR_PARAM,
     STATE_SVR_PARAM_READY,
     STATE_LOCAL_PARAM_READY,
@@ -51,10 +55,8 @@ typedef enum {
 typedef enum {
     EVENT_GET_SVRPUBKEY = 0,
     EVENT_RECV_SVRPUBKEY,
-    EVENT_GET_RA_REPORT,
-    EVENT_RECV_RA_REPORT,
-    EVENT_VERIFY_RA_REPORT,
-    EVENT_VERIFY_SVRPUBKEY,
+    EVENT_SET_ENC_KEY_TO_SVR,
+    EVENT_RECV_SET_ENC_KEY_RET,
     EVENT_GET_SVR_PARAM,
     EVENT_RECV_SVR_PARAM,
     EVENT_GEN_LOCAL_PARAM,
@@ -66,9 +68,6 @@ typedef enum {
 typedef cc_enclave_result_t (*sec_chl_init_fsm_action_t)(cc_sec_chl_ctx_t *ctx);
 
 typedef struct {
-    sec_chl_init_fsm_state_t cur_state;
-    sec_chl_init_fsm_event_id_t event_id;
-    sec_chl_init_fsm_state_t next_state;
     sec_chl_init_fsm_action_t action;
 } sec_chl_fsm_state_transform_t;
 
@@ -92,8 +91,11 @@ static void del_local_sec_chl_ctx(cc_sec_chl_ctx_t *ctx)
     if (ctx->handle->ecdh_ctx != NULL) {
         del_ecdh_ctx(ctx->handle->ecdh_ctx);
     }
-    if (ctx->handle->svr_pubkey != NULL) {
-        free(ctx->handle->svr_pubkey);
+    if (ctx->handle->b64_enc_key != NULL) {
+        free(ctx->handle->b64_enc_key);
+    }
+    if (ctx->handle->rsa_svr_pubkey != NULL) {
+        RSA_free(ctx->handle->rsa_svr_pubkey);
     }
     free(ctx->handle);
     ctx->handle = NULL;
@@ -180,11 +182,59 @@ cc_enclave_result_t cc_sec_chl_client_callback(cc_sec_chl_ctx_t *ctx, void *buf,
     return CC_SUCCESS;
 }
 
-static cc_enclave_result_t get_svr_pubkey(cc_sec_chl_ctx_t *ctx)
+static cc_enclave_result_t get_taid_from_file(char *file, char *taid)
 {
-    sec_chl_msg_t msg = {0};
-    msg.msg_type = SEC_CHL_MSG_GET_SVR_PUBKEY;
-    cc_enclave_result_t ret = sec_chl_send_request(&(ctx->conn_kit), &msg);
+    FILE *fp = fopen(file, "r");
+    if (!fp) {
+        printf("secure channel init read taid failed\n");
+        return CC_ERROR_SEC_CHL_INIT_GET_TAID;
+    }
+
+    int ret = fscanf(fp, "%s", taid);    // only read taid from line
+    
+    printf("read ret:%d, taid:%s\n", ret, taid);
+
+    fclose(fp);
+
+    return CC_SUCCESS;
+}
+
+static cc_enclave_result_t request_report(cc_sec_chl_ctx_t *ctx, sec_chl_msg_type_t type, bool with_request_key)
+{
+    cc_enclave_result_t ret;
+    sec_chl_msg_t *msg = NULL;
+    size_t data_len = 0;
+
+    if (ctx->basevalue != NULL) {
+        data_len = sizeof(sec_chl_ra_req_t);
+    }
+
+    msg = (sec_chl_msg_t *)calloc(1, sizeof(sec_chl_msg_t) + data_len);
+    if (msg == NULL) {
+        return CC_ERROR_SEC_CHL_MEMORY;
+    }
+    msg->msg_type = type;
+
+    if (ctx->basevalue != NULL) {
+        sec_chl_ra_req_t *ra_req = (sec_chl_ra_req_t *)msg->data;
+        ra_req->with_tcb = false;
+        ra_req->req_key = with_request_key;
+
+        ret = get_taid_from_file(ctx->basevalue, ra_req->taid);
+        if (ret != CC_SUCCESS) {
+            free(msg);
+            return ret;
+        }
+        if (RAND_priv_bytes(ra_req->nonce, SEC_CHL_REQ_NONCE_LEN) <= 0) {
+            free(msg);
+            return CC_FAIL;
+        }
+        memcpy(&ctx->handle->ra_req, ra_req, sizeof(sec_chl_ra_req_t));
+    }
+
+    msg->data_len = data_len;
+    ret = sec_chl_send_request(&(ctx->conn_kit), msg);
+    free(msg);
     if (ret != CC_SUCCESS) {
         return CC_ERROR_SEC_CHL_GET_SVR_PUBKEY;
     }
@@ -192,7 +242,31 @@ static cc_enclave_result_t get_svr_pubkey(cc_sec_chl_ctx_t *ctx)
     return CC_SUCCESS;
 }
 
-static cc_enclave_result_t recv_svr_pubkey(cc_sec_chl_ctx_t *ctx)
+static cc_enclave_result_t get_ra_report(cc_sec_chl_ctx_t *ctx)
+{
+    return request_report(ctx, SEC_CHL_MSG_GET_RA_REPORT, false);
+}
+
+static cc_enclave_result_t verify_report(cc_sec_chl_ctx_t *ctx, sec_chl_msg_t *msg)
+{
+    cc_enclave_result_t ret = CC_SUCCESS;
+    if (msg->sub_type == GET_SVRPUBKEY_SUBTYPE_REPORT) {
+        cc_ra_buf_t report = {0};
+        report.buf = msg->data;
+        report.len = msg->data_len;
+        cc_ra_buf_t nonce = {0};
+        nonce.len = SEC_CHL_REQ_NONCE_LEN;
+        nonce.buf = ctx->handle->ra_req.nonce;
+        ret = cc_verify_report(&report, &nonce, CC_RA_VERIFY_TYPE_STRICT, ctx->basevalue);
+        if (ret != CC_SUCCESS) {
+            printf("verify report failed ret:%u\n", ret);
+            return CC_ERROR_SEC_CHL_INIT_VERIFY_REPORT;
+        }
+    }
+    return ret;
+}
+
+static cc_enclave_result_t recv_ra_report(cc_sec_chl_ctx_t *ctx)
 {
     sec_chl_msg_t *msg = NULL;
 
@@ -202,13 +276,12 @@ static cc_enclave_result_t recv_svr_pubkey(cc_sec_chl_ctx_t *ctx)
         return CC_ERROR_SEC_CHL_WAITING_RECV_MSG;
     }
     msg = (sec_chl_msg_t *)ctx->handle->recv_buf;
-    ctx->handle->svr_pubkey = calloc(1, msg->data_len);
-    if (ctx->handle->svr_pubkey == NULL) {
+    cc_enclave_result_t ret = verify_report(ctx, msg);
+    if (ret != CC_SUCCESS) {
         pthread_mutex_unlock(&ctx->handle->lock);
-        return CC_ERROR_SEC_CHL_MEMORY;
+        return ret;
     }
-    memcpy(ctx->handle->svr_pubkey, msg->data, msg->data_len);
-    ctx->handle->svr_pubkey_len = msg->data_len;
+
     ctx->session_id = msg->session_id;
     ctx->handle->recv_buf_len = 0;
     pthread_mutex_unlock(&ctx->handle->lock);
@@ -216,30 +289,219 @@ static cc_enclave_result_t recv_svr_pubkey(cc_sec_chl_ctx_t *ctx)
     return CC_SUCCESS;
 }
 
-static cc_enclave_result_t get_ra_report(cc_sec_chl_ctx_t *ctx)
+static cc_enclave_result_t get_svr_pubkey(cc_sec_chl_ctx_t *ctx)
 {
-    (void)ctx;
-    return CC_SUCCESS;
+    return request_report(ctx, SEC_CHL_MSG_GET_SVR_PUBKEY, true);
 }
 
-static cc_enclave_result_t recv_ra_report(cc_sec_chl_ctx_t *ctx)
+static cc_enclave_result_t get_svr_key_from_report(cc_sec_chl_ctx_t *ctx, cc_ra_buf_t *report)
 {
-    (void)ctx;
-    return CC_SUCCESS;
+    cc_enclave_result_t ret = CC_ERROR_SEC_CHL_INVALID_REPORT;
+    uint8_t *n = NULL;
+    uint8_t *e = NULL;
+
+    cJSON *cj_report = cJSON_ParseWithLength((char *)report->buf, report->len);
+    if (cj_report == NULL) {
+        printf("report to json failed\n");
+        return CC_ERROR_SEC_CHL_INVALID_REPORT;
+    }
+    cJSON *cj_payload = cJSON_GetObjectItemCaseSensitive(cj_report, "payload");
+    if (cj_payload == NULL) {
+        printf("report payload failed!\n");
+        goto end;
+    }
+    cJSON *cj_nonce = cJSON_GetObjectItemCaseSensitive(cj_payload, "nonce");
+    if(cj_nonce == NULL) {
+        printf("report nonce failed!\n");
+        goto end;
+    }
+    // comput pubkey
+    cJSON *cj_pub_key = cJSON_GetObjectItemCaseSensitive(cj_nonce, "pub_key");
+    if(cj_pub_key == NULL) {
+        printf("report pub_key failed!\n");
+        goto end;
+    }
+    char *b64_n = cJSON_GetStringValue(cJSON_GetObjectItem(cj_pub_key, "n"));
+    if (b64_n == NULL) {
+        printf("parse n from json pub_key failed\n");
+        goto end;
+    }
+    size_t n_len = 0;
+    n = kpsecl_base64urldecode(b64_n, strlen(b64_n), &n_len);
+    char *b64_e = cJSON_GetStringValue(cJSON_GetObjectItem(cj_pub_key, "e"));
+    if (b64_e == NULL) {
+        printf("parse e from json pub_key failed\n");
+        goto end;
+    }
+    size_t e_len = 0;
+    e = kpsecl_base64urldecode(b64_e, strlen(b64_e), &e_len);
+
+    RSA *svr_pub_key = RSA_new();
+    BIGNUM *modulus = BN_new();
+    BIGNUM *pub_exponent = BN_new();
+    BN_hex2bn(&modulus, (char *)n);
+    BN_hex2bn(&pub_exponent, (char *)e);
+    RSA_set0_key(svr_pub_key, modulus, pub_exponent, NULL);
+    // svr pub key
+    ctx->handle->rsa_svr_pubkey = svr_pub_key;
+
+    // save enc key to ctx
+    cJSON *cj_enc_key = cJSON_GetObjectItemCaseSensitive(cj_nonce, "enc_key");
+    if(cj_enc_key == NULL) {
+        printf("report enc_key failed!\n");
+        goto fail;
+    }
+    ctx->handle->b64_enc_key = calloc(1, strlen(cj_enc_key->valuestring) + 1);
+    if (ctx->handle->b64_enc_key == NULL) {
+        printf("malloc enc key buff failed\n");
+        ret = CC_ERROR_SEC_CHL_MEMORY;
+        goto fail;
+    }
+    (void)memcpy(ctx->handle->b64_enc_key, cj_enc_key->valuestring, strlen(cj_enc_key->valuestring));
+
+    ret = CC_SUCCESS;
+    goto end;
+
+fail:
+    if (svr_pub_key != NULL) {
+        RSA_free(svr_pub_key);
+    }
+end:
+    if (n != NULL) {
+        free(n);
+    }
+    if (e != NULL) {
+        free(e);
+    }
+    cJSON_Delete(cj_report);
+
+    return ret;
 }
 
-static cc_enclave_result_t verify_ra_report(cc_sec_chl_ctx_t *ctx)
+RSA *get_rsakey_from_buffer(const uint8_t *rsa_key_buffer, size_t rsa_key_buffer_len, bool is_private_key)
 {
-    (void)ctx;
-    return CC_SUCCESS;
+    BIO *r_key = NULL;
+    RSA *rsa_key = NULL;
+    r_key = BIO_new_mem_buf(rsa_key_buffer, rsa_key_buffer_len);
+    if (r_key == NULL) {
+        goto end;
+    }
+    if (is_private_key) {
+        rsa_key = PEM_read_bio_RSAPrivateKey(r_key, NULL, NULL, NULL);
+    } else {
+        rsa_key = PEM_read_bio_RSAPublicKey(r_key, NULL, NULL, NULL);
+    }
+
+    if (rsa_key == NULL) {
+        goto end;
+    }
+
+end:
+    BIO_free(r_key);
+    r_key = NULL;
+    return rsa_key;
+}
+
+static cc_enclave_result_t parse_svrpubkey_from_recv_msg(cc_sec_chl_ctx_t *ctx, sec_chl_msg_t *msg)
+{
+    cc_enclave_result_t ret;
+    if (msg->sub_type == GET_SVRPUBKEY_SUBTYPE_REPORT) {
+        cc_ra_buf_t report = {0};
+        report.buf = msg->data;
+        report.len = msg->data_len;
+
+        ret = get_svr_key_from_report(ctx, &report);
+        if (ret != CC_SUCCESS) {
+            return ret;
+        }
+    } else {
+        RSA *rsa_pubkey = get_rsakey_from_buffer(msg->data, msg->data_len, false);
+        if (rsa_pubkey == NULL) {
+            return CC_ERROR_SEC_CHL_PARSE_SVR_PUBKEY;
+        }
+        ctx->handle->rsa_svr_pubkey = rsa_pubkey;
+        ret = CC_SUCCESS;
+    }
+
+    return ret;
 }
 
-static cc_enclave_result_t verify_svr_pubkey(cc_sec_chl_ctx_t *ctx)
+static cc_enclave_result_t recv_svr_pubkey(cc_sec_chl_ctx_t *ctx)
 {
-    (void)ctx;
+    sec_chl_msg_t *msg = NULL;
+
+    pthread_mutex_lock(&ctx->handle->lock);
+    if (ctx->handle->recv_buf_len == 0) {
+        pthread_mutex_unlock(&ctx->handle->lock);
+        return CC_ERROR_SEC_CHL_WAITING_RECV_MSG;
+    }
+    msg = (sec_chl_msg_t *)ctx->handle->recv_buf;
+    cc_enclave_result_t ret = parse_svrpubkey_from_recv_msg(ctx, msg);
+    if (ret != CC_SUCCESS) {
+        pthread_mutex_unlock(&ctx->handle->lock);
+        return ret;
+    }
+
+    ctx->session_id = msg->session_id;
+    ctx->handle->recv_buf_len = 0;
+    pthread_mutex_unlock(&ctx->handle->lock);
+
     return CC_SUCCESS;
 }
 
+static cc_enclave_result_t set_encrypt_key_to_server_ta(cc_sec_chl_ctx_t *ctx)
+{
+    int ret;
+    sec_chl_msg_t *msg = NULL;
+
+    if (ctx->handle->b64_enc_key == NULL) {
+        return CC_SUCCESS;
+    }
+
+    char *b64_enc_key = ctx->handle->b64_enc_key;
+    size_t len = sizeof(sec_chl_msg_t) + strlen(b64_enc_key);
+
+    msg = (sec_chl_msg_t *)calloc(1, len);
+    if (msg == NULL) {
+        return CC_ERROR_SEC_CHL_MEMORY;
+    }
+
+    memcpy(msg->data, b64_enc_key, strlen(b64_enc_key));
+    msg->data_len = strlen(b64_enc_key);
+
+    msg->session_id = ctx->session_id;
+    msg->msg_type = SEC_CHL_MSG_SET_ENC_KEY_TO_SVR;
+
+    ret = sec_chl_send_request(&ctx->conn_kit, msg);
+    free(msg);
+    if (ret != CC_SUCCESS) {
+        ret = CC_ERROR_SEC_CHL_SET_PARAM_TO_PEER;
+    }
+    return ret;
+}
+
+static cc_enclave_result_t recv_set_enc_key_ret(cc_sec_chl_ctx_t *ctx)
+{
+    sec_chl_msg_t *msg = NULL;
+    cc_enclave_result_t ret;
+    
+    if (ctx->handle->b64_enc_key == NULL) {
+        return CC_SUCCESS;
+    }
+
+    pthread_mutex_lock(&ctx->handle->lock);
+    if (ctx->handle->recv_buf_len == 0) {
+        pthread_mutex_unlock(&ctx->handle->lock);
+        return CC_ERROR_SEC_CHL_WAITING_RECV_MSG;
+    }
+    msg = (sec_chl_msg_t *)ctx->handle->recv_buf;
+    ret = msg->ret;
+    ctx->handle->recv_buf_len = 0;
+    pthread_mutex_unlock(&ctx->handle->lock);
+
+    return ret;
+}
+
 static cc_enclave_result_t get_svr_param(cc_sec_chl_ctx_t *ctx)
 {
     sec_chl_msg_t msg = {0};
@@ -266,7 +528,7 @@ static cc_enclave_result_t recv_svr_param(cc_sec_chl_ctx_t *ctx)
     msg = (sec_chl_msg_t *)ctx->handle->recv_buf;
     memcpy(&ec_nid, msg->data + RANDOM_LEN, sizeof(int));
 
-    ret = verify_signature(ctx->handle->svr_pubkey, ctx->handle->svr_pubkey_len, msg->data, msg->data_len);
+    ret = verify_signature(ctx->handle->rsa_svr_pubkey, msg->data, msg->data_len);
     if (ret != CC_SUCCESS) {
         pthread_mutex_unlock(&ctx->handle->lock);
         return ret;
@@ -372,18 +634,18 @@ static cc_enclave_result_t sec_chl_compute_session_key(cc_sec_chl_ctx_t *ctx)
 }
 
 static sec_chl_fsm_state_transform_t g_state_transform_table[] = {
-    {STATE_ORIGIN, EVENT_GET_SVRPUBKEY, STATE_WAIT_SVRPUBKEY, get_svr_pubkey},
-    {STATE_WAIT_SVRPUBKEY, EVENT_RECV_SVRPUBKEY, STATE_SVRPUBKEY_READY, recv_svr_pubkey},
-    {STATE_SVRPUBKEY_READY, EVENT_GET_RA_REPORT, STATE_WAIT_RA_REPORT, get_ra_report},
-    {STATE_WAIT_RA_REPORT, EVENT_RECV_RA_REPORT, STATE_RA_REPORT_READY, recv_ra_report},
-    {STATE_RA_REPORT_READY, EVENT_VERIFY_RA_REPORT, STATE_VERIFY_RA_SUCCESS, verify_ra_report},
-    {STATE_VERIFY_RA_SUCCESS, EVENT_VERIFY_SVRPUBKEY, STATE_VERIFY_SVRPUBKEY_SUCCESS, verify_svr_pubkey},
-    {STATE_VERIFY_SVRPUBKEY_SUCCESS, EVENT_GET_SVR_PARAM, STATE_WAIT_SVR_PARAM, get_svr_param},
-    {STATE_WAIT_SVR_PARAM, EVENT_RECV_SVR_PARAM, STATE_SVR_PARAM_READY, recv_svr_param},
-    {STATE_SVR_PARAM_READY, EVENT_GEN_LOCAL_PARAM, STATE_LOCAL_PARAM_READY, gen_local_param},
-    {STATE_LOCAL_PARAM_READY, EVENT_SET_PARAM_TO_PEER, STATE_WAIT_SET_PARAM_RET, set_local_param_to_peer},
-    {STATE_WAIT_SET_PARAM_RET, EVENT_RECV_SET_PARAM_RET, STATE_ALL_READY, recv_set_param_ret},
-    {STATE_ALL_READY, EVENT_COMPUTE_SESSIONKEY, STATE_SUCCESS, sec_chl_compute_session_key},
+    {get_ra_report},
+    {recv_ra_report},
+    {get_svr_pubkey},
+    {recv_svr_pubkey},
+    {set_encrypt_key_to_server_ta},
+    {recv_set_enc_key_ret},
+    {get_svr_param},
+    {recv_svr_param},
+    {gen_local_param},
+    {set_local_param_to_peer},
+    {recv_set_param_ret},
+    {sec_chl_compute_session_key},
 };
 
 #define RECV_MSG_TIMEOUT_CNT 1000
diff --git a/component/secure_channel/client/secure_channel_client.h b/component/secure_channel/client/secure_channel_client.h
index a77973a..e2d0b7e 100644
--- a/component/secure_channel/client/secure_channel_client.h
+++ b/component/secure_channel/client/secure_channel_client.h
@@ -41,6 +41,7 @@ typedef struct cc_sec_chl_ctx {
     size_t session_id;              // unique value return by server
     cc_conn_kit_t conn_kit;         // network transmission connection kit need register by user
     cc_sec_chl_handle_t *handle;
+    char *basevalue; // target ta basevalue file path
 } cc_sec_chl_ctx_t;
 
 typedef enum {
diff --git a/component/secure_channel/enclave/CMakeLists.txt b/component/secure_channel/enclave/CMakeLists.txt
index 0c651f5..a84de8a 100644
--- a/component/secure_channel/enclave/CMakeLists.txt
+++ b/component/secure_channel/enclave/CMakeLists.txt
@@ -12,6 +12,7 @@ project(secure_channel_enclave C)
 set(PREFIX secure_channel)
 
 set(SOURCE_FILES secure_channel_enclave.c ${CMAKE_CURRENT_SOURCE_DIR}/../secure_channel_common.c)
+FILE (GLOB_RECURSE BASE64_SRC "${LOCAL_ROOT_PATH}/thirdparty/base64url/*.c")
 
 set(PRINT_LEVEL 3)
 add_definitions(-DPRINT_LEVEL=${PRINT_LEVEL})
@@ -73,8 +74,9 @@ if(CC_GP)
             ${ITRUSTEE_LIBC}/arch/arm/bits
             ${ITRUSTEE_LIBC}/arch/generic
             ${ITRUSTEE_LIBC}/arch/arm
-            ${SSL_PATH}/include)
-    add_library(t${PREFIX} ${SOURCE_FILES} ${AUTO_FILES} ${LOCAL_ROOT_PATH}/src/enclave_src/gp/gp.c)
+            ${SSL_PATH}/include
+            ${LOCAL_ROOT_PATH}/thirdparty/base64url)
+    add_library(t${PREFIX} ${SOURCE_FILES} ${AUTO_FILES} ${LOCAL_ROOT_PATH}/src/enclave_src/gp/gp.c ${BASE64_SRC})
 
     if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
         target_link_directories(t${PREFIX} PRIVATE
@@ -125,8 +127,6 @@ else()
     endif()
 endif()
 
-set(LIBRARY_INSTALL ${LOCAL_ROOT_PATH_INSTALL}/usr/lib64)
-
 install(TARGETS t${PREFIX} 
         ARCHIVE
         DESTINATION ${LIBRARY_INSTALL}
diff --git a/component/secure_channel/enclave/secure_channel_enclave.c b/component/secure_channel/enclave/secure_channel_enclave.c
index 2867be4..fa0b935 100644
--- a/component/secure_channel/enclave/secure_channel_enclave.c
+++ b/component/secure_channel/enclave/secure_channel_enclave.c
@@ -9,13 +9,9 @@
  * PURPOSE.
  * See the Mulan PSL v2 for more details.
  */
-
-#ifdef SGX_ENCLAVE
-#include "tsgxsslio.h"
-#endif
+#include "secure_channel_enclave.h"
 
 #include <openssl/pem.h>
-
 #include "status.h"
 #include "secgear_log.h"
 #include "secgear_random.h"
@@ -23,9 +19,12 @@
 #include "secure_channel_t.h"
 
 #ifdef SGX_ENCLAVE
+    #include "tsgxsslio.h"
     #include "sgx_thread.h"
     typedef sgx_thread_rwlock_t sc_lock_t;
 #else
+    #include "base64url.h"
+    #include "tee_ra_api.h"
     typedef pthread_rwlock_t sc_lock_t;
 #endif
 
@@ -251,7 +250,7 @@ static int add_to_sec_chl_list(SEC_CHL_NODE *node)
     return CC_SUCCESS;
 }
 
-static int gen_sec_chl_node(size_t *session_id)
+int init_session(size_t *session_id)
 {
     size_t random_id = 0;
     int ret = cc_enclave_generate_random(&random_id, sizeof(size_t));
@@ -302,7 +301,7 @@ int get_enclave_pubkey(size_t *session_id, uint8_t *pubkey, size_t *pubkey_len)
         return CC_ERROR_BAD_PARAMETERS;
     }
     // 添加到g_sec_chl_manager
-    ret = gen_sec_chl_node(session_id);
+    ret = init_session(session_id);
     if (ret != CC_SUCCESS) {
         PrintInfo(PRINT_ERROR, "get enclave pubkey add node failed\n");
         return ret;
@@ -378,6 +377,72 @@ int get_enclave_exch_param(size_t session_id, uint8_t *exch_param, size_t exch_p
     return ret;
 }
 
+#define RSA_MAX_LEN 1024
+int set_enc_key(size_t session_id, uint8_t* data, size_t data_len)
+{
+    cc_enclave_result_t ret = CC_SUCCESS;
+
+#ifdef GP_ENCLAVE
+    // decode base64rul enc_key
+    size_t enc_key_len = 0;
+    uint8_t *enc_key = kpsecl_base64urldecode((char *)data, data_len, &enc_key_len);
+
+    // unseal enc_key
+    size_t dec_key_len = enc_key_len;
+    uint8_t *dec_key = (uint8_t *)calloc(1, dec_key_len);
+    if (dec_key == NULL) {
+        ret = CC_ERROR_SEC_CHL_MEMORY;
+        goto end;
+    }
+    TEE_Result gp_ret = ra_unseal(enc_key, enc_key_len, dec_key, &dec_key_len, TEE_ALG_AES_GCM);
+    if (gp_ret != TEE_SUCCESS) {
+        PrintInfo(PRINT_ERROR, "unseal enc key failed\n");
+        ret = CC_ERROR_SEC_CHL_ENCLAVE_UNSEAL_ENC_KEY;
+        goto end;
+    }
+
+    // compute private_key
+    // dec_key组成形式为：d_len | d | n_len | n | e_len | e ,其中d_len/n_len/e_len分别为四个字节
+    uint32_t d_len = *(uint32_t *)dec_key;
+    uint32_t n_len = *(uint32_t *)(dec_key + sizeof(uint32_t) + d_len);
+    uint32_t e_len = *(uint32_t *)(dec_key + sizeof(uint32_t) + d_len + sizeof(uint32_t) + n_len);
+    PrintInfo(PRINT_STRACE, "rsa param len d_len:%u, n_len:%u, e_len:%u\n", d_len, n_len, e_len);
+
+    uint8_t d[RSA_MAX_LEN] = {0};
+    uint8_t n[RSA_MAX_LEN] = {0};
+    uint8_t e[RSA_MAX_LEN] = {0};
+    memcpy(d, dec_key + sizeof(uint32_t), d_len);
+    memcpy(n, dec_key + sizeof(uint32_t) + d_len + sizeof(uint32_t), n_len);
+    memcpy(e, dec_key + sizeof(uint32_t) + d_len + sizeof(uint32_t) + n_len + sizeof(uint32_t), e_len);
+
+    RSA *rsa_key = RSA_new();
+    BIGNUM *modulus = BN_new();
+    BIGNUM *pub_exponent = BN_new();
+    BIGNUM *pri_exponent = BN_new();
+    BN_hex2bn(&modulus, (char *)n);
+    BN_hex2bn(&pub_exponent, (char *)e);
+    BN_hex2bn(&pri_exponent, (char *)d);
+    RSA_set0_key(rsa_key, modulus, pub_exponent, pri_exponent);
+    
+    sc_wtlock(&g_sec_chl_manager.sec_chl_list_lock);
+    sec_chl_ecdh_ctx_t *ecdh_ctx = get_ecdh_ctx_by_session_id(session_id);
+    if (ecdh_ctx == NULL) {
+        sc_wtunlock(&g_sec_chl_manager.sec_chl_list_lock);
+        RSA_free(rsa_key);
+        ret = CC_ERROR_SEC_CHL_INVALID_SESSION;
+        PrintInfo(PRINT_ERROR, "get ecdh ctx by session id\n");
+        goto end;
+    }
+    ecdh_ctx->svr_rsa_key = rsa_key;
+    sc_wtunlock(&g_sec_chl_manager.sec_chl_list_lock);
+end:
+    free(enc_key);
+    free(dec_key);
+
+#endif
+    return ret;
+}
+
 int set_peer_exch_param(size_t session_id, uint8_t* data, size_t data_len)
 {
     int ret;
diff --git a/component/secure_channel/enclave/secure_channel_enclave.h b/component/secure_channel/enclave/secure_channel_enclave.h
index 65bd205..8922337 100644
--- a/component/secure_channel/enclave/secure_channel_enclave.h
+++ b/component/secure_channel/enclave/secure_channel_enclave.h
@@ -13,6 +13,8 @@
 #ifndef SECURE_CHANNEL_ENCLAVE_H
 #define SECURE_CHANNEL_ENCLAVE_H
 
+#include <stddef.h>
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
diff --git a/component/secure_channel/host/CMakeLists.txt b/component/secure_channel/host/CMakeLists.txt
index 5c60b3f..8ecbc99 100644
--- a/component/secure_channel/host/CMakeLists.txt
+++ b/component/secure_channel/host/CMakeLists.txt
@@ -48,13 +48,16 @@ if(CC_GP)
         ${LOCAL_ROOT_PATH}/component/secure_channel
         ${SDK_PATH}/include/CA
         ${LOCAL_ROOT_PATH}/inc/host_inc
-        ${LOCAL_ROOT_PATH}/inc/host_inc/gp)
+        ${LOCAL_ROOT_PATH}/inc/host_inc/gp
+        ${LOCAL_ROOT_PATH}/component/remote_attest
+        ${LOCAL_ROOT_PATH}/component/remote_attest/ra_report)
     add_library(u${PREFIX} SHARED ${SOURCE_FILE} ${AUTO_FILES})
 
     if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
         target_link_directories(u${PREFIX} PRIVATE 
             ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
     endif()
+    target_link_libraries(u${PREFIX} secgear_ra)
 endif()
  
 if(CC_SGX)
@@ -65,7 +68,7 @@ if(CC_SGX)
     else()
         set(Urts_Library_Name sgx_urts_sim)
     endif()
-    set(host_C_Flags "${COMMON_CFLAGS} -fPIC -Wno-attributes -pthread")
+    set(host_C_Flags "${COMMON_CFLAGS} -fPIC -Wno-attributes -lz -pthread")
 
     if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
         link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
@@ -79,7 +82,9 @@ if(CC_SGX)
         ${LOCAL_ROOT_PATH}/inc/host_inc
         ${LOCAL_ROOT_PATH}/inc/host_inc/sgx
         ${OPENSSL_PATH}/include
-        ${SGX_SDK_PATH}/include)
+        ${SGX_SDK_PATH}/include
+        ${LOCAL_ROOT_PATH}/component/remote_attest
+        ${LOCAL_ROOT_PATH}/component/remote_attest/ra_report)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${host_C_Flags}")
     add_library(u${PREFIX} SHARED ${SOURCE_FILE} ${AUTO_FILES})
 
@@ -88,10 +93,9 @@ if(CC_SGX)
             ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
             ${CMAKE_BINARY_DIR}/lib/)
     endif()
+    target_link_libraries(u${PREFIX} secgear_ra)
 endif()
 
-set(LIBRARY_INSTALL ${LOCAL_ROOT_PATH_INSTALL}/usr/lib64)
-
 install(TARGETS u${PREFIX} 
         LIBRARY
         DESTINATION ${LIBRARY_INSTALL}
diff --git a/component/secure_channel/host/secure_channel_host.c b/component/secure_channel/host/secure_channel_host.c
index 6edaef6..e7adf3c 100644
--- a/component/secure_channel/host/secure_channel_host.c
+++ b/component/secure_channel/host/secure_channel_host.c
@@ -25,9 +25,11 @@
 #include "enclave_log.h"
 #include "secure_channel_u.h"
 #include "secure_channel_common.h"
+#include "sg_ra_report.h"
+#include "enclave_internal.h"
 
 #define RSA_PUBKEY_LEN 640
-static int sec_chl_get_pubkey(cc_enclave_t *context, sec_chl_msg_t *msg, sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
+static int sec_chl_gen_pubkey(cc_enclave_t *context, sec_chl_msg_t *msg, sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
 {
     int res;
     cc_enclave_result_t ret_val;
@@ -49,6 +51,7 @@ static int sec_chl_get_pubkey(cc_enclave_t *context, sec_chl_msg_t *msg, sec_chl
     }
     rsp->session_id = session_id;
     rsp->data_len = rsa_pubkey_len;
+    rsp->sub_type = GET_SVRPUBKEY_SUBTYPE_SVR_GEN;
     memcpy(rsp->data, rsa_pubkey, rsa_pubkey_len);
     *rsp_msg = rsp;
     *rsp_msg_len = sizeof(sec_chl_msg_t) + rsa_pubkey_len;
@@ -56,6 +59,94 @@ static int sec_chl_get_pubkey(cc_enclave_t *context, sec_chl_msg_t *msg, sec_chl
     return CC_SUCCESS;
 }
 
+static int sec_chl_get_ra_report(cc_enclave_t *context, sec_chl_msg_t *msg,
+    sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
+{
+    (void)context;
+    cc_enclave_result_t ret_val;
+    sec_chl_msg_t *rsp = NULL;
+
+    sec_chl_ra_req_t *ra_req = (sec_chl_ra_req_t *)(msg->data);
+
+    cc_get_ra_report_input_t ra_input = {0};
+    ra_input.taid = (uint8_t *)ra_req->taid;
+    (void)memcpy(ra_input.nonce, ra_req->nonce, SEC_CHL_REQ_NONCE_LEN);
+    ra_input.nonce_len = SEC_CHL_REQ_NONCE_LEN + 1;
+    ra_input.with_tcb = ra_req->with_tcb;
+    ra_input.req_key = ra_req->req_key;
+
+    uint8_t data[REPORT_OUT_LEN] = {0};
+    cc_ra_buf_t report = {REPORT_OUT_LEN, data};
+
+    ret_val = cc_get_ra_report(&ra_input, &report);
+
+    if (ret_val != CC_SUCCESS) {
+        print_error_term("secure channel host get ra report failed\n");
+        return CC_ERROR_SEC_CHL_GET_RA_REPORT;
+    }
+    rsp = (sec_chl_msg_t *)calloc(1, sizeof(sec_chl_msg_t) + report.len);
+    (void)memcpy(rsp->data, report.buf, report.len);
+    rsp->data_len = report.len;
+    rsp->sub_type = GET_SVRPUBKEY_SUBTYPE_REPORT;
+    rsp->session_id = msg->session_id;
+
+    *rsp_msg = rsp;
+    *rsp_msg_len = sizeof(sec_chl_msg_t) + report.len;
+
+    return CC_SUCCESS;
+}
+
+static int sec_chl_get_ra_report_ex(cc_enclave_t *context, sec_chl_msg_t *msg,
+    sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
+{
+    if (is_support_remote_attest(context)) {
+        return sec_chl_get_ra_report(context, msg, rsp_msg, rsp_msg_len);
+    }
+    return CC_SUCCESS;
+}
+
+static int sec_chl_get_pubkey(cc_enclave_t *context, sec_chl_msg_t *msg, sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
+{
+    if (is_support_remote_attest(context)) {
+        int ret;
+        cc_enclave_result_t ret_val;
+        size_t session_id = 0;
+        ret_val = init_session(context, &ret, &session_id);
+        if (ret_val != CC_SUCCESS || ret != CC_SUCCESS) {
+            print_error_term("init session failed\n");
+            return CC_ERROR_SEC_CHL_INIT_SESSEION;
+        }
+        msg->session_id = session_id;
+        return sec_chl_get_ra_report(context, msg, rsp_msg, rsp_msg_len);
+    } else {
+        return sec_chl_gen_pubkey(context, msg, rsp_msg, rsp_msg_len);
+    }
+}
+
+static int sec_chl_set_enc_key(cc_enclave_t *context, sec_chl_msg_t *msg,
+    sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
+{
+    int res;
+    cc_enclave_result_t ret_val;
+    size_t  session_id = msg->session_id;
+
+    ret_val = set_enc_key(context, &res, session_id, msg->data, msg->data_len);
+    if (ret_val != CC_SUCCESS || res != (int)CC_SUCCESS) {
+        print_error_term("set enc key error!\n");
+        return CC_FAIL;
+    }
+
+    sec_chl_msg_t *rsp = (sec_chl_msg_t *)calloc(1, sizeof(sec_chl_msg_t));
+    if (rsp == NULL) {
+        return CC_ERROR_SEC_CHL_MEMORY;
+    }
+
+    *rsp_msg = rsp;
+    *rsp_msg_len = sizeof(sec_chl_msg_t);
+
+    return CC_SUCCESS;
+}
+
 static int sec_chl_get_svr_exch_param(cc_enclave_t *context, sec_chl_msg_t *msg,
     sec_chl_msg_t **rsp_msg, size_t *rsp_msg_len)
 {
@@ -290,6 +381,13 @@ cc_enclave_result_t cc_sec_chl_svr_init(cc_sec_chl_svr_ctx_t *ctx)
         print_warning("secure channel already started\n");
         return CC_SUCCESS;
     }
+    if (is_support_remote_attest(ctx->enclave_ctx)) {
+        cc_enclave_result_t ret = cc_prepare_ra_env(CC_RA_SCENARIO_NO_AS);
+        if (ret != CC_SUCCESS) {
+            print_error_term("prepare ra env error, ret:%x!\n", ret);
+            return -1;
+        }
+    }
 
     ret_val = enclave_start_sec_chl(ctx->enclave_ctx, &res);
     if (ret_val != CC_SUCCESS || res != CC_SUCCESS) {
@@ -325,9 +423,15 @@ static cc_enclave_result_t handle_recv_msg(cc_enclave_t *context, sec_chl_msg_t
 {
     cc_enclave_result_t ret = CC_FAIL;
     switch (msg->msg_type) {
+        case SEC_CHL_MSG_GET_RA_REPORT:
+            ret = sec_chl_get_ra_report_ex(context, msg, rsp_msg, rsp_msg_len);
+            break;
         case SEC_CHL_MSG_GET_SVR_PUBKEY:
             ret = sec_chl_get_pubkey(context, msg, rsp_msg, rsp_msg_len);
             break;
+        case SEC_CHL_MSG_SET_ENC_KEY_TO_SVR:
+            ret = sec_chl_set_enc_key(context, msg, rsp_msg, rsp_msg_len);
+            break;
         case SEC_CHL_MSG_GET_SVR_EXCH_PARAM:
             ret = sec_chl_get_svr_exch_param(context, msg, rsp_msg, rsp_msg_len);
             break;
diff --git a/component/secure_channel/secure_channel.edl b/component/secure_channel/secure_channel.edl
index cf2a139..4c6f04c 100644
--- a/component/secure_channel/secure_channel.edl
+++ b/component/secure_channel/secure_channel.edl
@@ -19,6 +19,8 @@ enclave {
     trusted {
         // #define RSA_PUBKEY_LEN 640
         public int get_enclave_pubkey([in, out] size_t* session_id, [out, size = 640] uint8_t* pubkey, [in, out] size_t* pubkey_len);
+        public int init_session([in, out] size_t* session_id);
+        public int set_enc_key(size_t session_id, [in, size = data_len] uint8_t* data, size_t data_len);
         public int get_enclave_exch_param_len(size_t session_id, [in, out] size_t* exch_param_len);
         public int get_enclave_exch_param(size_t session_id, [out, size = exch_param_len] uint8_t* exch_param, size_t exch_param_len);
         public int set_peer_exch_param(size_t session_id, [in, size = data_len] uint8_t* data, size_t data_len);
diff --git a/component/secure_channel/secure_channel_common.c b/component/secure_channel/secure_channel_common.c
index 5800fd6..d8bc93f 100644
--- a/component/secure_channel/secure_channel_common.c
+++ b/component/secure_channel/secure_channel_common.c
@@ -56,42 +56,16 @@ void num_to_buf(size_t num, uint8_t *buf, size_t len)
     return;
 }
 
-static RSA *get_rsakey_from_buffer(const uint8_t *rsa_key_buffer, size_t rsa_key_buffer_len, bool is_private_key)
-{
-    BIO *r_key = NULL;
-    RSA *rsa_key = NULL;
-    r_key = BIO_new_mem_buf(rsa_key_buffer, rsa_key_buffer_len);
-    if (r_key == NULL) {
-        goto end;
-    }
-    if (is_private_key) {
-        rsa_key = PEM_read_bio_RSAPrivateKey(r_key, NULL, NULL, NULL);
-    } else {
-        rsa_key = PEM_read_bio_RSAPublicKey(r_key, NULL, NULL, NULL);
-    }
-
-    if (rsa_key == NULL) {
-        goto end;
-    }
-
-end:
-    BIO_free(r_key);
-    r_key = NULL;
-    return rsa_key;
-}
-
-int verify_rsa_signature(const uint8_t *rsa_pubkey, size_t rsa_pubkey_len, const uint8_t *signature, size_t sig_len,
+int verify_rsa_signature(RSA *rsa_pubkey, const uint8_t *signature, size_t sig_len,
     const uint8_t *buf, size_t buf_len)
 {
-    RSA *sign_rsa = NULL;
     EVP_PKEY *evp_sign_key = NULL;
     EVP_MD_CTX *md_ctx = NULL;
     EVP_PKEY_CTX *pctx = NULL;
     int ret_val = CC_FAIL;
 
-    sign_rsa = get_rsakey_from_buffer(rsa_pubkey, rsa_pubkey_len, 0);
     evp_sign_key = EVP_PKEY_new();
-    if (evp_sign_key == NULL || !EVP_PKEY_set1_RSA(evp_sign_key, sign_rsa) || ((size_t)RSA_size(sign_rsa) != sig_len)) {
+    if (evp_sign_key == NULL || !EVP_PKEY_set1_RSA(evp_sign_key, rsa_pubkey) || ((size_t)RSA_size(rsa_pubkey) != sig_len)) {
         goto end;
     }
     md_ctx = EVP_MD_CTX_new();
@@ -116,8 +90,6 @@ end:
     pctx = NULL;
     EVP_PKEY_free(evp_sign_key);
     evp_sign_key = NULL;
-    RSA_free(sign_rsa);
-    sign_rsa = NULL;
     return ret_val;
 }
 
@@ -771,7 +743,7 @@ cc_enclave_result_t get_exch_param_from_buf(uint8_t *exch_buf, size_t buf_len, s
     return CC_SUCCESS;
 }
 
-cc_enclave_result_t verify_signature(uint8_t *pubkey, size_t pubkey_len, uint8_t *exch_buf, size_t buf_len)
+cc_enclave_result_t verify_signature(RSA *rsa_pubkey, uint8_t *exch_buf, size_t buf_len)
 {
     size_t ecdh_pubkey_len;
     size_t signature_len;
@@ -802,7 +774,7 @@ cc_enclave_result_t verify_signature(uint8_t *pubkey, size_t pubkey_len, uint8_t
 
     // verify signature
     size_t data_len = p_buf - exch_buf - sizeof(signature_len);
-    int ret = verify_rsa_signature(pubkey, pubkey_len, p_buf, signature_len, exch_buf, data_len);
+    int ret = verify_rsa_signature(rsa_pubkey, p_buf, signature_len, exch_buf, data_len);
     if (ret != CC_SUCCESS) {
         return CC_ERROR_SEC_CHL_VERIFY_PEER_EXCH_BUF_SIGNATURE;
     }
diff --git a/component/secure_channel/secure_channel_common.h b/component/secure_channel/secure_channel_common.h
index e81c1e4..4250e60 100644
--- a/component/secure_channel/secure_channel_common.h
+++ b/component/secure_channel/secure_channel_common.h
@@ -12,6 +12,7 @@
 
 #ifndef SECURE_CHANNEL_COMMON_H
 #define SECURE_CHANNEL_COMMON_H
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -46,7 +47,8 @@ typedef enum {
     SEC_CHL_MSG_GET_SVR_PUBKEY = 1,
     SEC_CHL_MSG_GET_SVR_PUBKEY_RSP,
     SEC_CHL_MSG_GET_RA_REPORT,
-    SEC_CHL_MSG_VERIFY_SVR_PUBKEY,
+    SEC_CHL_MSG_GET_RA_REPORT_RSP,
+    SEC_CHL_MSG_SET_ENC_KEY_TO_SVR,
     SEC_CHL_MSG_GET_SVR_EXCH_PARAM,
     SEC_CHL_MSG_GET_SVR_EXCH_PARAM_RSP,
     SEC_CHL_MSG_GEN_LOCAL_EXCH_PARAM,
@@ -57,9 +59,25 @@ typedef enum {
     SEC_CHL_MSG_MAX,
 } sec_chl_msg_type_t;
 
+#define REPORT_OUT_LEN 0x3000
+typedef enum {
+    GET_SVRPUBKEY_SUBTYPE_SVR_GEN,
+    GET_SVRPUBKEY_SUBTYPE_REPORT,
+} sec_chl_get_svrpubkey_subtype_t;
+
+#define CC_TAID_LEN 36
+#define SEC_CHL_REQ_NONCE_LEN 32
+typedef struct {
+    char taid[CC_TAID_LEN + 1];
+    uint8_t nonce[SEC_CHL_REQ_NONCE_LEN + 1];
+    bool with_tcb;
+    bool req_key;
+} sec_chl_ra_req_t;
+
 #define RSP_BUF_LEN 640
 typedef struct sec_chl_msg {
     sec_chl_msg_type_t msg_type;
+    sec_chl_get_svrpubkey_subtype_t sub_type;
     size_t session_id;
     int32_t ret;
     size_t data_len;
@@ -84,7 +102,7 @@ void del_ecdh_ctx(sec_chl_ecdh_ctx_t *ecdh_ctx);
 cc_enclave_result_t compute_session_key(sec_chl_ecdh_ctx_t *ecdh_ctx, sec_chl_exch_param_t *local_exch_param,
     sec_chl_exch_param_t *peer_exch_param);
 cc_enclave_result_t get_exch_param_from_buf(uint8_t *exch_buf, size_t buf_len, sec_chl_exch_param_t **exch_param);
-cc_enclave_result_t verify_signature(uint8_t *pubkey, size_t pubkey_len, uint8_t *exch_buf, size_t buf_len);
+cc_enclave_result_t verify_signature(RSA *rsa_pubkey, uint8_t *exch_buf, size_t buf_len);
 int get_exch_buf_len(sec_chl_ecdh_ctx_t *ecdh_ctx);
 int get_exch_buf(sec_chl_ecdh_ctx_t *ecdh_ctx, uint8_t *exch_param, size_t exch_param_len);
 void del_exch_param(sec_chl_exch_param_t *exch_param);
diff --git a/examples/secure_channel/CMakeLists.txt b/examples/secure_channel/CMakeLists.txt
index 7594577..7b1d723 100644
--- a/examples/secure_channel/CMakeLists.txt
+++ b/examples/secure_channel/CMakeLists.txt
@@ -14,33 +14,34 @@ set(SGX_SDK_DEFAULT_PATH /opt/intel/sgxsdk)
 set(GP_SDK_DEFAULT_PATH /opt/itrustee_sdk)
 set(PL_SDK_DEFAULT_PATH /root/dev/sdk)
 
-set(SGX_SSL_DEFAULT_PATH /opt/intel/sgxssl)
-set(GP_SSL_DEFAULT_PATH /opt/itrustee_sdk/include/TA/openssl/)
+if (NOT DEFINED SSL_PATH)
+set(SSL_PATH /opt/intel/sgxssl)
+endif()
 
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 
 if(${ENCLAVE} STREQUAL "GP")
 if (NOT DEFINED SDK_PATH)
-set(iTrusteeSDK ${GP_SDK_DEFAULT_PATH})
+set(SDK_PATH ${GP_SDK_DEFAULT_PATH})
 else()
-set(iTrusteeSDK ${SDK_PATH})
+set(SDK_PATH ${SDK_PATH})
 endif()
-message("Current Platform: ARM Trustzone, iTrustee SDK PATH:${iTrusteeSDK}")
-if(NOT IS_DIRECTORY ${iTrusteeSDK})
-message(FATAL_ERROR "Please provide the correct iTrusteeSDK path")
+message("Current Platform: ARM Trustzone, iTrustee SDK PATH:${SDK_PATH}")
+if(NOT IS_DIRECTORY ${SDK_PATH})
+message(FATAL_ERROR "Please provide the correct SDK_PATH path")
 endif()
 set(CC_GP ON)
 endif()
 
 if(${ENCLAVE} STREQUAL "SGX")
 if (NOT DEFINED SDK_PATH)
-set(SGXSDK ${SGX_SDK_DEFAULT_PATH})
+set(SDK_PATH ${SGX_SDK_DEFAULT_PATH})
 else()
-set(SGXSDK ${SDK_PATH})
+set(SDK_PATH ${SDK_PATH})
 endif()
-message("Current Platform: Intel SGX, SGX SDK PATH:${SGXSDK}")
-if(NOT IS_DIRECTORY ${SGXSDK})
-message(FATAL_ERROR "Please provide the correct SGXSDK path")
+message("Current Platform: Intel SGX, SGX SDK PATH:${SDK_PATH}")
+if(NOT IS_DIRECTORY ${SDK_PATH})
+message(FATAL_ERROR "Please provide the correct SDK_PATH path")
 endif()
 set(CC_SGX ON)
 endif()
diff --git a/examples/secure_channel/Readme.md b/examples/secure_channel/Readme.md
index c5f5c69..514408e 100644
--- a/examples/secure_channel/Readme.md
+++ b/examples/secure_channel/Readme.md
@@ -38,7 +38,7 @@ git clone https://gitee.com/openeuler/secGear.git
 // build example secure channel
 cd secGear/examples/secure_channel
 source /opt/intel/sgxsdk/environment
-mkdir debug && cd debug && cmake -DSSL_PATH=/opt/intel/sgxssl .. && make && sudo make install
+mkdir debug && cd debug && cmake .. && make && sudo make install
 
 // start server
 ./bin/sc_server
diff --git a/examples/secure_channel/client/CMakeLists.txt b/examples/secure_channel/client/CMakeLists.txt
index 87838b4..4c05022 100644
--- a/examples/secure_channel/client/CMakeLists.txt
+++ b/examples/secure_channel/client/CMakeLists.txt
@@ -6,14 +6,14 @@ set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/client.c)
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-maybe-uninitialized -fPIE")
 
 if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
-    link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+    link_directories(/usr/lib64 /usr/local/lib)
 endif()
 add_executable(${OUTPUT} ${SOURCE_FILE})
 target_include_directories(${OUTPUT} PRIVATE
         ${CMAKE_CURRENT_SOURCE_DIR}/..
         ${SECGEAR_INSTALL_DIR})
 if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
-    target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+    target_link_directories(${OUTPUT} PRIVATE /usr/lib64 /usr/local/lib)
 endif()
 target_link_libraries(${OUTPUT} pthread csecure_channel)
 
diff --git a/examples/secure_channel/client/client.c b/examples/secure_channel/client/client.c
index 7582ae1..08d2574 100644
--- a/examples/secure_channel/client/client.c
+++ b/examples/secure_channel/client/client.c
@@ -10,7 +10,7 @@
 #include "secure_channel_client.h"
 
 
-#define MAXBUF 1024
+#define MAXBUF 12800
 cc_sec_chl_ctx_t g_ctx = {0};
 
 int socket_write_and_read(void *conn, void *buf, size_t count)
@@ -69,6 +69,7 @@ int main(int argc, char **argv)
     // step1: 初始化安全通道客户端，注册消息发送函数
     g_ctx.conn_kit.send = (void *)socket_write_and_read;
     g_ctx.conn_kit.conn = &sockfd;
+    g_ctx.basevalue = "/vendor/bin/basevalue.txt";  // content format:taid image_hash mem_hash
     ret = cc_sec_chl_client_init(CC_SEC_CHL_ALGO_RSA_ECDH_AES_GCM, &g_ctx);
     if (ret != CC_SUCCESS) {
         printf("secure channel init failed:%u\n", ret);
diff --git a/examples/secure_channel/enclave/CMakeLists.txt b/examples/secure_channel/enclave/CMakeLists.txt
index 9690bed..9485dea 100644
--- a/examples/secure_channel/enclave/CMakeLists.txt
+++ b/examples/secure_channel/enclave/CMakeLists.txt
@@ -26,7 +26,7 @@ endif()
 
 if(CC_SGX)
     #sgxsdk path
-    set(SGX_SDK_PATH ${SGXSDK})
+    set(SGX_SDK_PATH ${SDK_PATH})
     set(OUTPUT ${PREFIX}.signed.so)
     set(AUTO_FILES  ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c)
     add_custom_command(OUTPUT ${AUTO_FILES}
@@ -50,8 +50,8 @@ if(CC_GP)
     set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}  -s -fPIC")
     set(CMAKE_SHARED_LINKER_FLAGS  "${COMMON_C_LINK_FLAGS} -Wl,-s")
 
-    set(ITRUSTEE_TEEDIR ${iTrusteeSDK}/)
-    set(ITRUSTEE_LIBC ${iTrusteeSDK}/thirdparty/open_source/musl/libc/)
+    set(ITRUSTEE_TEEDIR ${SDK_PATH}/)
+    set(ITRUSTEE_LIBC ${SDK_PATH}/thirdparty/open_source/musl/libc/)
 
     if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
         link_directories(${CMAKE_BINARY_DIR}/lib/)
@@ -64,7 +64,7 @@ if(CC_GP)
         ${SECGEAR_INSTALL_DIR}
         ${ITRUSTEE_TEEDIR}/include/TA
         ${ITRUSTEE_TEEDIR}/include/TA/huawei_ext
-        ${ITRUSTEE_TEEDIR}/include/TA/openssl
+	${SDK_PATH}/thirdparty/open_source/openssl
         ${ITRUSTEE_LIBC}/arch/aarch64
         ${ITRUSTEE_LIBC}/
         ${ITRUSTEE_LIBC}/arch/arm/bits
@@ -82,9 +82,9 @@ if(CC_GP)
     add_definitions(-DWHITE_LIST_OWNER="${WHITE_LIST_OWNER}")
 
     target_link_libraries(${PREFIX} -ltsecure_channel -lsecgear_tee)
-    #add_custom_command(TARGET ${PREFIX}
-    # 	 POST_BUILD
-    #	         COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT})
+    add_custom_command(TARGET ${PREFIX}
+     	 POST_BUILD
+    	         COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT})
 
     install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}
              DESTINATION /data
diff --git a/examples/secure_channel/enclave/config_cloud.ini b/examples/secure_channel/enclave/config_cloud.ini
index 950c818..8c70225 100644
--- a/examples/secure_channel/enclave/config_cloud.ini
+++ b/examples/secure_channel/enclave/config_cloud.ini
@@ -1,50 +1,60 @@
-[config]
-;0 means debug
-;1 means release
+[signSecPrivateCfg]
+;;;
+;private key length for signing TA:
 ;[fixed value]
-releaseType = 1
+;256 ECDSA Alg
+;2048/4096 RSA Alg
+secSignKeyLen = 4096
 ;;;
-;0 means TA not installed by OTRP
-;1 means TA installed by OTRP
-otrpFlag = 0
+;[fixed value]
+;0 means SHA256 hash type
+;1 means SHA512 hash type
+secHashType = 0
 ;;;
-;server address for signing TA
-serverIp=
+; [fixed value]
+;0 means padding type is pkcs1v15
+;1 means padding type is PSS
+;[fixed value]
+secPaddingType = 1
 ;;;
-;public key for encrypt TA
 ;[fixed value]
-encryptKey = cloud/rsa_public_key_cloud.pem
+;RSA alg
+;ECDSA alg
+;SM2 alg
+secSignAlg = RSA
+;;;
+;public key for encrypt TA
+secEncryptKey = rsa_public_key_cloud.pem
 ;;;
 ;public key length
+secEncryptKeyLen = 3072
+
+[signSecPublicCfg]
+;;;
 ;[fixed value]
-encryptKeyLen = 3072
+; sec sign key type
+;0 means debug
+;1 means release
+secReleaseType = 1
+;;;
+;0 means TA not installed by OTRP
+;1 means TA installed by OTRP
+secOtrpFlag = 0
 ;;;
 ;0 means not sign
 ;1 means signed by local private
 ;2 means signed using native sign tool;
 ;3 means signed by CI
 ;[fixed value]
-signType = 1
+secSignType = 1
+;;;
+;server address for signing TA
+secSignServerIp =
 ;;;
 ;private key for signing TA
-;this private key is only for the debug mdoe so plaintext private key does exist in the production environment
 ;[private key owned by yourself]
-signKey = ../../examples/secure_channel/enclave/cert/private_key.pem
-;;;
-;private key length for signing TA
-;[key length should be 4096 for security enhance]
-signKeyLen = 4096
-;;;
-;0 means SHA256 hash type
-;1 means SHA512 hash type
-;[set value to 0 by default]
-hashType = 0
-;;;
-;0 means padding type is pkcs1v15
-;1 means padding type is PSS
-;[set value to 0 by default]
-paddingType = 0
+secSignKey = /home/TA_cert/private_key.pem
 ;;;
 ;config file
 ;[signed config file by Huawei]
-configPath= ../../examples/secure_channel/enclave/signed_config/config
+configPath = /home/TA_cert/secgear-app1/config
diff --git a/examples/secure_channel/host/CMakeLists.txt b/examples/secure_channel/host/CMakeLists.txt
index 33424f4..bd67eed 100644
--- a/examples/secure_channel/host/CMakeLists.txt
+++ b/examples/secure_channel/host/CMakeLists.txt
@@ -15,13 +15,13 @@ endif()
 
 if(CC_SGX)
     #sgxsdk path
-    set(SGX_SDK_PATH ${SGXSDK})
+    set(SGX_SDK_PATH ${SDK_PATH})
     set(AUTO_FILES  ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c)
     add_custom_command(OUTPUT ${AUTO_FILES}
     DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
     COMMAND ${CODEGEN} --${CODETYPE} --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE}
             --search-path ${SECGEAR_INSTALL_DIR}
-            --search-path ${SGXSDK}/include
+            --search-path ${SDK_PATH}/include
             --search-path ${SSL_PATH}/include)
 endif()
 
@@ -39,12 +39,12 @@ if(CC_GP)
     if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
         target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
     endif()
-    target_link_libraries(${OUTPUT} secgear usecure_channel pthread)
+    target_link_libraries(${OUTPUT} secgear usecure_channel pthread qca)
 endif()
 
 if(CC_SGX)
     if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
-        link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${SGXSDK}/lib64 ${SSL_PATH}/lib64)
+        link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${SDK_PATH}/lib64 ${SSL_PATH}/lib64)
     endif()
     set(SGX_MODE HW)
     set(COMMON_CFLAGS "-m64")
@@ -54,7 +54,7 @@ if(CC_SGX)
         ${CMAKE_CURRENT_BINARY_DIR}
         ${SECGEAR_INSTALL_DIR})
     if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
-        target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${SGXSDK}/lib64 ${SSL_PATH}/lib64)
+        target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${SDK_PATH}/lib64 ${SSL_PATH}/lib64)
     endif()
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${host_C_Flags}")
     target_link_libraries(${OUTPUT} secgear usecure_channel pthread sgx_usgxssl)
diff --git a/examples/secure_channel/host/server.c b/examples/secure_channel/host/server.c
index b6d3d62..1f7e54e 100644
--- a/examples/secure_channel/host/server.c
+++ b/examples/secure_channel/host/server.c
@@ -11,7 +11,7 @@
 #include "sc_demo_u.h"
 #include "usr_msg.h"
 
-#define MAXBUF 1024
+#define MAXBUF 10240
 #define MAX_LISTEN_NUM 100
 typedef struct {
     cc_sec_chl_svr_ctx_t *svr_ctx;
-- 
2.33.0

