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 7345a96010e71819df328d7e4c55a6c67cf9d696 Author: jeffery.wsj <[email protected]> AuthorDate: Fri May 6 14:22:49 2022 +0800 [sdk] Support MOCK_IN_SVM enclave mode Summary: 1. Fix interface mismatch between JavaEnclave host and enclave module 2. Add mock_in_svm jni file 3. Add test maven project for JavaEnclave Test Plan: all tests pass Reviewers: lei.yul, cengfeng.lzy, sanhong.lsh Issue: https://aone.alibaba-inc.com/task/41457548 CR: https://code.aone.alibaba-inc.com/java-tee/JavaEnclave/codereview/8686166 --- build.sh | 3 +- .../enclave/InvocationWrapper.java | 1 - .../enclave/c/EnclaveEnvironment.java | 4 +- .../native-image/serialization-config.json | 9 ++ .../src/main/resources/native/enc_environment.h | 4 +- .../test/resources/native/enc_invoke_entry_test.c | 8 +- sdk/host/pom.xml | 22 +++ .../host/AbstractEnclave.java | 11 +- .../host/MockInSvmEnclave.java | 111 +++---------- sdk/host/src/main/native/Makefile | 11 ++ .../native/bin/platform/mock_in_svm/jni/.gitkeep | 0 sdk/host/src/main/native/config/config.mk | 13 ++ .../config/platform/mock_in_svm/jni/config.mk | 5 + .../native/cpp/platform/mock_in_svm/jni/Makefile | 15 ++ .../cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c | 172 +++++++++++++++++++++ .../cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h | 66 ++++++++ .../src/main/native/include}/enc_environment.h | 18 ++- .../src/main/native/include/enc_exported_symbol.h | 19 +++ sdk/host/src/main/native/make.sh | 49 ++++++ .../host/MockTestEnclave.java | 10 +- sdk/pom.xml | 1 + test/common/pom.xml | 60 +++++++ .../test/common/EnclaveException.java | 8 + .../test/common/JavaEnclaveException.java | 7 + .../test/common/ReflectionCallService.java | 10 ++ .../test/common/SayHelloService.java | 8 + test/enclave/pom.xml | 146 +++++++++++++++++ .../test/enclave/Calculate.java | 11 ++ .../test/enclave/EnclaveExceptionImpl.java | 13 ++ .../test/enclave/ReflectionCallServiceImpl.java | 47 ++++++ .../test/enclave/SayHelloServiceImpl.java | 13 ++ .../test/enclave/TestEnclaveException.java | 14 ++ .../test/enclave/TestReflectionCallService.java | 15 ++ .../test/enclave/TestSayHelloServiceImpl.java | 14 ++ {sdk => test}/host/pom.xml | 76 +++------ .../test/host/TestJavaEnclaveService.java | 72 +++++++++ {sdk => test}/pom.xml | 31 +++- 37 files changed, 924 insertions(+), 173 deletions(-) diff --git a/build.sh b/build.sh index b4dbae1..c4bf999 100644 --- a/build.sh +++ b/build.sh @@ -25,4 +25,5 @@ mvn install:install-file -Dfile=$GRAALVM_HOME/lib/svm/builder/native-image-base. popd > /dev/null rm -rf jartmp -cd "${WORKDIR}"/sdk && mvn clean package +cd "${WORKDIR}"/sdk && mvn clean install +cd "${WORKDIR}"/test && mvn -Pnative -e clean package diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/InvocationWrapper.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/InvocationWrapper.java index c732f7c..98b5eb6 100644 --- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/InvocationWrapper.java +++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/InvocationWrapper.java @@ -46,7 +46,6 @@ public class InvocationWrapper { CCharPointer returned; if (callBacks.isNonNull() && callBacks.getMemCpyCCharPointerFunctionPointer().isNonNull()) { returned = callBacks.getMemCpyCCharPointerFunctionPointer().invoke(byteHolder.get(), returnedValLen); - } else { returned = byteHolder.get(); System.out.println("Warning: Not calling call backs in native, there is memory leak risk."); diff --git a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/c/EnclaveEnvironment.java b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/c/EnclaveEnvironment.java index 922ab29..21a9505 100644 --- a/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/c/EnclaveEnvironment.java +++ b/sdk/enclave/src/main/java/com/alibaba/confidentialcomputing/enclave/c/EnclaveEnvironment.java @@ -84,7 +84,7 @@ public class EnclaveEnvironment { } } - @CStruct("enc_data") + @CStruct("enc_data_t") public interface EncData extends PointerBase { @CField("data_len") int getLen(); @@ -99,7 +99,7 @@ public class EnclaveEnvironment { void setData(CCharPointer data); } - @CStruct("callbacks") + @CStruct("callbacks_t") public interface CallBacks extends PointerBase { @CField("exception_handler") ExceptionHandleFunctionPointer getExceptionHandler(); diff --git a/sdk/enclave/src/main/resources/META-INF/native-image/serialization-config.json b/sdk/enclave/src/main/resources/META-INF/native-image/serialization-config.json index 45dfb55..197813b 100644 --- a/sdk/enclave/src/main/resources/META-INF/native-image/serialization-config.json +++ b/sdk/enclave/src/main/resources/META-INF/native-image/serialization-config.json @@ -29,6 +29,15 @@ { "name":"java.io.IOException" }, + { + "name":"java.lang.ClassCastException" + }, + { + "name":"java.lang.reflect.InvocationTargetException" + }, + { + "name":"java.lang.NullPointerException" + }, { "name":"java.io.ObjectStreamException" }, diff --git a/sdk/enclave/src/main/resources/native/enc_environment.h b/sdk/enclave/src/main/resources/native/enc_environment.h index dc6f683..e6f1e0c 100644 --- a/sdk/enclave/src/main/resources/native/enc_environment.h +++ b/sdk/enclave/src/main/resources/native/enc_environment.h @@ -2,7 +2,7 @@ //char array is used as byte array to store serialized data char* data; int data_len; - }enc_data; + }enc_data_t; typedef struct callback_functions_struct{ /* @@ -14,4 +14,4 @@ typedef struct callback_functions_struct{ void (*exception_handler)(char* err_msg, char* stack_trace, char* exception_name); char* (*memcpy_char_pointer)(char* src, int len); -}callbacks; +}callbacks_t; diff --git a/sdk/enclave/src/test/resources/native/enc_invoke_entry_test.c b/sdk/enclave/src/test/resources/native/enc_invoke_entry_test.c index 8faa6f1..b564181 100644 --- a/sdk/enclave/src/test/resources/native/enc_invoke_entry_test.c +++ b/sdk/enclave/src/test/resources/native/enc_invoke_entry_test.c @@ -8,7 +8,7 @@ #include "libsvm_enclave_sdk.h" #endif -typedef int (*enclave_invoke)(graal_isolate_t* isolate, enc_data* input, enc_data* result, callbacks* callBacks); +typedef int (*enclave_invoke)(graal_isolate_t* isolate, enc_data_t* input, enc_data_t* result, callbacks_t* callBacks); char* memcpy_char_pointer(char* src, int len){ int size = sizeof(char); @@ -23,15 +23,15 @@ static graal_isolate_t *isolate = NULL; jbyteArray enclave_call(JNIEnv* env, jclass clazz, jbyteArray data, enclave_invoke invoke){ jboolean isCopy; jbyte* a = (*env)->GetByteArrayElements(env, data, &isCopy); - enc_data invoke_data; + enc_data_t invoke_data; invoke_data.data=(char*)a; invoke_data.data_len=(*env)->GetArrayLength(env, data); - callbacks callback_methods; + callbacks_t callback_methods; callback_methods.memcpy_char_pointer=&memcpy_char_pointer; callback_methods.exception_handler=NULL; // Must explicitly set - enc_data ret; + enc_data_t ret; int exit_code = invoke(isolate, &invoke_data, &ret, &callback_methods); jbyteArray retVal; if(exit_code == 0 ){ diff --git a/sdk/host/pom.xml b/sdk/host/pom.xml index dbaf6ce..05b0c51 100644 --- a/sdk/host/pom.xml +++ b/sdk/host/pom.xml @@ -14,6 +14,28 @@ <url></url> <build> <plugins> + <plugin> + <artifactId>exec-maven-plugin</artifactId> + <groupId>org.codehaus.mojo</groupId> + <executions> + <execution> + <id>JavaEnclaveNativeCompile</id> + <phase>compile</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <executable>bash</executable> + <arguments> + <argument>${project.basedir}/src/main/native/make.sh</argument> + <argument>${project.basedir}</argument> + <argument>${com.alibaba.enclave.platform}</argument> + <argument>build</argument> + </arguments> + </configuration> + </execution> + </executions> + </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</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 c290e6f..a5eea7d 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 @@ -58,13 +58,11 @@ abstract class AbstractEnclave implements Enclave { try { // Only need to provide service's interface name is enough to load service // in enclave. - EnclaveInvocationContext parasWrapper = new EnclaveInvocationContext( - new ServiceHandler(service.getName())); byte[] payload; try { - payload = SerializationHelper.serialize(parasWrapper); + payload = SerializationHelper.serialize(service.getName()); } catch (IOException e) { - throw new ServicesLoadingException("EnclaveInvokeMetaWrapper serialization failed.", e); + throw new ServicesLoadingException("service name serialization failed.", e); } InnerNativeInvocationResult resultNativeWrapper = loadServiceNative(payload); // If loadServiceNative native call return value is error, an ServicesLoadingException exception @@ -104,12 +102,11 @@ abstract class AbstractEnclave implements Enclave { throw new ServicesUnloadingException("enclave was destroyed."); } try { - EnclaveInvocationContext parasWrapper = new EnclaveInvocationContext(service); byte[] payload; try { - payload = SerializationHelper.serialize(parasWrapper); + payload = SerializationHelper.serialize(service); } catch (IOException e) { - throw new ServicesUnloadingException("EnclaveInvokeMetaWrapper serialization failed.", e); + throw new ServicesUnloadingException("unload service serialization failed.", e); } InnerNativeInvocationResult resultNativeWrapper = unloadServiceNative(payload); if (resultNativeWrapper.getRet() != 0) { 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 3b676ea..45575e8 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 @@ -15,11 +15,16 @@ import java.io.IOException; */ class MockInSvmEnclave extends AbstractEnclave { private final static String JNI_EXTRACTED_PACKAGE_PATH = "jni/lib_jni_mock_svm.so"; - private final static String ENCLAVE_SVM_WRAPPER_PACKAGE_PATH = "libs/lib_enclave_mock_svm_wrapper.so"; - private final static String ENCLAVE_SVM_PACKAGE_PATH = "libs/lib_svm_sdk.so"; + private final static String ENCLAVE_SVM_PACKAGE_PATH = "lib_mock_svm_load.so"; private static volatile MockInSvmExtractTempPath extractTempPath; - private final EnclaveNativeContextCache nativeHandlerContext = new EnclaveNativeContextCache( - 0, 0, 0, 0); + + // enclaveHandle stores created enclave svm sdk .so file handler. + private long enclaveSvmSdkHandle; + // isolate stores svm created isolate instance. + // In JavaEnclave only one isolateHandle instance will be created. + private long isolateHandle; + // isolateThreadHandle stores the first attached isolateThread Handle. + private long isolateThreadHandle; MockInSvmEnclave() throws EnclaveCreatingException { // Set EnclaveContext for this enclave instance. @@ -33,17 +38,14 @@ class MockInSvmEnclave extends AbstractEnclave { String jniTempFilePath = ExtractLibrary.extractLibrary( MockInSvmEnclave.class.getClassLoader(), JNI_EXTRACTED_PACKAGE_PATH); - String enclaveWrapperFilePath = ExtractLibrary.extractLibrary( - MockInSvmEnclave.class.getClassLoader(), - ENCLAVE_SVM_WRAPPER_PACKAGE_PATH); String enclaveSvmFilePath = ExtractLibrary.extractLibrary( MockInSvmEnclave.class.getClassLoader(), ENCLAVE_SVM_PACKAGE_PATH); extractTempPath = new MockInSvmEnclave.MockInSvmExtractTempPath( jniTempFilePath, - enclaveWrapperFilePath, enclaveSvmFilePath); - System.load(jniTempFilePath); + System.load(extractTempPath.getJniTempFilePath()); + registerNatives(); } catch (IOException e) { throw new EnclaveCreatingException("extracting tee sdk jni .so or signed .so failed.", e); } @@ -51,14 +53,13 @@ class MockInSvmEnclave extends AbstractEnclave { } } - // Create svm sdk enclave by native call, enclaveWrapperHandle and enclaveSvmSdkHandle are set in jni in nativeHandlerContext. - int ret = nativeCreateEnclave(extractTempPath.getJniTempFilePath()); + // Create svm sdk enclave by native call, enclaveSvmSdkHandle are set in jni in nativeHandlerContext. + int ret = nativeCreateEnclave(extractTempPath.getEnclaveSvmFilePath()); if (ret != 0) { throw new EnclaveCreatingException("create svm sdk enclave by native calling failed."); } // Create svm attach isolate and isolateThread, and they are set in jni in nativeHandlerContext. - ret = nativeSvmAttachIsolate(nativeHandlerContext.getEnclaveWrapperHandle(), - nativeHandlerContext.getEnclaveSvmSdkHandle()); + ret = nativeSvmAttachIsolate(enclaveSvmSdkHandle); if (ret != 0) { throw new EnclaveCreatingException("create svm isolate by native calling failed."); } @@ -75,29 +76,17 @@ class MockInSvmEnclave extends AbstractEnclave { @Override InnerNativeInvocationResult loadServiceNative(byte[] payload) { - return nativeLoadService( - nativeHandlerContext.getEnclaveWrapperHandle(), - nativeHandlerContext.getEnclaveSvmSdkHandle(), - nativeHandlerContext.getIsolateHandle(), - payload); + return nativeLoadService(enclaveSvmSdkHandle, isolateHandle, payload); } @Override InnerNativeInvocationResult unloadServiceNative(byte[] payload) { - return nativeUnloadService( - nativeHandlerContext.getEnclaveWrapperHandle(), - nativeHandlerContext.getEnclaveSvmSdkHandle(), - nativeHandlerContext.getIsolateHandle(), - payload); + return nativeUnloadService(enclaveSvmSdkHandle, isolateHandle, payload); } @Override InnerNativeInvocationResult invokeMethodNative(byte[] payload) { - return nativeInvokeMethod( - nativeHandlerContext.getEnclaveWrapperHandle(), - nativeHandlerContext.getEnclaveSvmSdkHandle(), - nativeHandlerContext.getIsolateHandle(), - payload); + return nativeInvokeMethod(enclaveSvmSdkHandle, isolateHandle, payload); } @Override @@ -108,104 +97,54 @@ class MockInSvmEnclave extends AbstractEnclave { this.getEnclaveContext().getEnclaveServicesRecycler().interruptServiceRecycler(); // destroy svm isolate. int ret = nativeSvmDetachIsolate( - nativeHandlerContext.getEnclaveWrapperHandle(), - nativeHandlerContext.getEnclaveSvmSdkHandle(), - nativeHandlerContext.getIsolateThreadHandle()); + enclaveSvmSdkHandle, + isolateThreadHandle); if (ret != 0) { throw new EnclaveDestroyingException("isolate destroy native call failed."); } ret = nativeDestroyEnclave( - nativeHandlerContext.getEnclaveWrapperHandle(), - nativeHandlerContext.getEnclaveSvmSdkHandle()); + enclaveSvmSdkHandle); if (ret != 0) { throw new EnclaveDestroyingException("enclave destroy native call failed."); } } - } + private static native void registerNatives(); + private native int nativeCreateEnclave(String path); private native int nativeSvmAttachIsolate( - long enclaveWrapperHandle, long enclaveSvmSdkHandle); private native InnerNativeInvocationResult nativeLoadService( - long enclaveWrapperHandle, long enclaveSvmSdkHandle, long isolateHandler, byte[] serviceHandler); private native InnerNativeInvocationResult nativeInvokeMethod( - long enclaveWrapperHandle, long enclaveSvmSdkHandle, long isolateHandler, byte[] enclaveInvokeMetaWrapper); private native InnerNativeInvocationResult nativeUnloadService( - long enclaveWrapperHandle, long enclaveSvmSdkHandle, long isolateHandler, byte[] serviceHandler); private native int nativeSvmDetachIsolate( - long enclaveWrapperHandle, long enclaveSvmSdkHandle, long isolateThreadHandler); private native int nativeDestroyEnclave( - long enclaveWrapperHandle, long enclaveSvmSdkHandle); - /** - * JavaEnclave will create svm isolate handle and isolateThread handle by native call, - * so EnclaveNativeContextCache will cache them for usage. - */ - class EnclaveNativeContextCache { - // enclaveHandle stores created enclave wrap .so file handler. - private final long enclaveWrapperHandle; - // enclaveHandle stores created enclave svm sdk .so file handler. - private final long enclaveSvmSdkHandle; - // isolate stores svm created isolate instance. - // In JavaEnclave only one isolateHandle instance will be created. - private final long isolateHandle; - // isolateThreadHandle stores the first attached isolateThread Handle. - private final long isolateThreadHandle; - - EnclaveNativeContextCache( - long enclaveWrapperHandle, long enclaveSvmSdkHandle, - long isolateHandle, long isolateThreadHandle) { - this.enclaveWrapperHandle = enclaveWrapperHandle; - this.enclaveSvmSdkHandle = enclaveSvmSdkHandle; - this.isolateHandle = isolateHandle; - this.isolateThreadHandle = isolateThreadHandle; - } - - long getEnclaveWrapperHandle() { - return enclaveWrapperHandle; - } - - long getEnclaveSvmSdkHandle() { - return enclaveSvmSdkHandle; - } - - long getIsolateHandle() { - return isolateHandle; - } - - long getIsolateThreadHandle() { - return isolateThreadHandle; - } - } - class MockInSvmExtractTempPath { private final String jniTempFilePath; - private final String enclaveWrapperFilePath; private final String enclaveSvmFilePath; - MockInSvmExtractTempPath(String jniTempFilePath, String enclaveWrapperFilePath, String enclaveSvmFilePath) { + MockInSvmExtractTempPath(String jniTempFilePath, String enclaveSvmFilePath) { this.jniTempFilePath = jniTempFilePath; - this.enclaveWrapperFilePath = enclaveWrapperFilePath; this.enclaveSvmFilePath = enclaveSvmFilePath; } @@ -213,10 +152,6 @@ class MockInSvmEnclave extends AbstractEnclave { return jniTempFilePath; } - String getEnclaveWrapperFilePath() { - return enclaveWrapperFilePath; - } - String getEnclaveSvmFilePath() { return enclaveSvmFilePath; } diff --git a/sdk/host/src/main/native/Makefile b/sdk/host/src/main/native/Makefile new file mode 100644 index 0000000..b498a00 --- /dev/null +++ b/sdk/host/src/main/native/Makefile @@ -0,0 +1,11 @@ +# Copyright (c) + +.PHONY: all build clean + +all: build + +build: + $(MAKE) -C cpp/platform/mock_in_svm/jni + +clean: + $(MAKE) -C cpp/platform/mock_in_svm/jni clean \ No newline at end of file diff --git a/sdk/host/src/main/native/bin/platform/mock_in_svm/jni/.gitkeep b/sdk/host/src/main/native/bin/platform/mock_in_svm/jni/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/sdk/host/src/main/native/config/config.mk b/sdk/host/src/main/native/config/config.mk new file mode 100644 index 0000000..a34d544 --- /dev/null +++ b/sdk/host/src/main/native/config/config.mk @@ -0,0 +1,13 @@ +# parse enable MOCK_IN_SVM platform, ${MOCK_IN_SVM} is from make.sh script. +BUILD_MOCK_IN_SVM ?= $(shell echo ${MOCK_IN_SVM}) +# parse JavaEnclave SDK base dir path, ${base_dir} is from make.sh script. +BASE_DIR_PATH = $(shell echo ${base_dir}) + +# parse BIN path. +BIN = $(BASE_DIR_PATH)/src/main/native/bin +# parse CONFIG path. +CONFIG = $(BASE_DIR_PATH)/src/main/native/config +# parse CPP path. +CPP = $(BASE_DIR_PATH)/src/main/native/cpp +# parse INCLUDE path. +INCLUDE = $(BASE_DIR_PATH)/src/main/native/include \ No newline at end of file diff --git a/sdk/host/src/main/native/config/platform/mock_in_svm/jni/config.mk b/sdk/host/src/main/native/config/platform/mock_in_svm/jni/config.mk new file mode 100644 index 0000000..ae3dcf2 --- /dev/null +++ b/sdk/host/src/main/native/config/platform/mock_in_svm/jni/config.mk @@ -0,0 +1,5 @@ +CC = gcc +CXX = g++ + +# define mock_in_svm jni.cpp compile option. +DB_LDFLAGS = -Wl,-z,noexecstack -lc -ldl -lpthread -std=c99 \ No newline at end of file diff --git a/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/Makefile b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/Makefile new file mode 100644 index 0000000..2e8074e --- /dev/null +++ b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/Makefile @@ -0,0 +1,15 @@ +include ./../../../../config/config.mk +include ./../../../../config/platform/mock_in_svm/jni/config.mk + +.PHONY: all build clean + +all: build + +# compile jni_mock_in_svm.c to $(BIN)/platform/mock_in_svm/jni/lib_jni_mock_svm.so +build: + $(CC) jni_mock_in_svm.c -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(shell uname -s | tr A-Z a-z) \ + -I$(JAVA_HOME)/lib $(DB_LDFLAGS) -I$(INCLUDE) -fPIC -shared -o $(BIN)/platform/mock_in_svm/jni/lib_jni_mock_svm.so + +# clean lib_jni_mock_svm.so +clean: + rm -rf *.o $(BIN)/platform/mock_in_svm/jni/lib_jni_mock_svm.so \ 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 new file mode 100644 index 0000000..1a8d6d8 --- /dev/null +++ b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.c @@ -0,0 +1,172 @@ +#include <assert.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dlfcn.h> + +#include <graal_isolate.h> +#include <enc_environment.h> +#include <enc_exported_symbol.h> + +#include "jni_mock_in_svm.h" + +typedef int (*java_enclave_stub)(graal_isolate_t*, enc_data_t*, enc_data_t*, callbacks_t*); + +static JNINativeMethod mock_in_svm_methods[] = { + {"nativeCreateEnclave", "(Ljava/lang/String;)I", (void *)&JavaEnclave_MockSVMNativeCreateEnclave}, + {"nativeSvmAttachIsolate", "(J)I", (void *)&JavaEnclave_MockSVMNativeSvmAttachIsolate}, + {"nativeLoadService", MOCK_IN_SVM_NATIVE_CALL_SIGNATURE, (void *)&JavaEnclave_MockSVMNativeLoadService}, + {"nativeInvokeMethod", MOCK_IN_SVM_NATIVE_CALL_SIGNATURE, (void *)&JavaEnclave_MockSVMNativeInvokeMethod}, + {"nativeUnloadService", MOCK_IN_SVM_NATIVE_CALL_SIGNATURE, (void *)&JavaEnclave_MockSVMNativeUnloadService}, + {"nativeSvmDetachIsolate", "(JJ)I", (void *)&JavaEnclave_MockSVMNativeSvmDetachIsolate}, + {"nativeDestroyEnclave", "(J)I", (void *)&JavaEnclave_MockSVMNativeDestroyEnclave}, +}; + +static void *mock_in_svm_load_service_symbol = NULL; +static void *mock_in_svm_invoke_service_symbol = NULL; +static void *mock_in_svm_unload_service_symbol = NULL; + +JNIEXPORT void JNICALL +Java_com_alibaba_confidentialcomputing_host_MockInSvmEnclave_registerNatives(JNIEnv *env, jclass cls) { + (*env)->RegisterNatives(env, cls, mock_in_svm_methods, sizeof(mock_in_svm_methods)/sizeof(mock_in_svm_methods[0])); +} + +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); +} + +char* memcpy_char_pointer(char* src, int len) { + char *ptr = malloc(len); + memcpy(ptr, src, len); + return (char*)ptr; +} + +jobject build_invocation_result(JNIEnv *env, jint ret, jbyteArray array) { + // build jni return object InnerNativeInvocationResult. + jclass invocation_result_clazz = (*env)->FindClass(env, MOCK_IN_SVM_RETURN_OBJECT_SIGNATURE); + jmethodID id = (*env)->GetMethodID(env, invocation_result_clazz, "<init>", "(I[B)V"); + return (*env)->NewObject(env, invocation_result_clazz, id, (jint)ret, array); +} + +jobject service_operate_common(JNIEnv *env, jlong isolate_handler, jbyteArray payload, java_enclave_stub p_function) { + jbyte *service_payload_copy = (*env)->GetByteArrayElements(env, payload, NULL); + int service_payload_copy_length = (*env)->GetArrayLength(env, payload); + enc_data_t invoke_data; + invoke_data.data = (char*)service_payload_copy; + invoke_data.data_len = service_payload_copy_length; + enc_data_t result; + result.data = NULL; + result.data_len = 0x0; + callbacks_t callback_methods; + callback_methods.memcpy_char_pointer = &memcpy_char_pointer; + callback_methods.exception_handler = NULL; + int ret = p_function((graal_isolate_t*)isolate_handler, &invoke_data, &result, &callback_methods); + (*env)->ReleaseByteArrayElements(env, payload, service_payload_copy, 0); + + // create a byte array. + jbyteArray invocation_result_arr = (*env)->NewByteArray(env, result.data_len); + jbyte *invocation_result_arr_point = (*env)->GetByteArrayElements(env, invocation_result_arr, NULL); + memcpy(invocation_result_arr_point, result.data, result.data_len); + + // free buffer malloc in jni. + (*env)->ReleaseByteArrayElements(env, invocation_result_arr, invocation_result_arr_point, 0); + // free buffer malloc in native image by callback mechanism. + free(result.data); + + return build_invocation_result(env, ret, invocation_result_arr); +} + +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeCreateEnclave(JNIEnv *env, jobject obj, jstring path) { + const char *path_str = (path == 0) ? 0 : (*env)->GetStringUTFChars(env, path, 0); + void *enclave_handler = dlopen(path_str , RTLD_LOCAL | RTLD_LAZY); + if (enclave_handler == 0x0) { + fprintf(stderr, "mock in svm dlopen error:%s\n", dlerror()); + return -1; + } + // find load service symbol. + mock_in_svm_load_service_symbol = dlsym((void *)enclave_handler, "java_loadservice_invoke"); + if (!mock_in_svm_load_service_symbol) { + fprintf(stderr, "java_loadservice_invoke error:%s\n", dlerror()); + dlclose(enclave_handler); + return -1; + } + // find invoke service symbol. + mock_in_svm_invoke_service_symbol = dlsym((void *)enclave_handler, "java_enclave_invoke"); + if (!mock_in_svm_invoke_service_symbol) { + fprintf(stderr, "mock_in_svm_invoke_service_symbol error:%s\n", dlerror()); + dlclose(enclave_handler); + return -1; + } + // find unload service symbol. + mock_in_svm_unload_service_symbol = dlsym((void *)enclave_handler, "java_unloadservice_invoke"); + if (!mock_in_svm_unload_service_symbol) { + fprintf(stderr, "mock_in_svm_unload_service_symbol error:%s\n", dlerror()); + dlclose(enclave_handler); + return -1; + } + // set enclave_handler back to MockInSvmEnclave.enclaveSvmSdkHandle field. + jclass class_enclave = (*env)->GetObjectClass(env, obj); + set_long_field_value(env, class_enclave, obj, "enclaveSvmSdkHandle", (jlong)enclave_handler); + return 0; +} + +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeSvmAttachIsolate(JNIEnv *env, jobject obj, jlong enclave_handler) { + graal_isolate_t* isolate_t; + graal_create_isolate_params_t p; + graal_isolatethread_t* isolate_thread_t; + + int (*graal_create_isolate)(graal_create_isolate_params_t* params, graal_isolate_t** isolate, graal_isolatethread_t** thread); + graal_create_isolate = (int (*)(graal_create_isolate_params_t*, graal_isolate_t**, graal_isolatethread_t**)) + dlsym((void *)enclave_handler, "graal_create_isolate"); + if (!graal_create_isolate) { + fprintf(stderr, "dlsym error:%s\n", dlerror()); + return -1; + } + + int ret = graal_create_isolate(NULL, &isolate_t, &isolate_thread_t); + if (ret != 0) { + fprintf(stderr, "graal_create_isolate create error:%s\n", dlerror()); + return ret; + } + + // set isolate_t and isolate_thread_t back to MockInSvmEnclave.isolateHandle and MockInSvmEnclave.isolateThreadHandle + jclass class_enclave = (*env)->GetObjectClass(env, obj); + set_long_field_value(env, class_enclave, obj, "isolateHandle", (jlong)isolate_t); + set_long_field_value(env, class_enclave, obj, "isolateThreadHandle", (jlong)isolate_thread_t); + return ret; +} + +JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeLoadService(JNIEnv *env, jobject obj, jlong enclave_handler, +jlong isolate_handler, jbyteArray service_payload) { + return service_operate_common(env, isolate_handler, service_payload, (java_enclave_stub) mock_in_svm_load_service_symbol); +} + +JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *env, jobject obj, jlong enclave_handler, +jlong isolate_handler, jbyteArray invoke_wrapper_payload) { + return service_operate_common(env, isolate_handler, invoke_wrapper_payload, (java_enclave_stub) mock_in_svm_invoke_service_symbol); +} + +JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeUnloadService(JNIEnv *env, jobject obj, jlong enclave_handler, +jlong isolate_handler, jbyteArray service_payload) { + return service_operate_common(env, isolate_handler, service_payload, (java_enclave_stub) mock_in_svm_unload_service_symbol); +} + +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeSvmDetachIsolate(JNIEnv *env, jobject obj, jlong enclave_handler, +jlong isolate_thread_handler) { + int (*graal_detach_all_threads_and_tear_down_isolate)(graal_isolatethread_t* isolateThread); + graal_detach_all_threads_and_tear_down_isolate = + (int (*)(graal_isolatethread_t*)) dlsym((void *)enclave_handler, "graal_detach_all_threads_and_tear_down_isolate"); + if (!graal_detach_all_threads_and_tear_down_isolate) { + fprintf(stderr, "graal_detach_all_threads_and_tear_down_isolate error:%s\n", dlerror()); + return -1; + } + return (jint)graal_detach_all_threads_and_tear_down_isolate((graal_isolatethread_t*)isolate_thread_handler); +} + +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeDestroyEnclave(JNIEnv *env, jobject obj, jlong enclave_handler) { + return dlclose((void *)enclave_handler); +} 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 new file mode 100644 index 0000000..bbcedf1 --- /dev/null +++ b/sdk/host/src/main/native/cpp/platform/mock_in_svm/jni/jni_mock_in_svm.h @@ -0,0 +1,66 @@ +#include <jni.h> + +#ifndef _Included_jni_mock_in_svm +#define _Included_jni_mock_in_svm + +#define MOCK_IN_SVM_NATIVE_CALL_SIGNATURE "(JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult;" +#define MOCK_IN_SVM_RETURN_OBJECT_SIGNATURE "com/alibaba/confidentialcomputing/host/InnerNativeInvocationResult" + +#ifdef __cplusplus +extern "C" { +#endif +JNIEXPORT void JNICALL Java_com_alibaba_confidentialcomputing_host_MockInSvmEnclave_registerNatives(JNIEnv *env, jclass cls); + +/* + * Class: JavaEnclave_MockSVMNativeCreateEnclave + * Method: nativeCreateEnclave + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeCreateEnclave(JNIEnv *, jobject, jstring); + +/* + * Class: JavaEnclave_MockSVMNativeSvmAttachIsolate + * Method: nativeSvmAttachIsolate + * Signature: (J)I + */ +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeSvmAttachIsolate(JNIEnv *, jobject, jlong); + +/* + * Class: JavaEnclave_MockSVMNativeLoadService + * Method: nativeLoadService + * Signature: (JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult; + */ +JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeLoadService(JNIEnv *, jobject, jlong, jlong, jbyteArray); + +/* + * Class: JavaEnclave_MockSVMNativeInvokeMethod + * Method: nativeInvokeMethod + * Signature: (JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult; + */ +JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeInvokeMethod(JNIEnv *, jobject, jlong, jlong, jbyteArray); + +/* + * Class: JavaEnclave_MockSVMNativeUnloadService + * Method: nativeUnloadService + * Signature: (JJ[B)Lcom/alibaba/confidentialcomputing/host/InnerNativeInvocationResult; + */ +JNIEXPORT jobject JNICALL JavaEnclave_MockSVMNativeUnloadService(JNIEnv *, jobject, jlong, jlong, jbyteArray); + +/* + * Class: JavaEnclave_MockSVMNativeSvmDetachIsolate + * Method: nativeSvmDetachIsolate + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeSvmDetachIsolate(JNIEnv *, jobject, jlong, jlong); + +/* + * Class: JavaEnclave_MockSVMNativeDestroyEnclave + * Method: nativeDestroyEnclave + * Signature: (J)I + */ +JNIEXPORT jint JNICALL JavaEnclave_MockSVMNativeDestroyEnclave(JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/sdk/enclave/src/main/resources/native/enc_environment.h b/sdk/host/src/main/native/include/enc_environment.h similarity index 73% copy from sdk/enclave/src/main/resources/native/enc_environment.h copy to sdk/host/src/main/native/include/enc_environment.h index dc6f683..6de8c9f 100644 --- a/sdk/enclave/src/main/resources/native/enc_environment.h +++ b/sdk/host/src/main/native/include/enc_environment.h @@ -1,8 +1,15 @@ - typedef struct enc_data_struct{ +#ifndef __ENC_ENVIRONMENT_H +#define __ENC_ENVIRONMENT_H + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct enc_data_struct{ //char array is used as byte array to store serialized data char* data; int data_len; - }enc_data; +}enc_data_t; typedef struct callback_functions_struct{ /* @@ -14,4 +21,9 @@ typedef struct callback_functions_struct{ void (*exception_handler)(char* err_msg, char* stack_trace, char* exception_name); char* (*memcpy_char_pointer)(char* src, int len); -}callbacks; +}callbacks_t; + +#if defined(__cplusplus) +} +#endif +#endif diff --git a/sdk/host/src/main/native/include/enc_exported_symbol.h b/sdk/host/src/main/native/include/enc_exported_symbol.h new file mode 100644 index 0000000..0e77dd9 --- /dev/null +++ b/sdk/host/src/main/native/include/enc_exported_symbol.h @@ -0,0 +1,19 @@ +#ifndef __ENC_EXPORTED_SYMBOL_H +#define __ENC_EXPORTED_SYMBOL_H + +#include "graal_isolate.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +int java_loadservice_invoke(graal_isolate_t* thread, enc_data_t* input, enc_data_t* result, callbacks_t* callBacks); + +int java_enclave_invoke(graal_isolate_t* thread, enc_data_t* input, enc_data_t* result, callbacks_t* callBacks); + +int java_unloadservice_invoke(graal_isolate_t* thread, enc_data_t* input, enc_data_t* result, callbacks_t* callBacks); + +#if defined(__cplusplus) +} +#endif +#endif \ No newline at end of file diff --git a/sdk/host/src/main/native/make.sh b/sdk/host/src/main/native/make.sh new file mode 100644 index 0000000..0340bb6 --- /dev/null +++ b/sdk/host/src/main/native/make.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# this script will build multi enclave platform's jni.so, +# also compile enclave's edge routine files which was +# generated by enclave sdk toolchain. + +# step one: cd make.sh script's path location. + +# shellcheck disable=SC2006 +this_script_dir=`dirname "$0"` +# shellcheck disable=SC2164 +cd "$this_script_dir" + +# step two: parse parameters from pom.xml +# parse and store base dir path +export base_dir=$1 +# parse and store supported enclave platform set +enclave_platform_config=$2 +# process supported enclave platform set +OLD_IFS="$IFS" +IFS=":" +enclave_platform_array=($enclave_platform_config) +IFS="$OLD_IFS" + +# shellcheck disable=SC2068 +for enclave_platform in ${enclave_platform_array[@]} +do + echo "$enclave_platform" + # set "enclave_platform" as TRUE to indicate how + # to compile jni.so and edge routine + export "$enclave_platform"=TRUE +done + +if [ "$3" == clean ]; +then + # make clean. + make -f ./Makefile clean + rm +elif [ "$3" == build ]; +then + # make build. + make -f ./Makefile build + # copy jni.so to target/classes, which will be packed into a jar file. + if [[ $MOCK_IN_SVM == TRUE ]]; then + cp -r "$base_dir"/src/main/native/bin/platform/mock_in_svm/jni "$base_dir"/target/classes + fi +else + echo "unsupported make command!!!" +fi 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 e1b8a3c..e655e46 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 @@ -75,13 +75,11 @@ class MockTestEnclave extends AbstractEnclave { @Override InnerNativeInvocationResult loadServiceNative(byte[] payload) { - EnclaveInvocationContext invocationContext; List<ServiceHandler> handlers = new ArrayList<>(); Throwable exception = null; EnclaveInvocationResult result; try { - invocationContext = (EnclaveInvocationContext) SerializationHelper.deserialize(payload); - String interfaceName = invocationContext.getServiceHandler().getServiceInterfaceName(); + String interfaceName = (String) SerializationHelper.deserialize(payload); Class<?> service = Class.forName(interfaceName); Iterator<?> services = ServiceLoader.load(service).iterator(); while (services.hasNext()) { @@ -107,12 +105,12 @@ class MockTestEnclave extends AbstractEnclave { @Override InnerNativeInvocationResult unloadServiceNative(byte[] payload) { - EnclaveInvocationContext invocationContext; + ServiceHandler serviceHandler; Throwable exception = null; EnclaveInvocationResult result; try { - invocationContext = (EnclaveInvocationContext) SerializationHelper.deserialize(payload); - instancesRegisterCenter.remove(invocationContext.getServiceHandler().getInstanceIdentity()); + serviceHandler = (ServiceHandler) SerializationHelper.deserialize(payload); + instancesRegisterCenter.remove(serviceHandler.getInstanceIdentity()); } catch (IOException | ClassNotFoundException e) { exception = e; } finally { diff --git a/sdk/pom.xml b/sdk/pom.xml index 464f84b..c5401b1 100644 --- a/sdk/pom.xml +++ b/sdk/pom.xml @@ -11,6 +11,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</com.alibaba.enclave.platform> </properties> <dependencyManagement> <dependencies> diff --git a/test/common/pom.xml b/test/common/pom.xml new file mode 100644 index 0000000..66e5588 --- /dev/null +++ b/test/common/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <parent> + <groupId>com.alibaba.confidentialcomputing</groupId> + <artifactId>test</artifactId> + <version>0.1.0</version> + </parent> + <artifactId>common</artifactId> + <packaging>jar</packaging> + <name>Test-Common</name> + <url></url> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>3.0.0</version> + <configuration> + <attach>true</attach> + </configuration> + <executions> + <execution> + <phase>compile</phase> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.0.0-M5</version> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>com.alibaba.confidentialcomputing</groupId> + <artifactId>common</artifactId> + </dependency> + <dependency> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service-annotations</artifactId> + <version>1.0-rc6</version> + <optional>true</optional> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service</artifactId> + <version>1.0-rc6</version> + <optional>true</optional> + <scope>provided</scope> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/EnclaveException.java b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/EnclaveException.java new file mode 100644 index 0000000..193b896 --- /dev/null +++ b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/EnclaveException.java @@ -0,0 +1,8 @@ +package com.alibaba.confidentialcomputing.test.common; + +import com.alibaba.confidentialcomputing.common.annotations.EnclaveService; + +@EnclaveService +public interface EnclaveException { + void enclaveException(String info) throws JavaEnclaveException; +} diff --git a/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/JavaEnclaveException.java b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/JavaEnclaveException.java new file mode 100644 index 0000000..9ed7f21 --- /dev/null +++ b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/JavaEnclaveException.java @@ -0,0 +1,7 @@ +package com.alibaba.confidentialcomputing.test.common; + +public class JavaEnclaveException extends Exception { + public JavaEnclaveException(String info) { + super(info); + } +} diff --git a/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/ReflectionCallService.java b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/ReflectionCallService.java new file mode 100644 index 0000000..f4dbf44 --- /dev/null +++ b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/ReflectionCallService.java @@ -0,0 +1,10 @@ +package com.alibaba.confidentialcomputing.test.common; + +import com.alibaba.confidentialcomputing.common.annotations.EnclaveService; + +@EnclaveService +public interface ReflectionCallService { + int add(int a, int b); + + int sub(int a, int b); +} diff --git a/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/SayHelloService.java b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/SayHelloService.java new file mode 100644 index 0000000..c3016b0 --- /dev/null +++ b/test/common/src/main/java/com/alibaba/confidentialcomputing/test/common/SayHelloService.java @@ -0,0 +1,8 @@ +package com.alibaba.confidentialcomputing.test.common; + +import com.alibaba.confidentialcomputing.common.annotations.EnclaveService; + +@EnclaveService +public interface SayHelloService { + String sayHelloService(String plainText); +} \ No newline at end of file diff --git a/test/enclave/pom.xml b/test/enclave/pom.xml new file mode 100644 index 0000000..63114bc --- /dev/null +++ b/test/enclave/pom.xml @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <parent> + <groupId>com.alibaba.confidentialcomputing</groupId> + <artifactId>test</artifactId> + <version>0.1.0</version> + </parent> + <artifactId>enclave</artifactId> + <packaging>jar</packaging> + <name>Test-Enclave</name> + <url></url> + <properties> + <svm.maven.version>0.9.10</svm.maven.version> + </properties> + <profiles> + <profile> + <id>native</id> + <build> + <plugins> + <plugin> + <groupId>org.graalvm.buildtools</groupId> + <artifactId>native-maven-plugin</artifactId> + <version>${svm.maven.version}</version> + <extensions>true</extensions> + <executions> + <execution> + <id>test-native</id> + <goals> + <goal>test</goal> + </goals> + <configuration> + <buildArgs> + <buildArg>--no-fallback</buildArg> + <buildArg>-H:+RunInEnclave</buildArg> + </buildArgs> + </configuration> + <phase>test</phase> + </execution> + <execution> + <id>build-native</id> + <goals> + <goal>build</goal> + </goals> + <configuration> + <imageName>lib_mock_svm_load</imageName> + <buildArgs> + <buildArg>--shared</buildArg> + <buildArg>--no-fallback</buildArg> + <buildArg>--allow-incomplete-classpath</buildArg> + <buildArg>-H:OutputRelocatableImage=.</buildArg> + <buildArg>-H:+RunInEnclave</buildArg> + <buildArg>-H:Path=svm-output</buildArg> + <buildArg>-H:ReflectionConfigurationFiles=${project.basedir}/target/native/agent-output/test/reflect-config.json</buildArg> + </buildArgs> + </configuration> + <phase>package</phase> + </execution> + </executions> + <configuration> + <agent> + <enabled>true</enabled> + </agent> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>3.0.0</version> + <configuration> + <attach>true</attach> + </configuration> + <executions> + <execution> + <phase>compile</phase> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.0.0-M5</version> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <artifactId>common</artifactId> + </dependency> + <dependency> + <groupId>com.alibaba.confidentialcomputing</groupId> + <artifactId>enclave</artifactId> + </dependency> + <dependency> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service-annotations</artifactId> + <version>1.0-rc6</version> + <optional>true</optional> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service</artifactId> + <version>1.0-rc6</version> + <optional>true</optional> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-launcher</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit-pioneer</groupId> + <artifactId>junit-pioneer</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/Calculate.java b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/Calculate.java new file mode 100644 index 0000000..3e4ca61 --- /dev/null +++ b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/Calculate.java @@ -0,0 +1,11 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +public class Calculate { + public static int add(int a, int b) { + return a + b; + } + + public static int sub(int a, int b) { + return a - b; + } +} diff --git a/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/EnclaveExceptionImpl.java b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/EnclaveExceptionImpl.java new file mode 100644 index 0000000..7c5d18b --- /dev/null +++ b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/EnclaveExceptionImpl.java @@ -0,0 +1,13 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +import com.alibaba.confidentialcomputing.test.common.EnclaveException; +import com.alibaba.confidentialcomputing.test.common.JavaEnclaveException; +import com.google.auto.service.AutoService; + +@AutoService(EnclaveException.class) +public class EnclaveExceptionImpl implements EnclaveException { + @Override + public void enclaveException(String info) throws JavaEnclaveException { + throw new JavaEnclaveException(info); + } +} diff --git a/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/ReflectionCallServiceImpl.java b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/ReflectionCallServiceImpl.java new file mode 100644 index 0000000..3aaf6f1 --- /dev/null +++ b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/ReflectionCallServiceImpl.java @@ -0,0 +1,47 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +import com.alibaba.confidentialcomputing.test.common.ReflectionCallService; + +import com.google.auto.service.AutoService; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +@AutoService(ReflectionCallService.class) +public class ReflectionCallServiceImpl implements ReflectionCallService { + private static Method addMethod; + private static Method subMethod; + + static { + try { + addMethod = Class.forName(Calculate.class.getName()).getMethod("add", int.class, int.class); + subMethod = Class.forName(Calculate.class.getName()).getMethod("sub", int.class, int.class); + } catch (ClassNotFoundException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + + @Override + public int add(int a, int b) { + try { + return (int) addMethod.invoke(null, a, b); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public int sub(int a, int b) { + try { + return (int) subMethod.invoke(null, a, b); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return -1; + } +} \ No newline at end of file diff --git a/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/SayHelloServiceImpl.java b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/SayHelloServiceImpl.java new file mode 100644 index 0000000..2dfd70c --- /dev/null +++ b/test/enclave/src/main/java/com/alibaba/confidentialcomputing/test/enclave/SayHelloServiceImpl.java @@ -0,0 +1,13 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +import com.alibaba.confidentialcomputing.test.common.SayHelloService; + +import com.google.auto.service.AutoService; + +@AutoService(SayHelloService.class) +public class SayHelloServiceImpl implements SayHelloService { + @Override + public String sayHelloService(String plainText) { + return plainText; + } +} \ No newline at end of file diff --git a/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestEnclaveException.java b/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestEnclaveException.java new file mode 100644 index 0000000..85d6f5c --- /dev/null +++ b/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestEnclaveException.java @@ -0,0 +1,14 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +import com.alibaba.confidentialcomputing.test.common.JavaEnclaveException; + +import org.junit.jupiter.api.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestEnclaveException { + @Test + public void testEnclaveException() { + assertThrows(JavaEnclaveException.class, () -> new EnclaveExceptionImpl().enclaveException("JavaEnclave Exception")); + } +} diff --git a/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestReflectionCallService.java b/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestReflectionCallService.java new file mode 100644 index 0000000..6288764 --- /dev/null +++ b/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestReflectionCallService.java @@ -0,0 +1,15 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestReflectionCallService { + + @Test + public void testReflectionCallService() { + ReflectionCallServiceImpl service = new ReflectionCallServiceImpl(); + assertEquals(20, service.add(2, 18)); + assertEquals(-20, service.sub(2, 22)); + } +} diff --git a/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestSayHelloServiceImpl.java b/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestSayHelloServiceImpl.java new file mode 100644 index 0000000..4c41d8e --- /dev/null +++ b/test/enclave/src/test/java/com/alibaba/confidentialcomputing/test/enclave/TestSayHelloServiceImpl.java @@ -0,0 +1,14 @@ +package com.alibaba.confidentialcomputing.test.enclave; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestSayHelloServiceImpl { + + @Test + public void testSayHelloServiceImpl() { + SayHelloServiceImpl service = new SayHelloServiceImpl(); + assertEquals("Hello World", service.sayHelloService("Hello World")); + } +} \ No newline at end of file diff --git a/sdk/host/pom.xml b/test/host/pom.xml similarity index 58% copy from sdk/host/pom.xml copy to test/host/pom.xml index dbaf6ce..6565a58 100644 --- a/sdk/host/pom.xml +++ b/test/host/pom.xml @@ -2,17 +2,25 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> - <groupId>com.alibaba.confidentialcomputing</groupId> + <groupId>com.alibaba.confidentialcomputing.test</groupId> <parent> <groupId>com.alibaba.confidentialcomputing</groupId> - <artifactId>JavaEnclave</artifactId> + <artifactId>test</artifactId> <version>0.1.0</version> </parent> <artifactId>host</artifactId> <packaging>jar</packaging> - <name>JavaEnclave-Host</name> + <name>Test-Host</name> <url></url> <build> + <resources> + <resource> + <directory>${project.basedir}/../enclave/target/svm-output</directory> + <includes> + <include>**/*.so</include> + </includes> + </resource> + </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -30,49 +38,6 @@ </execution> </executions> </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-javadoc-plugin</artifactId> - <configuration> - <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable> - <doclint>none</doclint> - </configuration> - <version>3.2.0</version> - <executions> - <execution> - <id>attach-javadoc</id> - <goals> - <goal>jar</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.3</version> - <configuration> - <includes> - <include>com/alibaba/confidentialcomputing/host/*</include> - <include>com/alibaba/confidentialcomputing/host/**/*</include> - </includes> - </configuration> - <executions> - <execution> - <id>pre-test</id> - <goals> - <goal>prepare-agent</goal> - </goals> - </execution> - <execution> - <id>post-test</id> - <phase>test</phase> - <goals> - <goal>report</goal> - </goals> - </execution> - </executions> - </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> @@ -81,10 +46,22 @@ </plugins> </build> <dependencies> + <dependency> + <groupId>com.alibaba.confidentialcomputing</groupId> + <artifactId>host</artifactId> + </dependency> <dependency> <groupId>com.alibaba.confidentialcomputing</groupId> <artifactId>common</artifactId> </dependency> + <dependency> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <artifactId>enclave</artifactId> + </dependency> + <dependency> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <artifactId>common</artifactId> + </dependency> <dependency> <groupId>com.google.auto.service</groupId> <artifactId>auto-service-annotations</artifactId> @@ -99,11 +76,6 @@ <optional>true</optional> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <scope>test</scope> - </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> @@ -125,4 +97,4 @@ <scope>test</scope> </dependency> </dependencies> -</project> +</project> \ No newline at end of file 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 new file mode 100644 index 0000000..3640a12 --- /dev/null +++ b/test/host/src/test/java/com/alibaba/confidentialcomputing/test/host/TestJavaEnclaveService.java @@ -0,0 +1,72 @@ +package com.alibaba.confidentialcomputing.test.host; + +import java.util.Iterator; + +import com.alibaba.confidentialcomputing.host.exception.EnclaveCreatingException; +import com.alibaba.confidentialcomputing.host.exception.EnclaveDestroyingException; +import com.alibaba.confidentialcomputing.host.exception.ServicesLoadingException; +import com.alibaba.confidentialcomputing.test.common.EnclaveException; +import com.alibaba.confidentialcomputing.test.common.JavaEnclaveException; +import com.alibaba.confidentialcomputing.test.common.ReflectionCallService; +import com.alibaba.confidentialcomputing.test.common.SayHelloService; +import com.alibaba.confidentialcomputing.host.Enclave; +import com.alibaba.confidentialcomputing.host.EnclaveFactory; +import com.alibaba.confidentialcomputing.host.EnclaveType; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestJavaEnclaveService { + private String sayHelloService(EnclaveType type, String plain) throws + EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException { + Enclave enclave = EnclaveFactory.create(type); + Iterator<SayHelloService> userServices = enclave.load(SayHelloService.class); + assertNotNull(userServices); + assertTrue(userServices.hasNext()); + SayHelloService service = userServices.next(); + String result = service.sayHelloService(plain); + enclave.destroy(); + return result; + } + + private void reflectionCallService(EnclaveType type) throws EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException { + Enclave enclave = EnclaveFactory.create(type); + Iterator<ReflectionCallService> userServices = enclave.load(ReflectionCallService.class); + assertNotNull(userServices); + assertTrue(userServices.hasNext()); + ReflectionCallService service = userServices.next(); + assertEquals(20, service.add(2, 18)); + assertEquals(-20, service.sub(2, 22)); + enclave.destroy(); + } + + private void javaEnclaveException(EnclaveType type) throws EnclaveCreatingException, ServicesLoadingException, EnclaveDestroyingException { + Enclave enclave = EnclaveFactory.create(type); + Iterator<EnclaveException> userServices = enclave.load(EnclaveException.class); + assertNotNull(userServices); + assertTrue(userServices.hasNext()); + EnclaveException service = userServices.next(); + assertThrows(JavaEnclaveException.class, () -> service.enclaveException("JavaEnclave Exception")); + enclave.destroy(); + } + + @Test + public void testSayHelloService() throws + EnclaveCreatingException, EnclaveDestroyingException, ServicesLoadingException { + assertEquals("Hello World", sayHelloService(EnclaveType.MOCK_IN_JVM, "Hello World")); + assertEquals("Hello World", sayHelloService(EnclaveType.MOCK_IN_SVM, "Hello World")); + } + + @Test + public void testReflectionCallService() throws ServicesLoadingException, EnclaveCreatingException, EnclaveDestroyingException { + reflectionCallService(EnclaveType.MOCK_IN_JVM); + reflectionCallService(EnclaveType.MOCK_IN_SVM); + } + + @Test + public void testJavaEnclaveException() throws ServicesLoadingException, EnclaveCreatingException, EnclaveDestroyingException { + javaEnclaveException(EnclaveType.MOCK_IN_JVM); + javaEnclaveException(EnclaveType.MOCK_IN_SVM); + } +} diff --git a/sdk/pom.xml b/test/pom.xml similarity index 69% copy from sdk/pom.xml copy to test/pom.xml index 464f84b..8e8df10 100644 --- a/sdk/pom.xml +++ b/test/pom.xml @@ -1,16 +1,18 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.alibaba.confidentialcomputing</groupId> - <artifactId>JavaEnclave</artifactId> + <artifactId>test</artifactId> <packaging>pom</packaging> <version>0.1.0</version> - <name>JavaEnclave</name> + <name>test</name> <url></url> <properties> <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</com.alibaba.enclave.platform> </properties> <dependencyManagement> <dependencies> @@ -30,10 +32,19 @@ <version>0.1.0</version> </dependency> <dependency> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.3</version> - <scope>test</scope> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <artifactId>common</artifactId> + <version>0.1.0</version> + </dependency> + <dependency> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <artifactId>enclave</artifactId> + <version>0.1.0</version> + </dependency> + <dependency> + <groupId>com.alibaba.confidentialcomputing.test</groupId> + <artifactId>host</artifactId> + <version>0.1.0</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> @@ -47,6 +58,12 @@ <version>1.8.2</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-launcher</artifactId> + <version>1.8.2</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
