You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by sh...@apache.org on 2022/11/11 05:18:07 UTC
[incubator-teaclave-java-tee-sdk] 27/48: [sdk] Add Embedded Libos tee enclave occlum for JavaEnclave
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 f2ebac3b8abeae9be73c6118bd6b066b8082ee77
Author: jeffery.wsj <je...@alibaba-inc.com>
AuthorDate: Tue Jun 28 10:48:51 2022 +0800
[sdk] Add Embedded Libos tee enclave occlum for JavaEnclave
Summary:
1. Add occlum enclave for JavaEnclave as embedded mode
2. Implement remote attestation generation and verification for Embedded LibOS enclave
Test Plan: all tests pass
Reviewers: lei.yul, cengfeng.lzy, sanhong.lsh
Issue: https://aone.alibaba-inc.com/task/43348805
CR: https://code.aone.alibaba-inc.com/java-tee/JavaEnclave/codereview/9413169
---
build.sh | 5 +-
sdk/common/pom.xml | 4 +
.../EmbeddedLibOSInnerAttestationReport.java | 40 ++++
.../common/EnclaveInvocationContext.java | 9 +-
.../common/SocketEnclaveInvocationContext.java | 51 +++++
.../exception/ConfidentialComputingException.java | 2 +
.../enclave/NativeCommandUtil.java | 1 -
.../enclave/agent/EnclaveAgent.java | 102 +++++++++
.../enclave/agent/EnclaveAgentServiceImpl.java | 86 +++++++
.../enclave/agent/EnclaveShutDown.java | 49 ++++
.../enclave/agent/RemoteAttestation.java | 21 ++
.../enclave/framework/LoadServiceInvoker.java | 4 +-
.../enclave/framework/ServiceMethodInvoker.java | 1 -
.../enclave/framework/UnloadServiceInvoker.java | 1 -
.../enclave/system/EnclavePhysicalMemory.java | 1 -
.../remote_attestation_generate/Makefile | 14 ++
.../jni_occlum_attestation_generate.c | 83 +++++++
.../jni_occlum_attestation_generate.h | 47 ++++
.../platform/tee_sdk_svm/wrapper/tee_sdk_wrapper.c | 1 -
sdk/host/pom.xml | 4 +
.../host/AbstractEnclave.java | 34 +--
.../host/AttestationReport.java | 3 +
.../host/EmbeddedLibOSAttestationReport.java | 10 +
.../host/EmbeddedLibOSEnclave.java | 248 +++++++++++++++++++++
.../host/EmbeddedLibOSEnclaveConfig.java | 83 +++++++
.../host/EnclaveConfigure.java | 5 +
.../confidentialcomputing/host/EnclaveDebug.java | 2 +-
.../{EnclaveDebug.java => EnclaveSimulate.java} | 14 +-
.../confidentialcomputing/host/EnclaveType.java | 7 +
.../confidentialcomputing/host/ExtractLibrary.java | 79 ++++++-
.../host/MockInJvmEnclave.java | 8 +-
.../host/MockInSvmEnclave.java | 28 ++-
.../host/ProxyEnclaveInvocationHandler.java | 32 +--
.../host/RemoteAttestation.java | 6 +-
...tationReport.java => SGXAttestationReport.java} | 20 +-
.../host/SGXRemoteAttestationVerify.java | 1 -
.../host/TeeSdkAttestationReport.java | 31 +--
.../confidentialcomputing/host/TeeSdkEnclave.java | 27 ++-
.../host/exception/EnclaveCreatingException.java | 1 +
.../native/cpp/attestation_verify/sgx/jni/Makefile | 1 +
.../sgx/jni/jni_remote_attestation_verify.c | 1 -
.../cpp/platform/libos_occlum_enclave/jni/Makefile | 13 ++
.../libos_occlum_enclave/jni/jni_occlum_enclave.c | 206 +++++++++++++++++
.../libos_occlum_enclave/jni/jni_occlum_enclave.h | 60 +++++
.../cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c | 7 +-
.../cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h | 6 +-
.../cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.c | 17 +-
.../cpp/platform/tee_sdk_svm/jni/jni_tee_sdk_svm.h | 6 +-
.../host/MockTestEnclave.java | 24 +-
.../host/TestRemoteAttestation.java | 12 +-
.../bin/platform/libos_occlum_enclave/jni/.gitkeep | 0
.../libos_occlum_enclave_attestation/.gitkeep | 0
.../libos_occlum_enclave/enclave/config.mk | 5 +
.../platform/libos_occlum_enclave/jni/config.mk | 17 ++
.../config/platform/tee_sdk_svm/jni/config.mk | 4 +-
.../config/remote_attestation_verify/sgx/config.mk | 2 +-
sdk/native/script/build_app/Makefile | 5 +-
.../script/build_app/libos_occlum_enclave_build.sh | 87 ++++++++
sdk/native/script/build_app/make.sh | 1 -
sdk/native/script/build_enclave_sdk/Makefile | 8 +
sdk/native/script/build_host_sdk/Makefile | 19 ++
sdk/native/script/build_host_sdk/make.sh | 7 +
sdk/pom.xml | 12 +-
test/enclave/pom.xml | 21 +-
.../src/main/resources/embedded_libos_enclave.json | 11 +
test/host/pom.xml | 4 +
.../test/host/TestJavaEnclaveService.java | 92 ++++++--
test/pom.xml | 2 +-
tools/cicd/Dockerfile | 19 +-
tools/cicd/make.sh | 6 +-
70 files changed, 1662 insertions(+), 178 deletions(-)
diff --git a/build.sh b/build.sh
index 5d096d2..fc270bc 100755
--- a/build.sh
+++ b/build.sh
@@ -9,6 +9,9 @@ SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
cd "${SHELL_FOLDER}"
+# fix occlum aesm service issue.
+sed -i '128,129s/.*//g' /opt/occlum/build/bin/occlum
+
# workspace dir is the same as build.sh path location.
WORKDIR="$PWD"
SETTING="--settings /root/tools/settings.xml"
@@ -19,4 +22,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 $SETTING -Pnative clean package
+cd "${WORKDIR}"/test && OCCLUM_RELEASE_ENCLAVE=true mvn $SETTING -Pnative clean package
diff --git a/sdk/common/pom.xml b/sdk/common/pom.xml
index b039d49..efe3fa5 100644
--- a/sdk/common/pom.xml
+++ b/sdk/common/pom.xml
@@ -80,6 +80,10 @@
</plugins>
</build>
<dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ </dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
diff --git a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EmbeddedLibOSInnerAttestationReport.java b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EmbeddedLibOSInnerAttestationReport.java
new file mode 100644
index 0000000..29e2c9f
--- /dev/null
+++ b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EmbeddedLibOSInnerAttestationReport.java
@@ -0,0 +1,40 @@
+package com.alibaba.confidentialcomputing.common;
+
+import java.io.Serializable;
+
+/**
+ * This class is used to transfer embedded lib os attestation report between JavaEnclave's
+ * host and enclave module.
+ */
+public final class EmbeddedLibOSInnerAttestationReport implements Serializable {
+ private static final long serialVersionUID = -6944029051086666440L;
+
+ private final byte[] quote;
+ private final byte[] mrSigner;
+ private final byte[] mrEnclave;
+ private final byte[] userData;
+
+
+ public EmbeddedLibOSInnerAttestationReport(byte[] quote, byte[] mrSigner, byte[] mrEnclave, byte[] userData) {
+ this.quote = quote;
+ this.mrSigner = mrSigner;
+ this.mrEnclave = mrEnclave;
+ this.userData = userData;
+ }
+
+ public byte[] getQuote() {
+ return this.quote;
+ }
+
+ public byte[] getMrSigner() {
+ return this.mrSigner;
+ }
+
+ public byte[] getMrEnclave() {
+ return this.mrEnclave;
+ }
+
+ public byte[] getUserData() {
+ return this.userData;
+ }
+}
diff --git a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EnclaveInvocationContext.java b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EnclaveInvocationContext.java
index c0325a0..de7244f 100644
--- a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EnclaveInvocationContext.java
+++ b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/EnclaveInvocationContext.java
@@ -7,7 +7,7 @@ import java.io.Serializable;
* call, including the service instance's unique instanceIdentity, interface name, class name,
* method name and its parameters.
*/
-public final class EnclaveInvocationContext implements Serializable {
+public class EnclaveInvocationContext implements Serializable {
private static final long serialVersionUID = 6878585714134748604L;
private final ServiceHandler serviceHandler;
@@ -15,6 +15,13 @@ public final class EnclaveInvocationContext implements Serializable {
private final String[] parameterTypes;
private final Object[] arguments;
+ public EnclaveInvocationContext() {
+ this.serviceHandler = null;
+ this.methodName = null;
+ this.parameterTypes = null;
+ this.arguments = null;
+ }
+
public EnclaveInvocationContext(ServiceHandler serviceHandler,
String methodName,
String[] parameterTypes,
diff --git a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/SocketEnclaveInvocationContext.java b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/SocketEnclaveInvocationContext.java
new file mode 100644
index 0000000..93926b5
--- /dev/null
+++ b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/SocketEnclaveInvocationContext.java
@@ -0,0 +1,51 @@
+package com.alibaba.confidentialcomputing.common;
+
+/**
+ * This class stores a method's necessary information for reflection
+ * call by socket http, including the service instance's unique instanceIdentity,
+ * interface name, class name, method name and its parameters.
+ * It's used for embedded lib os inner service invocation.
+ */
+public final class SocketEnclaveInvocationContext extends EnclaveInvocationContext {
+ private static final long serialVersionUID = 6202620980098144988L;
+ public static final String SERVICE_LOADING = "service_loading";
+ public static final String SERVICE_UNLOADING = "service_unloading";
+ public static final String METHOD_INVOCATION = "method_invocation";
+ public static final String REMOTE_ATTESTATION_GENERATE = "remote_attestation_generate";
+ public static final String ENCLAVE_DESTROY = "enclave_destroy";
+
+ private final String agentServiceName;
+ private final byte[] userData;
+
+ public SocketEnclaveInvocationContext(
+ String agentServiceName,
+ EnclaveInvocationContext context) {
+ super(context.getServiceHandler(), context.getMethodName(), context.getParameterTypes(), context.getArguments());
+ this.agentServiceName = agentServiceName;
+ this.userData = null;
+ }
+
+ public SocketEnclaveInvocationContext(String agentServiceName, ServiceHandler serviceHandler) {
+ super(serviceHandler);
+ this.agentServiceName = agentServiceName;
+ this.userData = null;
+ }
+
+ public SocketEnclaveInvocationContext(String agentServiceName, byte[] userData) {
+ this.agentServiceName = agentServiceName;
+ this.userData = userData;
+ }
+
+ public SocketEnclaveInvocationContext(String agentServiceName) {
+ this.agentServiceName = agentServiceName;
+ this.userData = null;
+ }
+
+ public String getAgentServiceName() {
+ return agentServiceName;
+ }
+
+ public byte[] getUserData() {
+ return userData;
+ }
+}
diff --git a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java
index 43c3b25..eaaba57 100644
--- a/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java
+++ b/sdk/common/src/main/java/com/alibaba/confidentialcomputing/common/exception/ConfidentialComputingException.java
@@ -9,6 +9,8 @@ public class ConfidentialComputingException extends Exception {
private static final long serialVersionUID = 5964126736764332957L;
+ public ConfidentialComputingException() {super();}
+
/**
* @param info exception information.
*/
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/NativeCommandUtil.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/NativeCommandUtil.java
index 9966a30..a5afe9f 100644
--- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/NativeCommandUtil.java
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/NativeCommandUtil.java
@@ -3,7 +3,6 @@ package com.alibaba.confidentialcomputing.enclave;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.io.SequenceInputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveAgent.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveAgent.java
new file mode 100644
index 0000000..3cf96df
--- /dev/null
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveAgent.java
@@ -0,0 +1,102 @@
+package com.alibaba.confidentialcomputing.enclave.agent;
+
+import com.alibaba.confidentialcomputing.common.SerializationHelper;
+import com.alibaba.confidentialcomputing.common.SocketEnclaveInvocationContext;
+import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+class EnclaveAgent {
+ private static final String HTTP_EXECUTE_THREAD_NAME = "enclave_http_remote_invoking_thread";
+ private static final String HTTP_SERVER_NAME = "/enclaveAgent";
+ private static volatile EnclaveAgentServiceImpl service = new EnclaveAgentServiceImpl();
+ private static volatile HttpServer httpServer = null;
+
+ // socket service port is from host side.
+ public static void main(String[] args) throws ConfidentialComputingException, IOException {
+ if (args.length != 3) {
+ throw new ConfidentialComputingException("lib os enclave agent service's port resource is not available.");
+ }
+ int portHost = Integer.parseInt(args[0]);
+ int portEnclave = Integer.parseInt(args[1]);
+ int httpThreadPoolSize = Integer.parseInt(args[2]);
+
+ notifyHostAndCreateHttpConnect(portHost, portEnclave, httpThreadPoolSize);
+
+ // wait for enclave shut down notification.
+ EnclaveShutDown.shutDownWait();
+ }
+
+ private static void notifyHostAndCreateHttpConnect(int portHost, int portEnclave, int threadPoolSize) throws IOException {
+ // create http connection and wait for request from host.
+ httpServer = HttpServer.create(new InetSocketAddress(portEnclave), 0);
+ httpServer.createContext(HTTP_SERVER_NAME, new EnclaveHttpHandler());
+ httpServer.setExecutor(Executors.newScheduledThreadPool(threadPoolSize, new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r);
+ thread.setName(HTTP_EXECUTE_THREAD_NAME);
+ thread.setDaemon(true);
+ return thread;
+ }
+ }));
+ httpServer.start();
+ // notify host that enclave jvm had started up.
+ new Socket("localhost", portHost);
+ }
+
+ static void closeHttpService() {
+ httpServer.stop(0);
+ }
+
+ private static void writeBackResponse(HttpExchange exchange, byte[] response) throws IOException {
+ exchange.sendResponseHeaders(200, response.length);
+ OutputStream outputStream = exchange.getResponseBody();
+ outputStream.write(response);
+ outputStream.flush();
+ outputStream.close();
+ }
+
+ static class EnclaveHttpHandler implements HttpHandler {
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ InputStream inputStream = exchange.getRequestBody();
+ byte[] payload = inputStream.readAllBytes();
+ inputStream.close();
+ SocketEnclaveInvocationContext context = null;
+
+ try {
+ context = (SocketEnclaveInvocationContext) SerializationHelper.deserialize(payload);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ switch (context.getAgentServiceName()) {
+ case SocketEnclaveInvocationContext.SERVICE_LOADING:
+ writeBackResponse(exchange, service.loadService(context.getServiceHandler().getServiceInterfaceName()));
+ break;
+ case SocketEnclaveInvocationContext.SERVICE_UNLOADING:
+ writeBackResponse(exchange, service.unloadService(context.getServiceHandler()));
+ break;
+ case SocketEnclaveInvocationContext.METHOD_INVOCATION:
+ writeBackResponse(exchange, service.invokeMethod(context));
+ break;
+ case SocketEnclaveInvocationContext.REMOTE_ATTESTATION_GENERATE:
+ writeBackResponse(exchange, service.generateAttestationReport(context.getUserData()));
+ break;
+ case SocketEnclaveInvocationContext.ENCLAVE_DESTROY:
+ writeBackResponse(exchange, service.destroy());
+ break;
+ default:
+ }
+ }
+ }
+}
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveAgentServiceImpl.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveAgentServiceImpl.java
new file mode 100644
index 0000000..b5e5716
--- /dev/null
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveAgentServiceImpl.java
@@ -0,0 +1,86 @@
+package com.alibaba.confidentialcomputing.enclave.agent;
+
+import com.alibaba.confidentialcomputing.common.EnclaveInvocationContext;
+import com.alibaba.confidentialcomputing.common.EnclaveInvocationResult;
+import com.alibaba.confidentialcomputing.common.SerializationHelper;
+import com.alibaba.confidentialcomputing.common.ServiceHandler;
+import com.alibaba.confidentialcomputing.common.EmbeddedLibOSInnerAttestationReport;
+import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException;
+import com.alibaba.confidentialcomputing.enclave.framework.LoadServiceInvoker;
+import com.alibaba.confidentialcomputing.enclave.framework.ServiceMethodInvoker;
+import com.alibaba.confidentialcomputing.enclave.framework.UnloadServiceInvoker;
+
+import java.io.IOException;
+
+public class EnclaveAgentServiceImpl {
+ private static final LoadServiceInvoker loadServiceInstance = new LoadServiceInvoker();
+ private static final ServiceMethodInvoker serviceInvokerInstance = new ServiceMethodInvoker();
+ private static final UnloadServiceInvoker unloadServiceInstance = new UnloadServiceInvoker();
+
+ protected EnclaveAgentServiceImpl() {
+ }
+
+ public byte[] loadService(String serviceName) {
+ try {
+ return SerializationHelper.serialize(loadServiceInstance.callMethod(serviceName));
+ } catch (IOException e) {
+ try {
+ return SerializationHelper.serialize(new EnclaveInvocationResult(null, e));
+ } catch (IOException ex) {
+ }
+ }
+ return null;
+ }
+
+ public byte[] unloadService(ServiceHandler handler) {
+ try {
+ return SerializationHelper.serialize(unloadServiceInstance.callMethod(handler));
+ } catch (IOException e) {
+ try {
+ return SerializationHelper.serialize(new EnclaveInvocationResult(null, e));
+ } catch (IOException ex) {
+ }
+ }
+ return null;
+ }
+
+ public byte[] invokeMethod(EnclaveInvocationContext context) {
+ try {
+ return SerializationHelper.serialize(serviceInvokerInstance.callMethod(context));
+ } catch (IOException e) {
+ try {
+ return SerializationHelper.serialize(new EnclaveInvocationResult(null, e));
+ } catch (IOException ex) {
+ }
+ }
+ return null;
+ }
+
+ public byte[] generateAttestationReport(byte[] userDate) {
+ EmbeddedLibOSInnerAttestationReport report = null;
+ Throwable exception = null;
+ try {
+ report = RemoteAttestation.generateAttestationReport(userDate);
+ } catch (ConfidentialComputingException e) {
+ exception = e;
+ }
+ try {
+ return SerializationHelper.serialize(new EnclaveInvocationResult(report, exception));
+ } catch (IOException e) {
+ try {
+ return SerializationHelper.serialize(new EnclaveInvocationResult(null, e));
+ } catch (IOException ex) {
+ }
+ }
+ return null;
+ }
+
+ public byte[] destroy() {
+ EnclaveShutDown.shutDownNotify();
+ try {
+ return SerializationHelper.serialize(new EnclaveInvocationResult(true, null));
+ } catch (IOException e) {
+ }
+ return null;
+ }
+}
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveShutDown.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveShutDown.java
new file mode 100644
index 0000000..b448c9f
--- /dev/null
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/EnclaveShutDown.java
@@ -0,0 +1,49 @@
+package com.alibaba.confidentialcomputing.enclave.agent;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+class EnclaveShutDown {
+ private static final int SHUTDOWN_DELAY_DURATION = 1000; // TimeUnit.MilliSecond
+ private static BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
+
+ static void shutDownNotify() {
+ boolean interrupted = false;
+ try {
+ while (true) {
+ try {
+ queue.put(0);
+ return;
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ } finally {
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ static void shutDownWait() {
+ boolean interrupted = false;
+ try {
+ while (true) {
+ try {
+ queue.take();
+ // wait for destroy localhost remote destroy invocation return.
+ Thread.sleep(SHUTDOWN_DELAY_DURATION);
+ // close cached socket resources and socket service.
+ EnclaveAgent.closeHttpService();
+ return;
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ } finally {
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+}
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/RemoteAttestation.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/RemoteAttestation.java
new file mode 100644
index 0000000..557058c
--- /dev/null
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/agent/RemoteAttestation.java
@@ -0,0 +1,21 @@
+package com.alibaba.confidentialcomputing.enclave.agent;
+
+import com.alibaba.confidentialcomputing.common.EmbeddedLibOSInnerAttestationReport;
+import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException;
+
+public class RemoteAttestation {
+ // lib os embedded enclave remote attestation jni.so path in occlum image.
+ private final static String JNI_EXTRACTED_PACKAGE_PATH = "/usr/lib/libos_occlum_enclave_attestation/lib_occlum_attestation_generate.so";
+
+ private static native void registerNatives();
+ private static native EmbeddedLibOSInnerAttestationReport generateAttestationReportNative(byte[] userDate) throws ConfidentialComputingException;
+
+ static {
+ System.load(JNI_EXTRACTED_PACKAGE_PATH);
+ registerNatives();
+ }
+
+ public static EmbeddedLibOSInnerAttestationReport generateAttestationReport(byte[] userDate) throws ConfidentialComputingException {
+ return generateAttestationReportNative(userDate);
+ }
+}
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/LoadServiceInvoker.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/LoadServiceInvoker.java
index d0c03ae..a4b2dec 100644
--- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/LoadServiceInvoker.java
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/LoadServiceInvoker.java
@@ -17,9 +17,9 @@ public final class LoadServiceInvoker implements EnclaveMethodInvoker<String> {
Class<?> service;
try {
service = Class.forName(inputData);
+ return new EnclaveInvocationResult(EnclaveContext.getInstance().loadService(service), null);
} catch (ClassNotFoundException e) {
- throw new RuntimeException("Can't find the service interface class.", e);
+ return new EnclaveInvocationResult(null, e);
}
- return new EnclaveInvocationResult(EnclaveContext.getInstance().loadService(service), null);
}
}
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java
index 8387804..7f12b9f 100644
--- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/ServiceMethodInvoker.java
@@ -6,7 +6,6 @@ import com.alibaba.confidentialcomputing.common.ServiceHandler;
import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException;
import jdk.vm.ci.meta.MetaUtil;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/UnloadServiceInvoker.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/UnloadServiceInvoker.java
index 5f5fb6b..0b82737 100644
--- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/UnloadServiceInvoker.java
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/framework/UnloadServiceInvoker.java
@@ -1,6 +1,5 @@
package com.alibaba.confidentialcomputing.enclave.framework;
-
import com.alibaba.confidentialcomputing.common.EnclaveInvocationResult;
import com.alibaba.confidentialcomputing.common.ServiceHandler;
import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException;
diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclavePhysicalMemory.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclavePhysicalMemory.java
index 35521b5..cdab91d 100644
--- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclavePhysicalMemory.java
+++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/system/EnclavePhysicalMemory.java
@@ -6,7 +6,6 @@ import com.oracle.svm.core.util.VMError;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;
-import java.util.Properties;
/**
* Physical memory implementation for Enclave environment. The sysconf(_SC_PAGESIZE()) and
diff --git a/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/Makefile b/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/Makefile
new file mode 100644
index 0000000..cdf38d9
--- /dev/null
+++ b/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/Makefile
@@ -0,0 +1,14 @@
+include $(NATIVE_BASE_DIR)/config/config.mk
+include $(NATIVE_BASE_DIR)/config/platform/libos_occlum_enclave/enclave/config.mk
+
+.PHONY: all build clean
+
+all: build
+
+build:
+ $(CC) jni_occlum_attestation_generate.c -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(shell uname -s | tr A-Z a-z) \
+ -I$(INCPATH) -I$(TEE_SDK_PATH)/include -L$(LIBPATH) -locclum_dcap -fPIC -shared \
+ -o $(BIN)/platform/libos_occlum_enclave/libos_occlum_enclave_attestation/lib_occlum_attestation_generate.so
+
+clean:
+ rm -rf $(BIN)/platform/libos_occlum_enclave/libos_occlum_enclave_attestation/lib_occlum_attestation_generate.so
\ No newline at end of file
diff --git a/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/jni_occlum_attestation_generate.c b/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/jni_occlum_attestation_generate.c
new file mode 100644
index 0000000..a9b689e
--- /dev/null
+++ b/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/jni_occlum_attestation_generate.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sgx_quote_3.h"
+#include "sgx_urts.h"
+#include "sgx_pce.h"
+#include "sgx_error.h"
+
+#include <occlum_dcap.h>
+
+#include "jni_occlum_attestation_generate.h"
+
+static JNINativeMethod embedded_libos_occlum_enclave_methods[] = {
+ {"generateAttestationReportNative", LIBOS_OCCLUM_ENCLAVE_REMOTE_ATTESTATION_GENERATION_SIGNATURE, (void *)&JavaEnclave_TeeLibOSNativeRemoteAttestationGenerate},
+};
+
+JNIEXPORT void JNICALL Java_com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation_registerNatives(JNIEnv *env, jclass cls) {
+ (*env)->RegisterNatives(env, cls, embedded_libos_occlum_enclave_methods, sizeof(embedded_libos_occlum_enclave_methods)/sizeof(embedded_libos_occlum_enclave_methods[0]));
+}
+
+JNIEXPORT jobject JNICALL JavaEnclave_TeeLibOSNativeRemoteAttestationGenerate(JNIEnv *env, jclass cls, jbyteArray userData) {
+
+ void *handle = dcap_quote_open();
+ if (handle == NULL) {
+ THROW_EXCEPTION(env, LIBOS_OCCLUM_ENCLAVE_REMOTE_ATTESTATION_EXCEPTION, "libos enclave occlum remote attestation generate: dcap_quote_open failed.")
+ }
+
+ uint32_t quote_size = dcap_get_quote_size(handle);
+ uint8_t *p_quote_buffer = (uint8_t*)malloc(quote_size);
+ if (p_quote_buffer == NULL) {
+ dcap_quote_close(handle);
+ THROW_EXCEPTION(env, LIBOS_OCCLUM_ENCLAVE_REMOTE_ATTESTATION_EXCEPTION, "libos enclave occlum remote attestation generate: malloc p_quote_buffer failed.")
+ }
+ memset(p_quote_buffer, 0, quote_size);
+
+ sgx_report_data_t report_data = {0};
+ jbyte *userData_copy = (*env)->GetByteArrayElements(env, userData, NULL);
+ int userData_copy_length = (*env)->GetArrayLength(env, userData);
+ memcpy(report_data.d, userData_copy, userData_copy_length);
+
+ int32_t ret = dcap_generate_quote(handle, p_quote_buffer, &report_data);
+ if (ret != 0x0) {
+ (*env)->ReleaseByteArrayElements(env, userData, userData_copy, 0);
+ free(p_quote_buffer);
+ dcap_quote_close(handle);
+ THROW_EXCEPTION(env, LIBOS_OCCLUM_ENCLAVE_REMOTE_ATTESTATION_EXCEPTION, "libos enclave occlum remote attestation generate: dcap_generate_quote failed.")
+ }
+
+ sgx_quote3_t *p_quote = (sgx_quote3_t *)p_quote_buffer;
+ sgx_report_body_t *p_rep_body = (sgx_report_body_t *)(&p_quote->report_body);
+
+ jbyteArray quote_array = (*env)->NewByteArray(env, quote_size);
+ jbyte *quote_array_ptr = (*env)->GetByteArrayElements(env, quote_array, NULL);
+ memcpy(quote_array_ptr, p_quote_buffer, 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, p_quote->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, p_quote->report_body.mr_signer.m, SGX_HASH_SIZE);
+
+ // create user data byte array.
+ jbyteArray user_data = (*env)->NewByteArray(env, SGX_REPORT_DATA_SIZE);
+ jbyte *user_data_buf = (*env)->GetByteArrayElements(env, user_data, NULL);
+ memcpy(user_data_buf, p_quote->report_body.report_data.d, SGX_REPORT_DATA_SIZE);
+
+ (*env)->ReleaseByteArrayElements(env, userData, userData_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);
+ (*env)->ReleaseByteArrayElements(env, user_data, user_data_buf, 0);
+ free(p_quote_buffer);
+ dcap_quote_close(handle);
+
+ jclass libos_inner_ra_report_clazz = (*env)->FindClass(env, LIBOS_OCCLUM_INNER_ATTESTATION_REPORT);
+ jmethodID construct = (*env)->GetMethodID(env, libos_inner_ra_report_clazz, "<init>", "([B[B[B[B)V");
+ return (*env)->NewObject(env, libos_inner_ra_report_clazz, construct, quote_array, mr_signer, mr_enclave, user_data);
+}
diff --git a/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/jni_occlum_attestation_generate.h b/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/jni_occlum_attestation_generate.h
new file mode 100644
index 0000000..c88e9ed
--- /dev/null
+++ b/sdk/enclave/src/main/native/cpp/platform/libos_occlum_enclave/remote_attestation_generate/jni_occlum_attestation_generate.h
@@ -0,0 +1,47 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation */
+
+#ifndef _Included_com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation
+#define _Included_com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LIBOS_OCCLUM_ENCLAVE_REMOTE_ATTESTATION_GENERATION_SIGNATURE "([B)Lcom/alibaba/confidentialcomputing/common/EmbeddedLibOSInnerAttestationReport;"
+#define LIBOS_OCCLUM_INNER_ATTESTATION_REPORT "com/alibaba/confidentialcomputing/common/EmbeddedLibOSInnerAttestationReport"
+#define LIBOS_OCCLUM_ENCLAVE_REMOTE_ATTESTATION_EXCEPTION "com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingException"
+
+#define THROW_EXCEPTION(env, exception, info) \
+{ \
+ jclass ra_class = (*env)->FindClass(env, exception); \
+ if (ra_class == NULL) { \
+ fprintf(stderr, "JavaEnclave Error: "); \
+ fprintf(stderr, exception); \
+ fprintf(stderr, " class loading failed.\n"); \
+ return; \
+ } \
+ (*env)->ThrowNew(env, ra_class, info); \
+ return; \
+}
+
+/*
+ * Class: com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation
+ * Method: registerNatives
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation_registerNatives
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_alibaba_confidentialcomputing_enclave_agent_RemoteAttestation
+ * Method: generateAttestationReportNative
+ * Signature: ([B)Lcom/alibaba/confidentialcomputing/common/agent/EmbeddedLibOSInnerAttestationReport;
+ */
+JNIEXPORT jobject JNICALL JavaEnclave_TeeLibOSNativeRemoteAttestationGenerate
+ (JNIEnv *, jclass, jbyteArray);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
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 95255d4..6d651ea 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,7 +33,6 @@ 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/pom.xml b/sdk/host/pom.xml
index 1a60a7a..c65e281 100644
--- a/sdk/host/pom.xml
+++ b/sdk/host/pom.xml
@@ -107,6 +107,10 @@
<groupId>com.alibaba.confidentialcomputing</groupId>
<artifactId>common</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ </dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service-annotations</artifactId>
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 486a59d..8b7bfe8 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
@@ -17,7 +17,6 @@ import com.alibaba.confidentialcomputing.host.exception.RemoteAttestationExcepti
import com.alibaba.confidentialcomputing.host.exception.ServicesLoadingException;
import com.alibaba.confidentialcomputing.host.exception.ServicesUnloadingException;
-
/**
* AbstractEnclave implements all kinds of enclave platform's common operation.
* Such as service loadingăunloading and service method invocation.
@@ -33,6 +32,9 @@ abstract class AbstractEnclave implements Enclave {
if (type == EnclaveType.TEE_SDK && mode == EnclaveDebug.NONE) {
throw new EnclaveCreatingException("TEE SDK enclave's debug mode must be RELEASE or DEBUG.");
}
+ if (type == EnclaveType.EMBEDDED_LIB_OS && mode == EnclaveDebug.NONE) {
+ throw new EnclaveCreatingException("EMBEDDED_LIB_OS enclave's debug mode must be RELEASE or DEBUG.");
+ }
enclaveContext = new EnclaveContext(type, mode, recycler);
}
@@ -44,11 +46,11 @@ abstract class AbstractEnclave implements Enclave {
return enclaveContext;
}
- abstract byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException;
+ abstract byte[] loadServiceNative(String service) throws ServicesLoadingException;
- abstract byte[] unloadServiceNative(byte[] payload) throws ServicesUnloadingException;
+ abstract byte[] unloadServiceNative(ServiceHandler handler) throws ServicesUnloadingException;
- abstract byte[] invokeMethodNative(byte[] payload) throws EnclaveMethodInvokingException;
+ abstract byte[] invokeMethodNative(EnclaveInvocationContext context) throws EnclaveMethodInvokingException;
abstract AttestationReport generateAttestationReportNative(byte[] userData) throws RemoteAttestationException;
@@ -60,15 +62,9 @@ abstract class AbstractEnclave implements Enclave {
try {
// Only need to provide service's interface name is enough to load service
// in enclave.
- byte[] payload;
- try {
- payload = SerializationHelper.serialize(service.getName());
- } catch (IOException e) {
- throw new ServicesLoadingException("service name serialization failed.", e);
- }
EnclaveInvocationResult resultWrapper;
try {
- resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(loadServiceNative(payload));
+ resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(loadServiceNative(service.getName()));
} catch (IOException | ClassNotFoundException e) {
throw new ServicesLoadingException("EnclaveInvokeResultWrapper deserialization failed.", e);
}
@@ -98,15 +94,9 @@ abstract class AbstractEnclave implements Enclave {
throw new ServicesUnloadingException("enclave was destroyed.");
}
try {
- byte[] payload;
- try {
- payload = SerializationHelper.serialize(service);
- } catch (IOException e) {
- throw new ServicesUnloadingException("unload service serialization failed.", e);
- }
EnclaveInvocationResult resultWrapper;
try {
- resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(unloadServiceNative(payload));
+ resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(unloadServiceNative(service));
} catch (IOException | ClassNotFoundException e) {
throw new ServicesUnloadingException("EnclaveInvokeResultWrapper deserialization failed.", e);
}
@@ -125,15 +115,9 @@ abstract class AbstractEnclave implements Enclave {
throw new EnclaveMethodInvokingException("enclave was destroyed.");
}
try {
- byte[] payload;
- try {
- payload = SerializationHelper.serialize(input);
- } catch (IOException e) {
- throw new EnclaveMethodInvokingException("EnclaveInvokeMetaWrapper serialization failed.", e);
- }
EnclaveInvocationResult resultWrapper;
try {
- resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(invokeMethodNative(payload));
+ resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(invokeMethodNative(input));
} catch (IOException | ClassNotFoundException e) {
throw new EnclaveMethodInvokingException("EnclaveInvokeResultWrapper deserialization failed.", e);
}
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 dd8bcf9..9847907 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
@@ -71,6 +71,9 @@ public class AttestationReport implements Serializable {
case 3:
enclaveType = EnclaveType.TEE_SDK;
break;
+ case 4:
+ enclaveType = EnclaveType.EMBEDDED_LIB_OS;
+ break;
}
System.arraycopy(attestationReport, 1, report, 0, report.length);
return new AttestationReport(enclaveType, report);
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSAttestationReport.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSAttestationReport.java
new file mode 100644
index 0000000..1913119
--- /dev/null
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSAttestationReport.java
@@ -0,0 +1,10 @@
+package com.alibaba.confidentialcomputing.host;
+
+/**
+ * EmbeddedLibOSAttestationReport parse more details information from a lib os embedded type enclave's remote attestation report.
+ */
+public final class EmbeddedLibOSAttestationReport extends SGXAttestationReport {
+ EmbeddedLibOSAttestationReport(byte[] quote, byte[] mrSigner, byte[] mrEnclave, byte[] userData) {
+ super(EnclaveType.EMBEDDED_LIB_OS, quote, mrSigner, mrEnclave, userData);
+ }
+}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclave.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclave.java
new file mode 100644
index 0000000..a0c7ff2
--- /dev/null
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclave.java
@@ -0,0 +1,248 @@
+package com.alibaba.confidentialcomputing.host;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.*;
+import java.util.concurrent.*;
+
+import com.alibaba.confidentialcomputing.common.*;
+import com.alibaba.confidentialcomputing.host.exception.*;
+
+/**
+ * EmbeddedLibOSEnclave is a sgx2 enclave based on Ant's Occlum libos.
+ * EmbeddedLibOSEnclave is a singleton object module, there is only one
+ * EmbeddedLibOSEnclave object in a process.
+ */
+public class EmbeddedLibOSEnclave extends AbstractEnclave {
+ private static final int HTTP_CONNECT_TIMEOUT_MS = 50; // ms.
+ private static final int HTTP_READ_TIMEOUT_MS = 200; // ms.
+ private static final int HTTP_READ_REMOTE_ATTESTATION_TIMEOUT_MS = HTTP_READ_TIMEOUT_MS * 10; // ms.
+ private static final String EMBEDDED_LIB_OS_ENCLAVE_STARTUP_THREAD_NAME = "async_lib_os_enclave_startup_thread";
+ private static final String HTTP_SERVER_PREFIX = "http://localhost:";
+ private static final String HTTP_SERVER_NAME = "/enclaveAgent";
+ private final static String JNI_EXTRACTED_PACKAGE_PATH = "jni/lib_jni_embedded_lib_os_enclave.so";
+ private final static String EMBEDDED_LIB_OS_ENCLAVE_SIGNED_PACKAGE_PATH = "lib_embedded_lib_os_enclave_load.tgz";
+ private final static String EMBEDDED_LIB_OS_ENCLAVE_SIGNED_PACKAGE_PATH_TAIL = "occlum_instance";
+ private static volatile LibOSExtractTempPath extractTempPath;
+ private static volatile EmbeddedLibOSEnclave singleInstance;
+
+ // enclaveHandle stores created enclave's handle id.
+ private long enclaveHandle;
+ private int portHost;
+ private int portEnclave;
+ private URL url;
+ private String httpURL;
+
+ static EmbeddedLibOSEnclave getEmbeddedLibOSEnclaveInstance(EnclaveDebug mode, EnclaveSimulate sim) throws EnclaveCreatingException {
+ synchronized (EmbeddedLibOSEnclave.class) {
+ if (singleInstance == null) {
+ singleInstance = new EmbeddedLibOSEnclave(mode, sim);
+ }
+ return singleInstance;
+ }
+ }
+
+ private EmbeddedLibOSEnclave(EnclaveDebug mode, EnclaveSimulate sim) throws EnclaveCreatingException {
+ // Set EnclaveContext for this enclave instance.
+ super(EnclaveType.EMBEDDED_LIB_OS, mode, new EnclaveServicesRecycler());
+ // Extract jni .so and signed tee .so from .jar file.
+ // Only once extract and load operation.
+ if (extractTempPath == null) {
+ synchronized (EmbeddedLibOSEnclave.class) {
+ if (extractTempPath == null) {
+ try {
+ String jniTempFilePath = ExtractLibrary.extractLibrary(
+ EmbeddedLibOSEnclave.class.getClassLoader(),
+ JNI_EXTRACTED_PACKAGE_PATH);
+ String embeddedLibOsSignedFilePath = ExtractLibrary.extractAndDeCompressTgz(
+ EmbeddedLibOSEnclave.class.getClassLoader(),
+ EMBEDDED_LIB_OS_ENCLAVE_SIGNED_PACKAGE_PATH) + "/" + EMBEDDED_LIB_OS_ENCLAVE_SIGNED_PACKAGE_PATH_TAIL;
+ extractTempPath = new EmbeddedLibOSEnclave.LibOSExtractTempPath(jniTempFilePath, embeddedLibOsSignedFilePath);
+ System.load(extractTempPath.getJniTempFilePath());
+ registerNatives();
+ } catch (IOException e) {
+ throw new EnclaveCreatingException("extracting embedded lib os enclave jni .so or signed .so failed.", e);
+ }
+ }
+ }
+ }
+
+ try {
+ portHost = getFreePort();
+ portEnclave = getFreePort();
+ httpURL = HTTP_SERVER_PREFIX + portEnclave + HTTP_SERVER_NAME;
+ url = new URL(httpURL);
+ // Attach to target enclave service by rmi.
+ attachToEnclaveAgent(mode, sim);
+ } catch (IOException e) {
+ throw new EnclaveCreatingException(e);
+ }
+ }
+
+ // apply a free port for localhost communication between host and enclave.
+ private int getFreePort() throws IOException {
+ try (ServerSocket serverSocket = new ServerSocket(0)) {
+ return serverSocket.getLocalPort();
+ }
+ }
+
+ private Future<EnclaveCreatingException> startupLibOSEnclaveAsync(EnclaveDebug mode, EnclaveSimulate sim) {
+ // Create embedded lib os enclave by native call asynchronously.
+ // Occlum embedded start up interface is occlum_pal_exec, it blocks until progress exit in enclave.
+ return Executors.newFixedThreadPool(1, new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r);
+ thread.setName(EMBEDDED_LIB_OS_ENCLAVE_STARTUP_THREAD_NAME);
+ thread.setDaemon(true);
+ return thread;
+ }
+ }).submit(() -> {
+ EnclaveCreatingException exception = null;
+ try {
+ nativeCreateEnclave(
+ mode.getValue(),
+ sim.getValue(),
+ portHost,
+ portEnclave,
+ EmbeddedLibOSEnclaveConfig.getEmbeddedLibOSEnclaveConfigInstance(),
+ extractTempPath.getLibOSSignedFilePath());
+ } catch (EnclaveCreatingException e) {
+ exception = e;
+ }
+ return exception;
+ });
+ }
+
+ // wait for enclave jvm start up and notify host.
+ private void waitForEnclaveStartup() throws IOException {
+ try (ServerSocket server = new ServerSocket(this.portHost)) {
+ server.setSoTimeout(EmbeddedLibOSEnclaveConfig.getEmbeddedLibOSEnclaveConfigInstance().getEmbeddedLibOSEnclaveStartupDuration());
+ server.accept();
+ }
+ }
+
+ // attach to enclave embedded lib os java service.
+ private void attachToEnclaveAgent(EnclaveDebug mode, EnclaveSimulate sim) throws EnclaveCreatingException {
+ startupLibOSEnclaveAsync(mode, sim);
+ try {
+ waitForEnclaveStartup();
+ } catch (IOException e) {
+ throw new EnclaveCreatingException(e);
+ }
+ }
+
+ private static native void registerNatives();
+
+ private native int nativeCreateEnclave(int mode, int sim, int portHost, int portEnclave, EmbeddedLibOSEnclaveConfig config, String path) throws EnclaveCreatingException;
+
+ private native int nativeDestroyEnclave(long enclaveHandler) throws EnclaveDestroyingException;
+
+ private byte[] remoteRequest(byte[] request, int connectTimeout, int inTimeout) throws IOException, InterruptedException {
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Connection", "Keep-Alive");
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ conn.setConnectTimeout(connectTimeout);
+ conn.setReadTimeout(inTimeout);
+ conn.connect();
+
+ try (OutputStream outputStream = conn.getOutputStream()) {
+ outputStream.write(request);
+ outputStream.flush();
+ }
+
+ try (InputStream inputStream = conn.getInputStream()) {
+ return inputStream.readAllBytes();
+ }
+ }
+
+ @Override
+ byte[] loadServiceNative(String service) throws ServicesLoadingException {
+ try {
+ SocketEnclaveInvocationContext context =
+ new SocketEnclaveInvocationContext(SocketEnclaveInvocationContext.SERVICE_LOADING, new ServiceHandler(service));
+ return remoteRequest(SerializationHelper.serialize(context), HTTP_CONNECT_TIMEOUT_MS, HTTP_READ_TIMEOUT_MS);
+ } catch (InterruptedException | IOException e) {
+ throw new ServicesLoadingException(e);
+ }
+ }
+
+ @Override
+ byte[] unloadServiceNative(ServiceHandler handler) throws ServicesUnloadingException {
+ try {
+ SocketEnclaveInvocationContext context =
+ new SocketEnclaveInvocationContext(SocketEnclaveInvocationContext.SERVICE_UNLOADING, handler);
+ return remoteRequest(SerializationHelper.serialize(context), HTTP_CONNECT_TIMEOUT_MS, HTTP_READ_TIMEOUT_MS);
+ } catch (InterruptedException | IOException e) {
+ throw new ServicesUnloadingException(e);
+ }
+ }
+
+ @Override
+ byte[] invokeMethodNative(EnclaveInvocationContext service) throws EnclaveMethodInvokingException {
+ try {
+ SocketEnclaveInvocationContext context =
+ new SocketEnclaveInvocationContext(SocketEnclaveInvocationContext.METHOD_INVOCATION, service);
+ // Should not set http timeout parameter in method invoke, the duration is deeply depends on user service.
+ return remoteRequest(SerializationHelper.serialize(context), HTTP_CONNECT_TIMEOUT_MS, 0x0);
+ } catch (InterruptedException | IOException e) {
+ throw new EnclaveMethodInvokingException(e);
+ }
+ }
+
+ @Override
+ AttestationReport generateAttestationReportNative(byte[] userData) throws RemoteAttestationException {
+ try {
+ SocketEnclaveInvocationContext context =
+ new SocketEnclaveInvocationContext(SocketEnclaveInvocationContext.REMOTE_ATTESTATION_GENERATE, userData);
+ EnclaveInvocationResult resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(
+ remoteRequest(SerializationHelper.serialize(context), HTTP_CONNECT_TIMEOUT_MS, HTTP_READ_REMOTE_ATTESTATION_TIMEOUT_MS));
+ if (resultWrapper.getException() != null) {
+ throw resultWrapper.getException();
+ }
+ EmbeddedLibOSInnerAttestationReport report = (EmbeddedLibOSInnerAttestationReport) resultWrapper.getResult();
+ return new EmbeddedLibOSAttestationReport(
+ report.getQuote(),
+ report.getMrSigner(),
+ report.getMrEnclave(),
+ report.getUserData());
+ } catch (InterruptedException | IOException | ClassNotFoundException e) {
+ throw new RemoteAttestationException(e);
+ } catch (Throwable e) {
+ throw new RemoteAttestationException(e);
+ }
+ }
+
+ static int verifyAttestationReport(byte[] quote) throws RemoteAttestationException {
+ return SGXRemoteAttestationVerify.VerifyAttestationReport(quote);
+ }
+
+ @Override
+ public void destroy() throws EnclaveDestroyingException {
+ synchronized (EmbeddedLibOSEnclave.class) {
+ // Because enclave libos occlum doesn't support creating a new occlum instance even
+ // destroy the pre-created occlum instance, Do nothing here.
+ // embedded lib os occlum instance in JavaEnclave is similar with a singleton instance.
+ }
+ }
+
+ class LibOSExtractTempPath {
+ private final String jniTempFilePath;
+ private final String libOsSignedFilePath;
+
+ LibOSExtractTempPath(String jniTempFilePath, String teeSdkSignedFilePath) {
+ this.jniTempFilePath = jniTempFilePath;
+ this.libOsSignedFilePath = teeSdkSignedFilePath;
+ }
+
+ String getJniTempFilePath() {
+ return jniTempFilePath;
+ }
+
+ String getLibOSSignedFilePath() {
+ return libOsSignedFilePath;
+ }
+ }
+}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclaveConfig.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclaveConfig.java
new file mode 100644
index 0000000..8eecb71
--- /dev/null
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclaveConfig.java
@@ -0,0 +1,83 @@
+package com.alibaba.confidentialcomputing.host;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import static com.alibaba.confidentialcomputing.host.ExtractLibrary.extractLibrary;
+
+class EmbeddedLibOSEnclaveConfig {
+ private final static String EMBEDDED_LIB_OS_ENCLAVE_CONFIG_FILE = "embedded_libos_enclave.json";
+ private static String configFilePath;
+ private static EmbeddedLibOSEnclaveConfig config;
+
+ private boolean debuggable = false;
+ private int agentHttpHandlerThreadPoolSize = 5;
+ private int embeddedLibOSEnclaveStartupDuration = (int) TimeUnit.MINUTES.toMillis(1);
+ private String libOSLogLevel = "off";
+ private String[] enclaveJVMArgs = null;
+
+ static {
+ try {
+ configFilePath = extractLibrary(EmbeddedLibOSEnclave.class.getClassLoader(), EMBEDDED_LIB_OS_ENCLAVE_CONFIG_FILE);
+ File file = new File(configFilePath);
+ String content = Files.readString(file.toPath(), Charset.forName("UTF-8"));
+ JSONObject jsonObject = new JSONObject(content);
+ boolean debuggable = jsonObject.getBoolean("debuggable");
+ int agentHttpHandlerThreadPoolSize = jsonObject.getInt("agent_http_handler_thread_pool_size");
+ int embeddedLibOSEnclaveStartupDuration = jsonObject.getInt("enclave_startup_duration_ms");
+ String libOSLogLevel = jsonObject.getString("log_level");
+ JSONArray jvmArgs = jsonObject.getJSONArray("enclave_jvm_args");
+ List<String> jvmArgsList = new ArrayList<>();
+ for (int i = 0; i < jvmArgs.length(); i++) {
+ jvmArgsList.add(jvmArgs.getString(i));
+ }
+ String[] enclaveJVMArgs = jvmArgsList.toArray(new String[jvmArgsList.size()]);
+ config = new EmbeddedLibOSEnclaveConfig(debuggable, agentHttpHandlerThreadPoolSize, embeddedLibOSEnclaveStartupDuration, libOSLogLevel, enclaveJVMArgs);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ static EmbeddedLibOSEnclaveConfig getEmbeddedLibOSEnclaveConfigInstance() {
+ return config;
+ }
+
+ private EmbeddedLibOSEnclaveConfig(boolean debuggable, int agentHttpHandlerThreadPoolSize, int embeddedLibOSEnclaveStartupDuration, String libOSLogLevel, String[] jvmArgs) {
+ this.debuggable = debuggable;
+ this.agentHttpHandlerThreadPoolSize = agentHttpHandlerThreadPoolSize;
+ this.embeddedLibOSEnclaveStartupDuration = embeddedLibOSEnclaveStartupDuration;
+ this.libOSLogLevel = libOSLogLevel;
+ this.enclaveJVMArgs = jvmArgs;
+ }
+
+ EnclaveDebug getDebuggable() {
+ if (this.debuggable) {
+ return EnclaveDebug.DEBUG;
+ }
+ return EnclaveDebug.RELEASE;
+ }
+
+ int getAgentHttpHandlerThreadPoolSize() {
+ return this.agentHttpHandlerThreadPoolSize;
+ }
+
+ int getEmbeddedLibOSEnclaveStartupDuration() {
+ return this.embeddedLibOSEnclaveStartupDuration;
+ }
+
+ String getLibOSLogLevel() {
+ return this.libOSLogLevel;
+ }
+
+ String[] getEnclaveJVMArgs() {
+ return this.enclaveJVMArgs;
+ }
+}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveConfigure.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveConfigure.java
index 208e4de..c958b4c 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveConfigure.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveConfigure.java
@@ -25,6 +25,9 @@ class EnclaveConfigure {
case "TEE_SDK":
enclaveType = EnclaveType.TEE_SDK;
break;
+ case "EMBEDDED_LIB_OS":
+ enclaveType = EnclaveType.EMBEDDED_LIB_OS;
+ break;
case "MOCK_IN_JVM":
enclaveType = EnclaveType.MOCK_IN_JVM;
break;
@@ -77,6 +80,8 @@ class EnclaveConfigure {
return new MockInSvmEnclave();
case TEE_SDK:
return new TeeSdkEnclave(enclaveDebug);
+ case EMBEDDED_LIB_OS:
+ return EmbeddedLibOSEnclave.getEmbeddedLibOSEnclaveInstance(EmbeddedLibOSEnclaveConfig.getEmbeddedLibOSEnclaveConfigInstance().getDebuggable(), EnclaveSimulate.HARDWARE);
case NONE:
default:
throw new EnclaveCreatingException("enclave type is not supported.");
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java
index bf8ab83..c0f2156 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java
@@ -3,7 +3,7 @@ package com.alibaba.confidentialcomputing.host;
/**
* An enumeration of enclave debug mode.
*/
-enum EnclaveDebug {
+public enum EnclaveDebug {
/**
* For MOCK_IN_JVM and MOCK_IN_SVM, there is no real enclave environment.
*/
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveSimulate.java
similarity index 53%
copy from sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java
copy to sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveSimulate.java
index bf8ab83..ce8b180 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveDebug.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveSimulate.java
@@ -1,25 +1,25 @@
package com.alibaba.confidentialcomputing.host;
/**
- * An enumeration of enclave debug mode.
+ * An enumeration of enclave simulate mode.
*/
-enum EnclaveDebug {
+enum EnclaveSimulate {
/**
* For MOCK_IN_JVM and MOCK_IN_SVM, there is no real enclave environment.
*/
NONE(0),
/**
- * TEE_SDK could debug by gdb tool in this mode.
+ * TEE_SDK/EMBEDDED_LIB_OS could run in simulate mode without sgx.
*/
- DEBUG(1),
+ SIMULATE(1),
/**
- * TEE_SDK could not debug by gdb tool in this mode.
+ * TEE_SDK/EMBEDDED_LIB_OS could run in hardware mode with sgx.
*/
- RELEASE(2);
+ HARDWARE(2);
private final int value;
- EnclaveDebug(int value) {
+ EnclaveSimulate(int value) {
this.value = value;
}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveType.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveType.java
index 8e7f098..45155c8 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveType.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/EnclaveType.java
@@ -23,4 +23,11 @@ public enum EnclaveType {
* host application runs in jvm environment, and enclave package were loaded by host.
*/
TEE_SDK,
+ /**
+ * An enclave based on Intel's SGX2, with OCCLUM Libos. Enclave application
+ * was compiled to .class files and packaged as a jar file, there is a jvm runs based
+ * on enclave's occlum libos. host application runs in jvm environment, and enclave
+ * package were loaded by host.
+ */
+ EMBEDDED_LIB_OS,
}
\ No newline at end of file
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ExtractLibrary.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ExtractLibrary.java
index 1ce65e0..890c624 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ExtractLibrary.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ExtractLibrary.java
@@ -1,15 +1,19 @@
package com.alibaba.confidentialcomputing.host;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.utils.IOUtils;
+
+import java.io.*;
+import java.util.zip.GZIPInputStream;
/**
- * JavaEnclave building tool will put native .so files into a java .jar file,
- * ExtractLibrary will extracts tee sdk's jni .so and enclave signed .so into
- * a temp path from the jar file. it's very convenient for deployment.
+ * JavaEnclave building tool will put native .so files or .tgz files into a java .jar file,
+ * ExtractLibrary will extract tee sdk's jni .so and enclave signed .so into a temp path
+ * from the jar file.
+ * extractAndDeCompressTgz will extract embedded lib os enclave's compressed .tgz image and
+ * decompress .tgz file into target temp path from the jar file.
+ * it's very convenient for deployment.
*/
public final class ExtractLibrary {
/**
@@ -35,4 +39,63 @@ public final class ExtractLibrary {
}
return fullPath;
}
+
+ /**
+ * get the temp file's full path.
+ *
+ * @param classLoader define the search scope for compressed fie .tgz.
+ * @param name lib.tgz name in the jar file.
+ * @return the temp decompression file's full path.
+ */
+ public static String extractAndDeCompressTgz(ClassLoader classLoader, String name) throws IOException {
+ String fullPath = extractLibrary(classLoader, name);
+ String destDir = fullPath.replace(".tgz", "");
+ deCompressTgz(fullPath, destDir);
+ return destDir;
+ }
+
+ private static void deCompressTgz(String fullPath, String destDir) throws IOException {
+ TarArchiveEntry entry;
+ TarArchiveEntry[] subEntries;
+ File subEntryFile = null;
+ try (FileInputStream fis = new FileInputStream(fullPath);
+ GZIPInputStream gis = new GZIPInputStream(fis);
+ TarArchiveInputStream tis = new TarArchiveInputStream(gis)) {
+ while ((entry = tis.getNextTarEntry()) != null) {
+ StringBuilder entryFileName = new StringBuilder();
+ entryFileName.append(destDir).append(File.separator).append(entry.getName());
+ File entryFile = new File(entryFileName.toString());
+ if (entry.isDirectory()) {
+ if (!entryFile.exists()) {
+ entryFile.mkdir();
+ }
+ subEntries = entry.getDirectoryEntries();
+ for (int i = 0; i < subEntries.length; i++) {
+ try (OutputStream out = new FileOutputStream(subEntryFile)) {
+ subEntryFile = new File(entryFileName + File.separator + subEntries[i].getName());
+ IOUtils.copy(tis, out);
+ }
+ }
+ } else {
+ checkFileExists(entryFile);
+ OutputStream out = new FileOutputStream(entryFile);
+ IOUtils.copy(tis, out);
+ out.close();
+ }
+ }
+ }
+ }
+
+ private static void checkFileExists(File file) throws IOException {
+ if (file.isDirectory()) {
+ if (!file.exists()) {
+ file.mkdir();
+ }
+ } else {
+ if (file.getParentFile() != null && !file.getParentFile().exists()) {
+ file.getParentFile().mkdirs();
+ }
+ file.createNewFile();
+ }
+ }
}
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 dc2e982..c25f114 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,5 +1,7 @@
package com.alibaba.confidentialcomputing.host;
+import com.alibaba.confidentialcomputing.common.EnclaveInvocationContext;
+import com.alibaba.confidentialcomputing.common.ServiceHandler;
import com.alibaba.confidentialcomputing.host.exception.*;
/**
@@ -22,17 +24,17 @@ class MockInJvmEnclave extends AbstractEnclave {
}
@Override
- byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
+ byte[] loadServiceNative(String service) throws ServicesLoadingException {
return null;
}
@Override
- byte[] unloadServiceNative(byte[] payload) throws ServicesUnloadingException {
+ byte[] unloadServiceNative(ServiceHandler handler) throws ServicesUnloadingException {
return null;
}
@Override
- byte[] invokeMethodNative(byte[] payload) throws EnclaveMethodInvokingException {
+ byte[] invokeMethodNative(EnclaveInvocationContext context) throws EnclaveMethodInvokingException {
return null;
}
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 d953afe..340553e 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,9 @@
package com.alibaba.confidentialcomputing.host;
+import com.alibaba.confidentialcomputing.common.EnclaveInvocationContext;
+import com.alibaba.confidentialcomputing.common.SerializationHelper;
+import com.alibaba.confidentialcomputing.common.ServiceHandler;
import com.alibaba.confidentialcomputing.host.exception.*;
-import com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
import java.io.IOException;
@@ -68,17 +70,35 @@ class MockInSvmEnclave extends AbstractEnclave {
}
@Override
- byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
+ byte[] loadServiceNative(String service) throws ServicesLoadingException {
+ byte[] payload;
+ try {
+ payload = SerializationHelper.serialize(service);
+ } catch (IOException e) {
+ throw new ServicesLoadingException("service name serialization failed.", e);
+ }
return nativeLoadService(enclaveSvmSdkHandle, isolateHandle, payload);
}
@Override
- byte[] unloadServiceNative(byte[] payload) throws ServicesUnloadingException {
+ byte[] unloadServiceNative(ServiceHandler handler) throws ServicesUnloadingException {
+ byte[] payload;
+ try {
+ payload = SerializationHelper.serialize(handler);
+ } catch (IOException e) {
+ throw new ServicesUnloadingException("unload service serialization failed.", e);
+ }
return nativeUnloadService(enclaveSvmSdkHandle, isolateHandle, payload);
}
@Override
- byte[] invokeMethodNative(byte[] payload) throws EnclaveMethodInvokingException {
+ byte[] invokeMethodNative(EnclaveInvocationContext context) throws EnclaveMethodInvokingException {
+ byte[] payload;
+ try {
+ payload = SerializationHelper.serialize(context);
+ } catch (IOException e) {
+ throw new EnclaveMethodInvokingException("EnclaveInvokeMetaWrapper serialization failed.", e);
+ }
return nativeInvokeMethod(enclaveSvmSdkHandle, isolateHandle, payload);
}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java
index db1a6be..8666dcb 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/ProxyEnclaveInvocationHandler.java
@@ -50,21 +50,23 @@ class ProxyEnclaveInvocationHandler implements InvocationHandler, Runnable {
result = enclave.InvokeEnclaveMethod(methodInvokeMetaWrapper);
} catch (EnclaveMethodInvokingException e) {
// Get cause exception if it has one.
- ConfidentialComputingException enclaveException = (ConfidentialComputingException) e.getCause();
- Throwable enclaveCauseException = enclaveException.getCause();
- Class<?>[] exceptionTypes = method.getExceptionTypes();
- if (enclaveCauseException instanceof InvocationTargetException) {
- // Check whether cause exception matches one of the method's exception declaration.
- // If it's true, it illustrates that an exception happened in enclave when the service
- // method was invoked in enclave, we should throw this exception directly and user will
- // handle it.
- // If it's false, it illustrates that an exception happened in host side or enclave side,
- // but the exception is not belong to the method's declaration. In the case we should throw
- // EnclaveMethodInvokingException again.
- Throwable rootCause = enclaveCauseException.getCause();
- for (Class<?> exception : exceptionTypes) {
- if (exception == rootCause.getClass()) {
- throw rootCause;
+ Throwable causeException = e.getCause();
+ if (causeException instanceof ConfidentialComputingException) {
+ Throwable enclaveCauseException = causeException.getCause();
+ Class<?>[] exceptionTypes = method.getExceptionTypes();
+ if (enclaveCauseException instanceof InvocationTargetException) {
+ // Check whether cause exception matches one of the method's exception declaration.
+ // If it's true, it illustrates that an exception happened in enclave when the service
+ // method was invoked in enclave, we should throw this exception directly and user will
+ // handle it.
+ // If it's false, it illustrates that an exception happened in host side or enclave side,
+ // but the exception is not belong to the method's declaration. In the case we should throw
+ // EnclaveMethodInvokingException again.
+ Throwable rootCause = enclaveCauseException.getCause();
+ for (Class<?> exception : exceptionTypes) {
+ if (exception == rootCause.getClass()) {
+ throw rootCause;
+ }
}
}
}
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 239a35d..20255e6 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
@@ -19,6 +19,8 @@ public final class RemoteAttestation {
System.arraycopy(userData, 0, result, 0, userData.length);
} else if (userData.length > 64) {
throw new RemoteAttestationException("enclave remote attestation user data length exceeds 64 bytes.");
+ } else {
+ result = userData;
}
return result;
}
@@ -59,8 +61,10 @@ public final class RemoteAttestation {
switch (report.getEnclaveType()) {
case TEE_SDK:
return TeeSdkEnclave.verifyAttestationReport(report.getQuote());
+ case EMBEDDED_LIB_OS:
+ return EmbeddedLibOSEnclave.verifyAttestationReport(report.getQuote());
default:
- throw new RemoteAttestationException("enclaveType must be TEE_SDK.");
+ throw new RemoteAttestationException("enclaveType must be TEE_SDK or EMBEDDED_LIB_OS.");
}
}
}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXAttestationReport.java
similarity index 56%
copy from sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
copy to sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXAttestationReport.java
index 6ab0f44..3d66eae 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXAttestationReport.java
@@ -1,16 +1,28 @@
package com.alibaba.confidentialcomputing.host;
/**
- * TeeSdkAttestationReport parse more details information from a tee sdk type enclave's remote attestation report.
+ * SGX type enclave's remote attestation report.
*/
-public final class TeeSdkAttestationReport extends AttestationReport {
+public class SGXAttestationReport extends AttestationReport {
private final byte[] mrSigner;
private final byte[] mrEnclave;
+ private final byte[] userData;
- TeeSdkAttestationReport(byte[] quote, byte[] mrSigner, byte[] mrEnclave) {
- super(EnclaveType.TEE_SDK, quote);
+ SGXAttestationReport(EnclaveType type, byte[] quote, byte[] mrSigner, byte[] mrEnclave, byte[] userData) {
+ super(type, quote);
this.mrSigner = mrSigner;
this.mrEnclave = mrEnclave;
+ this.userData = userData;
+ }
+
+ /**
+ * Get enclave userData from an enclave's remote attestation report.
+ * <p>
+ *
+ * @return Remote attestation userData value which is from user.
+ */
+ public byte[] getUserData() {
+ return this.userData;
}
/**
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
index c8c0343..2db853d 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXRemoteAttestationVerify.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/SGXRemoteAttestationVerify.java
@@ -1,6 +1,5 @@
package com.alibaba.confidentialcomputing.host;
-import com.alibaba.confidentialcomputing.host.ExtractLibrary;
import com.alibaba.confidentialcomputing.host.exception.RemoteAttestationException;
import java.io.IOException;
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
index 6ab0f44..4f75a2c 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/TeeSdkAttestationReport.java
@@ -3,33 +3,8 @@ 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;
+public final class TeeSdkAttestationReport extends SGXAttestationReport {
+ TeeSdkAttestationReport(byte[] quote, byte[] mrSigner, byte[] mrEnclave, byte[] userData) {
+ super(EnclaveType.TEE_SDK, quote, mrSigner, mrEnclave, userData);
}
}
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 50bd225..36052b5 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,5 +1,8 @@
package com.alibaba.confidentialcomputing.host;
+import com.alibaba.confidentialcomputing.common.EnclaveInvocationContext;
+import com.alibaba.confidentialcomputing.common.SerializationHelper;
+import com.alibaba.confidentialcomputing.common.ServiceHandler;
import com.alibaba.confidentialcomputing.host.exception.*;
import java.io.IOException;
@@ -75,17 +78,35 @@ class TeeSdkEnclave extends AbstractEnclave {
}
@Override
- byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
+ byte[] loadServiceNative(String service) throws ServicesLoadingException {
+ byte[] payload;
+ try {
+ payload = SerializationHelper.serialize(service);
+ } catch (IOException e) {
+ throw new ServicesLoadingException("service name serialization failed.", e);
+ }
return nativeLoadService(enclaveHandle, isolateHandle, payload);
}
@Override
- byte[] unloadServiceNative(byte[] payload) throws ServicesUnloadingException {
+ byte[] unloadServiceNative(ServiceHandler handler) throws ServicesUnloadingException {
+ byte[] payload;
+ try {
+ payload = SerializationHelper.serialize(handler);
+ } catch (IOException e) {
+ throw new ServicesUnloadingException("unload service serialization failed.", e);
+ }
return nativeUnloadService(enclaveHandle, isolateHandle, payload);
}
@Override
- byte[] invokeMethodNative(byte[] payload) throws EnclaveMethodInvokingException {
+ byte[] invokeMethodNative(EnclaveInvocationContext context) throws EnclaveMethodInvokingException {
+ byte[] payload;
+ try {
+ payload = SerializationHelper.serialize(context);
+ } catch (IOException e) {
+ throw new EnclaveMethodInvokingException("EnclaveInvokeMetaWrapper serialization failed.", e);
+ }
return nativeInvokeMethod(enclaveHandle, isolateHandle, payload);
}
diff --git a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java
index 53307bd..44c4d6a 100644
--- a/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java
+++ b/sdk/host/src/main/java/com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException.java
@@ -8,6 +8,7 @@ import com.alibaba.confidentialcomputing.common.exception.ConfidentialComputingE
* Programmers need to handle EnclaveCreatingException seriously.
*/
public class EnclaveCreatingException extends ConfidentialComputingException {
+
/**
* @param info exception information.
*/
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
index fda3ec9..a38e0b2 100644
--- a/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/Makefile
+++ b/sdk/host/src/main/native/cpp/attestation_verify/sgx/jni/Makefile
@@ -10,6 +10,7 @@ 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:
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
index fa53006..22b9478 100644
--- 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
@@ -65,7 +65,6 @@ verify_result_wrapper ecdsa_quote_verification_qvl(const uint8_t* quote, uint32_
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;
}
diff --git a/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/Makefile b/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/Makefile
new file mode 100644
index 0000000..cdd6548
--- /dev/null
+++ b/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/Makefile
@@ -0,0 +1,13 @@
+include $(NATIVE_BASE_DIR)/config/config.mk
+include $(NATIVE_BASE_DIR)/config/platform/libos_occlum_enclave/jni/config.mk
+
+.PHONY: all build clean
+
+all: build
+
+build:
+ $(CC) $(C_FLAGS) -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(shell uname -s | tr A-Z a-z) -fPIC jni_occlum_enclave.c
+ $(CC) jni_occlum_enclave.o $(LINK_FLAGS) -fPIC -shared -o $(BIN)/platform/libos_occlum_enclave/jni/lib_jni_embedded_lib_os_enclave.so
+
+clean:
+ rm -rf *.o $(BIN)/platform/libos_occlum_enclave/jni/lib_jni_embedded_lib_os_enclave.so
\ No newline at end of file
diff --git a/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.c b/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.c
new file mode 100644
index 0000000..8099c79
--- /dev/null
+++ b/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.c
@@ -0,0 +1,206 @@
+#include <linux/limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <occlum_pal_api.h>
+
+#include "jni_occlum_enclave.h"
+
+#define OCCLUM_CMD_ARGS_MAX_LENGTH 50
+#define OCCLUM_HARDWARE_PAL_PATH "/opt/occlum/build/lib/libocclum-pal.so"
+#define OCCLUM_SIMULATE_PAL_PATH "/opt/occlum/build/lib/libocclum-pal_sim.so"
+#define OCCLUM_CMD_PATH "/usr/lib/dragonwell11/jre/bin/java"
+#define OCCLUM_JVM_CMD_CP "-cp"
+#define OCCLUM_JVM_CMD_JAR_PATH "/usr/app/*"
+#define OCCLUM_JVM_CMD_MAIN_CLASS "com.alibaba.confidentialcomputing.enclave.agent.EnclaveAgent"
+
+void set_long_field_value(JNIEnv *env, jclass class_mirror, jobject obj, const char *field_name, jlong value) {
+ jfieldID field_id = (*env)->GetFieldID(env, class_mirror, field_name, "J");
+ (*env)->SetLongField(env, obj, field_id, value);
+}
+
+jint parse_http_handler_thread_pool_size(JNIEnv *env, jobject config) {
+ jclass config_class = (*env)->GetObjectClass(env, config);
+ jmethodID get_thread_pool_id = (*env)->GetMethodID(env, config_class, "getAgentHttpHandlerThreadPoolSize", "()I");
+ return (*env)->CallObjectMethod(env, config, get_thread_pool_id);
+}
+
+jstring parse_log_level(JNIEnv *env, jobject config) {
+ jclass config_class = (*env)->GetObjectClass(env, config);
+ jmethodID get_log_level_id = (*env)->GetMethodID(env, config_class, "getLibOSLogLevel", "()Ljava/lang/String;");
+ return (*env)->CallObjectMethod(env, config, get_log_level_id);
+}
+
+jobjectArray parse_jvm_cmd_args(JNIEnv *env, jobject config) {
+ jclass config_class = (*env)->GetObjectClass(env, config);
+ jmethodID get_jvm_args_id = (*env)->GetMethodID(env, config_class, "getEnclaveJVMArgs", "()[Ljava/lang/String;");
+ return (*env)->CallObjectMethod(env, config, get_jvm_args_id);
+}
+
+static JNINativeMethod tee_lib_os_methods[] = {
+ {"nativeCreateEnclave", ENCLAVE_CREATING_SIGNATURE, (void *)&JavaEnclave_TeeLibOSNativeCreateEnclave},
+ {"nativeDestroyEnclave", "(J)I", (void *)&JavaEnclave_TeeLibOSNativeDestroyEnclave},
+};
+
+JNIEXPORT void JNICALL
+Java_com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave_registerNatives(JNIEnv *env, jclass cls) {
+ (*env)->RegisterNatives(env, cls, tee_lib_os_methods, sizeof(tee_lib_os_methods)/sizeof(tee_lib_os_methods[0]));
+}
+
+JNIEXPORT jint JNICALL JavaEnclave_TeeLibOSNativeCreateEnclave(JNIEnv *env, jobject obj, jint debug, jint sim, jint portHost, jint portEnclave, jobject config, jstring path) {
+ char* occlum_pal_path = OCCLUM_HARDWARE_PAL_PATH;
+ if (sim == 1) {
+ occlum_pal_path = OCCLUM_SIMULATE_PAL_PATH;
+ }
+
+ void *lib_occlum_pal_handle = dlopen(occlum_pal_path, RTLD_LOCAL | RTLD_LAZY);
+ if (!lib_occlum_pal_handle) {
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlopen occlum_pal_path.so failed.")
+ }
+
+ // set .so file handle back to java enclave object.
+ jclass class_enclave = (*env)->GetObjectClass(env, obj);
+ set_long_field_value(env, class_enclave, obj, "enclaveHandle", (jlong)lib_occlum_pal_handle);
+
+ // lookup symbol occlum_pal_init in libocclum-pal.so
+ int (*occlum_pal_init)(const struct occlum_pal_attr *attr);
+ occlum_pal_init = (int (*)(const struct occlum_pal_attr *))dlsym((void *)lib_occlum_pal_handle, "occlum_pal_init");
+ if (!occlum_pal_init) {
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlsym symbol occlum_pal_init failed.")
+ }
+
+ /* lookup symbol occlum_pal_create_process in libocclum-pal.so */
+ int (*occlum_pal_create_process)(struct occlum_pal_create_process_args *args);
+ occlum_pal_create_process = (int (*)(struct occlum_pal_create_process_args *))dlsym((void *)lib_occlum_pal_handle, "occlum_pal_create_process");
+ if (!occlum_pal_create_process) {
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlsym symbol occlum_pal_create_process failed.")
+ }
+
+ // lookup symbol occlum_pal_exec in libocclum-pal.so
+ int (*occlum_pal_exec)(struct occlum_pal_exec_args *args);
+ occlum_pal_exec = (int (*)(struct occlum_pal_exec_args *))dlsym((void *)lib_occlum_pal_handle, "occlum_pal_exec");
+ if (!occlum_pal_exec) {
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: dlsym symbol occlum_pal_exec failed.")
+ }
+
+ // parse occlum enclave log level.
+ jstring log_level = parse_log_level(env, config);
+ const char *log_level_str = (*env)->GetStringUTFChars(env, log_level, 0);
+ const char *path_str = (path == 0) ? 0 : (*env)->GetStringUTFChars(env, path, 0);
+ occlum_pal_attr_t pal_attr = OCCLUM_PAL_ATTR_INITVAL;
+ pal_attr.instance_dir = path_str;
+ pal_attr.log_level = log_level_str;
+ if (occlum_pal_init(&pal_attr) < 0) {
+ (*env)->ReleaseStringUTFChars(env, path, path_str);
+ (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: occlum_pal_init failed.")
+ }
+
+ const char *cmd_path = OCCLUM_CMD_PATH;
+ char *cmd_args[OCCLUM_CMD_ARGS_MAX_LENGTH] = {NULL};
+ t_jvm_args jvm_args_record[OCCLUM_CMD_ARGS_MAX_LENGTH] = {NULL};
+
+ // parse jvm args from user config file.
+ cmd_args[0] = cmd_path;
+ jobjectArray jvm_args = parse_jvm_cmd_args(env, config);
+ jsize length = (*env)->GetArrayLength(env, jvm_args);
+ if (length >= OCCLUM_CMD_ARGS_MAX_LENGTH) {
+ (*env)->ReleaseStringUTFChars(env, path, path_str);
+ (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: jvm args number exceeds max limitation 50.")
+ }
+
+ // parse jvm args and cache them in jvm_args_record for later release.
+ int index = 0x0;
+ for (; index < length; index++) {
+ jvm_args_record[index].handler = (jstring)(*env)->GetObjectArrayElement(env, jvm_args, index);
+ jvm_args_record[index].handler_str = (char *)(*env)->GetStringUTFChars(env, jvm_args_record[index].handler, 0);
+ cmd_args[1+index] = jvm_args_record[index].handler_str;
+ }
+ // add cp path, main class name in cmd_args's tail.
+ cmd_args[1+index++] = OCCLUM_JVM_CMD_CP;
+ cmd_args[1+index++] = OCCLUM_JVM_CMD_JAR_PATH;
+ cmd_args[1+index++] = OCCLUM_JVM_CMD_MAIN_CLASS;
+
+ // add portHost number as java args.
+ char port_host_buf[10];
+ sprintf(port_host_buf, "%d", portHost);
+ cmd_args[1+index++] = port_host_buf;
+
+ // add portEnclave number as java args.
+ char port_enclave_buf[10];
+ sprintf(port_enclave_buf, "%d", portEnclave);
+ cmd_args[1+index++] = port_enclave_buf;
+
+ // add http thread pool size as java args.
+ char thread_pool_size[10];
+ sprintf(thread_pool_size, "%d", parse_http_handler_thread_pool_size(env, config));
+ cmd_args[1+index] = thread_pool_size;
+
+ struct occlum_stdio_fds io_fds = {
+ .stdin_fd = STDIN_FILENO,
+ .stdout_fd = STDOUT_FILENO,
+ .stderr_fd = STDERR_FILENO,
+ };
+
+ // Use Occlum PAL to create new process
+ int libos_tid = 0;
+ struct occlum_pal_create_process_args create_process_args = {
+ .path = cmd_path,
+ .argv = cmd_args,
+ .env = NULL,
+ .stdio = (const struct occlum_stdio_fds *) &io_fds,
+ .pid = &libos_tid,
+ };
+ if (occlum_pal_create_process(&create_process_args) < 0) {
+ (*env)->ReleaseStringUTFChars(env, path, path_str);
+ (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
+ for (int i = 0x0; i < length; i++) {
+ (*env)->ReleaseStringUTFChars(env, jvm_args_record[i].handler, jvm_args_record[i].handler_str);
+ }
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: occlum_pal_create_process failed.")
+ }
+
+ // Use Occlum PAL to execute the cmd
+ int exit_status = 0;
+ struct occlum_pal_exec_args exec_args = {
+ .pid = libos_tid,
+ .exit_value = &exit_status,
+ };
+ // occlum_pal_exec will block until application run in occlum enclave exit.
+ if (occlum_pal_exec(&exec_args) < 0) {
+ (*env)->ReleaseStringUTFChars(env, path, path_str);
+ (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
+ for (int i = 0x0; i < length; i++) {
+ (*env)->ReleaseStringUTFChars(env, jvm_args_record[i].handler, jvm_args_record[i].handler_str);
+ }
+ THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee lib os enclave: occlum_pal_exec failed.")
+ }
+
+ (*env)->ReleaseStringUTFChars(env, path, path_str);
+ (*env)->ReleaseStringUTFChars(env, log_level, log_level_str);
+ for (int i = 0x0; i < length; i++) {
+ (*env)->ReleaseStringUTFChars(env, jvm_args_record[i].handler, jvm_args_record[i].handler_str);
+ }
+ return 0;
+}
+
+JNIEXPORT jint JNICALL JavaEnclave_TeeLibOSNativeDestroyEnclave(JNIEnv *env, jobject obj, jlong handler) {
+ // lookup symbol occlum_pal_destroy in libocclum-pal.so
+ int (*occlum_pal_destroy)(void);
+ occlum_pal_destroy = (int (*)(void))dlsym((void *)handler, "occlum_pal_destroy");
+
+ if (!occlum_pal_destroy) {
+ THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "destroy tee lib os enclave: dlsym symbol occlum_pal_destroy failed.")
+ }
+
+ if (occlum_pal_destroy() != 0x0) {
+ THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "destroy tee lib os enclave: occlum_pal_destroy failed.")
+ }
+
+ if (dlclose((void *)handler) != 0x0) {
+ THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "destroy tee lib os enclave: close occlum_pal_path.so failed.")
+ }
+}
\ No newline at end of file
diff --git a/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.h b/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.h
new file mode 100644
index 0000000..c188536
--- /dev/null
+++ b/sdk/host/src/main/native/cpp/platform/libos_occlum_enclave/jni/jni_occlum_enclave.h
@@ -0,0 +1,60 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave */
+
+#ifndef _Included_com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave
+#define _Included_com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ENCLAVE_CREATING_SIGNATURE "(IIIILcom/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclaveConfig;Ljava/lang/String;)I"
+#define ENCLAVE_CREATING_EXCEPTION "com/alibaba/confidentialcomputing/host/exception/EnclaveCreatingException"
+#define ENCLAVE_DESTROYING_EXCEPTION "com/alibaba/confidentialcomputing/host/exception/EnclaveDestroyingException"
+
+typedef struct {
+ jstring handler;
+ char* handler_str;
+} t_jvm_args;
+
+#define THROW_EXCEPTION(env, exception, info) \
+{ \
+ jclass ra_class = (*env)->FindClass(env, exception); \
+ if (ra_class == NULL) { \
+ fprintf(stderr, "JavaEnclave Error: "); \
+ fprintf(stderr, exception); \
+ fprintf(stderr, " class loading failed.\n"); \
+ return; \
+ } \
+ (*env)->ThrowNew(env, ra_class, info); \
+ return; \
+}
+
+/*
+ * Class: com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave
+ * Method: registerNatives
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave_registerNatives
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave
+ * Method: nativeCreateEnclave
+ * Signature: (IIIILcom/alibaba/confidentialcomputing/host/EmbeddedLibOSEnclaveConfig;Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL JavaEnclave_TeeLibOSNativeCreateEnclave
+ (JNIEnv *, jobject, jint, jint, jint, jint, jobject, jstring);
+
+/*
+ * Class: com_alibaba_confidentialcomputing_host_EmbeddedLibOSEnclave
+ * Method: nativeDestroyEnclave
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL JavaEnclave_TeeLibOSNativeDestroyEnclave
+ (JNIEnv *, jobject, jlong);
+
+#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 32c189b..5510baa 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
@@ -134,7 +134,6 @@ JavaEnclave_MockSVMNativeSvmAttachIsolate(JNIEnv *env, jobject obj, jlong enclav
}
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.")
}
@@ -145,7 +144,7 @@ JavaEnclave_MockSVMNativeSvmAttachIsolate(JNIEnv *env, jobject obj, jlong enclav
return 0;
}
-JNIEXPORT jobject JNICALL
+JNIEXPORT jbyteArray JNICALL
JavaEnclave_MockSVMNativeLoadService(JNIEnv *env, jobject obj, jlong enclave_handler, jlong isolate_handler, jbyteArray load_service_payload) {
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) {
@@ -154,7 +153,7 @@ JavaEnclave_MockSVMNativeLoadService(JNIEnv *env, jobject obj, jlong enclave_han
return result_wrapper.result;
}
-JNIEXPORT jobject JNICALL
+JNIEXPORT jbyteArray JNICALL
JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *env, jobject obj, jlong enclave_handler, jlong isolate_handler, jbyteArray invoke_payload) {
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) {
@@ -163,7 +162,7 @@ JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *env, jobject obj, jlong enclave_ha
return result_wrapper.result;
}
-JNIEXPORT jobject JNICALL
+JNIEXPORT jbyteArray JNICALL
JavaEnclave_MockSVMNativeUnloadService(JNIEnv *env, jobject obj, jlong enclave_handler, jlong isolate_handler, jbyteArray unload_service_payload) {
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) {
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 53db1a2..5449a51 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
@@ -21,9 +21,9 @@ typedef struct {
{ \
jclass ra_class = (*env)->FindClass(env, exception); \
if (ra_class == NULL) { \
- printf("JavaEnclave Error: "); \
- printf(exception); \
- printf(" class loading failed.\n"); \
+ fprintf(stderr, "JavaEnclave Error: "); \
+ fprintf(stderr, exception); \
+ fprintf(stderr, " class loading failed.\n"); \
return; \
} \
(*env)->ThrowNew(env, ra_class, info); \
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 6a1870f..ad558d5 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
@@ -95,9 +95,7 @@ JavaEnclave_TeeSDKSVMNativeCreateEnclave(JNIEnv *env, jobject obj, jint mode, js
const char *path_str = (path == 0) ? 0 : (*env)->GetStringUTFChars(env, path, 0);
sgx_enclave_id_t enclave_id;
int ret = sgx_create_enclave(path_str, enable_debug_mode, NULL, NULL, &enclave_id, NULL);
-
(*env)->ReleaseStringUTFChars(env, path, path_str);
-
if (ret != SGX_SUCCESS) {
THROW_EXCEPTION(env, ENCLAVE_CREATING_EXCEPTION, "create tee sdk enclave by native calling failed.")
}
@@ -158,12 +156,12 @@ JavaEnclave_TeeSDKSVMNativeUnloadService(JNIEnv *env, jobject obj, jlong enclave
JNIEXPORT jint JNICALL
JavaEnclave_TeeSDKSVMNativeSvmDetachIsolate(JNIEnv *env, jobject obj, jlong enclave_handler, jlong isolate_thread_handler) {
- int ret = 0x0;
+ int ret = 0;
enclave_svm_isolate_destroy((sgx_enclave_id_t)enclave_handler, &ret, (uint64_t)isolate_thread_handler);
if (ret != 0) {
THROW_EXCEPTION(env, ENCLAVE_DESTROYING_EXCEPTION, "isolate destroy native call failed.")
}
- return 0;
+ return ret;
}
JNIEXPORT jint JNICALL
@@ -177,7 +175,6 @@ JavaEnclave_TeeSDKSVMNativeDestroyEnclave(JNIEnv *env, jobject obj, jlong enclav
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())) {
@@ -242,13 +239,19 @@ JavaEnclave_TeeSDK_REMOTE_ATTESTATION_REPORT(JNIEnv *env, jobject obj, jlong enc
jbyte *mr_signer_buf = (*env)->GetByteArrayElements(env, mr_signer, NULL);
memcpy(mr_signer_buf, ra_report.body.mr_signer.m, SGX_HASH_SIZE);
+ // create user data byte array.
+ jbyteArray user_data = (*env)->NewByteArray(env, SGX_REPORT_DATA_SIZE);
+ jbyte *user_data_buf = (*env)->GetByteArrayElements(env, user_data, NULL);
+ memcpy(user_data_buf, ra_report.body.report_data.d, SGX_REPORT_DATA_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);
+ (*env)->ReleaseByteArrayElements(env, user_data, user_data_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);
+ jmethodID construct = (*env)->GetMethodID(env, tee_sdk_ra_report_clazz, "<init>", "([B[B[B[B)V");
+ return (*env)->NewObject(env, tee_sdk_ra_report_clazz, construct, quote_array, mr_signer, mr_enclave, user_data);
}
\ 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 561b448..2dfced4 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
@@ -27,9 +27,9 @@ typedef struct {
{ \
jclass ra_class = (*env)->FindClass(env, exception); \
if (ra_class == NULL) { \
- printf("JavaEnclave Error: "); \
- printf(exception); \
- printf(" class loading failed.\n"); \
+ fprintf(stderr, "JavaEnclave Error: "); \
+ fprintf(stderr, exception); \
+ fprintf(stderr, " class loading failed.\n"); \
return; \
} \
(*env)->ThrowNew(env, ra_class, info); \
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 90df27e..e659c99 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
@@ -12,7 +12,6 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
-
class MockTestEnclave extends AbstractEnclave {
private static final AtomicLong instanceIdentity = new AtomicLong(0);
private static final Map<String, Object> instancesRegisterCenter = new ConcurrentHashMap<>();
@@ -73,12 +72,11 @@ class MockTestEnclave extends AbstractEnclave {
}
@Override
- byte[] loadServiceNative(byte[] payload) throws ServicesLoadingException {
+ byte[] loadServiceNative(String interfaceName) throws ServicesLoadingException {
List<ServiceHandler> handlers = new ArrayList<>();
Throwable exception = null;
EnclaveInvocationResult result;
try {
- String interfaceName = (String) SerializationHelper.deserialize(payload);
Class<?> service = Class.forName(interfaceName);
Iterator<?> services = ServiceLoader.load(service).iterator();
while (services.hasNext()) {
@@ -89,7 +87,7 @@ class MockTestEnclave extends AbstractEnclave {
cacheServiceHandler.add(sm);
instancesRegisterCenter.put(identity, instance);
}
- } catch (IOException | ClassNotFoundException e) {
+ } catch (ClassNotFoundException e) {
exception = e;
} finally {
result = new EnclaveInvocationResult(handlers.toArray(new ServiceHandler[0]), exception);
@@ -103,18 +101,12 @@ class MockTestEnclave extends AbstractEnclave {
}
@Override
- byte[] unloadServiceNative(byte[] payload) throws ServicesUnloadingException {
- ServiceHandler serviceHandler;
+ byte[] unloadServiceNative(ServiceHandler handler) throws ServicesUnloadingException {
Throwable exception = null;
EnclaveInvocationResult result;
- try {
- serviceHandler = (ServiceHandler) SerializationHelper.deserialize(payload);
- instancesRegisterCenter.remove(serviceHandler.getInstanceIdentity());
- } catch (IOException | ClassNotFoundException e) {
- exception = e;
- } finally {
- result = new EnclaveInvocationResult(null, exception);
- }
+
+ instancesRegisterCenter.remove(handler.getInstanceIdentity());
+ result = new EnclaveInvocationResult(null, exception);
try {
return SerializationHelper.serialize(result);
@@ -124,13 +116,11 @@ class MockTestEnclave extends AbstractEnclave {
}
@Override
- byte[] invokeMethodNative(byte[] payload) throws EnclaveMethodInvokingException {
- EnclaveInvocationContext invocationContext;
+ byte[] invokeMethodNative(EnclaveInvocationContext invocationContext) throws EnclaveMethodInvokingException {
Throwable exception = null;
Object invokeRet = null;
EnclaveInvocationResult result;
try {
- invocationContext = (EnclaveInvocationContext) SerializationHelper.deserialize(payload);
String className = invocationContext.getServiceHandler().getServiceImplClassName();
String[] parameterTypes = invocationContext.getParameterTypes();
String methodName = invocationContext.getMethodName();
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 d4b9a20..8f161c4 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
@@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*;
class TestRemoteAttestation {
@Test
- void testRemoteAttestation() throws EnclaveCreatingException {
+ void testRemoteAttestation() {
Enclave mockInJvmEnclave = new MockInJvmEnclave();
assertThrows(RemoteAttestationException.class, () -> RemoteAttestation.generateAttestationReport(mockInJvmEnclave, null));
assertThrows(RemoteAttestationException.class, () -> RemoteAttestation.verifyAttestationReport(new AttestationReport(EnclaveType.MOCK_IN_JVM, null)));
@@ -37,7 +37,7 @@ class TestRemoteAttestation {
}
@Test
- void testAttestationReport() throws Exception {
+ void testAttestationReport() {
byte[] quote = new byte[4];
for (int index = 0; index < quote.length; index++) {
quote[index] = (byte) 0x5f;
@@ -49,5 +49,13 @@ class TestRemoteAttestation {
for (int index = 0; index < quote.length; index++) {
assertEquals(quote[index], (deserializedReport.getQuote())[index]);
}
+
+ report = new AttestationReport(EnclaveType.EMBEDDED_LIB_OS, quote);
+ serializedReport = report.toByteArray();
+ deserializedReport = AttestationReport.fromByteArray(serializedReport);
+ assertEquals(EnclaveType.EMBEDDED_LIB_OS, deserializedReport.getEnclaveType());
+ for (int index = 0; index < quote.length; index++) {
+ assertEquals(quote[index], (deserializedReport.getQuote())[index]);
+ }
}
}
diff --git a/sdk/native/bin/platform/libos_occlum_enclave/jni/.gitkeep b/sdk/native/bin/platform/libos_occlum_enclave/jni/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/sdk/native/bin/platform/libos_occlum_enclave/libos_occlum_enclave_attestation/.gitkeep b/sdk/native/bin/platform/libos_occlum_enclave/libos_occlum_enclave_attestation/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/sdk/native/config/platform/libos_occlum_enclave/enclave/config.mk b/sdk/native/config/platform/libos_occlum_enclave/enclave/config.mk
new file mode 100644
index 0000000..941f478
--- /dev/null
+++ b/sdk/native/config/platform/libos_occlum_enclave/enclave/config.mk
@@ -0,0 +1,5 @@
+CC := /usr/local/occlum/bin/occlum-gcc
+
+TEE_SDK_PATH = /opt/teesdk/sgxsdk
+LIBPATH ?= /opt/occlum/toolchains/dcap_lib/musl
+INCPATH ?= /opt/occlum/toolchains/dcap_lib/inc
diff --git a/sdk/native/config/platform/libos_occlum_enclave/jni/config.mk b/sdk/native/config/platform/libos_occlum_enclave/jni/config.mk
new file mode 100644
index 0000000..c29f118
--- /dev/null
+++ b/sdk/native/config/platform/libos_occlum_enclave/jni/config.mk
@@ -0,0 +1,17 @@
+CC := gcc
+OCCLUM_PREFIX ?= /opt/occlum
+SGX_MODE ?= HW
+
+ifneq ($(SGX_MODE), HW)
+ URTS_LIBRARY_NAME := sgx_urts_sim
+ UAE_SERVICE_LIBRARY_NAME := sgx_uae_service_sim
+ OCCLUM_PAL_LIB := occlum-pal_sim
+else
+ URTS_LIBRARY_NAME := sgx_urts
+ UAE_SERVICE_LIBRARY_NAME := sgx_uae_service
+ OCCLUM_PAL_LIB := occlum-pal
+endif
+
+C_FLAGS := -Wl,-z,noexecstack -g -c -Wno-unused-parameter -I$(OCCLUM_PREFIX)/include
+
+LINK_FLAGS := -lpthread -L$(OCCLUM_PREFIX)/build/lib -L/opt/teesdk/sgxsdk/lib64 -l$(URTS_LIBRARY_NAME) -l$(UAE_SERVICE_LIBRARY_NAME) -lsgx_uprotected_fs
\ No newline at end of file
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 f54e623..76bc3bc 100644
--- a/sdk/native/config/platform/tee_sdk_svm/jni/config.mk
+++ b/sdk/native/config/platform/tee_sdk_svm/jni/config.mk
@@ -4,9 +4,9 @@ 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
+ DCAP_LIB_PATH = /usr/lib/x86_64-linux-gnu
else
- DCAP_LIB_PATH = /usr/lib64
+ DCAP_LIB_PATH = /usr/lib64
endif
# SGX_MODE ?= SIM
diff --git a/sdk/native/config/remote_attestation_verify/sgx/config.mk b/sdk/native/config/remote_attestation_verify/sgx/config.mk
index 032c4fb..2783eff 100644
--- a/sdk/native/config/remote_attestation_verify/sgx/config.mk
+++ b/sdk/native/config/remote_attestation_verify/sgx/config.mk
@@ -10,4 +10,4 @@ else
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
+RA_VERIFY_LDFLAGS = -L$(DCAP_LIB_PATH) -lsgx_dcap_quoteverify -lsgx_dcap_ql
diff --git a/sdk/native/script/build_app/Makefile b/sdk/native/script/build_app/Makefile
index 85d3a30..ec3d6c0 100644
--- a/sdk/native/script/build_app/Makefile
+++ b/sdk/native/script/build_app/Makefile
@@ -24,7 +24,6 @@ ifeq ($(TEE_SDK), TRUE)
-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
- # 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 \
@@ -36,3 +35,7 @@ ifeq ($(TEE_SDK), TRUE)
-config ${ENCLAVE_BASE_DIR}/src/main/resources/tee_sdk_svm.conf -key $(ENCLAVE_PRIVATE_PEM_PATH)
endif
endif
+
+ifeq ($(EMBEDDED_LIB_OS), TRUE)
+ /bin/bash ${BUILD_SCRIPT_DIR}/libos_occlum_enclave_build.sh
+endif
diff --git a/sdk/native/script/build_app/libos_occlum_enclave_build.sh b/sdk/native/script/build_app/libos_occlum_enclave_build.sh
new file mode 100644
index 0000000..3879514
--- /dev/null
+++ b/sdk/native/script/build_app/libos_occlum_enclave_build.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+
+enclave_target_path=${ENCLAVE_BASE_DIR}/target
+user_occlum_enclave_config_file=${ENCLAVE_BASE_DIR}/src/main/resources/embedded_libos_enclave.json
+
+# parse enclave with dependencies jar file name.
+# shellcheck disable=SC2061
+# shellcheck disable=SC2185
+# shellcheck disable=SC2035
+pushd "${enclave_target_path}"
+enclave_jar_name=$(find -name *-jar-with-dependencies.jar)
+if [[ -z $enclave_jar_name ]];
+then
+ echo "enclave with dependencies jar file is empty."
+ exit 1
+fi
+popd
+
+# create lib os enclave workspace.
+mkdir -p "${ENCLAVE_BASE_DIR}"/target/enclave_workspace/occlum_instance
+rm -rf "${ENCLAVE_BASE_DIR}"/target/enclave_workspace/occlum_instance/*
+
+pushd "${enclave_target_path}"/enclave_workspace/occlum_instance
+# create occlum instance and build occlum image.
+occlum init
+
+# update Occlum.json according to user's config file embedded_libos_enclave.json
+debuggable=$(< "${user_occlum_enclave_config_file}" jq -r '.debuggable')
+default_mmap_size=$(< "${user_occlum_enclave_config_file}" jq -r '.default_mmap_size')
+occlum_kernel_heap_size=$(< "${user_occlum_enclave_config_file}" jq -r '.kernel_space_heap_size')
+occlum_max_thread_num=$(< "${user_occlum_enclave_config_file}" jq -r '.max_num_of_threads')
+user_space_size=$(< "${user_occlum_enclave_config_file}" jq -r '.user_space_size')
+
+new_json="$(jq --arg default_mmap_size "$default_mmap_size" \
+ --arg user_space_size "$user_space_size" \
+ --arg occlum_kernel_heap_size "$occlum_kernel_heap_size" \
+ --argjson occlum_max_thread_num "$occlum_max_thread_num" \
+ --argjson debuggable "$debuggable" \
+ '.resource_limits.user_space_size = $user_space_size |
+ .resource_limits.kernel_space_heap_size = $occlum_kernel_heap_size |
+ .resource_limits.max_num_of_threads = $occlum_max_thread_num |
+ .process.default_heap_size = "150MB" |
+ .process.default_mmap_size = $default_mmap_size |
+ .metadata.debuggable = $debuggable |
+ .entry_points = [ "/usr/lib/dragonwell11/jre/bin" ] |
+ .env.default = [ "LD_LIBRARY_PATH=/usr/lib/dragonwell11/jre/lib/server:/usr/lib/dragonwell11/jre/lib:/usr/lib/dragonwell11/jre/../lib" ]' Occlum.json)"
+
+echo "${new_json}" > Occlum.json
+
+# prepare zlib for jvm in libos occlum enclave.
+cp /opt/occlum/toolchains/gcc/x86_64-linux-musl/lib/libz.so.1.2.11 ./image/lib/libz.so.1
+
+# prepare occlum_dcap for occlum remote attestation.
+cp /opt/occlum/toolchains/dcap_lib/musl/libocclum_dcap.so.0.1.0 ./image/lib/libocclum_dcap.so.0.1.0
+
+# prepare occlum remote attestation jni.so
+mkdir -p ./image/usr/lib
+cp -r /opt/javaenclave/bin/platform/libos_occlum_enclave/libos_occlum_enclave_attestation ./image/usr/lib
+
+# prepate musl-based jvm in libos occlum enclave.
+mkdir -p ./image/usr/lib/dragonwell11/jre
+cp -r /root/tools/dragonwell-11.0.15.11+9-GA/. ./image/usr/lib/dragonwell11/jre
+
+# prepare app jar with dependencies in libos occlum enclave.
+mkdir -p ./image/usr/app
+cp -r "${enclave_target_path}"/"${enclave_jar_name}" ./image/usr/app
+
+# prepare private.pem for image signing.
+if [[ -z ${ENCLAVE_PRIVATE_PEM_PATH} ]];
+then
+ openssl genrsa -out private.pem -3 3072
+ occlum build --sign-key private.pem
+else
+ occlum build --sign-key "${ENCLAVE_PRIVATE_PEM_PATH}"
+fi
+
+if [ $debuggable ]
+then
+ # occlum package --debug > /dev/null
+ occlum package --debug > /dev/null 2>&1
+else
+ occlum package
+fi
+
+mv ./occlum_instance.tar.gz "${ENCLAVE_BASE_DIR}"/target/svm-output/lib_embedded_lib_os_enclave_load.tgz
+
+popd
\ No newline at end of file
diff --git a/sdk/native/script/build_app/make.sh b/sdk/native/script/build_app/make.sh
index cf8bfb4..1fb70f4 100644
--- a/sdk/native/script/build_app/make.sh
+++ b/sdk/native/script/build_app/make.sh
@@ -2,7 +2,6 @@
# shellcheck disable=SC2006
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.
diff --git a/sdk/native/script/build_enclave_sdk/Makefile b/sdk/native/script/build_enclave_sdk/Makefile
index 6098d52..64088c9 100644
--- a/sdk/native/script/build_enclave_sdk/Makefile
+++ b/sdk/native/script/build_enclave_sdk/Makefile
@@ -11,9 +11,17 @@ ifeq ($(TEE_SDK), TRUE)
$(MAKE) -C $(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm/remote_attestation_generate
endif
+ifeq ($(EMBEDDED_LIB_OS), TRUE)
+ $(MAKE) -C $(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/libos_occlum_enclave/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
+
+ifeq ($(EMBEDDED_LIB_OS), TRUE)
+ $(MAKE) -C $(ENCLAVE_BASE_DIR)/src/main/native/cpp/platform/libos_occlum_enclave/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 ceff503..95e7b5b 100644
--- a/sdk/native/script/build_host_sdk/Makefile
+++ b/sdk/native/script/build_host_sdk/Makefile
@@ -11,6 +11,16 @@ 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/platform/libos_occlum_enclave/jni
+endif
+
+ifeq ($(EMBEDDED_LIB_OS), TRUE)
+ $(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/platform/libos_occlum_enclave/jni
+endif
+
+ifeq ($(TEE_SDK), TRUE)
+ $(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/attestation_verify/sgx/jni
+else ifeq ($(EMBEDDED_LIB_OS), TRUE)
$(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/attestation_verify/sgx/jni
endif
@@ -21,5 +31,14 @@ endif
ifeq ($(TEE_SDK), TRUE)
$(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/platform/tee_sdk_svm clean
+endif
+
+ifeq ($(EMBEDDED_LIB_OS), TRUE)
+ $(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/platform/libos_occlum_enclave/jni clean
+endif
+
+ifeq ($(TEE_SDK), TRUE)
+ $(MAKE) -C $(HOST_BASE_DIR)/src/main/native/cpp/attestation_verify/sgx/jni clean
+else ifeq ($(EMBEDDED_LIB_OS), TRUE)
$(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 70181db..26d72cd 100644
--- a/sdk/native/script/build_host_sdk/make.sh
+++ b/sdk/native/script/build_host_sdk/make.sh
@@ -48,6 +48,13 @@ 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
+ fi
+ # copy jni.so to target/classes, which will be packed into a jar file.
+ if [[ $EMBEDDED_LIB_OS == TRUE ]]; then
+ cp -r "$NATIVE_BASE_DIR"/bin/platform/libos_occlum_enclave/jni "$HOST_BASE_DIR"/target/classes
+ fi
+ # copy sgx remote attestation verification jni.so to target/classes, which will be packed into a jar file.
+ if [ "$TEE_SDK" == TRUE ] || [ "$EMBEDDED_LIB_OS" == TRUE ]; then
cp -r "$NATIVE_BASE_DIR"/bin/remote_attestation "$HOST_BASE_DIR"/target/classes
fi
else
diff --git a/sdk/pom.xml b/sdk/pom.xml
index 653eadc..bfe67d9 100644
--- a/sdk/pom.xml
+++ b/sdk/pom.xml
@@ -11,10 +11,20 @@
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <com.alibaba.enclave.platform>MOCK_IN_SVM:TEE_SDK</com.alibaba.enclave.platform>
+ <com.alibaba.enclave.platform>MOCK_IN_SVM:TEE_SDK:EMBEDDED_LIB_OS</com.alibaba.enclave.platform>
</properties>
<dependencyManagement>
<dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>1.19</version>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20211205</version>
+ </dependency>
<dependency>
<groupId>com.alibaba.confidentialcomputing</groupId>
<artifactId>common</artifactId>
diff --git a/test/enclave/pom.xml b/test/enclave/pom.xml
index 2bbb426..64e3d9f 100644
--- a/test/enclave/pom.xml
+++ b/test/enclave/pom.xml
@@ -123,6 +123,25 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>3.3.0</version>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
@@ -179,4 +198,4 @@
<scope>test</scope>
</dependency>
</dependencies>
-</project>
+</project>
\ No newline at end of file
diff --git a/test/enclave/src/main/resources/embedded_libos_enclave.json b/test/enclave/src/main/resources/embedded_libos_enclave.json
new file mode 100644
index 0000000..655b56a
--- /dev/null
+++ b/test/enclave/src/main/resources/embedded_libos_enclave.json
@@ -0,0 +1,11 @@
+{
+ "debuggable": false,
+ "agent_http_handler_thread_pool_size": 6,
+ "enclave_startup_duration_ms": 60000,
+ "kernel_space_heap_size": "32MB",
+ "user_space_size": "1200MB",
+ "default_mmap_size": "800MB",
+ "max_num_of_threads": 48,
+ "log_level": "off",
+ "enclave_jvm_args": ["-XX:-UseCompressedOops", "-Xmx512m", "-Dos.name=Linux"]
+}
\ No newline at end of file
diff --git a/test/host/pom.xml b/test/host/pom.xml
index ceacc29..9073a33 100644
--- a/test/host/pom.xml
+++ b/test/host/pom.xml
@@ -19,6 +19,7 @@
<includes>
<include>**/*.so</include>
<include>**/*.signed</include>
+ <include>**/*.tgz</include>
</includes>
</resource>
</resources>
@@ -42,6 +43,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
+ <!--configuration>
+ <forkCount>0</forkCount>
+ </configuration-->
<version>3.0.0-M5</version>
</plugin>
</plugins>
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 741bb3d..d589c65 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
@@ -2,6 +2,7 @@ package com.alibaba.confidentialcomputing.test.host;
import java.io.IOException;
import java.util.Iterator;
+import java.util.Random;
import com.alibaba.confidentialcomputing.host.*;
import com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException;
@@ -21,13 +22,28 @@ public class TestJavaEnclaveService {
private String sayHelloService(EnclaveType type, String plain) throws
EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException, RemoteAttestationException, IOException {
Enclave enclave = EnclaveFactory.create(type);
+ assertNotNull(enclave);
+ byte[] userData = new byte[64];
+ new Random().nextBytes(userData);
if (type == EnclaveType.TEE_SDK) {
- TeeSdkAttestationReport report = (TeeSdkAttestationReport) RemoteAttestation.generateAttestationReport(enclave, null);
+ TeeSdkAttestationReport report = (TeeSdkAttestationReport) RemoteAttestation.generateAttestationReport(enclave, userData);
assertEquals(report.getEnclaveType(), EnclaveType.TEE_SDK);
assertNotNull(report.getQuote());
assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
assertNotNull(report.getMeasurementEnclave());
assertNotNull(report.getMeasurementSigner());
+ assertNotNull(report.getUserData());
+ assertArrayEquals(userData, report.getUserData());
+ }
+ if (type == EnclaveType.EMBEDDED_LIB_OS) {
+ EmbeddedLibOSAttestationReport report = (EmbeddedLibOSAttestationReport) RemoteAttestation.generateAttestationReport(enclave, userData);
+ assertEquals(report.getEnclaveType(), EnclaveType.EMBEDDED_LIB_OS);
+ assertNotNull(report.getQuote());
+ assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
+ assertNotNull(report.getMeasurementEnclave());
+ assertNotNull(report.getMeasurementSigner());
+ assertNotNull(report.getUserData());
+ assertArrayEquals(userData, report.getUserData());
}
Iterator<SayHelloService> userServices = enclave.load(SayHelloService.class);
assertNotNull(userServices);
@@ -41,13 +57,28 @@ public class TestJavaEnclaveService {
private void reflectionCallService(EnclaveType type) throws EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException, RemoteAttestationException {
Enclave enclave = EnclaveFactory.create(type);
+ assertNotNull(enclave);
+ byte[] userData = new byte[64];
+ new Random().nextBytes(userData);
if (type == EnclaveType.TEE_SDK) {
- TeeSdkAttestationReport report = (TeeSdkAttestationReport) RemoteAttestation.generateAttestationReport(enclave, null);
+ TeeSdkAttestationReport report = (TeeSdkAttestationReport) RemoteAttestation.generateAttestationReport(enclave, userData);
assertEquals(report.getEnclaveType(), EnclaveType.TEE_SDK);
assertNotNull(report.getQuote());
assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
assertNotNull(report.getMeasurementEnclave());
assertNotNull(report.getMeasurementSigner());
+ assertNotNull(report.getUserData());
+ assertArrayEquals(userData, report.getUserData());
+ }
+ if (type == EnclaveType.EMBEDDED_LIB_OS) {
+ EmbeddedLibOSAttestationReport report = (EmbeddedLibOSAttestationReport) RemoteAttestation.generateAttestationReport(enclave, userData);
+ assertEquals(report.getEnclaveType(), EnclaveType.EMBEDDED_LIB_OS);
+ assertNotNull(report.getQuote());
+ assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
+ assertNotNull(report.getMeasurementEnclave());
+ assertNotNull(report.getMeasurementSigner());
+ assertNotNull(report.getUserData());
+ assertArrayEquals(userData, report.getUserData());
}
Iterator<ReflectionCallService> userServices = enclave.load(ReflectionCallService.class);
assertNotNull(userServices);
@@ -60,13 +91,28 @@ public class TestJavaEnclaveService {
private void javaEnclaveException(EnclaveType type) throws EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException, RemoteAttestationException {
Enclave enclave = EnclaveFactory.create(type);
+ assertNotNull(enclave);
+ byte[] userData = new byte[64];
+ new Random().nextBytes(userData);
if (type == EnclaveType.TEE_SDK) {
- TeeSdkAttestationReport report = (TeeSdkAttestationReport) RemoteAttestation.generateAttestationReport(enclave, null);
+ TeeSdkAttestationReport report = (TeeSdkAttestationReport) RemoteAttestation.generateAttestationReport(enclave, userData);
assertEquals(report.getEnclaveType(), EnclaveType.TEE_SDK);
assertNotNull(report.getQuote());
assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
assertNotNull(report.getMeasurementEnclave());
assertNotNull(report.getMeasurementSigner());
+ assertNotNull(report.getUserData());
+ assertArrayEquals(userData, report.getUserData());
+ }
+ if (type == EnclaveType.EMBEDDED_LIB_OS) {
+ EmbeddedLibOSAttestationReport report = (EmbeddedLibOSAttestationReport) RemoteAttestation.generateAttestationReport(enclave, userData);
+ assertEquals(report.getEnclaveType(), EnclaveType.EMBEDDED_LIB_OS);
+ assertNotNull(report.getQuote());
+ assertEquals(0, RemoteAttestation.verifyAttestationReport(report));
+ assertNotNull(report.getMeasurementEnclave());
+ assertNotNull(report.getMeasurementSigner());
+ assertNotNull(report.getUserData());
+ assertArrayEquals(userData, report.getUserData());
}
Iterator<EnclaveException> userServices = enclave.load(EnclaveException.class);
assertNotNull(userServices);
@@ -77,24 +123,38 @@ public class TestJavaEnclaveService {
}
@Test
- public void testSayHelloService() throws
- 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"));
+ public void testSayHelloService() {
+ try {
+ 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"));
+ assertEquals("Hello World", sayHelloService(EnclaveType.EMBEDDED_LIB_OS, "Hello World"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
@Test
- public void testReflectionCallService() throws ServicesLoadingException, EnclaveCreatingException, EnclaveDestroyingException, RemoteAttestationException {
- reflectionCallService(EnclaveType.MOCK_IN_JVM);
- reflectionCallService(EnclaveType.MOCK_IN_SVM);
- reflectionCallService(EnclaveType.TEE_SDK);
+ public void testReflectionCallService() {
+ try {
+ reflectionCallService(EnclaveType.MOCK_IN_JVM);
+ reflectionCallService(EnclaveType.MOCK_IN_SVM);
+ reflectionCallService(EnclaveType.TEE_SDK);
+ reflectionCallService(EnclaveType.EMBEDDED_LIB_OS);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
@Test
- public void testJavaEnclaveException() throws ServicesLoadingException, EnclaveCreatingException, EnclaveDestroyingException, RemoteAttestationException {
- javaEnclaveException(EnclaveType.MOCK_IN_JVM);
- javaEnclaveException(EnclaveType.MOCK_IN_SVM);
- javaEnclaveException(EnclaveType.TEE_SDK);
+ public void testJavaEnclaveException() {
+ try {
+ javaEnclaveException(EnclaveType.MOCK_IN_JVM);
+ javaEnclaveException(EnclaveType.MOCK_IN_SVM);
+ javaEnclaveException(EnclaveType.TEE_SDK);
+ javaEnclaveException(EnclaveType.EMBEDDED_LIB_OS);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/test/pom.xml b/test/pom.xml
index 7c2f566..97e1d9b 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -12,7 +12,7 @@
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <com.alibaba.enclave.platform>MOCK_IN_SVM:TEE_SDK</com.alibaba.enclave.platform>
+ <com.alibaba.enclave.platform>MOCK_IN_SVM:TEE_SDK:EMBEDDED_LIB_OS</com.alibaba.enclave.platform>
</properties>
<dependencyManagement>
<dependencies>
diff --git a/tools/cicd/Dockerfile b/tools/cicd/Dockerfile
index a611185..544392d 100644
--- a/tools/cicd/Dockerfile
+++ b/tools/cicd/Dockerfile
@@ -6,23 +6,29 @@ ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
ENV DEBIAN_FRONTEND noninteractive
ADD ["graalvm-enclave-22.1.0.tar", "/root/tools/"]
-ADD ["x86_64-linux-musl-native.tgz", "/root/tools/"]
ADD ["zlib-1.2.11.tar.gz", "/root/tools/"]
ADD ["settings.xml", "/root/tools/"]
+ADD ["zlib-1.2.11.tar.gz", "/root/tools/"]
+ADD ["Alibaba_Dragonwell_11.0.15.11.9_x64_alpine-linux.tar.gz", "/root/tools"]
ADD ["sgx_linux_x64_sdk_2.17.100.0.bin", "/root/tools/"]
ENV GRAALVM_HOME "/root/tools/graalvm-enclave-22.1.0"
ENV JAVA_HOME "/root/tools/graalvm-enclave-22.1.0"
-ENV CC "/root/tools/x86_64-linux-musl-native/bin/gcc"
-ENV PATH $PATH:"/root/tools/x86_64-linux-musl-native/bin"
+ENV PATH="/opt/occlum/build/bin:/usr/local/occlum/bin:$PATH"
+ENV CC=/usr/local/occlum/bin/occlum-gcc
ARG PSW_VERSION=2.17.100.3
ARG DCAP_VERSION=1.14.100.3
# install necessary tools.
-RUN apt-get update && apt-get install -y gdb gnupg wget aptitude && \
+RUN apt-get update && apt-get install -y gdb gnupg wget aptitude libfuse-dev libtool tzdata jq && \
+ echo -e 'yes\n' | apt-get install -y maven && \
+ echo -e 'yes\n' | apt-get install -y build-essential libz-dev zlib1g-dev && \
echo 'deb [arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu bionic main' > /etc/apt/sources.list.d/intel-sgx.list && \
wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add - && \
+ echo 'deb [arch=amd64] https://occlum.io/occlum-package-repos/debian bionic main' | tee /etc/apt/sources.list.d/occlum.list && \
+ wget -qO - https://occlum.io/occlum-package-repos/debian/public.key | apt-key add - && \
apt-get update && aptitude install -y \
+ occlum \
libsgx-launch-dev=$PSW_VERSION-bionic1 \
libsgx-urts=$PSW_VERSION-bionic1 \
libsgx-urts-dbgsym=$PSW_VERSION-bionic1 \
@@ -32,5 +38,8 @@ RUN apt-get update && apt-get install -y gdb gnupg wget aptitude && \
libsgx-dcap-default-qpl=$DCAP_VERSION-bionic1 && \
echo -e 'yes\n' | apt-get install -y maven && \
echo -e 'yes\n' | apt-get install -y build-essential libz-dev zlib1g-dev && \
- cd /root/tools/zlib-1.2.11 && ./configure --prefix=/root/tools/x86_64-linux-musl-native --static && make && make install && \
+ cd /root/tools/zlib-1.2.11 && ./configure --prefix=/opt/occlum/toolchains/gcc/x86_64-linux-musl && make && make install && \
cd /root/tools && chmod 777 sgx_linux_x64_sdk_2.17.100.0.bin && echo -e 'no\n/opt/teesdk\n' | ./sgx_linux_x64_sdk_2.17.100.0.bin
+
+# copy dcap_occlum lib from occlum docker image.
+COPY --from=occlum/occlum:0.26.4-ubuntu18.04 /opt/occlum/toolchains/dcap_lib /opt/occlum/toolchains/dcap_lib
\ No newline at end of file
diff --git a/tools/cicd/make.sh b/tools/cicd/make.sh
index f4667ea..5dc43d0 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.9
+BUILD_TAG=v0.1.10
SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
@@ -14,15 +14,15 @@ if [[ "$(docker images -q ${BUILD_IMAGE}:${BUILD_TAG} 2> /dev/null)" == "" ]]; t
# Get the customized Graal VM from git@gitlab.alibaba-inc.com:graal/SGXGraalVM.git
# This should be replaced to the offical version when all patches are accepted by the Graal community
wget https://graal.oss-cn-beijing.aliyuncs.com/graal-enclave/JDK11-22.1.0/graalvm-enclave-22.1.0.tar
- wget http://graal.oss-cn-beijing.aliyuncs.com/graal-enclave/x86_64-linux-musl-native.tgz
wget http://graal.oss-cn-beijing.aliyuncs.com/graal-enclave/zlib-1.2.11.tar.gz
wget http://graal.oss-cn-beijing.aliyuncs.com/graal-enclave/settings_taobao.xml -O settings.xml
wget https://dragonwell.oss-cn-shanghai.aliyuncs.com/11/tee_java/dependency/sgx_linux_x64_sdk_2.17.100.0.bin
+ wget https://dragonwell.oss-cn-shanghai.aliyuncs.com/11.0.15.11.9/Alibaba_Dragonwell_11.0.15.11.9_x64_alpine-linux.tar.gz
docker build -t ${BUILD_IMAGE}:${BUILD_TAG} .
rm -f graalvm-enclave-22.1.0.tar
- rm -f x86_64-linux-musl-native.tgz
rm -f zlib-1.2.11.tar.gz
rm -f sgx_linux_x64_sdk_2.17.100.0.bin
+ rm -f Alibaba_Dragonwell_11.0.15.11.9_x64_alpine-linux.tar.gz
fi
# Set PCCS for DCAP Remote Attestation.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org