This is an automated email from the ASF dual-hosted git repository.

shaojunwang pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-teaclave-java-tee-sdk.git

commit bda96fd9775d07b08fef58a2e570c2973aa36263
Author: jeffery.wsj <[email protected]>
AuthorDate: Wed Jun 15 19:02:49 2022 +0800

    [sdk] Support remote attestation for TEE_SDK enclave mode
    
    Summary:
    1. Add TeeSdkAttestationReport class for TEE_SDK enclave
    2. Refactor toolchains to support user giving private.pem for signing 
enclave .so
    3. Implement remote attestation generation and verification for TEE_SDK 
enclave
    
    Test Plan: all tests pass
    
    Reviewers: lei.yul, cengfeng.lzy, sanhong.lsh
    
    Issue: https://aone.alibaba-inc.com/task/42544014
    
    CR: 
https://code.aone.alibaba-inc.com/java-tee/JavaEnclave/codereview/9084250
---
 build.sh                                           |   6 +-
 .../remote_attestation_generate/Makefile           |  13 ++
 .../generate_attestation_report.c                  |  22 +++
 .../generate_attestation_report.h                  |  24 +++
 .../platform/tee_sdk_svm/wrapper/tee_sdk_wrapper.c |   1 +
 .../host/AbstractEnclave.java                      |  39 +++--
 .../host/AttestationReport.java                    |  22 +--
 .../host/InnerNativeInvocationResult.java          |  27 ----
 .../host/MockInJvmEnclave.java                     |  12 +-
 .../host/MockInSvmEnclave.java                     |  58 ++------
 .../host/RemoteAttestation.java                    |  10 +-
 .../host/RemoteAttestationVerifyResult.java        |  25 ++++
 .../host/SGXRemoteAttestationVerify.java           |  46 ++++++
 .../host/TeeSdkAttestationReport.java              |  35 +++++
 .../confidentialcomputing/host/TeeSdkEnclave.java  |  78 +++-------
 .../native/cpp/attestation_verify/sgx/jni/Makefile |  17 +++
 .../sgx/jni/jni_remote_attestation_verify.c        | 118 +++++++++++++++
 .../sgx/jni/jni_remote_attestation_verify.h        |  45 ++++++
 .../cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c |  91 +++++++-----
 .../cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h |  40 ++++-
 .../main/native/cpp/platform/tee_sdk_svm/Makefile  |   7 +-
 .../platform/tee_sdk_svm/edge_routines/Makefile    |   3 +
 .../tee_sdk_svm/edge_routines/ocall_attestation.c  |   6 +
 .../tee_sdk_svm/edge_routines/ocall_attestation.h  |  22 +++
 .../native/cpp/platform/tee_sdk_svm/jni/Makefile   |   3 +
 .../tee_sdk_svm/jni/generate_attestation_report.c  |  69 +++++++++
 .../tee_sdk_svm/jni/generate_attestation_report.h  |  38 +++++
 .../cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.c | 164 +++++++++++++++++----
 .../cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.h |  54 ++++++-
 .../host/MockTestEnclave.java                      |  25 ++--
 .../host/TestRemoteAttestation.java                |   2 +-
 sdk/native/bin/remote_attestation/sgx/jni/.gitkeep |   0
 .../platform/tee_sdk_svm/edl/tee_sdk_enclave.edl   |   6 +
 .../config/platform/tee_sdk_svm/jni/config.mk      |  10 +-
 .../config/remote_attestation_verify/sgx/config.mk |  13 ++
 sdk/native/script/build_app/Makefile               |  22 +--
 sdk/native/script/build_app/make.sh                |   8 +-
 sdk/native/script/build_enclave_sdk/Makefile       |   2 +
 sdk/native/script/build_host_sdk/Makefile          |   2 +
 sdk/native/script/build_host_sdk/make.sh           |   1 +
 test/enclave/pom.xml                               |   2 +
 .../test/host/TestJavaEnclaveService.java          |  42 ++++--
 tools/cicd/make.sh                                 |   7 +-
 43 files changed, 949 insertions(+), 288 deletions(-)

diff --git a/build.sh b/build.sh
index 44288a0..5d096d2 100755
--- a/build.sh
+++ b/build.sh
@@ -1,5 +1,9 @@
 #!/bin/bash
 
+# set sgx enclave remote attestation PCCS_URL.
+echo "PCCS_URL=${PCCS_URL}" > /etc/sgx_default_qcnl.conf
+echo "USE_SECURE_CERT=TRUE" >> /etc/sgx_default_qcnl.conf
+
 # parse shell file's path location.
 SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
 
@@ -15,4 +19,4 @@ cd "${WORKDIR}"/sdk && mvn $SETTING clean install
 rm -rf /opt/javaenclave && mkdir -p /opt/javaenclave && cp -r 
${SHELL_FOLDER}/sdk/native/bin /opt/javaenclave \
 && cp -r ${SHELL_FOLDER}/sdk/native/config /opt/javaenclave && cp -r 
${SHELL_FOLDER}/sdk/native/script/build_app /opt/javaenclave
 # Test unit test cases in JavaEnclave
-cd "${WORKDIR}"/test && mvn -X $SETTING -Pnative -e clean package
+cd "${WORKDIR}"/test && mvn $SETTING -Pnative clean package
diff --git 
a/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/Makefile
 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/Makefile
new file mode 100644
index 0000000..957be54
--- /dev/null
+++ 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/Makefile
@@ -0,0 +1,13 @@
+include $(NATIVE_BASE_DIR)/config/config.mk
+include $(NATIVE_BASE_DIR)/config/platform/tee_sdk_svm/jni/config.mk
+
+.PHONY: all build clean
+
+all: build
+
+build:
+       $(CC) -g -c -I$(INCLUDE) -I$(JAVA_HOME)/lib $(TS_ENCLAVE_INCDIR) 
$(TS_ENCLAVE_CFLAGS) generate_attestation_report.c \
+    -o $(BIN)/platform/tee_sdk_svm/generate_attestation_report.o
+
+clean:
+       rm -rf $(BIN)/platform/tee_sdk_svm/generate_attestation_report.o
\ No newline at end of file
diff --git 
a/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/generate_attestation_report.c
 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/generate_attestation_report.c
new file mode 100644
index 0000000..0935fd2
--- /dev/null
+++ 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/generate_attestation_report.c
@@ -0,0 +1,22 @@
+#include "generate_attestation_report.h"
+
+int generate_remote_attestation_report(void* hash, size_t hash_length, 
sgx_report_t* ra_report) {
+       sgx_report_data_t report_data;
+       quote3_error_t sgx_error;
+       if (hash_length != SGX_REPORT_DATA_SIZE) {
+           return (int)SGX_ERROR_INVALID_PARAMETER;
+       }
+       memset(&report_data, 0, sizeof(sgx_report_data_t));
+       memcpy(report_data.d, hash, SGX_REPORT_DATA_SIZE);
+
+       sgx_target_info_t qe_target_info;
+       memset(&qe_target_info, 0, sizeof(sgx_target_info_t));
+
+       ocall_get_target_info(&sgx_error, &qe_target_info);
+       if(sgx_error != SGX_QL_SUCCESS) {
+           return (int)sgx_error;
+       }
+
+       /* Generate the report for the app_enclave */
+       return (int)sgx_create_report(&qe_target_info, &report_data, ra_report);
+}
diff --git 
a/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/generate_attestation_report.h
 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/generate_attestation_report.h
new file mode 100644
index 0000000..f93c1b4
--- /dev/null
+++ 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate/generate_attestation_report.h
@@ -0,0 +1,24 @@
+#ifndef _GENERATE_ATTESTATION_REPORT_H_
+#define _GENERATE_ATTESTATION_REPORT_H_
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "sgx_trts.h"
+#include "sgx_error.h"
+#include "sgx_report.h"
+#include "sgx_utils.h"
+#include "sgx_quote_3.h"
+#include "sgx_ql_lib_common.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+    int generate_remote_attestation_report(void* hash, size_t hash_length, 
sgx_report_t* ra_report);
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_GENERATE_ATTESTATION_REPORT_H_ */
diff --git 
a/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/wrapper/tee_sdk_wrapper.c
 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/wrapper/tee_sdk_wrapper.c
index 6d651ea..95255d4 100644
--- 
a/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/wrapper/tee_sdk_wrapper.c
+++ 
b/sdk/enclave/src/main/native/cpp/platform/tee_sdk_svm/wrapper/tee_sdk_wrapper.c
@@ -33,6 +33,7 @@ int tee_sdk_random(void* data, long size) {
 }
 
 int enclave_svm_isolate_create(void* isolate, void* isolateThread) {
+    // printf("JavaEnclave Warning: %s is called in enclave svm.\n", 
__FUNCTION__);
     graal_isolate_t* isolate_t;
     graal_isolatethread_t* thread_t;
 
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java
index 15eefb1..486a59d 100644
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AbstractEnclave.java
@@ -44,11 +44,13 @@ abstract class AbstractEnclave implements Enclave {
         return enclaveContext;
     }
 
-    abstract InnerNativeInvocationResult loadServiceNative(byte[] payload);
+    abstract byte[] loadServiceNative(byte[] payload) throws 
ServicesLoadingException;
 
-    abstract InnerNativeInvocationResult unloadServiceNative(byte[] payload);
+    abstract byte[] unloadServiceNative(byte[] payload) throws 
ServicesUnloadingException;
 
-    abstract InnerNativeInvocationResult invokeMethodNative(byte[] payload);
+    abstract byte[] invokeMethodNative(byte[] payload) throws 
EnclaveMethodInvokingException;
+
+    abstract AttestationReport generateAttestationReportNative(byte[] 
userData) throws RemoteAttestationException;
 
     // load service by interface name.
     ServiceHandler[] loadService(Class<?> service) throws 
ServicesLoadingException {
@@ -64,15 +66,9 @@ abstract class AbstractEnclave implements Enclave {
             } catch (IOException e) {
                 throw new ServicesLoadingException("service name serialization 
failed.", e);
             }
-            InnerNativeInvocationResult resultNativeWrapper = 
loadServiceNative(payload);
-            // If loadServiceNative native call return value is error, an 
ServicesLoadingException exception
-            // will be thrown.
-            if (resultNativeWrapper.getRet() != 0) {
-                throw new ServicesLoadingException("load service native call 
failed.");
-            }
             EnclaveInvocationResult resultWrapper;
             try {
-                resultWrapper = (EnclaveInvocationResult) 
SerializationHelper.deserialize(resultNativeWrapper.getPayload());
+                resultWrapper = (EnclaveInvocationResult) 
SerializationHelper.deserialize(loadServiceNative(payload));
             } catch (IOException | ClassNotFoundException e) {
                 throw new ServicesLoadingException("EnclaveInvokeResultWrapper 
deserialization failed.", e);
             }
@@ -108,13 +104,9 @@ abstract class AbstractEnclave implements Enclave {
             } catch (IOException e) {
                 throw new ServicesUnloadingException("unload service 
serialization failed.", e);
             }
-            InnerNativeInvocationResult resultNativeWrapper = 
unloadServiceNative(payload);
-            if (resultNativeWrapper.getRet() != 0) {
-                throw new ServicesUnloadingException("unload service native 
call failed.");
-            }
             EnclaveInvocationResult resultWrapper;
             try {
-                resultWrapper = (EnclaveInvocationResult) 
SerializationHelper.deserialize(resultNativeWrapper.getPayload());
+                resultWrapper = (EnclaveInvocationResult) 
SerializationHelper.deserialize(unloadServiceNative(payload));
             } catch (IOException | ClassNotFoundException e) {
                 throw new 
ServicesUnloadingException("EnclaveInvokeResultWrapper deserialization 
failed.", e);
             }
@@ -139,13 +131,9 @@ abstract class AbstractEnclave implements Enclave {
             } catch (IOException e) {
                 throw new 
EnclaveMethodInvokingException("EnclaveInvokeMetaWrapper serialization 
failed.", e);
             }
-            InnerNativeInvocationResult resultNativeWrapper = 
invokeMethodNative(payload);
-            if (resultNativeWrapper.getRet() != 0) {
-                throw new EnclaveMethodInvokingException("method invoke native 
call failed.");
-            }
             EnclaveInvocationResult resultWrapper;
             try {
-                resultWrapper = (EnclaveInvocationResult) 
SerializationHelper.deserialize(resultNativeWrapper.getPayload());
+                resultWrapper = (EnclaveInvocationResult) 
SerializationHelper.deserialize(invokeMethodNative(payload));
             } catch (IOException | ClassNotFoundException e) {
                 throw new 
EnclaveMethodInvokingException("EnclaveInvokeResultWrapper deserialization 
failed.", e);
             }
@@ -161,7 +149,16 @@ abstract class AbstractEnclave implements Enclave {
         }
     }
 
-    abstract AttestationReport generateAttestationReport(byte[] userData) 
throws RemoteAttestationException;
+    AttestationReport generateAttestationReport(byte[] userData) throws 
RemoteAttestationException {
+        if (!getEnclaveContext().getEnclaveToken().tryAcquireToken()) {
+            throw new RemoteAttestationException("enclave was destroyed.");
+        }
+        try {
+            return generateAttestationReportNative(userData);
+        } finally {
+            getEnclaveContext().getEnclaveToken().restoreToken();
+        }
+    }
 
     @Override
     public <T> Iterator<T> load(Class<T> service) throws 
ServicesLoadingException {
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AttestationReport.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AttestationReport.java
index 4dd574d..dd8bcf9 100644
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AttestationReport.java
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/AttestationReport.java
@@ -5,15 +5,15 @@ import java.io.Serializable;
 /**
  * AttestationReport wraps enclave's type and generated remote attestation 
report.
  */
-public final class AttestationReport implements Serializable {
+public class AttestationReport implements Serializable {
     private static final long serialVersionUID = -2781780414647128479L;
 
     private final EnclaveType enclaveType;
-    private final byte[] report;
+    private final byte[] quote;
 
-    AttestationReport(EnclaveType enclaveType, byte[] report) {
+    AttestationReport(EnclaveType enclaveType, byte[] quote) {
         this.enclaveType = enclaveType;
-        this.report = report;
+        this.quote = quote;
     }
 
     /**
@@ -27,25 +27,25 @@ public final class AttestationReport implements 
Serializable {
     }
 
     /**
-     * Get enclave report from an AttestationReport instance.
+     * Get enclave quote from an AttestationReport instance.
      * <p>
      *
-     * @return Remote attestation report data.
+     * @return Remote attestation quote data.
      */
-    public byte[] getReport() {
-        return report;
+    public byte[] getQuote() {
+        return quote;
     }
 
     /**
-     * Bind an AttestationReport's type and report into a buffer for rpc 
transmission.
+     * Bind an AttestationReport's type and quote into a buffer for rpc 
transmission.
      * <p>
      *
      * @return Serialized buffer.
      */
     public byte[] toByteArray() {
-        byte[] bindReport = new byte[1 + report.length];
+        byte[] bindReport = new byte[1 + quote.length];
         bindReport[0] = (byte) enclaveType.ordinal();
-        System.arraycopy(report, 0, bindReport, 1, report.length);
+        System.arraycopy(quote, 0, bindReport, 1, quote.length);
         return bindReport;
     }
 
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/InnerNativeInvocationResult.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/InnerNativeInvocationResult.java
deleted file mode 100644
index 6e8e240..0000000
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/InnerNativeInvocationResult.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.alibaba.confidentialcomputing.host;
-
-/**
- * InnerNativeInvocationResult is load_service unload_service and invoke_method
- * native call's return value. It not only contains enclave e_call's return 
value,
- * also contains an EnclaveInvocationResult object's serialization payload from
- * method invocation in enclave.
- */
-class InnerNativeInvocationResult {
-    // enclave method native call's result.
-    private final int ret;
-    // payload is an EnclaveInvocationResult object's serialization data.
-    private final byte[] payload;
-
-    InnerNativeInvocationResult(int ret, byte[] payload) {
-        this.ret = ret;
-        this.payload = payload;
-    }
-
-    int getRet() {
-        return ret;
-    }
-
-    byte[] getPayload() {
-        return payload;
-    }
-}
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInJvmEnclave.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInJvmEnclave.java
index 030feaf..dc2e982 100644
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInJvmEnclave.java
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInJvmEnclave.java
@@ -1,6 +1,6 @@
 package com.alibaba.confidentialcomputing.host;
 
-import 
com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
+import com.alibaba.confidentialcomputing.host.exception.*;
 
 /**
  * MockInJvmEnclave is a mock jvm enclave. Both host and enclave codes run
@@ -13,7 +13,7 @@ class MockInJvmEnclave extends AbstractEnclave {
     }
 
     @Override
-    AttestationReport generateAttestationReport(byte[] userData) throws 
RemoteAttestationException {
+    AttestationReport generateAttestationReportNative(byte[] userData) throws 
RemoteAttestationException {
         throw new RemoteAttestationException("MOCK_IN_JVM enclave doesn't 
support remote attestation generation.");
     }
 
@@ -22,22 +22,22 @@ class MockInJvmEnclave extends AbstractEnclave {
     }
 
     @Override
-    InnerNativeInvocationResult loadServiceNative(byte[] payload) {
+    byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
         return null;
     }
 
     @Override
-    InnerNativeInvocationResult unloadServiceNative(byte[] payload) {
+    byte[] unloadServiceNative(byte[] payload) throws 
ServicesUnloadingException {
         return null;
     }
 
     @Override
-    InnerNativeInvocationResult invokeMethodNative(byte[] payload) {
+    byte[] invokeMethodNative(byte[] payload) throws 
EnclaveMethodInvokingException {
         return null;
     }
 
     @Override
-    public void destroy() {
+    public void destroy() throws EnclaveDestroyingException {
         ; // Do nothing here.
     }
 }
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInSvmEnclave.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInSvmEnclave.java
index 3c4d030..d953afe 100644
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInSvmEnclave.java
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/MockInSvmEnclave.java
@@ -1,7 +1,6 @@
 package com.alibaba.confidentialcomputing.host;
 
-import 
com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException;
-import 
com.alibaba.confidentialcomputing.host.exception.EnclaveDestroyingException;
+import com.alibaba.confidentialcomputing.host.exception.*;
 import 
com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
 
 import java.io.IOException;
@@ -54,19 +53,13 @@ class MockInSvmEnclave extends AbstractEnclave {
         }
 
         // Create svm sdk enclave by native call, enclaveSvmSdkHandle are set 
in jni in nativeHandlerContext.
-        int ret = nativeCreateEnclave(extractTempPath.getEnclaveSvmFilePath());
-        if (ret != 0) {
-            throw new EnclaveCreatingException("create svm sdk enclave by 
native calling failed.");
-        }
+        nativeCreateEnclave(extractTempPath.getEnclaveSvmFilePath());
         // Create svm attach isolate and isolateThread, and they are set in 
jni in nativeHandlerContext.
-        ret = nativeSvmAttachIsolate(enclaveSvmSdkHandle);
-        if (ret != 0) {
-            throw new EnclaveCreatingException("create svm isolate by native 
calling failed.");
-        }
+        nativeSvmAttachIsolate(enclaveSvmSdkHandle);
     }
 
     @Override
-    AttestationReport generateAttestationReport(byte[] userData) throws 
RemoteAttestationException {
+    AttestationReport generateAttestationReportNative(byte[] userData) throws 
RemoteAttestationException {
         throw new RemoteAttestationException("MOCK_IN_SVM enclave doesn't 
support remote attestation generation.");
     }
 
@@ -75,17 +68,17 @@ class MockInSvmEnclave extends AbstractEnclave {
     }
 
     @Override
-    InnerNativeInvocationResult loadServiceNative(byte[] payload) {
+    byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
         return nativeLoadService(enclaveSvmSdkHandle, isolateHandle, payload);
     }
 
     @Override
-    InnerNativeInvocationResult unloadServiceNative(byte[] payload) {
+    byte[] unloadServiceNative(byte[] payload) throws 
ServicesUnloadingException {
         return nativeUnloadService(enclaveSvmSdkHandle, isolateHandle, 
payload);
     }
 
     @Override
-    InnerNativeInvocationResult invokeMethodNative(byte[] payload) {
+    byte[] invokeMethodNative(byte[] payload) throws 
EnclaveMethodInvokingException {
         return nativeInvokeMethod(enclaveSvmSdkHandle, isolateHandle, payload);
     }
 
@@ -96,45 +89,26 @@ class MockInSvmEnclave extends AbstractEnclave {
             // interrupt enclave services' recycler firstly.
             
this.getEnclaveContext().getEnclaveServicesRecycler().interruptServiceRecycler();
             // destroy svm isolate.
-            int ret = nativeSvmDetachIsolate(enclaveSvmSdkHandle, 
isolateThreadHandle);
-            if (ret != 0) {
-                throw new EnclaveDestroyingException("isolate destroy native 
call failed.");
-            }
-            ret = nativeDestroyEnclave(enclaveSvmSdkHandle);
-            if (ret != 0) {
-                throw new EnclaveDestroyingException("enclave destroy native 
call failed.");
-            }
+            nativeSvmDetachIsolate(enclaveSvmSdkHandle, isolateThreadHandle);
+            nativeDestroyEnclave(enclaveSvmSdkHandle);
         }
     }
 
     private static native void registerNatives();
 
-    private native int nativeCreateEnclave(String path);
+    private native int nativeCreateEnclave(String path) throws 
EnclaveCreatingException;
 
-    private native int nativeSvmAttachIsolate(
-            long enclaveSvmSdkHandle);
+    private native int nativeSvmAttachIsolate(long enclaveSvmSdkHandle) throws 
EnclaveCreatingException;
 
-    private native InnerNativeInvocationResult nativeLoadService(
-            long enclaveSvmSdkHandle,
-            long isolateHandler,
-            byte[] serviceHandler);
+    private native byte[] nativeLoadService(long enclaveSvmSdkHandle, long 
isolateHandler, byte[] serviceHandler) throws ServicesLoadingException;
 
-    private native InnerNativeInvocationResult nativeInvokeMethod(
-            long enclaveSvmSdkHandle,
-            long isolateHandler,
-            byte[] enclaveInvokeMetaWrapper);
+    private native byte[] nativeInvokeMethod(long enclaveSvmSdkHandle, long 
isolateHandler, byte[] enclaveInvokeMetaWrapper) throws 
EnclaveMethodInvokingException;
 
-    private native InnerNativeInvocationResult nativeUnloadService(
-            long enclaveSvmSdkHandle,
-            long isolateHandler,
-            byte[] serviceHandler);
+    private native byte[] nativeUnloadService(long enclaveSvmSdkHandle, long 
isolateHandler, byte[] serviceHandler) throws ServicesUnloadingException;
 
-    private native int nativeSvmDetachIsolate(
-            long enclaveSvmSdkHandle,
-            long isolateThreadHandler);
+    private native int nativeSvmDetachIsolate(long enclaveSvmSdkHandle, long 
isolateThreadHandler) throws EnclaveDestroyingException;
 
-    private native int nativeDestroyEnclave(
-            long enclaveSvmSdkHandle);
+    private native int nativeDestroyEnclave(long enclaveSvmSdkHandle) throws 
EnclaveDestroyingException;
 
     class MockInSvmExtractTempPath {
         private final String jniTempFilePath;
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestation.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestation.java
index c5bd9df..239a35d 100644
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestation.java
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestation.java
@@ -52,11 +52,15 @@ public final class RemoteAttestation {
      *
      * @param report signed data in an enclave and its tee type info.
      * @return Zero means enclave is valid, Other value means enclave is 
invalid.
+     * @throws RemoteAttestationException {@link RemoteAttestationException} 
If enclave remote
+     *                                    attestation verify failed.
      */
     public static int verifyAttestationReport(AttestationReport report) throws 
RemoteAttestationException {
-        if (report.getEnclaveType() != EnclaveType.TEE_SDK) {
-            throw new RemoteAttestationException("enclaveType must be 
TEE_SDK.");
+        switch (report.getEnclaveType()) {
+            case TEE_SDK:
+                return 
TeeSdkEnclave.verifyAttestationReport(report.getQuote());
+            default:
+                throw new RemoteAttestationException("enclaveType must be 
TEE_SDK.");
         }
-        return TeeSdkEnclave.verifyAttestationReport(report.getReport());
     }
 }
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestationVerifyResult.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestationVerifyResult.java
new file mode 100644
index 0000000..b99cb2d
--- /dev/null
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/RemoteAttestationVerifyResult.java
@@ -0,0 +1,25 @@
+package com.alibaba.confidentialcomputing.host;
+
+class RemoteAttestationVerifyResult {
+    private volatile int status;
+    private volatile int versionCheck;
+    private volatile int verifyFlag;
+
+    RemoteAttestationVerifyResult(int status, int versionCheck, int 
verifyFlag) {
+        this.status = status;
+        this.versionCheck = versionCheck;
+        this.verifyFlag = verifyFlag;
+    }
+
+    int getStatus() {
+        return this.status;
+    }
+
+    int getVersionCheck() {
+        return this.versionCheck;
+    }
+
+    int getVerifyFlag() {
+        return this.verifyFlag;
+    }
+}
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXRemoteAttestationVerify.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXRemoteAttestationVerify.java
new file mode 100644
index 0000000..c8c0343
--- /dev/null
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXRemoteAttestationVerify.java
@@ -0,0 +1,46 @@
+package com.alibaba.confidentialcomputing.host;
+
+import com.alibaba.confidentialcomputing.host.ExtractLibrary;
+import 
com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
+
+import java.io.IOException;
+
+public class SGXRemoteAttestationVerify {
+    private final static String JNI_EXTRACTED_PACKAGE_PATH = 
"remote_attestation/sgx/jni/lib_jni_sgx_remote_attestation_verify.so";
+
+    static {
+        try {
+            String jniTempFilePath = 
ExtractLibrary.extractLibrary(SGXRemoteAttestationVerify.class.getClassLoader(),
+                    JNI_EXTRACTED_PACKAGE_PATH);
+            System.load(jniTempFilePath);
+            registerNatives();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static native void registerNatives();
+    private static native int nativeVerifyAttestationReport(byte[] report, 
RemoteAttestationVerifyResult result);
+
+    public static int VerifyAttestationReport(byte[] report) throws 
RemoteAttestationException {
+        RemoteAttestationVerifyResult verifyResult = new 
RemoteAttestationVerifyResult(0, 0, 0);
+        nativeVerifyAttestationReport(report, verifyResult);
+        if (verifyResult.getVersionCheck() == -1) {
+            throw new 
RemoteAttestationException("sgx_qv_get_quote_supplemental_data_size returned 
size is not same with header definition in SGX SDK");
+        } else if (verifyResult.getStatus() == 1) {
+            throw new 
RemoteAttestationException("sgx_qv_get_quote_supplemental_data_size failed");
+        } else if (verifyResult.getStatus() == 2) {
+            throw new RemoteAttestationException("sgx_qv_verify_quote failed");
+        } else if (verifyResult.getStatus() == 3) {
+            throw new RemoteAttestationException("supplemental data memory 
allocation failed");
+        } else if (verifyResult.getVerifyFlag() == 1) {
+            throw new RemoteAttestationException("verification completed, but 
collateral is out of date");
+        } else if (verifyResult.getVerifyFlag() == 2) {
+            throw new RemoteAttestationException("verification completed with 
non-terminal result");
+        } else if (verifyResult.getVerifyFlag() == 3) {
+            throw new RemoteAttestationException("verification completed with 
terminal result, but verification check failed");
+        } else {
+            return verifyResult.getVerifyFlag();
+        }
+    }
+}
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
new file mode 100644
index 0000000..6ab0f44
--- /dev/null
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
@@ -0,0 +1,35 @@
+package com.alibaba.confidentialcomputing.host;
+
+/**
+ * TeeSdkAttestationReport parse more details information from a tee sdk type 
enclave's remote attestation report.
+ */
+public final class TeeSdkAttestationReport extends AttestationReport {
+    private final byte[] mrSigner;
+    private final byte[] mrEnclave;
+
+    TeeSdkAttestationReport(byte[] quote, byte[] mrSigner, byte[] mrEnclave) {
+        super(EnclaveType.TEE_SDK, quote);
+        this.mrSigner = mrSigner;
+        this.mrEnclave = mrEnclave;
+    }
+
+    /**
+     * Get enclave measurementEnclave from an enclave's remote attestation 
report.
+     * <p>
+     *
+     * @return Remote attestation measurementEnclave value.
+     */
+    public byte[] getMeasurementEnclave() {
+        return this.mrEnclave;
+    }
+
+    /**
+     * Get enclave measurementSigner from an enclave's remote attestation 
report.
+     * <p>
+     *
+     * @return Remote attestation measurementSigner value.
+     */
+    public byte[] getMeasurementSigner() {
+        return this.mrSigner;
+    }
+}
diff --git 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkEnclave.java
 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkEnclave.java
index ef71ece..50bd225 100644
--- 
a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkEnclave.java
+++ 
b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkEnclave.java
@@ -1,8 +1,6 @@
 package com.alibaba.confidentialcomputing.host;
 
-import 
com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException;
-import 
com.alibaba.confidentialcomputing.host.exception.EnclaveDestroyingException;
-import 
com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
+import com.alibaba.confidentialcomputing.host.exception.*;
 
 import java.io.IOException;
 
@@ -49,75 +47,53 @@ class TeeSdkEnclave extends AbstractEnclave {
         }
 
         // Create tee sdk enclave by native call, enclaveHandler is set in jni 
in nativeHandlerContext.
-        int ret = nativeCreateEnclave(mode.getValue(), 
extractTempPath.getTeeSdkSignedFilePath());
-        if (ret != 0) {
-            throw new EnclaveCreatingException("create tee sdk enclave by 
native calling failed.");
-        }
+        nativeCreateEnclave(mode.getValue(), 
extractTempPath.getTeeSdkSignedFilePath());
         // Create svm attach isolate and isolateThread, and they are set in 
jni in nativeHandlerContext.
-        ret = nativeSvmAttachIsolate(enclaveHandle);
-        if (ret != 0) {
-            throw new EnclaveCreatingException("create svm isolate by native 
calling failed.");
-        }
+        nativeSvmAttachIsolate(enclaveHandle);
     }
 
     private static native void registerNatives();
 
-    private native int nativeCreateEnclave(int mode, String path);
-
-    private native InnerNativeInvocationResult 
nativeGenerateAttestationReport(byte[] userData);
-
-    private static native InnerNativeInvocationResult 
nativeVerifyAttestationReport(byte[] report);
+    private native int nativeCreateEnclave(int mode, String path) throws 
EnclaveCreatingException;
 
-    private native int nativeSvmAttachIsolate(long enclaveHandler);
+    private native TeeSdkAttestationReport 
nativeGenerateAttestationReport(long enclaveHandler, byte[] userData) throws 
RemoteAttestationException;
 
-    private native InnerNativeInvocationResult nativeLoadService(
-            long enclaveHandler, long isolateHandler, byte[] serviceHandler);
+    private native int nativeSvmAttachIsolate(long enclaveHandler) throws 
EnclaveCreatingException;
 
-    private native InnerNativeInvocationResult nativeInvokeMethod(
-            long enclaveHandler, long isolateHandler, byte[] 
enclaveInvokeMetaWrapper);
+    private native byte[] nativeLoadService(long enclaveHandler, long 
isolateHandler, byte[] serviceHandler) throws ServicesLoadingException;
 
-    private native InnerNativeInvocationResult nativeUnloadService(
-            long enclaveHandler, long isolateHandler, byte[] serviceHandler);
+    private native byte[] nativeInvokeMethod(long enclaveHandler, long 
isolateHandler, byte[] enclaveInvokeMetaWrapper) throws 
EnclaveMethodInvokingException;
 
-    private native int nativeSvmDetachIsolate(long enclaveHandler, long 
isolateThreadHandler);
+    private native byte[] nativeUnloadService(long enclaveHandler, long 
isolateHandler, byte[] serviceHandler) throws ServicesUnloadingException;
 
-    private native int nativeDestroyEnclave(long enclaveHandler);
+    private native int nativeSvmDetachIsolate(long enclaveHandler, long 
isolateThreadHandler) throws EnclaveDestroyingException;
 
-    @Override
-    AttestationReport generateAttestationReport(byte[] userData) throws 
RemoteAttestationException {
-        InnerNativeInvocationResult result = 
nativeGenerateAttestationReport(userData);
-        if (result.getRet() != 0) {
-            throw new RemoteAttestationException("TEE_SDK's attestation report 
generation native call error code: " + result.getRet());
-        }
-        return new AttestationReport(EnclaveType.TEE_SDK, result.getPayload());
-    }
+    private native int nativeDestroyEnclave(long enclaveHandler) throws 
EnclaveDestroyingException;
 
-    static int verifyAttestationReport(byte[] report) throws 
RemoteAttestationException {
-        InnerNativeInvocationResult result = 
nativeVerifyAttestationReport(report);
-        if (result.getRet() != 0) {
-            throw new RemoteAttestationException("TEE_SDK's attestation 
verification native call error code: " + result.getRet());
-        }
-        if (result.getPayload() == null) {
-            return 0;  // Remote Attestation Verification result is succeed.
-        }
-        return 1; // Remote Attestation Verification result is failed.
+    static int verifyAttestationReport(byte[] quote) throws 
RemoteAttestationException {
+        return SGXRemoteAttestationVerify.VerifyAttestationReport(quote);
     }
 
     @Override
-    InnerNativeInvocationResult loadServiceNative(byte[] payload) {
+    byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
         return nativeLoadService(enclaveHandle, isolateHandle, payload);
     }
 
     @Override
-    InnerNativeInvocationResult unloadServiceNative(byte[] payload) {
+    byte[] unloadServiceNative(byte[] payload) throws 
ServicesUnloadingException {
         return nativeUnloadService(enclaveHandle, isolateHandle, payload);
     }
 
     @Override
-    InnerNativeInvocationResult invokeMethodNative(byte[] payload) {
+    byte[] invokeMethodNative(byte[] payload) throws 
EnclaveMethodInvokingException {
         return nativeInvokeMethod(enclaveHandle, isolateHandle, payload);
     }
 
+    @Override
+    AttestationReport generateAttestationReportNative(byte[] userData) throws 
RemoteAttestationException {
+        return nativeGenerateAttestationReport(enclaveHandle, userData);
+    }
+
     @Override
     public void destroy() throws EnclaveDestroyingException {
         // destroyToken will wait for all ongoing enclave invocations finished.
@@ -125,19 +101,13 @@ class TeeSdkEnclave extends AbstractEnclave {
             // interrupt enclave services' recycler firstly.
             
this.getEnclaveContext().getEnclaveServicesRecycler().interruptServiceRecycler();
             // destroy svm isolate.
-            int ret = nativeSvmDetachIsolate(enclaveHandle, 
isolateThreadHandle);
-            if (ret != 0) {
-                throw new EnclaveDestroyingException("isolate destroy native 
call failed.");
-            }
+            nativeSvmDetachIsolate(enclaveHandle, isolateThreadHandle);
             // destroy the enclave.
-            ret = nativeDestroyEnclave(enclaveHandle);
-            if (ret != 0) {
-                throw new EnclaveDestroyingException("enclave destroy native 
call failed.");
-            }
+            nativeDestroyEnclave(enclaveHandle);
         }
     }
 
-    class TeeSdkExtractTempPath {
+    static class TeeSdkExtractTempPath {
         private final String jniTempFilePath;
         private final String teeSdkSignedFilePath;
 
diff --git a/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/Makefile 
b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/Makefile
new file mode 100644
index 0000000..fda3ec9
--- /dev/null
+++ b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/Makefile
@@ -0,0 +1,17 @@
+# Copyright (c)
+
+include $(NATIVE_BASE_DIR)/config/config.mk
+include $(NATIVE_BASE_DIR)/config/remote_attestation_verify/sgx/config.mk
+
+.PHONY: all build clean
+
+all: build
+
+build:
+       $(CC) -g -c -Wno-unused-parameter $(RA_VERIFY_INCDIR) 
-I$(JAVA_HOME)/lib -I$(JAVA_HOME)/include \
+       -I$(JAVA_HOME)/include/$(shell uname -s | tr A-Z a-z) -fPIC 
jni_remote_attestation_verify.c
+       $(CC) jni_remote_attestation_verify.o $(RA_VERIFY_LDFLAGS) -fPIC 
-shared -o 
$(BIN)/remote_attestation/sgx/jni/lib_jni_sgx_remote_attestation_verify.so
+
+clean:
+       rm -rf *.o
+       rm -rf 
$(BIN)/remote_attestation/sgx/jni/lib_jni_sgx_remote_attestation_verify.so
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/jni_remote_attestation_verify.c
 
b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/jni_remote_attestation_verify.c
new file mode 100644
index 0000000..fa53006
--- /dev/null
+++ 
b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/jni_remote_attestation_verify.c
@@ -0,0 +1,118 @@
+#include "jni_remote_attestation_verify.h"
+
+#define QUOTE_VERIFICATION_STATUS_SUCCESS                 0
+#define QUOTE_VERIFICATION_STATUS_GET_DATA_SIZE_FAILED    1
+#define QUOTE_VERIFICATION_STATUS_QUOTE_VERIFY_FAILED     2
+#define QUOTE_VERIFICATION_STATUS_MEMORY_MALLOC_FAILED    3
+#define QUOTE_VERIFICATION_VERSION_CHECK_SUCCESS          0
+#define QUOTE_VERIFICATION_VERSION_CHECK_FAILED          -1
+#define QUOTE_VERIFICATION_SUCCESS                        0
+#define QUOTE_VERIFICATION_OUT_OF_DATA                    1
+#define QUOTE_VERIFICATION_NO_TERMINAL                    2
+#define QUOTE_VERIFICATION_FAILED_WITH_TERMINAL           3
+
+static JNINativeMethod sgx_remote_attestation_verify_methods[] = {
+    {"nativeVerifyAttestationReport", 
SGX_ENCLAVE_REMOTE_ATTESTATION_VERIFY_SIGNATURE, (void 
*)&JavaEnclave_SGX_ENCLAVE_REMOTE_ATTESTATION_VERIFY},
+};
+
+void set_int_field_value(JNIEnv *env, jclass class_mirror, jobject obj, const 
char *field_name, jint value) {
+    jfieldID field_id = (*env)->GetFieldID(env, class_mirror, field_name, "I");
+    (*env)->SetIntField(env, obj, field_id, value);
+}
+
+verify_result_wrapper ecdsa_quote_verification_qvl(const uint8_t* quote, 
uint32_t length) {
+    verify_result_wrapper result;
+    result.status = QUOTE_VERIFICATION_STATUS_SUCCESS;
+    result.version_check = QUOTE_VERIFICATION_VERSION_CHECK_SUCCESS;
+    result.verify_flag = QUOTE_VERIFICATION_SUCCESS;
+
+    quote3_error_t dcap_ret = SGX_QL_ERROR_UNEXPECTED;
+    uint32_t supplemental_data_size = 0;
+    uint8_t *p_supplemental_data = NULL;
+    time_t current_time = 0;
+    uint32_t collateral_expiration_status = 1;
+    sgx_ql_qv_result_t quote_verification_result = 
SGX_QL_QV_RESULT_UNSPECIFIED;
+
+    // Step one, get supplemental_data_size.
+    dcap_ret = 
sgx_qv_get_quote_supplemental_data_size(&supplemental_data_size);
+    if (dcap_ret != SGX_QL_SUCCESS) {
+        // printf("JavaEnclave Remote Attestation Error: 
sgx_qv_get_quote_supplemental_data_size failed: 0x%04x\n", dcap_ret);
+        result.status = QUOTE_VERIFICATION_STATUS_GET_DATA_SIZE_FAILED;
+        return result;
+    }
+    if (supplemental_data_size != sizeof(sgx_ql_qv_supplemental_t)) {
+        // printf("JavaEnclave Remote Attestation Warning: 
sgx_qv_get_quote_supplemental_data_size returned size is not same with header 
definition in SGX SDK, please make sure you are using same version of SGX SDK 
and DCAP QVL.\n");
+        result.version_check = QUOTE_VERIFICATION_VERSION_CHECK_FAILED;
+        return result;
+    }
+
+    p_supplemental_data = (uint8_t*)malloc(supplemental_data_size);
+    if (p_supplemental_data != NULL) {
+        memset(p_supplemental_data, 0, sizeof(supplemental_data_size));
+    } else {
+        result.status = QUOTE_VERIFICATION_STATUS_MEMORY_MALLOC_FAILED;
+        return result;
+    }
+
+    current_time = time(NULL);
+    dcap_ret = sgx_qv_verify_quote(
+        quote, length, NULL,
+        current_time, &collateral_expiration_status,
+        &quote_verification_result, NULL,
+        supplemental_data_size, p_supplemental_data);
+
+    free(p_supplemental_data);
+
+    if (dcap_ret != SGX_QL_SUCCESS) {
+        result.status = QUOTE_VERIFICATION_STATUS_QUOTE_VERIFY_FAILED;
+        // printf("JavaEnclave Remote Attestation Error: sgx_qv_verify_quote 
failed: 0x%04x\n", dcap_ret);
+        return result;
+    }
+
+    switch (quote_verification_result) {
+        case SGX_QL_QV_RESULT_OK:
+            if (collateral_expiration_status == 0) {
+                // Verification completed successfully.
+                result.verify_flag = QUOTE_VERIFICATION_SUCCESS;
+            } else {
+                // Verification completed, but collateral is out of date based 
on 'expiration_check_date' you provided.
+                result.verify_flag = QUOTE_VERIFICATION_OUT_OF_DATA;
+            }
+            break;
+        case SGX_QL_QV_RESULT_CONFIG_NEEDED:
+        case SGX_QL_QV_RESULT_OUT_OF_DATE:
+        case SGX_QL_QV_RESULT_OUT_OF_DATE_CONFIG_NEEDED:
+        case SGX_QL_QV_RESULT_SW_HARDENING_NEEDED:
+        case SGX_QL_QV_RESULT_CONFIG_AND_SW_HARDENING_NEEDED:
+            // Verification completed with Non-terminal result, you could view 
value of quote_verification_result for more info.
+            result.verify_flag = QUOTE_VERIFICATION_NO_TERMINAL;
+            break;
+        case SGX_QL_QV_RESULT_INVALID_SIGNATURE:
+        case SGX_QL_QV_RESULT_REVOKED:
+        case SGX_QL_QV_RESULT_UNSPECIFIED:
+        default:
+            // Verification completed with Terminal result, you could view 
value of quote_verification_result for more info.
+            result.verify_flag = QUOTE_VERIFICATION_FAILED_WITH_TERMINAL;
+            break;
+    }
+    return result;
+}
+
+JNIEXPORT void JNICALL 
Java_com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify_registerNatives(JNIEnv
 *env, jclass cls) {
+    (*env)->RegisterNatives(env, cls, sgx_remote_attestation_verify_methods, 
sizeof(sgx_remote_attestation_verify_methods)/sizeof(sgx_remote_attestation_verify_methods[0]));
+}
+
+JNIEXPORT jint JNICALL
+JavaEnclave_SGX_ENCLAVE_REMOTE_ATTESTATION_VERIFY(JNIEnv *env, jclass mirror, 
jbyteArray quote, jobject jResult) {
+    jbyte *quote_copy = (*env)->GetByteArrayElements(env, quote, NULL);
+    int quote_length = (*env)->GetArrayLength(env, quote);
+    verify_result_wrapper result = ecdsa_quote_verification_qvl(quote_copy, 
quote_length);
+    (*env)->ReleaseByteArrayElements(env, quote, quote_copy, 0);
+
+    jclass j_result_class = (*env)->GetObjectClass(env, jResult);
+    set_int_field_value(env, j_result_class, jResult, "status", 
(jint)result.status);
+    set_int_field_value(env, j_result_class, jResult, "versionCheck", 
(jint)result.version_check);
+    set_int_field_value(env, j_result_class, jResult, "verifyFlag", 
(jint)result.verify_flag);
+
+    return 0;
+}
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/jni_remote_attestation_verify.h
 
b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/jni_remote_attestation_verify.h
new file mode 100644
index 0000000..a387909
--- /dev/null
+++ 
b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/jni_remote_attestation_verify.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class 
com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sgx_urts.h"
+#include "sgx_ql_quote.h"
+#include "sgx_dcap_quoteverify.h"
+
+#ifndef 
_Included_com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify
+#define 
_Included_com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SGX_ENCLAVE_REMOTE_ATTESTATION_VERIFY_SIGNATURE  
"([BLcom/alibaba/confidentialcomputing/host/RemoteAttestationVerifyResult;)I"
+
+typedef struct {
+    int status;
+    int version_check;
+    int verify_flag;
+} verify_result_wrapper;
+
+/*
+ * Class:     com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify
+ * Method:    registerNatives
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL 
Java_com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify_registerNatives
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_alibaba_confidentialcomputing_host_SGXRemoteAttestationVerify
+ * Method:    nativeVerifyAttestationReport
+ * Signature: 
([BLcom/alibaba/confidentialcomputing/host/RemoteAttestationVerifyResult;)I
+ */
+JNIEXPORT jint JNICALL JavaEnclave_SGX_ENCLAVE_REMOTE_ATTESTATION_VERIFY
+  (JNIEnv *, jclass, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c 
b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c
index 88be3a0..32c189b 100644
--- a/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c
+++ b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c
@@ -18,9 +18,9 @@ typedef int (*mock_enclave_stub)(graal_isolate_t*, 
enc_data_t*, enc_data_t*, cal
 static JNINativeMethod mock_in_svm_methods[] = {
     {"nativeCreateEnclave",       "(Ljava/lang/String;)I",           (void 
*)&JavaEnclave_MockSVMNativeCreateEnclave},
     {"nativeSvmAttachIsolate",    "(J)I",                            (void 
*)&JavaEnclave_MockSVMNativeSvmAttachIsolate},
-    {"nativeLoadService",         MOCK_IN_SVM_NATIVE_CALL_SIGNATURE, (void 
*)&JavaEnclave_MockSVMNativeLoadService},
-    {"nativeInvokeMethod",        MOCK_IN_SVM_NATIVE_CALL_SIGNATURE, (void 
*)&JavaEnclave_MockSVMNativeInvokeMethod},
-    {"nativeUnloadService",       MOCK_IN_SVM_NATIVE_CALL_SIGNATURE, (void 
*)&JavaEnclave_MockSVMNativeUnloadService},
+    {"nativeLoadService",         "(JJ[B)[B",                        (void 
*)&JavaEnclave_MockSVMNativeLoadService},
+    {"nativeInvokeMethod",        "(JJ[B)[B",                        (void 
*)&JavaEnclave_MockSVMNativeInvokeMethod},
+    {"nativeUnloadService",       "(JJ[B)[B",                        (void 
*)&JavaEnclave_MockSVMNativeUnloadService},
     {"nativeSvmDetachIsolate",    "(JJ)I",                           (void 
*)&JavaEnclave_MockSVMNativeSvmDetachIsolate},
     {"nativeDestroyEnclave",      "(J)I",                            (void 
*)&JavaEnclave_MockSVMNativeDestroyEnclave},
 };
@@ -46,14 +46,7 @@ char* memcpy_char_pointer(char* src, int len) {
     return (char*)ptr;
 }
 
-jobject build_invocation_result(JNIEnv *env, jint ret, jbyteArray array) {
-    // build jni return object InnerNativeInvocationResult.
-    jclass invocation_result_clazz = (*env)->FindClass(env, 
MOCK_IN_SVM_RETURN_OBJECT_SIGNATURE);
-    jmethodID id = (*env)->GetMethodID(env, invocation_result_clazz, "<init>", 
"(I[B)V");
-    return (*env)->NewObject(env, invocation_result_clazz, id, (jint)ret, 
array);
-}
-
-jobject mock_enclave_calling_entry(JNIEnv *env, jlong isolate_handler, 
jbyteArray payload, mock_enclave_stub stub) {
+enclave_calling_stub_result mock_enclave_calling_entry(JNIEnv *env, jlong 
isolate_handler, jbyteArray payload, mock_enclave_stub stub) {
     jbyte *payload_copy = (*env)->GetByteArrayElements(env, payload, NULL);
     int payload_copy_length = (*env)->GetArrayLength(env, payload);
 
@@ -64,14 +57,25 @@ jobject mock_enclave_calling_entry(JNIEnv *env, jlong 
isolate_handler, jbyteArra
     output.data = NULL;
     output.data_len = 0x0;
 
+    jbyteArray invocation_result_array;
+    enclave_calling_stub_result result_wrapper;
+    result_wrapper.ret = 0;
+    result_wrapper.result = invocation_result_array;
+
     callbacks_t callback_methods;
     callback_methods.memcpy_char_pointer = &memcpy_char_pointer;
     callback_methods.exception_handler = NULL;
     callback_methods.get_random_number = NULL;
-    int ret = stub((graal_isolate_t*)isolate_handler, &input, &output, 
&callback_methods);
+
+    result_wrapper.ret = stub((graal_isolate_t*)isolate_handler, &input, 
&output, &callback_methods);
+    if (result_wrapper.ret != 0) {
+        (*env)->ReleaseByteArrayElements(env, payload, payload_copy, 0);
+        free(output.data);
+        return result_wrapper;
+    }
 
     // create a byte array.
-    jbyteArray invocation_result_array = (*env)->NewByteArray(env, 
output.data_len);
+    invocation_result_array = (*env)->NewByteArray(env, output.data_len);
     jbyte *invocation_result_array_ptr = (*env)->GetByteArrayElements(env, 
invocation_result_array, NULL);
     memcpy(invocation_result_array_ptr, output.data, output.data_len);
 
@@ -81,7 +85,8 @@ jobject mock_enclave_calling_entry(JNIEnv *env, jlong 
isolate_handler, jbyteArra
     // free buffer malloc in native image by callback mechanism.
     free(output.data);
 
-    return build_invocation_result(env, ret, invocation_result_array);
+    result_wrapper.result = invocation_result_array;
+    return result_wrapper;
 }
 
 JNIEXPORT jint JNICALL
@@ -90,29 +95,25 @@ JavaEnclave_MockSVMNativeCreateEnclave(JNIEnv *env, jobject 
obj, jstring path) {
     void *enclave_handler = dlopen(path_str , RTLD_LOCAL | RTLD_LAZY);
     (*env)->ReleaseStringUTFChars(env, path, path_str);
     if (enclave_handler == 0x0) {
-        fprintf(stderr, "mock in svm dlopen error:%s\n", dlerror());
-        return -1;
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "mock in svm dlopen 
error.")
     }
     // find load service symbol.
     mock_in_svm_load_service_symbol = dlsym((void *)enclave_handler, 
"java_loadservice_invoke");
     if (!mock_in_svm_load_service_symbol) {
-        fprintf(stderr, "java_loadservice_invoke error:%s\n", dlerror());
         dlclose(enclave_handler);
-        return -1;
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, 
"java_loadservice_invoke error.")
     }
     // find invoke service symbol.
     mock_in_svm_invoke_service_symbol = dlsym((void *)enclave_handler, 
"java_enclave_invoke");
     if (!mock_in_svm_invoke_service_symbol) {
-        fprintf(stderr, "mock_in_svm_invoke_service_symbol error:%s\n", 
dlerror());
         dlclose(enclave_handler);
-        return -1;
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, 
"mock_in_svm_invoke_service_symbol error.")
     }
     // find unload service symbol.
     mock_in_svm_unload_service_symbol = dlsym((void *)enclave_handler, 
"java_unloadservice_invoke");
     if (!mock_in_svm_unload_service_symbol) {
-        fprintf(stderr, "mock_in_svm_unload_service_symbol error:%s\n", 
dlerror());
         dlclose(enclave_handler);
-        return -1;
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, 
"mock_in_svm_unload_service_symbol error.")
     }
     // set enclave_handler back to MockInSvmEnclave.enclaveSvmSdkHandle field.
     jclass class_enclave = (*env)->GetObjectClass(env, obj);
@@ -127,39 +128,48 @@ JavaEnclave_MockSVMNativeSvmAttachIsolate(JNIEnv *env, 
jobject obj, jlong enclav
     graal_isolatethread_t* isolate_thread_t;
 
     int (*graal_create_isolate)(graal_create_isolate_params_t* params, 
graal_isolate_t** isolate, graal_isolatethread_t** thread);
-    graal_create_isolate = (int (*)(graal_create_isolate_params_t*, 
graal_isolate_t**, graal_isolatethread_t**))
-    dlsym((void *)enclave_handler, "graal_create_isolate");
+    graal_create_isolate = (int (*)(graal_create_isolate_params_t*, 
graal_isolate_t**, graal_isolatethread_t**)) dlsym((void *)enclave_handler, 
"graal_create_isolate");
     if (!graal_create_isolate) {
-        fprintf(stderr, "dlsym error:%s\n", dlerror());
-        return -1;
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create isolate dlsym 
error.")
     }
 
-    int ret = graal_create_isolate(NULL, &isolate_t, &isolate_thread_t);
-    if (ret != 0) {
-        fprintf(stderr, "graal_create_isolate create error:%s\n", dlerror());
-        return ret;
+    if (graal_create_isolate(NULL, &isolate_t, &isolate_thread_t) != 0) {
+        // fprintf(stderr, "graal_create_isolate create error:%s\n", 
dlerror());
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "graal_create_isolate 
create error.")
     }
 
     // set isolate_t and isolate_thread_t back to 
MockInSvmEnclave.isolateHandle and MockInSvmEnclave.isolateThreadHandle
     jclass class_enclave = (*env)->GetObjectClass(env, obj);
     set_long_field_value(env, class_enclave, obj, "isolateHandle", 
(jlong)isolate_t);
     set_long_field_value(env, class_enclave, obj, "isolateThreadHandle", 
(jlong)isolate_thread_t);
-    return ret;
+    return 0;
 }
 
 JNIEXPORT jobject JNICALL
 JavaEnclave_MockSVMNativeLoadService(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_handler, jbyteArray load_service_payload) {
-    return mock_enclave_calling_entry(env, isolate_handler, 
load_service_payload, (mock_enclave_stub) mock_in_svm_load_service_symbol);
+    enclave_calling_stub_result result_wrapper =  
mock_enclave_calling_entry(env, isolate_handler, load_service_payload, 
(mock_enclave_stub) mock_in_svm_load_service_symbol);
+    if (result_wrapper.ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_SERVICE_LOADING_EXCEPTION, "tee sdk 
service loading native call failed.")
+    }
+    return result_wrapper.result;
 }
 
 JNIEXPORT jobject JNICALL
 JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_handler, jbyteArray invoke_payload) {
-    return mock_enclave_calling_entry(env, isolate_handler, invoke_payload, 
(mock_enclave_stub) mock_in_svm_invoke_service_symbol);
+    enclave_calling_stub_result result_wrapper = 
mock_enclave_calling_entry(env, isolate_handler, invoke_payload, 
(mock_enclave_stub) mock_in_svm_invoke_service_symbol);
+    if (result_wrapper.ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_SERVICE_INVOKING_EXCEPTION, "tee sdk 
service method invoking native call failed.")
+    }
+    return result_wrapper.result;
 }
 
 JNIEXPORT jobject JNICALL
 JavaEnclave_MockSVMNativeUnloadService(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_handler, jbyteArray unload_service_payload) {
-    return mock_enclave_calling_entry(env, isolate_handler, 
unload_service_payload, (mock_enclave_stub) mock_in_svm_unload_service_symbol);
+    enclave_calling_stub_result result_wrapper = 
mock_enclave_calling_entry(env, isolate_handler, unload_service_payload, 
(mock_enclave_stub) mock_in_svm_unload_service_symbol);
+    if (result_wrapper.ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_SERVICE_UNLOADING_EXCEPTION, "tee sdk 
service unloading native call failed.")
+    }
+    return result_wrapper.result;
 }
 
 JNIEXPORT jint JNICALL
@@ -168,13 +178,18 @@ JavaEnclave_MockSVMNativeSvmDetachIsolate(JNIEnv *env, 
jobject obj, jlong enclav
     graal_detach_all_threads_and_tear_down_isolate =
     (int (*)(graal_isolatethread_t*)) dlsym((void *)enclave_handler, 
"graal_detach_all_threads_and_tear_down_isolate");
     if (!graal_detach_all_threads_and_tear_down_isolate) {
-        fprintf(stderr, "graal_detach_all_threads_and_tear_down_isolate 
error:%s\n", dlerror());
-        return -1;
+        THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, 
"graal_detach_all_threads_and_tear_down_isolate dlsym error.")
+    }
+    if (0x0 != 
graal_detach_all_threads_and_tear_down_isolate((graal_isolatethread_t*)isolate_thread_handler))
 {
+        THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, 
"graal_detach_all_threads_and_tear_down_isolate error.")
     }
-    return 
(jint)graal_detach_all_threads_and_tear_down_isolate((graal_isolatethread_t*)isolate_thread_handler);
+    return 0;
 }
 
 JNIEXPORT jint JNICALL
 JavaEnclave_MockSVMNativeDestroyEnclave(JNIEnv *env, jobject obj, jlong 
enclave_handler) {
-    return dlclose((void *)enclave_handler);
+    if(0x0 != dlclose((void *)enclave_handler)) {
+        THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "dlclose failed.")
+    }
+    return 0;
 }
diff --git 
a/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h 
b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h
index bbcedf1..53db1a2 100644
--- a/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h
+++ b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h
@@ -3,8 +3,32 @@
 #ifndef _Included_jni_mock_in_svm
 #define _Included_jni_mock_in_svm
 
-#define MOCK_IN_SVM_NATIVE_CALL_SIGNATURE   
"(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;"
-#define MOCK_IN_SVM_RETURN_OBJECT_SIGNATURE 
"com/alibaba/confidentialcomputing/host/InnerNativeInvocationResult"
+typedef struct {
+    int        ret;
+    jbyteArray result;
+} enclave_calling_stub_result;
+
+#define REMOTE_ATTESTATION_CLASS_NAME                
"com/alibaba/confidentialcomputing/host/exception/RemoteAttestationException"
+#define ENCLAVE_CREATING_EXCEPTION                   
"com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException"
+#define ENCLAVE_DESTROYING_EXCEPTION                 
"com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException"
+#define ENCLAVE_SERVICE_LOADING_EXCEPTION            
"com/alibaba/confidentialcomputing/host/exception/ServicesLoadingException"
+#define ENCLAVE_SERVICE_UNLOADING_EXCEPTION          
"com/alibaba/confidentialcomputing/host/exception/ServicesUnloadingException"
+#define ENCLAVE_SERVICE_INVOKING_EXCEPTION           
"com/alibaba/confidentialcomputing/host/exception/EnclaveMethodInvokingException"
+
+#define MOCK_IN_SVM_NATIVE_CALL_SIGNATURE            "(JJ[B)[B"
+
+#define THROW_EXCEPTION(env, exception, info)                                  
\
+{                                                                              
\
+    jclass ra_class = (*env)->FindClass(env, exception);                       
\
+    if (ra_class == NULL) {                                                    
\
+        printf("JavaEnclave Error:  ");                                        
\
+        printf(exception);                                                     
\
+        printf(" class loading failed.\n");                                    
\
+        return;                                                                
\
+    }                                                                          
\
+    (*env)->ThrowNew(env, ra_class, info);                                     
\
+    return;                                                                    
\
+}
 
 #ifdef __cplusplus
 extern "C" {
@@ -28,23 +52,23 @@ JNIEXPORT jint JNICALL 
JavaEnclave_MockSVMNativeSvmAttachIsolate(JNIEnv *, jobje
 /*
  * Class:     JavaEnclave_MockSVMNativeLoadService
  * Method:    nativeLoadService
- * Signature: 
(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;
+ * Signature: (JJ[B)[B
  */
-JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeLoadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
+JNIEXPORT jbyteArray JNICALL JavaEnclave_MockSVMNativeLoadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
 
 /*
  * Class:     JavaEnclave_MockSVMNativeInvokeMethod
  * Method:    nativeInvokeMethod
- * Signature: 
(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;
+ * Signature: (JJ[B)[B
  */
-JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
+JNIEXPORT jbyteArray JNICALL JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
 
 /*
  * Class:     JavaEnclave_MockSVMNativeUnloadService
  * Method:    nativeUnloadService
- * Signature: 
(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;
+ * Signature: (JJ[B)[B
  */
-JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeUnloadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
+JNIEXPORT jbyteArray JNICALL JavaEnclave_MockSVMNativeUnloadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
 
 /*
  * Class:     JavaEnclave_MockSVMNativeSvmDetachIsolate
diff --git a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/Makefile 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/Makefile
index 0620ffd..7bc2590 100644
--- a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/Makefile
+++ b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/Makefile
@@ -8,9 +8,10 @@ include 
$(NATIVE_BASE_DIR)/config/platform/tee_sdk_svm/jni/config.mk
 all: build
 
 build: jni.o
-       $(CC) edge_routines/ocall_svm.o edge_routines/tee_sdk_enclave_u.o 
jni/jni_tee_sdk_svm.o \
-       $(TS_HOST_CFLAGS) $(TS_HOST_LDFLAGS) -fPIC -shared -o 
$(BIN)/platform/tee_sdk_svm/jni/lib_jni_tee_sdk_svm.so
-       
+       $(CC) edge_routines/ocall_svm.o edge_routines/ocall_attestation.o 
edge_routines/tee_sdk_enclave_u.o \
+       jni/generate_attestation_report.o jni/jni_tee_sdk_svm.o 
$(TS_HOST_CFLAGS) $(TS_HOST_LDFLAGS) \
+       -fPIC -shared -o $(BIN)/platform/tee_sdk_svm/jni/lib_jni_tee_sdk_svm.so
+
        rm -rf edge_routines/*.o edge_routines/tee_sdk_enclave_u.* jni/*.o
 
 edge_routines.o:
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/Makefile 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/Makefile
index 26b7183..7fc3254 100644
--- a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/Makefile
+++ b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/Makefile
@@ -12,6 +12,9 @@ build:
        --search-path $(TEE_SDK_PATH)/include
 
        $(CC) -g -c -fPIC $(TS_HOST_INCDIR) $(TS_HOST_CFLAGS) -fPIC ocall_svm.c
+
+       $(CC) -g -c -fPIC $(TS_HOST_INCDIR) $(TS_HOST_CFLAGS) -fPIC 
ocall_attestation.c
+
        $(CC) -g -c -fPIC $(TS_HOST_INCDIR) $(TS_HOST_CFLAGS) -fPIC 
tee_sdk_enclave_u.c
 
 clean:
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/ocall_attestation.c
 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/ocall_attestation.c
new file mode 100644
index 0000000..7d741dd
--- /dev/null
+++ 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/ocall_attestation.c
@@ -0,0 +1,6 @@
+#include "ocall_attestation.h"
+
+// ocall_get_target_info get target info from host.
+quote3_error_t ocall_get_target_info(sgx_target_info_t *qe_target_info) {
+    return sgx_qe_get_target_info(qe_target_info);
+}
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/ocall_attestation.h
 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/ocall_attestation.h
new file mode 100644
index 0000000..2051781
--- /dev/null
+++ 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/edge_routines/ocall_attestation.h
@@ -0,0 +1,22 @@
+#ifndef _OCALL_ATTESTATION_H_
+#define _OCALL_ATTESTATION_H_
+
+#include <stdio.h>
+
+#include "sgx_urts.h"
+#include "sgx_report.h"
+#include "sgx_dcap_ql_wrapper.h"
+#include "sgx_pce.h"
+#include "sgx_error.h"
+#include "sgx_quote_3.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+    quote3_error_t ocall_get_target_info(sgx_target_info_t *qe_target_info);
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_OCALL_ATTESTATION_H_ */
\ No newline at end of file
diff --git a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/Makefile 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/Makefile
index e635614..9a212ab 100644
--- a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/Makefile
+++ b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/Makefile
@@ -11,5 +11,8 @@ build:
        $(CC) -g -c -Wno-unused-parameter -fPIC $(TS_HOST_CFLAGS) 
$(TS_HOST_INCDIR) -I./../edge_routines -I$(JAVA_HOME)/lib -I$(INCLUDE) 
-I$(JAVA_HOME)/include \
        -I$(JAVA_HOME)/include/$(shell uname -s | tr A-Z a-z) jni_tee_sdk_svm.c
 
+       $(CC) -g -c -Wno-unused-parameter -fPIC $(TS_HOST_CFLAGS) 
$(TS_HOST_INCDIR) -I$(JAVA_HOME)/lib -I$(INCLUDE) -I$(JAVA_HOME)/include \
+       -I$(JAVA_HOME)/include/$(shell uname -s | tr A-Z a-z) 
generate_attestation_report.c
+
 clean:
        rm -rf *.o
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/generate_attestation_report.c
 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/generate_attestation_report.c
new file mode 100644
index 0000000..715c68e
--- /dev/null
+++ 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/generate_attestation_report.c
@@ -0,0 +1,69 @@
+#include "generate_attestation_report.h"
+
+// use_aesm_qe_service determines sgx aesm remote attestation service or local 
qe service.
+bool use_aesm_qe_service() {
+    bool flag = false;
+    // If environment "SGX_AESM_ADDR" is set, remote qe will be adapted.
+    char *sgx_aesm_address = getenv(SGX_AESM_ADR);
+    if(sgx_aesm_address) {
+        flag = true;
+    }
+    return flag;
+}
+
+// load_qe_signed_package loads all .signed packages which qe will use.
+quote3_error_t load_qe_signed_package() {
+    quote3_error_t qe3_ret = SGX_QL_SUCCESS;
+    if(!use_aesm_qe_service()) {
+        // Set enclave load policy.
+        qe3_ret = sgx_qe_set_enclave_load_policy(SGX_QL_PERSISTENT);
+        if(SGX_QL_SUCCESS != qe3_ret) {
+            // printf("Error in set enclave load policy: 0x%04x\n", qe3_ret);
+            return qe3_ret;
+        }
+
+        // Check it is Ubuntu-like OS system or RedHat-like OS system.
+        char* lib_sgx_pce_path = NULL;
+        char* lib_sgx_qe3_path = NULL;
+        char* lib_dcap_quote_prov = NULL;
+        const char* folder_ubuntu = UBUNTU_LIB_PATH;
+        const char* folder_rhel = RHEL_LIB_PATH;
+        struct stat sb;
+        if (stat(folder_ubuntu, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+            // Ubuntu-like OS system.
+            lib_sgx_pce_path = UBUNTU_LIB_SGX_PCE_PATH;
+            lib_sgx_qe3_path = UBUNTU_LIB_SGX_QE3_PATH;
+            lib_dcap_quote_prov = UBUNTU_LIB_DCAP_QUOTE_PROV;
+        } else if (stat(folder_rhel, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+            // RedHat-like OS system.
+            lib_sgx_pce_path = RHEL_LIB_SGX_PCE_PATH;
+            lib_sgx_qe3_path = RHEL_LIB_SGX_QE3_PATH;
+            lib_dcap_quote_prov = RHEL_LIB_DCAP_QUOTE_PROV;
+        } else {
+            // printf("Unsupported OS Platform Type.\n");
+            return SGX_QL_SERVICE_UNAVAILABLE;
+        }
+
+        if (SGX_QL_SUCCESS != (qe3_ret = sgx_ql_set_path(SGX_QL_PCE_PATH, 
lib_sgx_pce_path)) ||
+            SGX_QL_SUCCESS != (qe3_ret = sgx_ql_set_path(SGX_QL_QE3_PATH, 
lib_sgx_qe3_path))) {
+            // printf("Error in set PCE/QE3 directory.\n");
+            return qe3_ret;
+        }
+        if (SGX_QL_SUCCESS != (qe3_ret = sgx_ql_set_path(SGX_QL_QPL_PATH, 
lib_dcap_quote_prov))) {
+            // printf("Warning: Cannot set QPL directory, you may get ECDSA 
quote with `Encrypted PPID` cert type.\n");
+            return qe3_ret;
+        }
+    }
+    return qe3_ret;
+}
+
+// unload_qe_signed_package unloads .signed packages load_qe_signed_package 
loaded.
+quote3_error_t unload_qe_signed_package() {
+    quote3_error_t qe3_ret = SGX_QL_SUCCESS;
+    if(!use_aesm_qe_service()) {
+        if(SGX_QL_SUCCESS != (qe3_ret = sgx_qe_cleanup_by_policy())) {
+            // printf("Error in cleanup enclave load policy: 0x%04x\n", 
qe3_ret);
+        }
+    }
+    return qe3_ret;
+}
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/generate_attestation_report.h
 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/generate_attestation_report.h
new file mode 100644
index 0000000..a36724e
--- /dev/null
+++ 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/generate_attestation_report.h
@@ -0,0 +1,38 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include <graal_isolate.h>
+
+#include "sgx_urts.h"
+#include "sgx_report.h"
+#include "sgx_dcap_ql_wrapper.h"
+#include "sgx_pce.h"
+#include "sgx_error.h"
+#include "sgx_quote_3.h"
+
+#define SGX_AESM_ADR                 "SGX_AESM_ADDR"
+#define UBUNTU_LIB_PATH              "/usr/lib/x86_64-linux-gnu"
+#define RHEL_LIB_PATH                "/usr/lib64"
+#define UBUNTU_LIB_SGX_PCE_PATH      
"/usr/lib/x86_64-linux-gnu/libsgx_pce.signed.so"
+#define UBUNTU_LIB_SGX_QE3_PATH      
"/usr/lib/x86_64-linux-gnu/libsgx_qe3.signed.so"
+#define UBUNTU_LIB_DCAP_QUOTE_PROV   
"/usr/lib/x86_64-linux-gnu/libdcap_quoteprov.so.1"
+#define RHEL_LIB_SGX_PCE_PATH        "/usr/lib64/libsgx_pce.signed.so"
+#define RHEL_LIB_SGX_QE3_PATH        "/usr/lib64/libsgx_qe3.signed.so"
+#define RHEL_LIB_DCAP_QUOTE_PROV     "/usr/lib64/libdcap_quoteprov.so.1"
+
+#ifndef _Included_jni_generate_attestation_report
+#define _Included_jni_generate_attestation_report
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+quote3_error_t load_qe_signed_package();
+quote3_error_t unload_qe_signed_package();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.c 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.c
index 7142959..6a1870f 100644
--- a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.c
+++ b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.c
@@ -16,16 +16,15 @@
 #include "tee_sdk_enclave_u.h"
 #include "jni_tee_sdk_svm.h"
 
-typedef void (*enclave_calling_stub)(jlong, int*, graal_isolate_t*, void*, 
size_t, void*, size_t*);
-
 static JNINativeMethod tee_sdk_svm_methods[] = {
-    {"nativeCreateEnclave",       "(ILjava/lang/String;)I",          (void 
*)&JavaEnclave_TeeSDKSVMNativeCreateEnclave},
-    {"nativeSvmAttachIsolate",    "(J)I",                            (void 
*)&JavaEnclave_TeeSDKSVMNativeSvmAttachIsolate},
-    {"nativeLoadService",         TEE_SDK_SVM_NATIVE_CALL_SIGNATURE, (void 
*)&JavaEnclave_TeeSDKSVMNativeLoadService},
-    {"nativeInvokeMethod",        TEE_SDK_SVM_NATIVE_CALL_SIGNATURE, (void 
*)&JavaEnclave_TeeSDKSVMNativeInvokeMethod},
-    {"nativeUnloadService",       TEE_SDK_SVM_NATIVE_CALL_SIGNATURE, (void 
*)&JavaEnclave_TeeSDKSVMNativeUnloadService},
-    {"nativeSvmDetachIsolate",    "(JJ)I",                           (void 
*)&JavaEnclave_TeeSDKSVMNativeSvmDetachIsolate},
-    {"nativeDestroyEnclave",      "(J)I",                            (void 
*)&JavaEnclave_TeeSDKSVMNativeDestroyEnclave},
+    {"nativeCreateEnclave",             "(ILjava/lang/String;)I",              
      (void *)&JavaEnclave_TeeSDKSVMNativeCreateEnclave},
+    {"nativeSvmAttachIsolate",          "(J)I",                                
      (void *)&JavaEnclave_TeeSDKSVMNativeSvmAttachIsolate},
+    {"nativeLoadService",               TEE_SDK_SVM_NATIVE_CALL_SIGNATURE,     
      (void *)&JavaEnclave_TeeSDKSVMNativeLoadService},
+    {"nativeInvokeMethod",              TEE_SDK_SVM_NATIVE_CALL_SIGNATURE,     
      (void *)&JavaEnclave_TeeSDKSVMNativeInvokeMethod},
+    {"nativeUnloadService",             TEE_SDK_SVM_NATIVE_CALL_SIGNATURE,     
      (void *)&JavaEnclave_TeeSDKSVMNativeUnloadService},
+    {"nativeSvmDetachIsolate",          "(JJ)I",                               
      (void *)&JavaEnclave_TeeSDKSVMNativeSvmDetachIsolate},
+    {"nativeDestroyEnclave",            "(J)I",                                
      (void *)&JavaEnclave_TeeSDKSVMNativeDestroyEnclave},
+    {"nativeGenerateAttestationReport", 
TEE_SDK_REMOTE_ATTESTATION_REPORT_SIGNATURE, (void 
*)&JavaEnclave_TeeSDK_REMOTE_ATTESTATION_REPORT},
 };
 
 JNIEXPORT void JNICALL
@@ -38,14 +37,12 @@ void set_long_field_value(JNIEnv *env, jclass class_mirror, 
jobject obj, const c
     (*env)->SetLongField(env, obj, field_id, value);
 }
 
-jobject build_invocation_result(JNIEnv *env, jint ret, jbyteArray array) {
-    // build jni return object InnerNativeInvocationResult.
-    jclass invocation_result_clazz = (*env)->FindClass(env, 
TEE_SDK_SVM_RETURN_OBJECT_SIGNATURE);
-    jmethodID id = (*env)->GetMethodID(env, invocation_result_clazz, "<init>", 
"(I[B)V");
-    return (*env)->NewObject(env, invocation_result_clazz, id, (jint)ret, 
array);
+void set_int_field_value(JNIEnv *env, jclass class_mirror, jobject obj, const 
char *field_name, jint value) {
+    jfieldID field_id = (*env)->GetFieldID(env, class_mirror, field_name, "I");
+    (*env)->SetIntField(env, obj, field_id, value);
 }
 
-jobject enclave_calling_entry(JNIEnv *env, jlong enclave_handler, jlong 
isolate_handler, jbyteArray payload, enclave_calling_stub stub) {
+enclave_calling_stub_result enclave_calling_entry(JNIEnv *env, jlong 
enclave_handler, jlong isolate_handler, jbyteArray payload, 
enclave_calling_stub stub) {
     jbyte *payload_copy = (*env)->GetByteArrayElements(env, payload, NULL);
     int payload_copy_length = (*env)->GetArrayLength(env, payload);
 
@@ -56,11 +53,21 @@ jobject enclave_calling_entry(JNIEnv *env, jlong 
enclave_handler, jlong isolate_
     output.data = NULL;
     output.data_len = 0x0;
 
-    int ret = 0x0;
-    stub(enclave_handler, &ret, (graal_isolate_t*)isolate_handler, 
(void*)(input.data), (size_t)(input.data_len), (void*)(&(output.data)), 
(size_t*)(&(output.data_len)));
+    jbyteArray invocation_result_array;
+    enclave_calling_stub_result result_wrapper;
+    result_wrapper.ret = 0;
+    result_wrapper.result = invocation_result_array;
+
+    stub(enclave_handler, &result_wrapper.ret, 
(graal_isolate_t*)isolate_handler, (void*)(input.data), 
(size_t)(input.data_len), (void*)(&(output.data)), 
(size_t*)(&(output.data_len)));
+    if (result_wrapper.ret != 0) {
+        (*env)->ReleaseByteArrayElements(env, payload, payload_copy, 0);
+        // free buffer malloc in native image by callback mechanism.
+        free(output.data);
+        return result_wrapper;
+    }
 
     // create a byte array.
-    jbyteArray invocation_result_array = (*env)->NewByteArray(env, 
output.data_len);
+    invocation_result_array = (*env)->NewByteArray(env, output.data_len);
     jbyte *invocation_result_array_ptr = (*env)->GetByteArrayElements(env, 
invocation_result_array, NULL);
     memcpy(invocation_result_array_ptr, output.data, (size_t)output.data_len);
 
@@ -70,7 +77,8 @@ jobject enclave_calling_entry(JNIEnv *env, jlong 
enclave_handler, jlong isolate_
     // free buffer malloc in native image by callback mechanism.
     free(output.data);
 
-    return build_invocation_result(env, ret, invocation_result_array);
+    result_wrapper.result = invocation_result_array;
+    return result_wrapper;
 }
 
 JNIEXPORT jint JNICALL
@@ -91,7 +99,7 @@ JavaEnclave_TeeSDKSVMNativeCreateEnclave(JNIEnv *env, jobject 
obj, jint mode, js
     (*env)->ReleaseStringUTFChars(env, path, path_str);
 
     if (ret != SGX_SUCCESS) {
-        return (int)ret;
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee sdk 
enclave by native calling failed.")
     }
 
     // set enclave_handler back to TeeSdkEnclave.enclaveHandle field.
@@ -108,6 +116,9 @@ JavaEnclave_TeeSDKSVMNativeSvmAttachIsolate(JNIEnv *env, 
jobject obj, jlong encl
     uint64_t isolateThread = 0;
     int ret = 0;
     enclave_svm_isolate_create((size_t)enclave_handler, &ret, (void 
*)(&isolate), (void *)(&isolateThread));
+    if (ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "attach native svm 
failed when creating an enclave.")
+    }
 
     jclass enclave_class = (*env)->GetObjectClass(env, obj);
     // set isolate back to isolateHandle field.
@@ -118,29 +129,126 @@ JavaEnclave_TeeSDKSVMNativeSvmAttachIsolate(JNIEnv *env, 
jobject obj, jlong encl
     return ret;
 }
 
-JNIEXPORT jobject JNICALL
+JNIEXPORT jbyteArray JNICALL
 JavaEnclave_TeeSDKSVMNativeLoadService(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_handler, jbyteArray load_service_payload) {
-    return enclave_calling_entry(env, enclave_handler, isolate_handler, 
load_service_payload, (enclave_calling_stub) load_enclave_svm_services);
+    enclave_calling_stub_result result_wrapper = enclave_calling_entry(env, 
enclave_handler, isolate_handler, load_service_payload, (enclave_calling_stub) 
load_enclave_svm_services);
+    if (result_wrapper.ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_SERVICE_LOADING_EXCEPTION, "tee sdk 
service loading native call failed.")
+    }
+    return result_wrapper.result;
 }
 
-JNIEXPORT jobject JNICALL
+JNIEXPORT jbyteArray JNICALL
 JavaEnclave_TeeSDKSVMNativeInvokeMethod(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_handler, jbyteArray invoke_service_payload) {
-    return enclave_calling_entry(env, enclave_handler, isolate_handler, 
invoke_service_payload, (enclave_calling_stub) invoke_enclave_svm_service);
+    enclave_calling_stub_result result_wrapper = enclave_calling_entry(env, 
enclave_handler, isolate_handler, invoke_service_payload, 
(enclave_calling_stub) invoke_enclave_svm_service);
+    if (result_wrapper.ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_SERVICE_INVOKING_EXCEPTION, "tee sdk 
service method invoking native call failed.")
+    }
+    return result_wrapper.result;
 }
 
-JNIEXPORT jobject JNICALL
+JNIEXPORT jbyteArray JNICALL
 JavaEnclave_TeeSDKSVMNativeUnloadService(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_handler, jbyteArray unload_service_payload) {
-    return enclave_calling_entry(env, enclave_handler, isolate_handler, 
unload_service_payload, (enclave_calling_stub) unload_enclave_svm_service);
+    enclave_calling_stub_result result_wrapper = enclave_calling_entry(env, 
enclave_handler, isolate_handler, unload_service_payload, 
(enclave_calling_stub) unload_enclave_svm_service);
+    if (result_wrapper.ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_SERVICE_UNLOADING_EXCEPTION, "tee sdk 
service unloading native call failed.")
+    }
+    return result_wrapper.result;
 }
 
 JNIEXPORT jint JNICALL
 JavaEnclave_TeeSDKSVMNativeSvmDetachIsolate(JNIEnv *env, jobject obj, jlong 
enclave_handler, jlong isolate_thread_handler) {
     int ret = 0x0;
     enclave_svm_isolate_destroy((sgx_enclave_id_t)enclave_handler, &ret, 
(uint64_t)isolate_thread_handler);
-    return ret;
+    if (ret != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "isolate destroy 
native call failed.")
+    }
+    return 0;
 }
 
 JNIEXPORT jint JNICALL
 JavaEnclave_TeeSDKSVMNativeDestroyEnclave(JNIEnv *env, jobject obj, jlong 
enclave_handler) {
-    return (jint)sgx_destroy_enclave((sgx_enclave_id_t)enclave_handler);
+    if ((jint)sgx_destroy_enclave((sgx_enclave_id_t)enclave_handler) != 0) {
+        THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "enclave destroy 
native call failed.")
+    }
+    return 0;
+}
+
+JNIEXPORT jobject JNICALL
+JavaEnclave_TeeSDK_REMOTE_ATTESTATION_REPORT(JNIEnv *env, jobject obj, jlong 
enclave_handler, jbyteArray data) {
+    int ret = 0;
+
+    quote3_error_t qe3_ret = SGX_QL_SUCCESS;
+    // Step one, load remote attestation related .signed files.
+    if (SGX_QL_SUCCESS != (qe3_ret = load_qe_signed_package())) {
+        THROW_EXCEPTION(env, REMOTE_ATTESTATION_CLASS_NAME, "load remote 
attestation related .signed files failed")
+    }
+
+    // Step two, generate target enclave's report info.
+    sgx_report_t ra_report;
+    jbyte *data_copy = (*env)->GetByteArrayElements(env, data, NULL);
+    int length = (*env)->GetArrayLength(env, data);
+    generate_remote_attestation_report(enclave_handler, &ret, (void 
*)data_copy, (size_t)length, &ra_report);
+    if (ret != 0) {
+        (*env)->ReleaseByteArrayElements(env, data, data_copy, 0);
+        THROW_EXCEPTION(env, REMOTE_ATTESTATION_CLASS_NAME, "generate target 
enclave's report info failed")
+    }
+
+    // Step three, get quote size.
+    uint32_t quote_size = 0;
+    qe3_ret = sgx_qe_get_quote_size(&quote_size);
+    if (SGX_QL_SUCCESS != qe3_ret) {
+        (*env)->ReleaseByteArrayElements(env, data, data_copy, 0);
+        THROW_EXCEPTION(env, REMOTE_ATTESTATION_CLASS_NAME, "get quote size 
failed")
+    }
+
+    // Step four, get quote data from target enclave's report.
+    // quote_buffer_ptr will store sgx_quote3_t struct data.
+    uint8_t* quote_buffer_ptr = NULL;
+    quote_buffer_ptr = (uint8_t*)malloc(quote_size);
+    if (NULL == quote_buffer_ptr) {
+        (*env)->ReleaseByteArrayElements(env, data, data_copy, 0);
+        THROW_EXCEPTION(env, REMOTE_ATTESTATION_CLASS_NAME, "get quote temp 
heap for target enclave's report failed")
+    }
+    memset(quote_buffer_ptr, 0, quote_size);
+
+    qe3_ret = sgx_qe_get_quote(&ra_report, quote_size, quote_buffer_ptr);
+    if (SGX_QL_SUCCESS != qe3_ret) {
+        if (NULL != quote_buffer_ptr) {
+            free(quote_buffer_ptr);
+        }
+        (*env)->ReleaseByteArrayElements(env, data, data_copy, 0);
+        THROW_EXCEPTION(env, REMOTE_ATTESTATION_CLASS_NAME ,"get quote data 
from target enclave's report failed")
+    }
+
+    // Step five, clear up loaded qe.
+    qe3_ret = unload_qe_signed_package();
+    if (SGX_QL_SUCCESS != qe3_ret) {
+        printf("JavaEnclave Warning: clear up loaded qe files failed");
+    }
+
+    // create a quote byte array.
+    jbyteArray quote_array = (*env)->NewByteArray(env, quote_size);
+    jbyte *quote_array_ptr = (*env)->GetByteArrayElements(env, quote_array, 
NULL);
+    memcpy(quote_array_ptr, quote_buffer_ptr, (size_t)quote_size);
+
+    // create mr enclave byte array.
+    jbyteArray mr_enclave = (*env)->NewByteArray(env, SGX_HASH_SIZE);
+    jbyte *mr_enclave_buf = (*env)->GetByteArrayElements(env, mr_enclave, 
NULL);
+    memcpy(mr_enclave_buf, ra_report.body.mr_enclave.m, SGX_HASH_SIZE);
+
+    // create mr signer byte array.
+    jbyteArray mr_signer = (*env)->NewByteArray(env, SGX_HASH_SIZE);
+    jbyte *mr_signer_buf = (*env)->GetByteArrayElements(env, mr_signer, NULL);
+    memcpy(mr_signer_buf, ra_report.body.mr_signer.m, SGX_HASH_SIZE);
+
+    (*env)->ReleaseByteArrayElements(env, data, data_copy, 0);
+    (*env)->ReleaseByteArrayElements(env, quote_array, quote_array_ptr, 0);
+    (*env)->ReleaseByteArrayElements(env, mr_enclave, mr_enclave_buf, 0);
+    (*env)->ReleaseByteArrayElements(env, mr_signer, mr_signer_buf, 0);
+    free(quote_buffer_ptr);
+
+    jclass tee_sdk_ra_report_clazz = (*env)->FindClass(env, 
TEE_SDK_REMOTE_ATTESTATION_REPORT_CLASS_NAME);
+    jmethodID construct = (*env)->GetMethodID(env, tee_sdk_ra_report_clazz, 
"<init>", "([B[B[B)V");
+    return (*env)->NewObject(env, tee_sdk_ra_report_clazz, construct, 
quote_array, mr_signer, mr_enclave);
 }
\ No newline at end of file
diff --git 
a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.h 
b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.h
index 7ac0650..561b448 100644
--- a/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.h
+++ b/sdk/host/src/main/native/cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.h
@@ -1,14 +1,45 @@
 #include <jni.h>
 
+#include "generate_attestation_report.h"
+
 #ifndef _Included_jni_tee_sdk_svm
 #define _Included_jni_tee_sdk_svm
 
-#define TEE_SDK_SVM_NATIVE_CALL_SIGNATURE   
"(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;"
-#define TEE_SDK_SVM_RETURN_OBJECT_SIGNATURE 
"com/alibaba/confidentialcomputing/host/InnerNativeInvocationResult"
+typedef void (*enclave_calling_stub)(jlong, int*, graal_isolate_t*, void*, 
size_t, void*, size_t*);
+
+typedef struct {
+    int        ret;
+    jbyteArray result;
+} enclave_calling_stub_result;
+
+#define REMOTE_ATTESTATION_CLASS_NAME                
"com/alibaba/confidentialcomputing/host/exception/RemoteAttestationException"
+#define ENCLAVE_CREATING_EXCEPTION                   
"com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException"
+#define ENCLAVE_DESTROYING_EXCEPTION                 
"com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException"
+#define ENCLAVE_SERVICE_LOADING_EXCEPTION            
"com/alibaba/confidentialcomputing/host/exception/ServicesLoadingException"
+#define ENCLAVE_SERVICE_UNLOADING_EXCEPTION          
"com/alibaba/confidentialcomputing/host/exception/ServicesUnloadingException"
+#define ENCLAVE_SERVICE_INVOKING_EXCEPTION           
"com/alibaba/confidentialcomputing/host/exception/EnclaveMethodInvokingException"
+
+#define TEE_SDK_SVM_NATIVE_CALL_SIGNATURE            "(JJ[B)[B"
+#define TEE_SDK_REMOTE_ATTESTATION_REPORT_SIGNATURE  
"(J[B)Lcom/alibaba/confidentialcomputing/host/TeeSdkAttestationReport;"
+#define TEE_SDK_REMOTE_ATTESTATION_REPORT_CLASS_NAME 
"com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport"
+
+#define THROW_EXCEPTION(env, exception, info)                                  
\
+{                                                                              
\
+    jclass ra_class = (*env)->FindClass(env, exception);                       
\
+    if (ra_class == NULL) {                                                    
\
+        printf("JavaEnclave Error:  ");                                        
\
+        printf(exception);                                                     
\
+        printf(" class loading failed.\n");                                    
\
+        return;                                                                
\
+    }                                                                          
\
+    (*env)->ThrowNew(env, ra_class, info);                                     
\
+    return;                                                                    
\
+}
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+
 JNIEXPORT void JNICALL 
Java_com_alibaba_confidentialcomputing_host_TeeSdkEnclave_registerNatives(JNIEnv
 *env, jclass cls);
 
 /*
@@ -28,23 +59,23 @@ JNIEXPORT jint JNICALL 
JavaEnclave_TeeSDKSVMNativeSvmAttachIsolate(JNIEnv *, job
 /*
  * Class:     com_alibaba_confidentialcomputing_host_TeeSdkEnclave
  * Method:    nativeLoadService
- * Signature: 
(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;
+ * Signature: (JJ[B)[B
  */
-JNIEXPORT jobject JNICALL JavaEnclave_TeeSDKSVMNativeLoadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
+JNIEXPORT jbyteArray JNICALL JavaEnclave_TeeSDKSVMNativeLoadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
 
 /*
  * Class:     com_alibaba_confidentialcomputing_host_TeeSdkEnclave
  * Method:    nativeInvokeMethod
- * Signature: 
(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;
+ * Signature: (JJ[B)[B
  */
-JNIEXPORT jobject JNICALL JavaEnclave_TeeSDKSVMNativeInvokeMethod(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
+JNIEXPORT jbyteArray JNICALL JavaEnclave_TeeSDKSVMNativeInvokeMethod(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
 
 /*
  * Class:     com_alibaba_confidentialcomputing_host_TeeSdkEnclave
  * Method:    nativeUnloadService
- * Signature: 
(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;
+ * Signature: (JJ[B)[B
  */
-JNIEXPORT jobject JNICALL JavaEnclave_TeeSDKSVMNativeUnloadService(JNIEnv *, 
jobject, jlong, jlong, jbyteArray);
+JNIEXPORT jbyteArray JNICALL JavaEnclave_TeeSDKSVMNativeUnloadService(JNIEnv 
*, jobject, jlong, jlong, jbyteArray);
 
 /*
  * Class:     com_alibaba_confidentialcomputing_host_TeeSdkEnclave
@@ -60,6 +91,13 @@ JNIEXPORT jint JNICALL 
JavaEnclave_TeeSDKSVMNativeSvmDetachIsolate(JNIEnv *, job
  */
 JNIEXPORT jint JNICALL JavaEnclave_TeeSDKSVMNativeDestroyEnclave(JNIEnv *, 
jobject, jlong);
 
+/*
+ * Class:     com_alibaba_confidentialcomputing_host_TeeSdkEnclave
+ * Method:    nativeGenerateAttestationReport
+ * Signature: 
(J[B)Lcom/alibaba/confidentialcomputing/host/TeeSdkAttestationReport;
+ */
+JNIEXPORT jobject JNICALL JavaEnclave_TeeSDK_REMOTE_ATTESTATION_REPORT(JNIEnv 
*, jobject, jlong, jbyteArray);
+
 #ifdef __cplusplus
 }
 #endif
diff --git 
a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java
 
b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java
index e655e46..90df27e 100644
--- 
a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java
+++ 
b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/MockTestEnclave.java
@@ -2,8 +2,7 @@ package com.alibaba.confidentialcomputing.host;
 
 import com.alibaba.confidentialcomputing.common.*;
 import 
com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException;
-import 
com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException;
-import 
com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
+import com.alibaba.confidentialcomputing.host.exception.*;
 
 import static org.junit.jupiter.api.Assertions.*;
 
@@ -65,7 +64,7 @@ class MockTestEnclave extends AbstractEnclave {
     }
 
     @Override
-    AttestationReport generateAttestationReport(byte[] userData) throws 
RemoteAttestationException {
+    AttestationReport generateAttestationReportNative(byte[] userData) throws 
RemoteAttestationException {
         throw new RemoteAttestationException("MockTestEnclave enclave doesn't 
support remote attestation generation.");
     }
 
@@ -74,7 +73,7 @@ class MockTestEnclave extends AbstractEnclave {
     }
 
     @Override
-    InnerNativeInvocationResult loadServiceNative(byte[] payload) {
+    byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
         List<ServiceHandler> handlers = new ArrayList<>();
         Throwable exception = null;
         EnclaveInvocationResult result;
@@ -97,14 +96,14 @@ class MockTestEnclave extends AbstractEnclave {
         }
 
         try {
-            return new InnerNativeInvocationResult(0, 
SerializationHelper.serialize(result));
+            return SerializationHelper.serialize(result);
         } catch (IOException e) {
-            return new InnerNativeInvocationResult(-1, null);
+            throw new ServicesLoadingException(e);
         }
     }
 
     @Override
-    InnerNativeInvocationResult unloadServiceNative(byte[] payload) {
+    byte[] unloadServiceNative(byte[] payload) throws 
ServicesUnloadingException {
         ServiceHandler serviceHandler;
         Throwable exception = null;
         EnclaveInvocationResult result;
@@ -118,14 +117,14 @@ class MockTestEnclave extends AbstractEnclave {
         }
 
         try {
-            return new InnerNativeInvocationResult(0, 
SerializationHelper.serialize(result));
+            return SerializationHelper.serialize(result);
         } catch (IOException e) {
-            return new InnerNativeInvocationResult(-1, null);
+            throw new ServicesUnloadingException(e);
         }
     }
 
     @Override
-    InnerNativeInvocationResult invokeMethodNative(byte[] payload) {
+    byte[] invokeMethodNative(byte[] payload) throws 
EnclaveMethodInvokingException {
         EnclaveInvocationContext invocationContext;
         Throwable exception = null;
         Object invokeRet = null;
@@ -150,14 +149,14 @@ class MockTestEnclave extends AbstractEnclave {
         }
 
         try {
-            return new InnerNativeInvocationResult(0, 
SerializationHelper.serialize(result));
+            return SerializationHelper.serialize(result);
         } catch (IOException e) {
-            return new InnerNativeInvocationResult(-1, null);
+            throw new EnclaveMethodInvokingException(e);
         }
     }
 
     @Override
-    public void destroy() {
+    public void destroy() throws EnclaveDestroyingException {
         // destroyToken will wait for all ongoing enclave invocations finished.
         if (this.getEnclaveContext().getEnclaveToken().destroyToken()) {
             // interrupt enclave services' recycler firstly.
diff --git 
a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestRemoteAttestation.java
 
b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestRemoteAttestation.java
index 4773b0c..d4b9a20 100644
--- 
a/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestRemoteAttestation.java
+++ 
b/sdk/host/src/test/java/com/alibaba/confidentialcomputing/host/TestRemoteAttestation.java
@@ -47,7 +47,7 @@ class TestRemoteAttestation {
         AttestationReport deserializedReport = 
AttestationReport.fromByteArray(serializedReport);
         assertEquals(EnclaveType.TEE_SDK, deserializedReport.getEnclaveType());
         for (int index = 0; index < quote.length; index++) {
-            assertEquals(quote[index], 
(deserializedReport.getReport())[index]);
+            assertEquals(quote[index], (deserializedReport.getQuote())[index]);
         }
     }
 }
diff --git a/sdk/native/bin/remote_attestation/sgx/jni/.gitkeep 
b/sdk/native/bin/remote_attestation/sgx/jni/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/sdk/native/config/platform/tee_sdk_svm/edl/tee_sdk_enclave.edl 
b/sdk/native/config/platform/tee_sdk_svm/edl/tee_sdk_enclave.edl
index 6f61cee..4736611 100644
--- a/sdk/native/config/platform/tee_sdk_svm/edl/tee_sdk_enclave.edl
+++ b/sdk/native/config/platform/tee_sdk_svm/edl/tee_sdk_enclave.edl
@@ -1,5 +1,6 @@
 enclave {
     include "sgx_report.h"
+    include "sgx_ql_lib_common.h"
 
     from "sgx_tstdc.edl"              import *;
     from "sgx_pthread.edl"            import *;
@@ -16,6 +17,8 @@ enclave {
         public int unload_enclave_svm_service(uint64_t isolate, [in, 
size=len0] void* input,  size_t len0, [out, size=8] void* output, [out, size=8] 
size_t* len1);
         // destroy a graal isolate;
         public int enclave_svm_isolate_destroy(uint64_t isolateThread);
+        // generate sgx enclave remote attestation report;
+        public int generate_remote_attestation_report([in, size=hash_length] 
void* hash,  size_t hash_length, [out]sgx_report_t* ra_report);
     };
 
     untrusted {
@@ -23,5 +26,8 @@ enclave {
         int ocall_getrlimit(int resource, [out, size=16]void *rlim);
         // malloc memory buffer from host side to store an returned object's 
serialization result.
         int ocall_malloc(size_t size, [out, size=8]void *ptr);
+
+        // get target info from host.
+        quote3_error_t ocall_get_target_info([out] sgx_target_info_t 
*qe_target_info);
     };
 };
diff --git a/sdk/native/config/platform/tee_sdk_svm/jni/config.mk 
b/sdk/native/config/platform/tee_sdk_svm/jni/config.mk
index 536f413..f54e623 100644
--- a/sdk/native/config/platform/tee_sdk_svm/jni/config.mk
+++ b/sdk/native/config/platform/tee_sdk_svm/jni/config.mk
@@ -2,6 +2,14 @@ CC = gcc
 CXX = g++
 
 TEE_SDK_PATH = /opt/teesdk/sgxsdk
+UBUNTU_OS = $(shell if [ -d "/usr/lib/x86_64-linux-gnu" ]; then echo "yes"; 
else echo "no"; fi;)
+ifeq ("$(UBUNTU_OS)", "yes")
+    DCAP_LIB_PATH = /usr/lib/x86_64-linux-gnu
+else
+    DCAP_LIB_PATH = /usr/lib64
+endif
+
+# SGX_MODE ?= SIM
 SGX_MODE ?= HW
 SGX_ARCH ?= x64
 SGX_DEBUG ?= 1
@@ -46,7 +54,7 @@ SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor 
-std=c++11
 TS_HOST_INCDIR = -I$(TEE_SDK_PATH)/include
 TS_HOST_CFLAGS = $(TS_HOST_INCDIR) $(SGX_COMMON_CFLAGS)
 TS_HOST_CXXFLAGS = $(SGX_COMMON_CXXFLAGS)
-TS_HOST_LDFLAGS = -L$(SGX_LIBRARY_PATH) -Wl,-z,noexecstack -lc 
-l$(Urts_Library_Name) -lpthread -lsgx_ustdc_ex
+TS_HOST_LDFLAGS = -L$(SGX_LIBRARY_PATH) -L$(DCAP_LIB_PATH) -Wl,-z,noexecstack 
-lc -l$(Urts_Library_Name) -lpthread -lsgx_ustdc_ex -lsgx_dcap_quoteverify 
-lsgx_dcap_ql -lsgx_quote_ex
 
 Enclave_Security_Link_Flags = -Wl,-z,relro,-z,now,-z,noexecstack
 
diff --git a/sdk/native/config/remote_attestation_verify/sgx/config.mk 
b/sdk/native/config/remote_attestation_verify/sgx/config.mk
new file mode 100644
index 0000000..032c4fb
--- /dev/null
+++ b/sdk/native/config/remote_attestation_verify/sgx/config.mk
@@ -0,0 +1,13 @@
+CC = gcc
+CXX = g++
+
+TEE_SDK_PATH = /opt/teesdk/sgxsdk
+UBUNTU_OS = $(shell if [ -d "/usr/lib/x86_64-linux-gnu" ]; then echo "yes"; 
else echo "no"; fi;)
+ifeq ("$(UBUNTU_OS)", "yes")
+    DCAP_LIB_PATH = /usr/lib/x86_64-linux-gnu
+else
+    DCAP_LIB_PATH = /usr/lib64
+endif
+
+RA_VERIFY_INCDIR = -I$(TEE_SDK_PATH)/include
+RA_VERIFY_LDFLAGS = -L$(DCAP_LIB_PATH) -lsgx_dcap_quoteverify -lsgx_dcap_ql
\ No newline at end of file
diff --git a/sdk/native/script/build_app/Makefile 
b/sdk/native/script/build_app/Makefile
index 4130e8b..85d3a30 100644
--- a/sdk/native/script/build_app/Makefile
+++ b/sdk/native/script/build_app/Makefile
@@ -1,11 +1,10 @@
 include /opt/javaenclave/config/config.mk
 include /opt/javaenclave/config/platform/tee_sdk_svm/jni/config.mk
 
-.PHONY: all build sign keys clean
+.PHONY: all build clean
 
 all:
        $(MAKE) build
-       $(MAKE) sign
 
 build:
 ifeq ($(TEE_SDK), TRUE)
@@ -24,13 +23,16 @@ ifeq ($(TEE_SDK), TRUE)
        -L${ENCLAVE_BASE_DIR}/target/enclave_workspace \
        -fpie -ljava -lzip -lnio -lnet -ljvm -lfdlibm -llibchelper \
        $(TS_ENCLAVE_LDFLAGS) 
-Wl,--version-script=/opt/javaenclave/config/platform/tee_sdk_svm/edl/tee_sdk_enclave.lds
-endif
 
-sign:
-ifeq ($(TEE_SDK), TRUE)
-       openssl genrsa -out private.pem -3 3072
-       openssl rsa -in private.pem -pubout -out public.pem
-       $(SGX_ENCLAVE_SIGNER) sign -enclave 
${ENCLAVE_BASE_DIR}/target/svm-output/lib_tee_sdk_svm_load \
-       -out ${ENCLAVE_BASE_DIR}/target/svm-output/lib_tee_sdk_svm_load.signed \
-       -config ${ENCLAVE_BASE_DIR}/src/main/resources/tee_sdk_svm.conf -key 
private.pem
+    # sign the enclave image
+    ifeq ($(ENCLAVE_PRIVATE_PEM_PATH), )
+               openssl genrsa -out 
${ENCLAVE_BASE_DIR}/target/enclave_workspace/private.pem -3 3072
+               $(SGX_ENCLAVE_SIGNER) sign -enclave 
${ENCLAVE_BASE_DIR}/target/svm-output/lib_tee_sdk_svm_load \
+               -out 
${ENCLAVE_BASE_DIR}/target/svm-output/lib_tee_sdk_svm_load.signed \
+               -config ${ENCLAVE_BASE_DIR}/src/main/resources/tee_sdk_svm.conf 
-key ${ENCLAVE_BASE_DIR}/target/enclave_workspace/private.pem
+    else
+               $(SGX_ENCLAVE_SIGNER) sign -enclave 
${ENCLAVE_BASE_DIR}/target/svm-output/lib_tee_sdk_svm_load \
+        -out ${ENCLAVE_BASE_DIR}/target/svm-output/lib_tee_sdk_svm_load.signed 
\
+        -config ${ENCLAVE_BASE_DIR}/src/main/resources/tee_sdk_svm.conf -key 
$(ENCLAVE_PRIVATE_PEM_PATH)
+    endif
 endif
diff --git a/sdk/native/script/build_app/make.sh 
b/sdk/native/script/build_app/make.sh
index 3c522dd..cf8bfb4 100644
--- a/sdk/native/script/build_app/make.sh
+++ b/sdk/native/script/build_app/make.sh
@@ -1,15 +1,19 @@
 #!/bin/bash
 
 # shellcheck disable=SC2006
-this_script_dir=`dirname "$0"`
+export BUILD_SCRIPT_DIR=`dirname "$0"`
 
+# set enclave project's base dir path.
 export ENCLAVE_BASE_DIR="$1"
+# set enclave platform, such as mock_in_svm and tee_sdk.
 enclave_platform_config=$2
+# get enclave private pem for making .signed file.
+export ENCLAVE_PRIVATE_PEM_PATH=$3
 
 # Create a native image building workspace in application's enclave submodule.
 mkdir -p "${ENCLAVE_BASE_DIR}"/target/enclave_workspace
 # copy Makefile script to enclave_workspace.
-cp -r "${this_script_dir}"/Makefile 
"${ENCLAVE_BASE_DIR}"/target/enclave_workspace
+cp -r "${BUILD_SCRIPT_DIR}"/Makefile 
"${ENCLAVE_BASE_DIR}"/target/enclave_workspace
 
 # cd to enclave workspace.
 cd "${ENCLAVE_BASE_DIR}"/target/enclave_workspace
diff --git a/sdk/native/script/build_enclave_sdk/Makefile 
b/sdk/native/script/build_enclave_sdk/Makefile
index 0154540..6098d52 100644
--- a/sdk/native/script/build_enclave_sdk/Makefile
+++ b/sdk/native/script/build_enclave_sdk/Makefile
@@ -8,10 +8,12 @@ build:
 ifeq ($(TEE_SDK), TRUE)
        $(MAKE) -C 
$(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/wrapper
        $(MAKE) -C 
$(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/edge_routines
+       $(MAKE) -C 
$(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate
 endif
 
 clean:
 ifeq ($(TEE_SDK), TRUE)
        $(MAKE) -C 
$(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/wrapper clean
        $(MAKE) -C 
$(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/edge_routines clean
+       $(MAKE) -C 
$(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate
 clean
 endif
\ No newline at end of file
diff --git a/sdk/native/script/build_host_sdk/Makefile 
b/sdk/native/script/build_host_sdk/Makefile
index 9d65c19..ceff503 100644
--- a/sdk/native/script/build_host_sdk/Makefile
+++ b/sdk/native/script/build_host_sdk/Makefile
@@ -11,6 +11,7 @@ endif
 
 ifeq ($(TEE_SDK), TRUE)
        $(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm
+       $(MAKE) -C 
$(HOST_BASE_DIR)/src/main/native/cpp/attestation_verify/sgx/jni
 endif
 
 clean:
@@ -20,4 +21,5 @@ endif
 
 ifeq ($(TEE_SDK), TRUE)
        $(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm 
clean
+       $(MAKE) -C 
$(HOST_BASE_DIR)/src/main/native/cpp/attestation_verify/sgx/jni clean
 endif
\ No newline at end of file
diff --git a/sdk/native/script/build_host_sdk/make.sh 
b/sdk/native/script/build_host_sdk/make.sh
index c543036..70181db 100644
--- a/sdk/native/script/build_host_sdk/make.sh
+++ b/sdk/native/script/build_host_sdk/make.sh
@@ -48,6 +48,7 @@ then
   # copy jni.so to target/classes, which will be packed into a jar file.
   if [[ $TEE_SDK == TRUE ]]; then
     cp -r "$NATIVE_BASE_DIR"/bin/platform/tee_sdk_svm/jni 
"$HOST_BASE_DIR"/target/classes
+    cp -r "$NATIVE_BASE_DIR"/bin/remote_attestation 
"$HOST_BASE_DIR"/target/classes
   fi
 else
   echo "unsupported make command!!!"
diff --git a/test/enclave/pom.xml b/test/enclave/pom.xml
index 9300bd2..2bbb426 100644
--- a/test/enclave/pom.xml
+++ b/test/enclave/pom.xml
@@ -14,6 +14,7 @@
     <url></url>
     <properties>
         <svm.maven.version>0.9.10</svm.maven.version>
+        
<com.alibaba.enclave.privatePem.path></com.alibaba.enclave.privatePem.path>
     </properties>
     <profiles>
         <profile>
@@ -94,6 +95,7 @@
                                         
<argument>/opt/javaenclave/build_app/make.sh</argument>
                                         <argument>${project.basedir}</argument>
                                         
<argument>${com.alibaba.enclave.platform}</argument>
+                                        
<argument>${com.alibaba.enclave.privatePem.path}</argument>
                                     </arguments>
                                 </configuration>
                             </execution>
diff --git 
a/test/host/src/test/java/com/alibaba/confidentialcomputing/test/host/TestJavaEnclaveService.java
 
b/test/host/src/test/java/com/alibaba/confidentialcomputing/test/host/TestJavaEnclaveService.java
index 4304ac9..c913318 100644
--- 
a/test/host/src/test/java/com/alibaba/confidentialcomputing/test/host/TestJavaEnclaveService.java
+++ 
b/test/host/src/test/java/com/alibaba/confidentialcomputing/test/host/TestJavaEnclaveService.java
@@ -1,17 +1,17 @@
 package com.alibaba.confidentialcomputing.test.host;
 
+import java.io.IOException;
 import java.util.Iterator;
 
+import com.alibaba.confidentialcomputing.host.*;
 import 
com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException;
 import 
com.alibaba.confidentialcomputing.host.exception.EnclaveDestroyingException;
+import 
com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
 import 
com.alibaba.confidentialcomputing.host.exception.ServicesLoadingException;
 import com.alibaba.confidentialcomputing.test.common.EnclaveException;
 import com.alibaba.confidentialcomputing.test.common.JavaEnclaveException;
 import com.alibaba.confidentialcomputing.test.common.ReflectionCallService;
 import com.alibaba.confidentialcomputing.test.common.SayHelloService;
-import com.alibaba.confidentialcomputing.host.Enclave;
-import com.alibaba.confidentialcomputing.host.EnclaveFactory;
-import com.alibaba.confidentialcomputing.host.EnclaveType;
 
 import org.junit.jupiter.api.Test;
 
@@ -19,8 +19,16 @@ import static org.junit.jupiter.api.Assertions.*;
 
 public class TestJavaEnclaveService {
     private String sayHelloService(EnclaveType type, String plain) throws
-            EnclaveCreatingException, ServicesLoadingException, 
EnclaveDestroyingException {
+            EnclaveCreatingException, ServicesLoadingException, 
EnclaveDestroyingException, RemoteAttestationException, IOException {
         Enclave enclave = EnclaveFactory.create(type);
+        if (type == EnclaveType.TEE_SDK) {
+            TeeSdkAttestationReport report = (TeeSdkAttestationReport) 
RemoteAttestation.generateAttestationReport(enclave, null);
+            assertEquals(report.getEnclaveType(), EnclaveType.TEE_SDK);
+            assertNotNull(report.getQuote());
+            assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
+            assertNotNull(report.getMeasurementEnclave());
+            assertNotNull(report.getMeasurementSigner());
+        }
         Iterator<SayHelloService> userServices = 
enclave.load(SayHelloService.class);
         assertNotNull(userServices);
         assertTrue(userServices.hasNext());
@@ -30,8 +38,16 @@ public class TestJavaEnclaveService {
         return result;
     }
 
-    private void reflectionCallService(EnclaveType type) throws 
EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException {
+    private void reflectionCallService(EnclaveType type) throws 
EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException, 
RemoteAttestationException {
         Enclave enclave = EnclaveFactory.create(type);
+        if (type == EnclaveType.TEE_SDK) {
+            TeeSdkAttestationReport report = (TeeSdkAttestationReport) 
RemoteAttestation.generateAttestationReport(enclave, null);
+            assertEquals(report.getEnclaveType(), EnclaveType.TEE_SDK);
+            assertNotNull(report.getQuote());
+            assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
+            assertNotNull(report.getMeasurementEnclave());
+            assertNotNull(report.getMeasurementSigner());
+        }
         Iterator<ReflectionCallService> userServices = 
enclave.load(ReflectionCallService.class);
         assertNotNull(userServices);
         assertTrue(userServices.hasNext());
@@ -41,8 +57,16 @@ public class TestJavaEnclaveService {
         enclave.destroy();
     }
 
-    private void javaEnclaveException(EnclaveType type) throws 
EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException {
+    private void javaEnclaveException(EnclaveType type) throws 
EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException, 
RemoteAttestationException {
         Enclave enclave = EnclaveFactory.create(type);
+        if (type == EnclaveType.TEE_SDK) {
+            TeeSdkAttestationReport report = (TeeSdkAttestationReport) 
RemoteAttestation.generateAttestationReport(enclave, null);
+            assertEquals(report.getEnclaveType(), EnclaveType.TEE_SDK);
+            assertNotNull(report.getQuote());
+            assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
+            assertNotNull(report.getMeasurementEnclave());
+            assertNotNull(report.getMeasurementSigner());
+        }
         Iterator<EnclaveException> userServices = 
enclave.load(EnclaveException.class);
         assertNotNull(userServices);
         assertTrue(userServices.hasNext());
@@ -53,21 +77,21 @@ public class TestJavaEnclaveService {
 
     @Test
     public void testSayHelloService() throws
-            EnclaveCreatingException, EnclaveDestroyingException, 
ServicesLoadingException {
+            EnclaveCreatingException, EnclaveDestroyingException, 
ServicesLoadingException, RemoteAttestationException, IOException {
         assertEquals("Hello World", sayHelloService(EnclaveType.MOCK_IN_JVM, 
"Hello World"));
         assertEquals("Hello World", sayHelloService(EnclaveType.MOCK_IN_SVM, 
"Hello World"));
         assertEquals("Hello World", sayHelloService(EnclaveType.TEE_SDK, 
"Hello World"));
     }
 
     @Test
-    public void testReflectionCallService() throws ServicesLoadingException, 
EnclaveCreatingException, EnclaveDestroyingException {
+    public void testReflectionCallService() throws ServicesLoadingException, 
EnclaveCreatingException, EnclaveDestroyingException, 
RemoteAttestationException {
         reflectionCallService(EnclaveType.MOCK_IN_JVM);
         reflectionCallService(EnclaveType.MOCK_IN_SVM);
         reflectionCallService(EnclaveType.TEE_SDK);
     }
 
     @Test
-    public void testJavaEnclaveException() throws ServicesLoadingException, 
EnclaveCreatingException, EnclaveDestroyingException {
+    public void testJavaEnclaveException() throws ServicesLoadingException, 
EnclaveCreatingException, EnclaveDestroyingException, 
RemoteAttestationException {
         javaEnclaveException(EnclaveType.MOCK_IN_JVM);
         javaEnclaveException(EnclaveType.MOCK_IN_SVM);
         javaEnclaveException(EnclaveType.TEE_SDK);
diff --git a/tools/cicd/make.sh b/tools/cicd/make.sh
index 77f0311..f4667ea 100755
--- a/tools/cicd/make.sh
+++ b/tools/cicd/make.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 BUILD_IMAGE=javaenclave_build
-BUILD_TAG=v0.1.8
+BUILD_TAG=v0.1.9
 
 SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
 
@@ -25,11 +25,14 @@ if [[ "$(docker images -q ${BUILD_IMAGE}:${BUILD_TAG} 2> 
/dev/null)" == "" ]]; t
   rm -f sgx_linux_x64_sdk_2.17.100.0.bin
 fi
 
+# Set PCCS for DCAP Remote Attestation.
+PCCS_URL='https://sgx-dcap-server.cn-beijing.aliyuncs.com/sgx/certification/v3/'
+
 # test JavaEnclave's unit test cases and samples
 docker run -i --rm --privileged --network host                    \
 -w "${WORKDIR}"                                                   \
 -v "${HOME}"/.m2:/root/.m2 -v "${WORKDIR}":"${WORKDIR}"           \
+-e PCCS_URL=${PCCS_URL}                                           \
 -v /dev/sgx_enclave:/dev/sgx/enclave             \
 -v /dev/sgx_provision:/dev/sgx/provision         \
 ${BUILD_IMAGE}:${BUILD_TAG} /bin/bash build.sh
-


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to