Add local attestation demo
This commit is contained in:
parent
83dfdc4f0f
commit
95ef2819db
@ -26,4 +26,5 @@ This set of demos shows how real-world apps can be easily run inside SGX enclave
|
||||
|
||||
* `embedded_mode/`: A cross-enclave memory throughput benchmark enabled by the embedded mode of Occlum.
|
||||
* `gdb_support/`: This demo explains the technical detail of GDB support and demonstrates how to debug an app running upon Occlum with GDB.
|
||||
* `local_attestation/`: This project demonstrates how an app running upon Occlum can perform SGX local attestation.
|
||||
* `remote_attestation/`: This project demonstrates how an app running upon Occlum can perform SGX remote attestation.
|
||||
|
8
demos/local_attestation/.gitignore
vendored
Normal file
8
demos/local_attestation/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
bin
|
||||
deps
|
||||
occlum_context
|
||||
DiffieHellmanLibrary/*.cpp
|
||||
DiffieHellmanLibrary/*.so
|
||||
DiffieHellmanLibrary/*.o
|
||||
DiffieHellmanLibrary/include
|
||||
Include
|
118
demos/local_attestation/AppInitiator/Makefile
Normal file
118
demos/local_attestation/AppInitiator/Makefile
Normal file
@ -0,0 +1,118 @@
|
||||
#
|
||||
# Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#
|
||||
|
||||
include ../buildenv.mk
|
||||
|
||||
TARGET = appinitiator
|
||||
|
||||
RM = rm -f
|
||||
|
||||
#SGX_SDK ?= /opt/intel/sgxsdk
|
||||
OCCLUM_PREFIX ?= /opt/occlum
|
||||
|
||||
CFLAGS := -Wall \
|
||||
-I$(SGX_SDK)/include \
|
||||
-I$(OCCLUM_PREFIX)/include \
|
||||
-I../Include
|
||||
CXXFLAGS := -Wall \
|
||||
-I$(SGX_SDK)/include \
|
||||
-I$(OCCLUM_PREFIX)/include \
|
||||
-I../Include
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
URTS_LIB_NAME := sgx_urts_sim
|
||||
UAE_SERVICE_LIB := sgx_uae_service_sim
|
||||
BUILD_DIR:= build_sim
|
||||
else
|
||||
URTS_LIB_NAME := sgx_urts
|
||||
UAE_SERVICE_LIB := sgx_uae_service
|
||||
BUILD_DIR:= build
|
||||
endif
|
||||
|
||||
INC:=-I$(SGX_SDK)/include -I../Include
|
||||
LIB := -l$(URTS_LIB_NAME) -l$(UAE_SERVICE_LIB) -L$(SGX_SDK)/lib64 -lpthread
|
||||
CXXFLAGS += $(INC) $(LIB)
|
||||
CFLAGS += $(INC) $(LIB)
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
CXXFLAGS += -DDEBUG -UNDEBUG -UEDEBUG
|
||||
CFLAGS += -DDEBUG -UNDEBUG -UEDEBUG
|
||||
else ifeq ($(SGX_PRERELEASE), 1)
|
||||
CXXFLAGS += -DEDEBUG -DNDEBUG -UDEBUG
|
||||
CFLAGS += -DEDEBUG -DNDEBUG -UDEBUG
|
||||
else
|
||||
CXXFLAGS += -DNDEBUG -UEDEBUG -UDEBUG
|
||||
CFLAGS += -DNDEBUG -UEDEBUG -UDEBUG
|
||||
endif
|
||||
|
||||
LINK_FLAGS := $(CXXFLAGS) -lpthread \
|
||||
-L$(SGX_SDK)/lib64 -lsgx_uprotected_fs \
|
||||
-L$(OCCLUM_PREFIX)/$(BUILD_DIR)/lib -locclum-pal
|
||||
|
||||
SRC_CPP=$(wildcard *.cpp)
|
||||
|
||||
SRC_OBJ += $(SRC_CPP:.cpp=.o)
|
||||
SRC_OBJ += $(SRC_C:.c=.o)
|
||||
|
||||
|
||||
.PHONY = all clean
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
SGX_COMMON_CFLAGS := -I$(SGX_SDK)/include
|
||||
|
||||
UntrustedEnclaveMessageExchange.o: UntrustedEnclaveMessageExchange.cpp
|
||||
@$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
App.o: App.cpp
|
||||
@$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
fifo.o: fifo.cpp
|
||||
@$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
EnclaveInitiator_u.o: EnclaveInitiator_u.c
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
EnclaveInitiator_u.c:
|
||||
@$(SGX_EDGER8R) --untrusted ../EnclaveInitiator/EnclaveInitiator.edl --search-path $(SGX_SDK)/include
|
||||
|
||||
$(TARGET): EnclaveInitiator_u.o $(SRC_OBJ)
|
||||
@$(CXX) $^ $(LINK_FLAGS) -o $@
|
||||
@echo "GEN => $@"
|
||||
@mkdir -p $(TOPDIR)/$(OUTDIR)
|
||||
@mv $@ $(TOPDIR)/$(OUTDIR)/
|
||||
|
||||
clean:
|
||||
@$(RM) $(TARGET) *.o *_u.c *_u.h
|
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "sgx_eid.h"
|
||||
#include "error_codes.h"
|
||||
#include "datatypes.h"
|
||||
#include "sgx_urts.h"
|
||||
#include "UntrustedEnclaveMessageExchange.h"
|
||||
#include "sgx_dh.h"
|
||||
|
||||
#include "fifo_def.h"
|
||||
|
||||
/* Function Description: This is OCALL interface for initiator enclave to get ECDH message 1 and session id from responder enclave
|
||||
* Parameter Description:
|
||||
* [input, output] dh_msg1: pointer to ecdh msg1 buffer, this buffer is alloated in initiator enclave and filled by reponser enclave
|
||||
* [output] session_id: pointer to session id which is allocated by responder enclave
|
||||
* */
|
||||
extern "C" ATTESTATION_STATUS session_request_ocall(sgx_dh_msg1_t* dh_msg1, uint32_t* session_id)
|
||||
{
|
||||
FIFO_MSG msg1_request;
|
||||
FIFO_MSG *msg1_response;
|
||||
SESSION_MSG1_RESP * msg1_respbody = NULL;
|
||||
size_t msg1_resp_size;
|
||||
|
||||
msg1_request.header.type = FIFO_DH_REQ_MSG1;
|
||||
msg1_request.header.size = 0;
|
||||
|
||||
if ((client_send_receive(&msg1_request, sizeof(FIFO_MSG), &msg1_response, &msg1_resp_size) != 0)
|
||||
|| (msg1_response == NULL))
|
||||
{
|
||||
printf("fail to send and receive message: session_request_ocall.\n");
|
||||
return INVALID_SESSION;
|
||||
}
|
||||
|
||||
msg1_respbody = (SESSION_MSG1_RESP *)msg1_response->msgbuf;
|
||||
memcpy(dh_msg1, &msg1_respbody->dh_msg1, sizeof(sgx_dh_msg1_t));
|
||||
*session_id = msg1_respbody->sessionid;
|
||||
free(msg1_response);
|
||||
|
||||
return (ATTESTATION_STATUS)0;
|
||||
}
|
||||
|
||||
/* Function Description: This is OCALL interface for initiator enclave to send ECDH message 2 to responder enclave, and receive ECDH message 3 from responder enclave
|
||||
* Parameter Description:
|
||||
* [input] dh_msg2: this is pointer to ECDH message 2 generated by initiator enclave
|
||||
* [input, output]dh_msg3: this is pointer to ECDH message 3, this buffer is allocated in initiator enclave and filled by respoonder enclave
|
||||
* [input] session_id: this is session id allocated by responder enclave
|
||||
* */
|
||||
ATTESTATION_STATUS exchange_report_ocall(sgx_dh_msg2_t *dh_msg2, sgx_dh_msg3_t *dh_msg3, uint32_t session_id)
|
||||
{
|
||||
FIFO_MSG * msg2 = NULL, * msg3 = NULL;
|
||||
FIFO_MSG_HEADER * msg2_header = NULL;
|
||||
SESSION_MSG2 *msg2_body = NULL;
|
||||
SESSION_MSG3 *msg3_body = NULL;
|
||||
size_t msg2size, msg3size;
|
||||
|
||||
msg2size = sizeof(FIFO_MSG_HEADER) + sizeof(SESSION_MSG2);
|
||||
msg2 = (FIFO_MSG *)malloc(msg2size);
|
||||
if (!msg2)
|
||||
{
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(msg2, 0, msg2size);
|
||||
|
||||
msg2_header = (FIFO_MSG_HEADER *)msg2;
|
||||
msg2_header->type = FIFO_DH_MSG2;
|
||||
msg2_header->size = sizeof(SESSION_MSG2);
|
||||
|
||||
msg2_body = (SESSION_MSG2 *)msg2->msgbuf;
|
||||
memcpy(&msg2_body->dh_msg2, dh_msg2, sizeof(sgx_dh_msg2_t));
|
||||
msg2_body->sessionid = session_id;
|
||||
|
||||
if (client_send_receive(msg2, msg2size, &msg3, &msg3size) != 0)
|
||||
{
|
||||
printf("failed to send and receive message.exchange_report_ocall\n");
|
||||
return INVALID_SESSION;
|
||||
}
|
||||
|
||||
msg3_body = (SESSION_MSG3 *)msg3->msgbuf;
|
||||
memcpy(dh_msg3, &msg3_body->dh_msg3, sizeof(sgx_dh_msg3_t));
|
||||
|
||||
free(msg3);
|
||||
free(msg2);
|
||||
|
||||
return (ATTESTATION_STATUS)0;
|
||||
}
|
||||
|
||||
/* Function Description: This is OCALL interface for initiator enclave to send request message(encrypted) to responder enclave, and receive response message from responder enclave
|
||||
* Parameter Description:
|
||||
* [input] session_id: this is session id allocated by responder enclave
|
||||
* [input] req_message: this is pointer to request message
|
||||
* [input] req_message_size: this is request message size
|
||||
* [input] max_payload_size: this is maxium payload size in response message
|
||||
* [input, output] this is pointer to response message, the buffer is allocated by initiator enclave and filled by responder enclave
|
||||
* [input] response message size
|
||||
* */
|
||||
ATTESTATION_STATUS send_request_ocall(uint32_t session_id, secure_message_t* req_message, size_t req_message_size, size_t max_payload_size, secure_message_t* resp_message, size_t resp_message_size)
|
||||
{
|
||||
FIFO_MSG *msgreq = NULL, * msgresp= NULL;
|
||||
FIFO_MSGBODY_REQ * msgbody;
|
||||
|
||||
size_t reqsize, respsize;
|
||||
|
||||
reqsize = sizeof(FIFO_MSG_HEADER) + sizeof(FIFO_MSGBODY_REQ) + req_message_size;
|
||||
|
||||
msgreq = (FIFO_MSG *)malloc(reqsize);
|
||||
if (!msgreq)
|
||||
{
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(msgreq, 0, reqsize);
|
||||
|
||||
msgreq->header.type = FIFO_DH_MSG_REQ;
|
||||
msgreq->header.size = sizeof(FIFO_MSGBODY_REQ) + req_message_size;
|
||||
|
||||
msgbody = (FIFO_MSGBODY_REQ *)msgreq->msgbuf;
|
||||
msgbody->max_payload_size = max_payload_size;
|
||||
msgbody->size = req_message_size;
|
||||
msgbody->session_id = session_id;
|
||||
|
||||
memcpy(msgbody->buf, req_message, req_message_size);
|
||||
|
||||
if (client_send_receive(msgreq, reqsize, &msgresp, &respsize) != 0)
|
||||
{
|
||||
printf("fail to send and receive message.send_request_ocall\n");
|
||||
return INVALID_SESSION;
|
||||
}
|
||||
|
||||
memcpy(resp_message, msgresp->msgbuf, msgresp->header.size < resp_message_size ? msgresp->header.size : resp_message_size);
|
||||
|
||||
free(msgresp);
|
||||
free(msgreq);
|
||||
|
||||
return (ATTESTATION_STATUS)0;
|
||||
}
|
||||
|
||||
/* Function Description: this is OCALL interface for initiator enclave to close secure session
|
||||
* Parameter Description:
|
||||
* [input] session_id: this is session id allocated by responder enclave
|
||||
* */
|
||||
ATTESTATION_STATUS end_session_ocall(uint32_t session_id)
|
||||
{
|
||||
FIFO_MSG *msgresp = NULL;
|
||||
FIFO_MSG *closemsg;
|
||||
SESSION_CLOSE_REQ * body;
|
||||
size_t reqsize, respsize;
|
||||
|
||||
reqsize = sizeof(FIFO_MSG) + sizeof(SESSION_CLOSE_REQ);
|
||||
closemsg = (FIFO_MSG *)malloc(reqsize);
|
||||
if (!closemsg)
|
||||
{
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(closemsg, 0,reqsize);
|
||||
|
||||
closemsg->header.type = FIFO_DH_CLOSE_REQ;
|
||||
closemsg->header.size = sizeof(SESSION_CLOSE_REQ);
|
||||
|
||||
body = (SESSION_CLOSE_REQ *)closemsg->msgbuf;
|
||||
body->session_id = session_id;
|
||||
|
||||
if (client_send_receive(closemsg, reqsize, &msgresp, &respsize) != 0)
|
||||
{
|
||||
printf("fail to send and receive message.end_session_ocall\n");
|
||||
return INVALID_SESSION;
|
||||
}
|
||||
|
||||
free(msgresp);
|
||||
|
||||
return (ATTESTATION_STATUS)0;
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "sgx_eid.h"
|
||||
#include "error_codes.h"
|
||||
#include "datatypes.h"
|
||||
#include "sgx_urts.h"
|
||||
#include "dh_session_protocol.h"
|
||||
#include "sgx_dh.h"
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
#ifndef ULOCALATTESTATION_H_
|
||||
#define ULOCALATTESTATION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Function Description: This is OCALL interface for initiator enclave to get ECDH message 1 and session id from responder enclave
|
||||
* Parameter Description:
|
||||
* [input, output] dh_msg1: pointer to ecdh msg1 buffer, this buffer is alloated in initiator enclave and filled by reponser enclave
|
||||
* [output] session_id: pointer to session id which is allocated by responder enclave
|
||||
* */
|
||||
uint32_t session_request_ocall(sgx_dh_msg1_t* dh_msg1, uint32_t* session_id);
|
||||
|
||||
/* Function Description: This is OCALL interface for initiator enclave to send ECDH message 2 to responder enclave, and receive ECDH message 3 from responder enclave
|
||||
* Parameter Description:
|
||||
* [input] dh_msg2: this is pointer to ECDH message 2 generated by initiator enclave
|
||||
* [input, output]dh_msg3: this is pointer to ECDH message 3, this buffer is allocated in initiator enclave and filled by respoonder enclave
|
||||
* [input] session_id: this is session id allocated by responder enclave
|
||||
* */
|
||||
uint32_t exchange_report_ocall(sgx_dh_msg2_t* dh_msg2, sgx_dh_msg3_t* dh_msg3, uint32_t session_id);
|
||||
|
||||
/* Function Description: This is OCALL interface for initiator enclave to send request message(encrypted) to responder enclave, and receive response message from responder enclave
|
||||
* Parameter Description:
|
||||
* [input] session_id: this is session id allocated by responder enclave
|
||||
* [input] req_message: this is pointer to request message
|
||||
* [input] req_message_size: this is request message size
|
||||
* [input] max_payload_size: this is maxium payload size in response message
|
||||
* [input, output] this is pointer to response message, the buffer is allocated by initiator enclave and filled by responder enclave
|
||||
* [input] response message size
|
||||
* */
|
||||
uint32_t send_request_ocall(uint32_t session_id, secure_message_t* req_message, size_t req_message_size, size_t max_payload_size, secure_message_t* resp_message, size_t resp_message_size);
|
||||
|
||||
/* Function Description: this is OCALL interface for initiator enclave to close secure session
|
||||
* Parameter Description:
|
||||
* [input] session_id: this is session id allocated by responder enclave
|
||||
* */
|
||||
uint32_t end_session_ocall(uint32_t session_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
116
demos/local_attestation/AppInitiator/app.cpp
Normal file
116
demos/local_attestation/AppInitiator/app.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <occlum_pal_api.h>
|
||||
#include "sgx_eid.h"
|
||||
#include "sgx_urts.h"
|
||||
|
||||
#include "EnclaveInitiator_u.h"
|
||||
|
||||
#define ENCLAVE_INITIATOR_NAME "./bin/libenclave_initiator.signed.so"
|
||||
|
||||
pthread_t thread;
|
||||
sgx_enclave_id_t initiator_enclave_id = 0;
|
||||
void* attestation(void *arg);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int update = 0;
|
||||
sgx_launch_token_t token = {0};
|
||||
sgx_status_t status;
|
||||
int exit_status = 0;
|
||||
const char* occlum_instance_dir = ".occlum";
|
||||
const char* cmd_path = "/bin/responder"; // Prepare cmd path and arguments
|
||||
const char* cmd_args[] = {NULL};
|
||||
|
||||
// create ECDH initiator enclave
|
||||
status = sgx_create_enclave(ENCLAVE_INITIATOR_NAME, SGX_DEBUG_FLAG, &token, &update, &initiator_enclave_id, NULL);
|
||||
if (status != SGX_SUCCESS)
|
||||
{
|
||||
printf("failed to load enclave %s, error code is 0x%x.\n", ENCLAVE_INITIATOR_NAME, status);
|
||||
return -1;
|
||||
}
|
||||
printf("succeed to load enclave %s\n", ENCLAVE_INITIATOR_NAME);
|
||||
|
||||
if (occlum_pal_init(occlum_instance_dir) < 0)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (pthread_create(&thread, NULL, attestation, NULL) < 0)
|
||||
{
|
||||
printf("pthread_create failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use Occlum PAL to execute the cmd
|
||||
if (occlum_pal_exec(cmd_path, cmd_args, &exit_status) < 0)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// wait for end and destroy
|
||||
if (pthread_join(thread, NULL) < 0)
|
||||
{
|
||||
printf("pthread_join failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = sgx_destroy_enclave(initiator_enclave_id);
|
||||
if (status != SGX_SUCCESS)
|
||||
{
|
||||
printf("failed to destroy enclave %s, error code is 0x%x.\n", ENCLAVE_INITIATOR_NAME, status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (occlum_pal_destroy() < 0)
|
||||
{
|
||||
printf("occlum_pal_destroy failed, errno is %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Local attestation Sucess!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create ECDH session using initiator enclave
|
||||
// it would create ECDH session with responder enclave running in another process
|
||||
void* attestation(void *arg)
|
||||
{
|
||||
sgx_status_t status;
|
||||
uint32_t ret_status;
|
||||
|
||||
sleep(3);
|
||||
status = test_create_session(initiator_enclave_id, &ret_status);
|
||||
if (status != SGX_SUCCESS || ret_status != 0)
|
||||
{
|
||||
printf("failed to establish secure channel: ECALL return 0x%x, error code is 0x%x.\n", status, ret_status);
|
||||
return NULL;
|
||||
}
|
||||
printf("succeed to establish secure channel.\n");
|
||||
|
||||
status = test_message_exchange(initiator_enclave_id, &ret_status);
|
||||
if (status != SGX_SUCCESS || ret_status != 0)
|
||||
{
|
||||
printf("test_message_exchange Ecall failed: ECALL return 0x%x, error code is 0x%x.\n", status, ret_status);
|
||||
sgx_destroy_enclave(initiator_enclave_id);
|
||||
return NULL;
|
||||
}
|
||||
printf("Succeed to exchange secure message.\n");
|
||||
|
||||
// close ECDH session
|
||||
status = test_close_session(initiator_enclave_id, &ret_status);
|
||||
if (status != SGX_SUCCESS || ret_status != 0)
|
||||
{
|
||||
printf("test_close_session Ecall failed: ECALL return 0x%x, error code is 0x%x.\n", status, ret_status);
|
||||
return NULL;
|
||||
}
|
||||
printf("Succeed to close session.\n");
|
||||
pthread_exit(NULL);
|
||||
}
|
121
demos/local_attestation/AppInitiator/fifo.cpp
Normal file
121
demos/local_attestation/AppInitiator/fifo.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "fifo_def.h"
|
||||
|
||||
#define SERVER_ADDR "127.0.0.1"
|
||||
#define SERVER_PORT 8888
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
/* Function Description: this is for client to send request message and receive response message
|
||||
* Parameter Description:
|
||||
* [input] fiforequest: this is pointer to request message
|
||||
* [input] fiforequest_size: this is request message size
|
||||
* [output] fiforesponse: this is pointer fo response message, the buffer is allocated inside this function
|
||||
* [output] fiforesponse_size: this is response message size
|
||||
* */
|
||||
int client_send_receive(FIFO_MSG *fiforequest, size_t fiforequest_size, FIFO_MSG **fiforesponse, size_t *fiforesponse_size) {
|
||||
int ret = 0;
|
||||
long byte_num;
|
||||
char recv_msg[BUFFER_SIZE + 1] = {0};
|
||||
FIFO_MSG * response = NULL;
|
||||
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr)) ;
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
|
||||
serv_addr.sin_port = htons(SERVER_PORT);
|
||||
|
||||
int server_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_sock_fd == -1) {
|
||||
printf("socket error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (connect(server_sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
|
||||
printf("connection error, %s, line %d.\n", strerror(errno), __LINE__);
|
||||
ret = -1;
|
||||
goto CLEAN;
|
||||
} else printf("client connected\n");
|
||||
|
||||
|
||||
if ((byte_num = send(server_sock_fd, reinterpret_cast<char *>(fiforequest), static_cast<int>(fiforequest_size), 0)) == -1) {
|
||||
printf("connection error, %s, line %d..\n", strerror(errno), __LINE__);
|
||||
ret = -1;
|
||||
goto CLEAN;
|
||||
} else printf("client send\n");
|
||||
|
||||
byte_num = recv(server_sock_fd, reinterpret_cast<char *>(recv_msg), BUFFER_SIZE, 0);
|
||||
if (byte_num > 0) {
|
||||
if (byte_num > BUFFER_SIZE) {
|
||||
byte_num = BUFFER_SIZE;
|
||||
}
|
||||
|
||||
recv_msg[byte_num] = '\0';
|
||||
|
||||
response = (FIFO_MSG *)malloc((size_t)byte_num);
|
||||
if (!response) {
|
||||
printf("memory allocation failure.\n");
|
||||
return -1;
|
||||
}
|
||||
memset(response, 0, (size_t)byte_num);
|
||||
|
||||
memcpy(response, recv_msg, (size_t)byte_num);
|
||||
|
||||
*fiforesponse = response;
|
||||
*fiforesponse_size = (size_t)byte_num;
|
||||
printf("client received\n");
|
||||
ret = 0;
|
||||
} else if(byte_num < 0) {
|
||||
printf("server error, error message is %s!\n", strerror(errno));
|
||||
ret = -1;
|
||||
} else {
|
||||
printf("server exit!\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
CLEAN:
|
||||
close(server_sock_fd);
|
||||
|
||||
return ret;
|
||||
}
|
23
demos/local_attestation/AppResponder/Makefile
Normal file
23
demos/local_attestation/AppResponder/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
PROJECT_DIR := $(realpath $(CUR_DIR)/../../../)
|
||||
OPENSSL ?= $(CUR_DIR)/../deps/openssl
|
||||
SGX_SDK ?= /opt/intel/sgxsdk
|
||||
OBJS := session.o proc_msg.o
|
||||
CC := occlum-gcc
|
||||
CFLAGS := -fPIC
|
||||
SOFLAGS := -shared $(CFLAGS)
|
||||
OPENSSL := -L$(OPENSSL) -lcrypto
|
||||
ECDH := -L$(CUR_DIR)/../DiffieHellmanLibrary -lecdh
|
||||
INCLUDE_PATH := -I$(SGX_SDK)/include -I../Include
|
||||
|
||||
responder : $(OBJS)
|
||||
$(CC) responder.c $(OBJS) $(OPENSSL) $(ECDH) $(INCLUDE_PATH) -o responder
|
||||
|
||||
session.o : session.c
|
||||
$(CC) -c session.c $(CFLAGS) $(INCLUDE_PATH) -o session.o
|
||||
|
||||
proc_msg.o : proc_msg.c
|
||||
$(CC) -c proc_msg.c $(CFLAGS) $(INCLUDE_PATH) -o proc_msg.o
|
||||
|
||||
clean:
|
||||
rm -rf *.o responder
|
517
demos/local_attestation/AppResponder/proc_msg.c
Normal file
517
demos/local_attestation/AppResponder/proc_msg.c
Normal file
@ -0,0 +1,517 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sched.h>
|
||||
#include "sgx_tseal.h"
|
||||
#include "session.h"
|
||||
#include "proc_msg.h"
|
||||
|
||||
#define SAFE_FREE(ptr) {if (NULL != (ptr)) {free(ptr); (ptr) = NULL;}}
|
||||
#define MESSAGE_EXCHANGE 0x0
|
||||
|
||||
int proc(FIFO_MSG * message);
|
||||
extern int m_shutdown;
|
||||
|
||||
typedef struct _secure_message_t
|
||||
{
|
||||
uint32_t session_id; //Session ID identifyting the session to which the message belongs
|
||||
sgx_aes_gcm_data_t message_aes_gcm_data;
|
||||
} secure_message_t;
|
||||
|
||||
typedef struct _ms_in_msg_exchange_t
|
||||
{
|
||||
uint32_t msg_type; //Type of Call E2E or general message exchange
|
||||
uint32_t target_fn_id; //Function Id to be called in Destination. Is valid only when msg_type=ENCLAVE_TO_ENCLAVE_CALL
|
||||
uint32_t inparam_buff_len; //Length of the serialized input parameters
|
||||
char inparam_buff[1]; //Serialized input parameters
|
||||
} ms_in_msg_exchange_t;
|
||||
|
||||
//Format of the return value and output function parameter structure
|
||||
typedef struct _ms_out_msg_exchange_t
|
||||
{
|
||||
uint32_t retval_len; //Length of the return value
|
||||
uint32_t ret_outparam_buff_len; //Length of the serialized return value and output parameters
|
||||
char ret_outparam_buff[1]; //Serialized return value and output parameters
|
||||
} ms_out_msg_exchange_t;
|
||||
|
||||
/* Function Description:
|
||||
* This function responds to initiator enclave's connection request by generating and sending back ECDH message 1
|
||||
* Parameter Description:
|
||||
* [input] clientfd: this is client's connection id. After generating ECDH message 1, server would send back response through this connection id.
|
||||
* */
|
||||
int generate_and_send_session_msg1_resp(int clientfd)
|
||||
{
|
||||
int retcode = 0;
|
||||
uint32_t status = 0;
|
||||
sgx_status_t ret = SGX_SUCCESS;
|
||||
SESSION_MSG1_RESP msg1resp;
|
||||
FIFO_MSG * fifo_resp = NULL;
|
||||
size_t respmsgsize;
|
||||
|
||||
memset(&msg1resp, 0, sizeof(SESSION_MSG1_RESP));
|
||||
|
||||
// call responder enclave to generate ECDH message 1
|
||||
ret = session_request(&msg1resp.dh_msg1, &msg1resp.sessionid);
|
||||
if (ret != SGX_SUCCESS)
|
||||
{
|
||||
printf("failed to do ECALL session_request.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
respmsgsize = sizeof(FIFO_MSG) + sizeof(SESSION_MSG1_RESP);
|
||||
fifo_resp = (FIFO_MSG *)malloc(respmsgsize);
|
||||
if (!fifo_resp)
|
||||
{
|
||||
printf("memory allocation failure.\n");
|
||||
return -1;
|
||||
}
|
||||
memset(fifo_resp, 0, respmsgsize);
|
||||
|
||||
fifo_resp->header.type = FIFO_DH_RESP_MSG1;
|
||||
fifo_resp->header.size = sizeof(SESSION_MSG1_RESP);
|
||||
|
||||
memcpy(fifo_resp->msgbuf, &msg1resp, sizeof(SESSION_MSG1_RESP));
|
||||
|
||||
//send message 1 to client
|
||||
if (send(clientfd, (char *)(fifo_resp), (int)(respmsgsize), 0) == -1)
|
||||
{
|
||||
printf("fail to send msg1 response.\n");
|
||||
retcode = -1;
|
||||
}
|
||||
free(fifo_resp);
|
||||
return retcode;
|
||||
}
|
||||
/* Function Description:
|
||||
* This function process ECDH message 2 received from client and send message 3 to client
|
||||
* Parameter Description:
|
||||
* [input] clientfd: this is client's connection id
|
||||
* [input] msg2: this contains ECDH message 2 received from client
|
||||
* */
|
||||
int process_exchange_report(int clientfd, SESSION_MSG2 * msg2)
|
||||
{
|
||||
uint32_t status = 0;
|
||||
sgx_status_t ret = SGX_SUCCESS;
|
||||
FIFO_MSG *response;
|
||||
SESSION_MSG3 * msg3;
|
||||
size_t msgsize;
|
||||
|
||||
if (!msg2)
|
||||
return -1;
|
||||
|
||||
msgsize = sizeof(FIFO_MSG_HEADER) + sizeof(SESSION_MSG3);
|
||||
response = (FIFO_MSG *)malloc(msgsize);
|
||||
if (!response)
|
||||
{
|
||||
printf("memory allocation failure\n");
|
||||
return -1;
|
||||
}
|
||||
memset(response, 0, msgsize);
|
||||
|
||||
response->header.type = FIFO_DH_MSG3;
|
||||
response->header.size = sizeof(SESSION_MSG3);
|
||||
|
||||
msg3 = (SESSION_MSG3 *)response->msgbuf;
|
||||
msg3->sessionid = msg2->sessionid;
|
||||
|
||||
// call responder enclave to process ECDH message 2 and generate message 3
|
||||
ret = exchange_report(&msg2->dh_msg2, &msg3->dh_msg3, msg2->sessionid);
|
||||
if (ret != SGX_SUCCESS)
|
||||
{
|
||||
printf("Enclave Response_exchange_report failure.\n");
|
||||
free(response);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// send ECDH message 3 to client
|
||||
if (send(clientfd, (char *)(response), (int)(msgsize), 0) == -1)
|
||||
{
|
||||
printf("server_send() failure.\n");
|
||||
free(response);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(response);
|
||||
|
||||
return 0;
|
||||
}
|
||||
uint32_t get_message_exchange_response(uint32_t inp_secret_data)
|
||||
{
|
||||
uint32_t secret_response;
|
||||
printf("secret=0x%x\n",inp_secret_data);
|
||||
//User should use more complex encryption method to protect their secret, below is just a simple example
|
||||
secret_response = inp_secret_data & 0x11111111;
|
||||
|
||||
return secret_response;
|
||||
|
||||
}
|
||||
int umarshal_message_exchange_request(uint32_t* inp_secret_data, ms_in_msg_exchange_t* ms)
|
||||
{
|
||||
char* buff;
|
||||
size_t len;
|
||||
if(!inp_secret_data || !ms)
|
||||
return -1;
|
||||
buff = ms->inparam_buff;
|
||||
len = ms->inparam_buff_len;
|
||||
if(len != sizeof(uint32_t))
|
||||
return -1;
|
||||
|
||||
memcpy(inp_secret_data, buff, sizeof(uint32_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
int marshal_message_exchange_response(char** resp_buffer, size_t* resp_length, uint32_t secret_response)
|
||||
{
|
||||
ms_out_msg_exchange_t *ms;
|
||||
size_t secret_response_len, ms_len;
|
||||
size_t retval_len, ret_param_len;
|
||||
if(!resp_length)
|
||||
return -1;
|
||||
secret_response_len = sizeof(secret_response);
|
||||
retval_len = secret_response_len;
|
||||
ret_param_len = secret_response_len;
|
||||
ms_len = sizeof(ms_out_msg_exchange_t) + ret_param_len;
|
||||
ms = (ms_out_msg_exchange_t *)malloc(ms_len);
|
||||
if(!ms)
|
||||
return -1;
|
||||
|
||||
ms->retval_len = (uint32_t)retval_len;
|
||||
ms->ret_outparam_buff_len = (uint32_t)ret_param_len;
|
||||
memcpy(&ms->ret_outparam_buff, &secret_response, secret_response_len);
|
||||
*resp_buffer = (char*)ms;
|
||||
*resp_length = ms_len;
|
||||
return 0;
|
||||
}
|
||||
int message_exchange_response_generator(char* decrypted_data,
|
||||
char** resp_buffer,
|
||||
size_t* resp_length)
|
||||
{
|
||||
ms_in_msg_exchange_t *ms;
|
||||
uint32_t inp_secret_data;
|
||||
uint32_t out_secret_data;
|
||||
|
||||
if(!decrypted_data || !resp_length)
|
||||
return -1;
|
||||
|
||||
ms = (ms_in_msg_exchange_t *)decrypted_data;
|
||||
|
||||
if(umarshal_message_exchange_request(&inp_secret_data,ms) <0)
|
||||
return -1;
|
||||
|
||||
out_secret_data = get_message_exchange_response(inp_secret_data);
|
||||
|
||||
if(marshal_message_exchange_response(resp_buffer, resp_length, out_secret_data) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int generate_response(secure_message_t* req_message,
|
||||
size_t req_message_size,
|
||||
size_t max_payload_size,
|
||||
secure_message_t* resp_message,
|
||||
size_t resp_message_size,
|
||||
uint32_t session_id)
|
||||
{
|
||||
#define TAG_SIZE 16
|
||||
const uint8_t* plaintext;
|
||||
uint32_t plaintext_length;
|
||||
uint8_t *decrypted_data;
|
||||
uint32_t decrypted_data_length;
|
||||
uint32_t plain_text_offset;
|
||||
ms_in_msg_exchange_t * ms;
|
||||
size_t resp_data_length;
|
||||
size_t resp_message_calc_size;
|
||||
char* resp_data;
|
||||
uint8_t l_tag[TAG_SIZE];
|
||||
size_t header_size, expected_payload_size;
|
||||
dh_session_t *session_info;
|
||||
secure_message_t* temp_resp_message;
|
||||
uint32_t ret;
|
||||
sgx_status_t status;
|
||||
|
||||
plaintext = (const uint8_t*)(" ");
|
||||
plaintext_length = 0;
|
||||
|
||||
if(!req_message || !resp_message)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Get the session information from the map corresponding to the source enclave id
|
||||
session_info= get_session_info(session_id);
|
||||
if (session_info == NULL) return -1;
|
||||
//Set the decrypted data length to the payload size obtained from the message
|
||||
decrypted_data_length = req_message->message_aes_gcm_data.payload_size;
|
||||
|
||||
header_size = sizeof(secure_message_t);
|
||||
expected_payload_size = req_message_size - header_size;
|
||||
|
||||
//Verify the size of the payload
|
||||
if(expected_payload_size != decrypted_data_length)
|
||||
return -1;
|
||||
|
||||
memset(&l_tag, 0, 16);
|
||||
plain_text_offset = decrypted_data_length;
|
||||
decrypted_data = (uint8_t*)malloc(decrypted_data_length);
|
||||
if(!decrypted_data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(decrypted_data, 0, decrypted_data_length);
|
||||
status = sgx_rijndael128GCM_decrypt(&session_info->active.AEK, req_message->message_aes_gcm_data.payload,
|
||||
decrypted_data_length, decrypted_data,
|
||||
(uint8_t *)(&(req_message->message_aes_gcm_data.reserved)),
|
||||
sizeof(req_message->message_aes_gcm_data.reserved), &(req_message->message_aes_gcm_data.payload[plain_text_offset]), plaintext_length,
|
||||
&req_message->message_aes_gcm_data.payload_tag);
|
||||
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
SAFE_FREE(decrypted_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Casting the decrypted data to the marshaling structure type to obtain type of request (generic message exchange/enclave to enclave call)
|
||||
ms = (ms_in_msg_exchange_t *)decrypted_data;
|
||||
|
||||
// Verify if the nonce obtained in the request is equal to the session nonce
|
||||
if((uint32_t)*(req_message->message_aes_gcm_data.reserved) != session_info->active.counter || *(req_message->message_aes_gcm_data.reserved) > ((2^32)-2))
|
||||
{
|
||||
SAFE_FREE(decrypted_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ms->msg_type == MESSAGE_EXCHANGE)
|
||||
{
|
||||
//Call the generic secret response generator for message exchange
|
||||
ret = message_exchange_response_generator((char*)decrypted_data, &resp_data, &resp_data_length);
|
||||
if(ret !=0)
|
||||
{
|
||||
SAFE_FREE(decrypted_data);
|
||||
SAFE_FREE(resp_data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SAFE_FREE(decrypted_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(resp_data_length > max_payload_size)
|
||||
{
|
||||
SAFE_FREE(resp_data);
|
||||
SAFE_FREE(decrypted_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
resp_message_calc_size = sizeof(secure_message_t)+ resp_data_length;
|
||||
|
||||
if(resp_message_calc_size > resp_message_size)
|
||||
{
|
||||
SAFE_FREE(resp_data);
|
||||
SAFE_FREE(decrypted_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Code to build the response back to the Source Enclave
|
||||
temp_resp_message = (secure_message_t*)malloc(resp_message_calc_size);
|
||||
if(!temp_resp_message)
|
||||
{
|
||||
SAFE_FREE(resp_data);
|
||||
SAFE_FREE(decrypted_data);
|
||||
return -1;
|
||||
}
|
||||
memset(temp_resp_message,0,sizeof(secure_message_t)+ resp_data_length);
|
||||
const uint32_t data2encrypt_length = (uint32_t)resp_data_length;
|
||||
temp_resp_message->session_id = session_info->session_id;
|
||||
temp_resp_message->message_aes_gcm_data.payload_size = data2encrypt_length;
|
||||
|
||||
//Increment the Session Nonce (Replay Protection)
|
||||
session_info->active.counter = session_info->active.counter + 1;
|
||||
|
||||
//Set the response nonce as the session nonce
|
||||
memcpy(&temp_resp_message->message_aes_gcm_data.reserved,&session_info->active.counter,sizeof(session_info->active.counter));
|
||||
|
||||
//Prepare the response message with the encrypted payload
|
||||
status = sgx_rijndael128GCM_encrypt(&session_info->active.AEK, (uint8_t*)resp_data, data2encrypt_length,
|
||||
(uint8_t *)(&(temp_resp_message->message_aes_gcm_data.payload)),
|
||||
(uint8_t *)(&(temp_resp_message->message_aes_gcm_data.reserved)),
|
||||
sizeof(temp_resp_message->message_aes_gcm_data.reserved), plaintext, plaintext_length,
|
||||
&(temp_resp_message->message_aes_gcm_data.payload_tag));
|
||||
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
SAFE_FREE(resp_data);
|
||||
SAFE_FREE(decrypted_data);
|
||||
SAFE_FREE(temp_resp_message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(resp_message, 0, sizeof(secure_message_t)+ resp_data_length);
|
||||
memcpy(resp_message, temp_resp_message, sizeof(secure_message_t)+ resp_data_length);
|
||||
|
||||
SAFE_FREE(decrypted_data);
|
||||
SAFE_FREE(resp_data);
|
||||
SAFE_FREE(temp_resp_message);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_msg_transfer(int clientfd, FIFO_MSGBODY_REQ *req_msg)
|
||||
{
|
||||
uint32_t status = 0;
|
||||
sgx_status_t ret = SGX_SUCCESS;
|
||||
secure_message_t *resp_message = NULL;
|
||||
FIFO_MSG * fifo_resp = NULL;
|
||||
size_t resp_message_size;
|
||||
|
||||
if (!req_msg)
|
||||
{
|
||||
printf("invalid parameter.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
resp_message_size = sizeof(secure_message_t) + req_msg->max_payload_size;
|
||||
//Allocate memory for the response message
|
||||
resp_message = (secure_message_t*)malloc(resp_message_size);
|
||||
if (!resp_message)
|
||||
{
|
||||
printf("memory allocation failure.\n");
|
||||
return -1;
|
||||
}
|
||||
memset(resp_message, 0, resp_message_size);
|
||||
|
||||
ret = generate_response( (secure_message_t *)req_msg->buf, req_msg->size, req_msg->max_payload_size, resp_message, resp_message_size, req_msg->session_id);
|
||||
if (ret <0)
|
||||
{
|
||||
printf("EnclaveResponder_generate_response error.\n");
|
||||
free(resp_message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fifo_resp = (FIFO_MSG *)malloc(sizeof(FIFO_MSG) + resp_message_size);
|
||||
if (!fifo_resp)
|
||||
{
|
||||
printf("memory allocation failure.\n");
|
||||
free(resp_message);
|
||||
return -1;
|
||||
}
|
||||
memset(fifo_resp, 0, sizeof(FIFO_MSG) + resp_message_size);
|
||||
|
||||
fifo_resp->header.type = FIFO_DH_MSG_RESP;
|
||||
fifo_resp->header.size = resp_message_size;
|
||||
memcpy(fifo_resp->msgbuf, resp_message, resp_message_size);
|
||||
|
||||
free(resp_message);
|
||||
|
||||
if (send(clientfd, (char *)(fifo_resp), sizeof(FIFO_MSG) + (int)(resp_message_size), 0) == -1)
|
||||
{
|
||||
printf("server_send() failure.\n");
|
||||
free(fifo_resp);
|
||||
return -1;
|
||||
}
|
||||
free(fifo_resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int process_close_req(int clientfd, SESSION_CLOSE_REQ * close_req)
|
||||
{
|
||||
uint32_t status = 0;
|
||||
sgx_status_t ret = SGX_SUCCESS;
|
||||
FIFO_MSG close_ack;
|
||||
|
||||
if (!close_req)
|
||||
return -1;
|
||||
|
||||
// call responder enclave to close this session
|
||||
ret = end_session( close_req->session_id);
|
||||
if (ret != SGX_SUCCESS)
|
||||
return -1;
|
||||
|
||||
// send back response
|
||||
close_ack.header.type = FIFO_DH_CLOSE_RESP;
|
||||
close_ack.header.size = 0;
|
||||
|
||||
if (send(clientfd, (char *)(&close_ack), sizeof(FIFO_MSG), 0) == -1)
|
||||
{
|
||||
printf("server_send() failure.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int proc (FIFO_MSG * message)
|
||||
{
|
||||
if (message == NULL) return 0;
|
||||
switch (message->header.type)
|
||||
{
|
||||
case FIFO_DH_REQ_MSG1:
|
||||
{
|
||||
// process ECDH session connection request
|
||||
int clientfd = message->header.sockfd;
|
||||
|
||||
if (generate_and_send_session_msg1_resp(clientfd) != 0)
|
||||
{
|
||||
printf("failed to generate and send session msg1 resp.\n");
|
||||
break;
|
||||
}
|
||||
else printf("generate and send session msg1 resp.\n");
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case FIFO_DH_MSG2:
|
||||
{
|
||||
// process ECDH message 2
|
||||
int clientfd = message->header.sockfd;
|
||||
SESSION_MSG2 * msg2 = NULL;
|
||||
msg2 = (SESSION_MSG2 *)message->msgbuf;
|
||||
|
||||
if (process_exchange_report(clientfd, msg2) != 0)
|
||||
{
|
||||
printf("failed to process exchange_report request.\n");
|
||||
break;
|
||||
}
|
||||
else printf(" process exchange_report request.\n");
|
||||
}
|
||||
break;
|
||||
case FIFO_DH_MSG_REQ:
|
||||
{
|
||||
// process message transfer request
|
||||
int clientfd = message->header.sockfd;
|
||||
FIFO_MSGBODY_REQ *msg = NULL;
|
||||
|
||||
msg = (FIFO_MSGBODY_REQ *)message->msgbuf;
|
||||
|
||||
if (process_msg_transfer(clientfd, msg) != 0)
|
||||
{
|
||||
printf("failed to process message transfer request.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FIFO_DH_CLOSE_REQ:
|
||||
{
|
||||
// process message close request
|
||||
int clientfd = message->header.sockfd;
|
||||
|
||||
SESSION_CLOSE_REQ * closereq = NULL;
|
||||
closereq = (SESSION_CLOSE_REQ *)message->msgbuf;
|
||||
process_close_req(clientfd, closereq);
|
||||
printf("process close_requestt request.\n");
|
||||
m_shutdown = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
printf("Unknown message.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(message);
|
||||
}
|
5
demos/local_attestation/AppResponder/proc_msg.h
Normal file
5
demos/local_attestation/AppResponder/proc_msg.h
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef _PROC_MSG_H_
|
||||
#define _PROC_MSG_H_
|
||||
#include "fifo_def.h"
|
||||
int proc(FIFO_MSG * message);
|
||||
#endif
|
195
demos/local_attestation/AppResponder/responder.c
Normal file
195
demos/local_attestation/AppResponder/responder.c
Normal file
@ -0,0 +1,195 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include "fifo_def.h"
|
||||
#include "proc_msg.h"
|
||||
|
||||
#define BACKLOG 5
|
||||
#define CONCURRENT_MAX 32
|
||||
#define SERVER_PORT 8888
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
int m_server_sock_fd;
|
||||
int m_shutdown;
|
||||
|
||||
int server_init()
|
||||
{
|
||||
struct sockaddr_in srv_addr;
|
||||
|
||||
memset(&srv_addr, 0, sizeof(srv_addr));
|
||||
srv_addr.sin_family = AF_INET;
|
||||
srv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
srv_addr.sin_port = htons(SERVER_PORT);
|
||||
|
||||
m_server_sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);;
|
||||
if (m_server_sock_fd == -1)
|
||||
{
|
||||
printf("socket initiazation error: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bind_result = bind(m_server_sock_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));
|
||||
if (bind_result == -1)
|
||||
{
|
||||
printf("bind error: %d\n", errno);
|
||||
close(m_server_sock_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(m_server_sock_fd, BACKLOG) == -1)
|
||||
{
|
||||
printf("listen error: %d\n", errno);
|
||||
close(m_server_sock_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_shutdown = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int work()
|
||||
{
|
||||
int client_fds[CONCURRENT_MAX] = {0};
|
||||
fd_set server_fd_set;
|
||||
int max_fd = -1;
|
||||
struct timeval tv;
|
||||
char input_msg[BUFFER_SIZE];
|
||||
char recv_msg[BUFFER_SIZE];
|
||||
int ret;
|
||||
|
||||
while (!m_shutdown)
|
||||
{
|
||||
// set 10s timeout for select()
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&server_fd_set);
|
||||
// listening on server socket
|
||||
FD_SET(m_server_sock_fd, &server_fd_set);
|
||||
if (max_fd < m_server_sock_fd)
|
||||
max_fd = m_server_sock_fd;
|
||||
|
||||
// listening on all client connections
|
||||
for(int i =0; i < CONCURRENT_MAX; i++)
|
||||
{
|
||||
if(client_fds[i] != 0)
|
||||
{
|
||||
FD_SET(client_fds[i], &server_fd_set);
|
||||
if(max_fd < client_fds[i])
|
||||
max_fd = client_fds[i];
|
||||
}
|
||||
}
|
||||
|
||||
ret = select(max_fd + 1, &server_fd_set, NULL, NULL, &tv);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Warning: server would shutdown\n");
|
||||
continue;
|
||||
}
|
||||
else if(ret == 0)
|
||||
{
|
||||
// timeout
|
||||
continue;
|
||||
}
|
||||
|
||||
if(FD_ISSET(m_server_sock_fd, &server_fd_set))
|
||||
{
|
||||
// if there is new connection request
|
||||
struct sockaddr_in clt_addr;
|
||||
socklen_t len = sizeof(clt_addr);
|
||||
|
||||
// accept this connection request
|
||||
int client_sock_fd = accept(m_server_sock_fd, (struct sockaddr *)&clt_addr, &len);
|
||||
|
||||
if (client_sock_fd > 0)
|
||||
{
|
||||
// add new connection to connection pool if it's not full
|
||||
int index = -1;
|
||||
for(int i = 0; i < CONCURRENT_MAX; i++)
|
||||
{
|
||||
if(client_fds[i] == 0)
|
||||
{
|
||||
index = i;
|
||||
client_fds[i] = client_sock_fd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(index < 0)
|
||||
{
|
||||
printf("server reach maximum connection!\n");
|
||||
bzero(input_msg, BUFFER_SIZE);
|
||||
strcpy(input_msg, "server reach maximum connection\n");
|
||||
send(client_sock_fd, input_msg, BUFFER_SIZE, 0);
|
||||
}
|
||||
}
|
||||
else if (client_sock_fd < 0)
|
||||
{
|
||||
printf("server: accept() return failure, %s, would exit.\n", strerror(errno));
|
||||
close(m_server_sock_fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i =0; i < CONCURRENT_MAX; i++)
|
||||
{
|
||||
if ((client_fds[i] !=0)
|
||||
&& (FD_ISSET(client_fds[i], &server_fd_set)))
|
||||
{
|
||||
// there is request messages from client connectsions
|
||||
FIFO_MSG * msg;
|
||||
bzero(recv_msg, BUFFER_SIZE);
|
||||
long byte_num = recv(client_fds[i], recv_msg, BUFFER_SIZE, 0);
|
||||
if (byte_num > 0)
|
||||
{
|
||||
if(byte_num > BUFFER_SIZE)
|
||||
byte_num = BUFFER_SIZE;
|
||||
|
||||
recv_msg[byte_num] = '\0';
|
||||
msg = (FIFO_MSG *)malloc(byte_num);
|
||||
if (!msg)
|
||||
{
|
||||
printf("memory allocation failure\n");
|
||||
continue;
|
||||
}
|
||||
memset(msg, 0, byte_num);
|
||||
memcpy(msg, recv_msg, byte_num);
|
||||
msg->header.sockfd = client_fds[i];
|
||||
proc(msg);
|
||||
}
|
||||
else if(byte_num < 0)
|
||||
{
|
||||
printf("failed to receive message.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// client connect is closed
|
||||
FD_CLR(client_fds[i], &server_fd_set);
|
||||
close(client_fds[i]);
|
||||
client_fds[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = server_init();
|
||||
if (rc != 0)
|
||||
{
|
||||
printf("server init failure\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return work();
|
||||
}
|
195
demos/local_attestation/AppResponder/session.c
Normal file
195
demos/local_attestation/AppResponder/session.c
Normal file
@ -0,0 +1,195 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "session.h"
|
||||
|
||||
#define MAX_SESSION_COUNT 16
|
||||
typedef struct _session_id_tracker_t
|
||||
{
|
||||
uint32_t session_id;
|
||||
} session_id_tracker_t;
|
||||
|
||||
int generate_session_id(uint32_t *session_id);
|
||||
int is_session_id_valid(uint32_t session_id);
|
||||
|
||||
session_id_tracker_t *g_session_id_tracker[MAX_SESSION_COUNT];
|
||||
dh_session_t g_dest_session_info_map[MAX_SESSION_COUNT];
|
||||
uint32_t g_session_count = 0;
|
||||
int verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity)
|
||||
{
|
||||
if(!peer_enclave_identity)
|
||||
return ERROR;
|
||||
|
||||
if(!(peer_enclave_identity->attributes.flags & SGX_FLAGS_INITTED))
|
||||
return ERROR;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
int session_request(sgx_dh_msg1_t *dh_msg1,
|
||||
uint32_t *session_id )
|
||||
{
|
||||
sgx_dh_session_t sgx_dh_session;
|
||||
sgx_status_t status = SGX_SUCCESS;
|
||||
|
||||
if(!session_id || !dh_msg1)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
//Intialize the session as a session responder
|
||||
status = sgx_dh_init_session(SGX_DH_SESSION_RESPONDER, &sgx_dh_session);
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
printf("sgx_dh_init_session failed\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
//get a new SessionID
|
||||
if (generate_session_id(session_id) < 0)
|
||||
return ERROR; //no more sessions available
|
||||
|
||||
//Allocate memory for the session id tracker
|
||||
g_session_id_tracker[*session_id] = (session_id_tracker_t *)malloc(sizeof(session_id_tracker_t));
|
||||
if(!g_session_id_tracker[*session_id])
|
||||
{
|
||||
printf("g_session_id_tracker failed\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
memset(g_session_id_tracker[*session_id], 0, sizeof(session_id_tracker_t));
|
||||
g_session_id_tracker[*session_id]->session_id = *session_id;
|
||||
|
||||
//Generate Message1 that will be returned to Source Enclave
|
||||
status = sgx_dh_responder_gen_msg1((sgx_dh_msg1_t*)dh_msg1, &sgx_dh_session);
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
free(g_session_id_tracker[*session_id]);
|
||||
printf("sgx_dh_responder_gen_msg1 failed\n");
|
||||
return ERROR;
|
||||
}
|
||||
memcpy(&g_dest_session_info_map[*session_id].in_progress.dh_session, &sgx_dh_session, sizeof(sgx_dh_session_t));
|
||||
//Store the session information under the correspoding source enlave id key
|
||||
g_dest_session_info_map[*session_id].status = IN_PROGRESS;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
int exchange_report(sgx_dh_msg2_t *dh_msg2,
|
||||
sgx_dh_msg3_t *dh_msg3,
|
||||
uint32_t session_id)
|
||||
{
|
||||
sgx_key_128bit_t dh_aek; // Session key
|
||||
dh_session_t *session_info;
|
||||
int status = SUCCESS;
|
||||
sgx_dh_session_t sgx_dh_session;
|
||||
sgx_dh_session_enclave_identity_t initiator_identity;
|
||||
|
||||
if(!dh_msg2 || !dh_msg3|| !is_session_id_valid(session_id))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
|
||||
do
|
||||
{
|
||||
//Retreive the session information for the corresponding source enclave id
|
||||
session_info = &g_dest_session_info_map[session_id];
|
||||
|
||||
memcpy(&sgx_dh_session, &session_info->in_progress.dh_session, sizeof(sgx_dh_session_t));
|
||||
|
||||
dh_msg3->msg3_body.additional_prop_length = 0;
|
||||
//Process message 2 from source enclave and obtain message 3
|
||||
sgx_status_t se_ret = sgx_dh_responder_proc_msg2(dh_msg2,
|
||||
dh_msg3,
|
||||
&sgx_dh_session,
|
||||
&dh_aek,
|
||||
&initiator_identity);
|
||||
if(SGX_SUCCESS != se_ret)
|
||||
{
|
||||
status = ERROR;
|
||||
printf("sgx_dh_responder_proc_msg2 failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
//Verify source enclave's trust
|
||||
if(verify_peer_enclave_trust(&initiator_identity) != SUCCESS)
|
||||
{
|
||||
status = ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
//save the session ID, status and initialize the session nonce
|
||||
session_info->session_id = session_id;
|
||||
session_info->status = ACTIVE;
|
||||
session_info->active.counter = 0;
|
||||
memcpy(session_info->active.AEK, &dh_aek, sizeof(sgx_key_128bit_t));
|
||||
memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
|
||||
g_session_count++;
|
||||
}
|
||||
while(0);
|
||||
|
||||
if(status != SUCCESS)
|
||||
{
|
||||
end_session(session_id);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int end_session(uint32_t session_id)
|
||||
{
|
||||
int status = SUCCESS;
|
||||
int i;
|
||||
dh_session_t *session_info;
|
||||
if (!is_session_id_valid(session_id)) return ERROR;
|
||||
//Get the session information from the map corresponding to the source enclave id
|
||||
session_info = &g_dest_session_info_map[session_id];
|
||||
|
||||
//Erase the session information for the current session
|
||||
//Update the session id tracker
|
||||
if (g_session_count > 0)
|
||||
{
|
||||
//check if session exists
|
||||
for (i=1; i <= MAX_SESSION_COUNT; i++)
|
||||
{
|
||||
if(g_session_id_tracker[i-1] != NULL && g_session_id_tracker[i-1]->session_id == session_id)
|
||||
{
|
||||
memset(g_session_id_tracker[i-1], 0, sizeof(session_id_tracker_t));
|
||||
free(g_session_id_tracker[i-1]);
|
||||
g_session_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int is_session_id_valid(uint32_t session_id)
|
||||
{
|
||||
if (session_id >= MAX_SESSION_COUNT|| session_id <0) return 0;
|
||||
return (g_session_id_tracker[session_id] != NULL);
|
||||
|
||||
}
|
||||
|
||||
dh_session_t* get_session_info(uint32_t session_id )
|
||||
{
|
||||
if (!is_session_id_valid(session_id))
|
||||
return NULL;
|
||||
return &(g_dest_session_info_map[session_id]);
|
||||
|
||||
}
|
||||
|
||||
int generate_session_id(uint32_t *session_id)
|
||||
{
|
||||
if(!session_id)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
//if the session structure is untintialized, set that as the next session ID
|
||||
for (int i = 0; i < MAX_SESSION_COUNT; i++)
|
||||
{
|
||||
if (g_session_id_tracker[i] == NULL)
|
||||
{
|
||||
*session_id = i;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
}
|
22
demos/local_attestation/AppResponder/session.h
Normal file
22
demos/local_attestation/AppResponder/session.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef _EC_DH_SESSION_H_
|
||||
#define _EC_DH_SESSION_H_
|
||||
|
||||
#define ERROR -1
|
||||
#define SUCCESS 0
|
||||
|
||||
#define CLOSED 0x0
|
||||
#define IN_PROGRESS 0x1
|
||||
#define ACTIVE 0x2
|
||||
|
||||
#include "sgx_dh.h"
|
||||
#include "dh_session_protocol.h"
|
||||
|
||||
int session_request(sgx_dh_msg1_t *dh_msg1,
|
||||
uint32_t *session_id );
|
||||
int exchange_report(sgx_dh_msg2_t *dh_msg2,
|
||||
sgx_dh_msg3_t *dh_msg3,
|
||||
uint32_t session_id);
|
||||
int end_session(uint32_t session_id);
|
||||
dh_session_t* get_session_info(uint32_t session_id );
|
||||
|
||||
#endif
|
@ -0,0 +1,386 @@
|
||||
From a99d284c16a46f02bff4ff56c8e7361ebc0ae7b2 Mon Sep 17 00:00:00 2001
|
||||
From: "Hui,Chunyang" <sanqian.hcy@antfin.com>
|
||||
Date: Tue, 3 Mar 2020 09:45:53 +0000
|
||||
Subject: [PATCH] Diffie-hellman library change for Occlum local attestation
|
||||
demo
|
||||
|
||||
---
|
||||
.../DiffieHellmanLibrary/crypto_aes_gcm.cpp | 7 +-
|
||||
.../DiffieHellmanLibrary/ec_dh.cpp | 221 +++++++++++++++++-
|
||||
.../include/sgx_dh_internal.h | 3 +-
|
||||
.../DiffieHellmanLibrary/sgx_cmac128.cpp | 1 -
|
||||
.../DiffieHellmanLibrary/sgx_ecc256.cpp | 11 +-
|
||||
.../DiffieHellmanLibrary/sgx_sha256_msg.cpp | 1 -
|
||||
6 files changed, 225 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/demos/local_attestation/DiffieHellmanLibrary/crypto_aes_gcm.cpp b/demos/local_attestation/DiffieHellmanLibrary/crypto_aes_gcm.cpp
|
||||
index 329338b..bb0c604 100644
|
||||
--- a/demos/local_attestation/DiffieHellmanLibrary/crypto_aes_gcm.cpp
|
||||
+++ b/demos/local_attestation/DiffieHellmanLibrary/crypto_aes_gcm.cpp
|
||||
@@ -31,8 +31,7 @@
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
-#include "ssl_crypto.h"
|
||||
-#include "sgx_memset_s.h"
|
||||
+#include "sgx_tcrypto.h"
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@@ -143,7 +142,7 @@ sgx_status_t sgx_rijndael128GCM_decrypt(const sgx_aes_gcm_128bit_key_t *p_key, c
|
||||
|
||||
// Autenthication Tag returned by Decrypt to be compared with Tag created during seal
|
||||
//
|
||||
- memset_s(&l_tag, SGX_AESGCM_MAC_SIZE, 0, SGX_AESGCM_MAC_SIZE);
|
||||
+ memset(&l_tag, 0, SGX_AESGCM_MAC_SIZE);
|
||||
memcpy(l_tag, p_in_mac, SGX_AESGCM_MAC_SIZE);
|
||||
|
||||
do {
|
||||
@@ -205,6 +204,6 @@ sgx_status_t sgx_rijndael128GCM_decrypt(const sgx_aes_gcm_128bit_key_t *p_key, c
|
||||
{
|
||||
EVP_CIPHER_CTX_free(pState);
|
||||
}
|
||||
- memset_s(&l_tag, SGX_AESGCM_MAC_SIZE, 0, SGX_AESGCM_MAC_SIZE);
|
||||
+ memset(&l_tag, 0, SGX_AESGCM_MAC_SIZE);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/demos/local_attestation/DiffieHellmanLibrary/ec_dh.cpp b/demos/local_attestation/DiffieHellmanLibrary/ec_dh.cpp
|
||||
index 40c1539..dd8ab9e 100644
|
||||
--- a/demos/local_attestation/DiffieHellmanLibrary/ec_dh.cpp
|
||||
+++ b/demos/local_attestation/DiffieHellmanLibrary/ec_dh.cpp
|
||||
@@ -29,21 +29,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-#include <sgx_secure_align.h>
|
||||
+#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#include <limits.h>
|
||||
-#include "stdlib.h"
|
||||
-#include "string.h"
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdio.h>
|
||||
+#include <unistd.h>
|
||||
+#include "sgx_secure_align.h"
|
||||
#include "sgx.h"
|
||||
#include "sgx_defs.h"
|
||||
-#include "sgx_utils.h"
|
||||
#include "sgx_ecp_types.h"
|
||||
#include "sgx_key.h"
|
||||
#include "sgx_report.h"
|
||||
#include "sgx_attributes.h"
|
||||
-#include "sgx_trts.h"
|
||||
#include "ecp_interface.h"
|
||||
#include "sgx_dh_internal.h"
|
||||
#include "sgx_lfence.h"
|
||||
+#include "sgx_dh.h"
|
||||
|
||||
#define NONCE_SIZE 16
|
||||
#define MSG_BUF_LEN (static_cast<uint32_t>(sizeof(sgx_ec256_public_t)*2))
|
||||
@@ -53,6 +57,213 @@
|
||||
#define SAFE_FREE(ptr) {if (NULL != (ptr)) {free(ptr); (ptr)=NULL;}}
|
||||
#endif
|
||||
|
||||
+typedef struct {
|
||||
+ const sgx_target_info_t* target_info; // input (optinal)
|
||||
+ const sgx_report_data_t* report_data; // input (optional)
|
||||
+ sgx_report_t* report; // output
|
||||
+} sgxioc_create_report_arg_t;
|
||||
+
|
||||
+#define SGXIOC_SELF_TARGET _IOR('s', 3, sgx_target_info_t)
|
||||
+#define SGXIOC_CREATE_REPORT _IOWR('s', 4, sgxioc_create_report_arg_t)
|
||||
+#define SGXIOC_VERIFY_REPORT _IOW('s', 5, sgx_report_t)
|
||||
+
|
||||
+sgx_status_t sgx_create_report(const sgx_target_info_t *target_info, const sgx_report_data_t *report_data, sgx_report_t *report)
|
||||
+{
|
||||
+ sgxioc_create_report_arg_t arg;
|
||||
+ arg.target_info = target_info;
|
||||
+ arg.report_data = report_data;
|
||||
+ arg.report=report;
|
||||
+ int sgx_fd;
|
||||
+
|
||||
+ if ((sgx_fd = open("/dev/sgx", O_RDONLY)) < 0) {
|
||||
+ printf("open sgx device error\n");
|
||||
+ return SGX_ERROR_UNEXPECTED;
|
||||
+ }
|
||||
+
|
||||
+ if (ioctl(sgx_fd, SGXIOC_CREATE_REPORT, &arg) < 0) {
|
||||
+ close(sgx_fd);
|
||||
+ printf("ioctl error\n");
|
||||
+ return SGX_ERROR_UNEXPECTED;
|
||||
+ }
|
||||
+ close(sgx_fd);
|
||||
+ return SGX_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+sgx_status_t sgx_verify_report(const sgx_report_t *report)
|
||||
+{
|
||||
+ int sgx_fd;
|
||||
+ if ((sgx_fd = open("/dev/sgx", O_RDONLY)) < 0) {
|
||||
+ return SGX_ERROR_UNEXPECTED;
|
||||
+ }
|
||||
+ if (ioctl(sgx_fd, SGXIOC_VERIFY_REPORT, report) < 0) {
|
||||
+ printf("failed to verify report");
|
||||
+ close(sgx_fd);
|
||||
+ return SGX_ERROR_UNEXPECTED;
|
||||
+ }
|
||||
+ close(sgx_fd);
|
||||
+ return SGX_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+const sgx_report_t *sgx_self_report(void)
|
||||
+{
|
||||
+ static sgx_report_t _report = {
|
||||
+ .body = {
|
||||
+ .cpu_svn = {0},
|
||||
+ .misc_select = 0,
|
||||
+ .reserved1 = {0},
|
||||
+ .isv_ext_prod_id = {0},
|
||||
+ .attributes = {0, 0},
|
||||
+ .mr_enclave = {0},
|
||||
+ .reserved2 = {0},
|
||||
+ .mr_signer = {0},
|
||||
+ .reserved3 = {0},
|
||||
+ .config_id = {0},
|
||||
+ .isv_prod_id = 0,
|
||||
+ .isv_svn = 0,
|
||||
+ .config_svn = 0,
|
||||
+ .reserved4 = {0},
|
||||
+ .isv_family_id = {0},
|
||||
+ .report_data = {0}
|
||||
+ },
|
||||
+ .key_id = {0},
|
||||
+ .mac = {0}
|
||||
+ };
|
||||
+ if (0 == _report.body.attributes.flags)
|
||||
+ sgx_create_report(nullptr, nullptr, &_report);
|
||||
+
|
||||
+ return &_report;
|
||||
+}
|
||||
+
|
||||
+#ifndef ERROR_BREAK
|
||||
+#define ERROR_BREAK(x) if(x != ippStsNoErr){break;}
|
||||
+#endif
|
||||
+#ifndef NULL_BREAK
|
||||
+#define NULL_BREAK(x) if(!x){break;}
|
||||
+#endif
|
||||
+#ifndef SAFE_FREE
|
||||
+#define SAFE_FREE(ptr) {if (NULL != (ptr)) {free(ptr); (ptr)=NULL;}}
|
||||
+#endif
|
||||
+
|
||||
+#define MAC_KEY_SIZE 16
|
||||
+
|
||||
+#define EC_DERIVATION_BUFFER_SIZE(label_length) ((label_length) +4)
|
||||
+
|
||||
+sgx_status_t derive_key(
|
||||
+ const sgx_ec256_dh_shared_t* shared_key,
|
||||
+ const char* label,
|
||||
+ uint32_t label_length,
|
||||
+ sgx_ec_key_128bit_t* derived_key)
|
||||
+{
|
||||
+ sgx_status_t se_ret = SGX_SUCCESS;
|
||||
+ uint8_t cmac_key[MAC_KEY_SIZE];
|
||||
+ sgx_ec_key_128bit_t key_derive_key;
|
||||
+ if (!shared_key || !derived_key || !label) {
|
||||
+ return SGX_ERROR_INVALID_PARAMETER;
|
||||
+ }
|
||||
+
|
||||
+ /*check integer overflow */
|
||||
+ if (label_length > EC_DERIVATION_BUFFER_SIZE(label_length)) {
|
||||
+ return SGX_ERROR_INVALID_PARAMETER;
|
||||
+ }
|
||||
+ memset(cmac_key, 0, MAC_KEY_SIZE);
|
||||
+ se_ret = sgx_rijndael128_cmac_msg((sgx_cmac_128bit_key_t *)cmac_key,
|
||||
+ (uint8_t*)shared_key,
|
||||
+ sizeof(sgx_ec256_dh_shared_t),
|
||||
+ (sgx_cmac_128bit_tag_t *)&key_derive_key);
|
||||
+ if (SGX_SUCCESS != se_ret) {
|
||||
+ memset(&key_derive_key, 0, sizeof(key_derive_key));
|
||||
+ INTERNAL_SGX_ERROR_CODE_CONVERTOR(se_ret);
|
||||
+ return se_ret;
|
||||
+ }
|
||||
+ /* derivation_buffer = counter(0x01) || label || 0x00 || output_key_len(0x0080) */
|
||||
+ uint32_t derivation_buffer_length = EC_DERIVATION_BUFFER_SIZE(label_length);
|
||||
+ uint8_t *p_derivation_buffer = (uint8_t *)malloc(derivation_buffer_length);
|
||||
+ if (p_derivation_buffer == NULL) {
|
||||
+ return SGX_ERROR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+ memset(p_derivation_buffer, 0, derivation_buffer_length);
|
||||
+
|
||||
+ /*counter = 0x01 */
|
||||
+ p_derivation_buffer[0] = 0x01;
|
||||
+ /*label*/
|
||||
+ memcpy(&p_derivation_buffer[1], label, label_length);
|
||||
+ /*output_key_len=0x0080*/
|
||||
+ uint16_t *key_len = (uint16_t *)&p_derivation_buffer[derivation_buffer_length - 2];
|
||||
+ *key_len = 0x0080;
|
||||
+
|
||||
+ se_ret = sgx_rijndael128_cmac_msg((sgx_cmac_128bit_key_t *)&key_derive_key,
|
||||
+ p_derivation_buffer,
|
||||
+ derivation_buffer_length,
|
||||
+ (sgx_cmac_128bit_tag_t *)derived_key);
|
||||
+ memset(&key_derive_key, 0, sizeof(key_derive_key));
|
||||
+ free(p_derivation_buffer);
|
||||
+ if(SGX_SUCCESS != se_ret) {
|
||||
+ INTERNAL_SGX_ERROR_CODE_CONVERTOR(se_ret);
|
||||
+ }
|
||||
+ return se_ret;
|
||||
+}
|
||||
+
|
||||
+static void * (* const volatile __memset_vp)(void *, int, size_t)
|
||||
+ = (memset);
|
||||
+
|
||||
+#undef memset_s /* in case it was defined as a macro */
|
||||
+
|
||||
+int memset_s(void *s, size_t smax, int c, size_t n)
|
||||
+{
|
||||
+ int err = 0;
|
||||
+
|
||||
+ if (s == NULL) {
|
||||
+ err = -1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (smax > SIZE_MAX) {
|
||||
+ err = -1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (n > SIZE_MAX) {
|
||||
+ err = -1;
|
||||
+ n = smax;
|
||||
+ }
|
||||
+ if (n > smax) {
|
||||
+ err = -1;
|
||||
+ n = smax;
|
||||
+ }
|
||||
+
|
||||
+ /* Calling through a volatile pointer should never be optimised away. */
|
||||
+ (*__memset_vp)(s, c, n);
|
||||
+
|
||||
+out:
|
||||
+ if (err == 0)
|
||||
+ return 0;
|
||||
+ else {
|
||||
+ /* XXX call runtime-constraint handler */
|
||||
+ return err;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int consttime_memequal(const void *b1, const void *b2, size_t len)
|
||||
+{
|
||||
+ const unsigned char *c1 = (const unsigned char *)b1, *c2 =(const unsigned char *) b2;
|
||||
+ unsigned int res = 0;
|
||||
+
|
||||
+ while (len--)
|
||||
+ res |= *c1++ ^ *c2++;
|
||||
+
|
||||
+ /*
|
||||
+ * Map 0 to 1 and [1, 256) to 0 using only constant-time
|
||||
+ * arithmetic.
|
||||
+ *
|
||||
+ * This is not simply `!res' because although many CPUs support
|
||||
+ * branchless conditional moves and many compilers will take
|
||||
+ * advantage of them, certain compilers generate branches on
|
||||
+ * certain CPUs for `!res'.
|
||||
+ */
|
||||
+ return (1 & ((res - 1) >> 8));
|
||||
+}
|
||||
+
|
||||
+#define sgx_is_within_enclave(ptr, len) (1)
|
||||
+#define offsetof(type,field) ((char *) &((type *) 0)->field - (char *) 0)
|
||||
+
|
||||
static bool LAv2_verify_message2(const sgx_dh_msg2_t *, const sgx_key_128bit_t *);
|
||||
static sgx_status_t LAv2_generate_message3(const sgx_dh_msg2_t *,
|
||||
const sgx_ec256_public_t *, const sgx_key_128bit_t *, sgx_dh_msg3_t *);
|
||||
diff --git a/demos/local_attestation/DiffieHellmanLibrary/include/sgx_dh_internal.h b/demos/local_attestation/DiffieHellmanLibrary/include/sgx_dh_internal.h
|
||||
index 98b7d3f..5a7a75a 100644
|
||||
--- a/demos/local_attestation/DiffieHellmanLibrary/include/sgx_dh_internal.h
|
||||
+++ b/demos/local_attestation/DiffieHellmanLibrary/include/sgx_dh_internal.h
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "sgx.h"
|
||||
#include "sgx_defs.h"
|
||||
#include "sgx_ecp_types.h"
|
||||
-#include "arch.h"
|
||||
|
||||
// Disable SGX_USE_LAv2_INITIATOR to allow compiling both LAv1/2 APIs
|
||||
#ifdef SGX_USE_LAv2_INITIATOR
|
||||
@@ -81,7 +80,7 @@ typedef struct _sgx_internal_dh_session_t{
|
||||
};
|
||||
} sgx_internal_dh_session_t;
|
||||
|
||||
-se_static_assert(sizeof(sgx_internal_dh_session_t) == SGX_DH_SESSION_DATA_SIZE); /*size mismatch on sgx_internal_dh_session_t and sgx_dh_session_t*/
|
||||
+//se_static_assert(sizeof(sgx_internal_dh_session_t) == SGX_DH_SESSION_DATA_SIZE); /*size mismatch on sgx_internal_dh_session_t and sgx_dh_session_t*/
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
diff --git a/demos/local_attestation/DiffieHellmanLibrary/sgx_cmac128.cpp b/demos/local_attestation/DiffieHellmanLibrary/sgx_cmac128.cpp
|
||||
index a810542..53f9b90 100644
|
||||
--- a/demos/local_attestation/DiffieHellmanLibrary/sgx_cmac128.cpp
|
||||
+++ b/demos/local_attestation/DiffieHellmanLibrary/sgx_cmac128.cpp
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "sgx_tcrypto.h"
|
||||
-#include "se_tcrypto_common.h"
|
||||
#include "openssl/cmac.h"
|
||||
#include "openssl/err.h"
|
||||
|
||||
diff --git a/demos/local_attestation/DiffieHellmanLibrary/sgx_ecc256.cpp b/demos/local_attestation/DiffieHellmanLibrary/sgx_ecc256.cpp
|
||||
index 85a482e..ed8ec46 100644
|
||||
--- a/demos/local_attestation/DiffieHellmanLibrary/sgx_ecc256.cpp
|
||||
+++ b/demos/local_attestation/DiffieHellmanLibrary/sgx_ecc256.cpp
|
||||
@@ -30,7 +30,6 @@
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
-#include "se_tcrypto_common.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -170,9 +169,9 @@ sgx_status_t sgx_ecc256_create_key_pair(sgx_ec256_private_t *p_private,
|
||||
if (SGX_SUCCESS != ret) {
|
||||
// in case of error, clear output buffers
|
||||
//
|
||||
- memset_s(p_private, sizeof(p_private), 0, sizeof(p_private));
|
||||
- memset_s(p_public->gx, sizeof(p_public->gx), 0, sizeof(p_public->gx));
|
||||
- memset_s(p_public->gy, sizeof(p_public->gy), 0, sizeof(p_public->gy));
|
||||
+ memset(p_private, 0, sizeof(p_private));
|
||||
+ memset(p_public->gx, 0, sizeof(p_public->gx));
|
||||
+ memset(p_public->gy, 0, sizeof(p_public->gy));
|
||||
}
|
||||
|
||||
//free temp data
|
||||
@@ -367,7 +366,7 @@ sgx_status_t sgx_ecc256_compute_shared_dhkey(sgx_ec256_private_t *p_private_b,
|
||||
} while(0);
|
||||
|
||||
if (ret != SGX_SUCCESS) {
|
||||
- memset_s(p_shared_key->s, sizeof(p_shared_key->s), 0, sizeof(p_shared_key->s));
|
||||
+ memset(p_shared_key->s, 0, sizeof(p_shared_key->s));
|
||||
}
|
||||
|
||||
// clear and free memory
|
||||
@@ -470,7 +469,7 @@ sgx_status_t sgx_ecc256_calculate_pub_from_priv(const sgx_ec256_private_t *p_att
|
||||
//in case of failure clear public key
|
||||
//
|
||||
if (ret != SGX_SUCCESS) {
|
||||
- (void)memset_s(p_att_pub_key, sizeof(sgx_ec256_public_t), 0, sizeof(sgx_ec256_public_t));
|
||||
+ (void)memset(p_att_pub_key, 0, sizeof(sgx_ec256_public_t));
|
||||
}
|
||||
|
||||
BN_clear_free(bn_o);
|
||||
diff --git a/demos/local_attestation/DiffieHellmanLibrary/sgx_sha256_msg.cpp b/demos/local_attestation/DiffieHellmanLibrary/sgx_sha256_msg.cpp
|
||||
index 44fd1e2..b3ee3ed 100644
|
||||
--- a/demos/local_attestation/DiffieHellmanLibrary/sgx_sha256_msg.cpp
|
||||
+++ b/demos/local_attestation/DiffieHellmanLibrary/sgx_sha256_msg.cpp
|
||||
@@ -29,7 +29,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
-#include "se_tcrypto_common.h"
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/err.h>
|
||||
#include "sgx_tcrypto.h"
|
||||
--
|
||||
2.17.1
|
||||
|
29
demos/local_attestation/DiffieHellmanLibrary/Makefile
Normal file
29
demos/local_attestation/DiffieHellmanLibrary/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
PROJECT_DIR := $(realpath $(CUR_DIR)/../../../)
|
||||
OPENSSL ?= $(CUR_DIR)/../deps/openssl
|
||||
SGX_SDK ?= /opt/intel/sgxsdk
|
||||
|
||||
OBJS = sgx_ecc256.o sgx_cmac128.o sgx_sha256_msg.o crypto_aes_gcm.o
|
||||
CC = occlum-gcc
|
||||
CXX = occlum-g++
|
||||
CFLAGS = -I$(OPENSSL)/include -L$(OPENSSL) -lcrypto -fPIC
|
||||
SOFLAGS = -shared $(CFLAGS)
|
||||
CFLAGS += -I$(SGX_SDK)/include -Iinclude
|
||||
|
||||
ec_dh : $(OBJS)
|
||||
$(CXX) $(SOFLAGS) -o libecdh.so ec_dh.cpp $(OBJS)
|
||||
|
||||
sgx_ecc256.o : sgx_ecc256.cpp
|
||||
$(CXX) -c sgx_ecc256.cpp $(CFLAGS) -o sgx_ecc256.o
|
||||
|
||||
sgx_cmac128.o : sgx_cmac128.cpp
|
||||
$(CXX) -c sgx_cmac128.cpp $(CFLAGS) -o sgx_cmac128.o
|
||||
|
||||
sgx_sha256_msg.o : sgx_sha256_msg.cpp
|
||||
$(CXX) -c sgx_sha256_msg.cpp $(CFLAGS) -o sgx_sha256_msg.o
|
||||
|
||||
crypto_aes_gcm.o : crypto_aes_gcm.cpp
|
||||
$(CXX) -c crypto_aes_gcm.cpp $(CFLAGS) -o crypto_aes_gcm.o
|
||||
|
||||
clean:
|
||||
rm -rf *.o ec_dh *.so
|
@ -0,0 +1,9 @@
|
||||
<EnclaveConfiguration>
|
||||
<ProdID>0</ProdID>
|
||||
<ISVSVN>0</ISVSVN>
|
||||
<StackMaxSize>0x40000</StackMaxSize>
|
||||
<HeapMaxSize>0x100000</HeapMaxSize>
|
||||
<TCSNum>1</TCSNum>
|
||||
<TCSPolicy>1</TCSPolicy>
|
||||
<DisableDebug>0</DisableDebug>
|
||||
</EnclaveConfiguration>
|
187
demos/local_attestation/EnclaveInitiator/EnclaveInitiator.cpp
Normal file
187
demos/local_attestation/EnclaveInitiator/EnclaveInitiator.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include "sgx_eid.h"
|
||||
#include "EnclaveInitiator_t.h"
|
||||
#include "EnclaveMessageExchange.h"
|
||||
#include "error_codes.h"
|
||||
#include "Utility_EnclaveInitiator.h"
|
||||
#include "sgx_dh.h"
|
||||
|
||||
#define UNUSED(val) (void)(val)
|
||||
|
||||
#define RESPONDER_PRODID 1
|
||||
|
||||
dh_session_t g_session;
|
||||
|
||||
/* Function Description:
|
||||
* This is ECALL routine to create ECDH session.
|
||||
* When it succeeds to create ECDH session, the session context is saved in g_session.
|
||||
* */
|
||||
extern "C" uint32_t test_create_session()
|
||||
{
|
||||
return create_session(&g_session);
|
||||
}
|
||||
|
||||
/* Function Description:
|
||||
* This is ECALL routine to transfer message with ECDH peer
|
||||
* */
|
||||
uint32_t test_message_exchange()
|
||||
{
|
||||
ATTESTATION_STATUS ke_status = SUCCESS;
|
||||
uint32_t target_fn_id, msg_type;
|
||||
char* marshalled_inp_buff;
|
||||
size_t marshalled_inp_buff_len;
|
||||
char* out_buff;
|
||||
size_t out_buff_len;
|
||||
size_t max_out_buff_size;
|
||||
char* secret_response;
|
||||
uint32_t secret_data;
|
||||
|
||||
target_fn_id = 0;
|
||||
msg_type = MESSAGE_EXCHANGE;
|
||||
max_out_buff_size = 50; // it's assumed the maximum payload size in response message is 50 bytes, it's for demontration purpose
|
||||
secret_data = 0x12345678; //Secret Data here is shown only for purpose of demonstration.
|
||||
|
||||
//Marshals the secret data into a buffer
|
||||
ke_status = marshal_message_exchange_request(target_fn_id, msg_type, secret_data, &marshalled_inp_buff, &marshalled_inp_buff_len);
|
||||
if(ke_status != SUCCESS)
|
||||
{
|
||||
return ke_status;
|
||||
}
|
||||
|
||||
//Core Reference Code function
|
||||
ke_status = send_request_receive_response(&g_session, marshalled_inp_buff,
|
||||
marshalled_inp_buff_len, max_out_buff_size, &out_buff, &out_buff_len);
|
||||
if(ke_status != SUCCESS)
|
||||
{
|
||||
SAFE_FREE(marshalled_inp_buff);
|
||||
SAFE_FREE(out_buff);
|
||||
return ke_status;
|
||||
}
|
||||
|
||||
//Un-marshal the secret response data
|
||||
ke_status = umarshal_message_exchange_response(out_buff, &secret_response);
|
||||
if(ke_status != SUCCESS)
|
||||
{
|
||||
SAFE_FREE(marshalled_inp_buff);
|
||||
SAFE_FREE(out_buff);
|
||||
return ke_status;
|
||||
}
|
||||
|
||||
SAFE_FREE(marshalled_inp_buff);
|
||||
SAFE_FREE(out_buff);
|
||||
SAFE_FREE(secret_response);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Function Descriptin:
|
||||
* This is ECALL interface to close secure session*/
|
||||
uint32_t test_close_session()
|
||||
{
|
||||
ATTESTATION_STATUS ke_status;
|
||||
|
||||
ke_status = close_session(&g_session);
|
||||
|
||||
//Erase the session context
|
||||
memset(&g_session, 0, sizeof(dh_session_t));
|
||||
return ke_status;
|
||||
}
|
||||
|
||||
/* Function Description:
|
||||
* This is to verify peer enclave's identity.
|
||||
* For demonstration purpose, we verify below points:
|
||||
* 1. peer enclave's MRSIGNER is as expected
|
||||
* 2. peer enclave's PROD_ID is as expected
|
||||
* 3. peer enclave's attribute is reasonable: it's INITIALIZED'ed enclave; in non-debug build configuraiton, the enlave isn't loaded with enclave debug mode.
|
||||
**/
|
||||
extern "C" uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity)
|
||||
{
|
||||
if (!peer_enclave_identity)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
// check peer enclave's MRSIGNER
|
||||
|
||||
// check peer enclave's product ID and enclave attribute (should be INITIALIZED'ed)
|
||||
if ( !(peer_enclave_identity->attributes.flags & SGX_FLAGS_INITTED))
|
||||
{
|
||||
return ENCLAVE_TRUST_ERROR;
|
||||
}
|
||||
|
||||
// check the enclave isn't loaded in enclave debug mode, except that the project is built for debug purpose
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Function Desciption: Operates on the input secret and generate the output secret
|
||||
* */
|
||||
uint32_t get_message_exchange_response(uint32_t inp_secret_data)
|
||||
{
|
||||
uint32_t secret_response;
|
||||
|
||||
//User should use more complex encryption method to protect their secret, below is just a simple example
|
||||
secret_response = inp_secret_data & 0x11111111;
|
||||
|
||||
return secret_response;
|
||||
|
||||
}
|
||||
|
||||
//Generates the response from the request message
|
||||
/* Function Description:
|
||||
* process request message and generate response
|
||||
* Parameter Descriptin:
|
||||
* [input] decrypted_data: this is pointer to decrypted message
|
||||
* [output] resp_buffer: this is pointer to response message, the buffer is allocated inside this function
|
||||
* [output] resp_length: this points to response length
|
||||
* */
|
||||
extern "C" uint32_t message_exchange_response_generator(char* decrypted_data,
|
||||
char** resp_buffer,
|
||||
size_t* resp_length)
|
||||
{
|
||||
ms_in_msg_exchange_t *ms;
|
||||
uint32_t inp_secret_data;
|
||||
uint32_t out_secret_data;
|
||||
if(!decrypted_data || !resp_length)
|
||||
{
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
ms = (ms_in_msg_exchange_t *)decrypted_data;
|
||||
|
||||
if(umarshal_message_exchange_request(&inp_secret_data,ms) != SUCCESS)
|
||||
return ATTESTATION_ERROR;
|
||||
|
||||
out_secret_data = get_message_exchange_response(inp_secret_data);
|
||||
|
||||
if(marshal_message_exchange_response(resp_buffer, resp_length, out_secret_data) != SUCCESS)
|
||||
return MALLOC_ERROR;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
enclave {
|
||||
include "sgx_eid.h"
|
||||
include "datatypes.h"
|
||||
include "dh_session_protocol.h"
|
||||
|
||||
trusted{
|
||||
public uint32_t test_create_session();
|
||||
public uint32_t test_message_exchange();
|
||||
public uint32_t test_close_session();
|
||||
};
|
||||
|
||||
untrusted{
|
||||
uint32_t session_request_ocall([out] sgx_dh_msg1_t *dh_msg1,[out] uint32_t *session_id);
|
||||
uint32_t exchange_report_ocall([in] sgx_dh_msg2_t *dh_msg2, [out] sgx_dh_msg3_t *dh_msg3, uint32_t session_id);
|
||||
uint32_t send_request_ocall(uint32_t session_id, [in, size = req_message_size] secure_message_t* req_message, size_t req_message_size, size_t max_payload_size, [out, size=resp_message_size] secure_message_t* resp_message, size_t resp_message_size);
|
||||
uint32_t end_session_ocall(uint32_t session_id);
|
||||
};
|
||||
|
||||
};
|
@ -0,0 +1,10 @@
|
||||
Enclave1.so
|
||||
{
|
||||
global:
|
||||
g_global_data_sim;
|
||||
g_global_data;
|
||||
enclave_entry;
|
||||
g_peak_heap_used;
|
||||
local:
|
||||
*;
|
||||
};
|
@ -0,0 +1,39 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIG4wIBAAKCAYEAuJh4w/KzndQhzEqwH6Ut/3BmOom5CN117KT1/cemEbDLPhn0
|
||||
c5yjAfe4NL1qtGqz0RTK9X9BBSi89b6BrsM9S6c2cUJaeYAPrAtJ+IuzN/5BAmmf
|
||||
RXbPccETd7rHvDdQ9KBRjCipTx+H0D5nOB76S5PZPVrduwrCmSqVFmLNVWWfPYQx
|
||||
YewbJ2QfEfioICZFYR0Jou38mJqDTl+CH0gLAuQ4n1kdpQ3VGymzt3oUiPzf5ImJ
|
||||
oZh5HjarRRiWV+cyNyXYJTnx0dOtFQDgd8HhniagbRB0ZOIt6599JjMkWGkVP0Ni
|
||||
U/NIlXG5musU35GfLB8MbTcxblMNm9sMYz1R8y/eAreoPTXUhtK8NG2TEywRh3UP
|
||||
RF9/jM9WczjQXxJ3RznKOwNVwg4cRY2AOqD2vb1iGSqyc/WMzVULgfclkcScp75/
|
||||
Auz9Y6473CQvaxyrseSWHGwCG7KG1GxYE8Bg8T6OlYD4mzKggoMdwVLAzUepRaPZ
|
||||
5hqRDZzbTGUxJ+GLAgEDAoIBgHsQUIKhzRPiwTLcdWpuHqpK7tGxJgXo+Uht+VPa
|
||||
brZ13NQRTaJobKv6es3TnHhHIotjMfj/gK4bKKPUVnSCKN0aJEuBkaZVX8gHhqWy
|
||||
d3qpgKxGai5PNPaAt6UnL9LPi03ANl1wcN9qWorURNAUpt0NO348k9IHLGYcY2RB
|
||||
3jjuaikCy5adZ2+YFLalxWrELkC+BmyeqGW8V4mVAWowB1dC0Go7aRiz42dxInpR
|
||||
YwX96phbsRZlphQkci4QZDqaIFg3ndzTO5bo704zaMcbWtEjmFrYRyb519tRoDkN
|
||||
Y0rGwOxFANeRV5dSfGGLm7K5JztiuHN0nMu3PhY4LOV0SeZ4+5sYn0LzB2nyKqgy
|
||||
/c3AA2OG34DEdGxxh94kD66iKFVPyJG38/gnu9CsGmrLl3n4fgutPEVIbPdSSjex
|
||||
4Y9EQfcnqImPxTrpP9CqD208VPcQHD/uy8s9q3961Ew3RPdHMZ8amIJdXkOmPEme
|
||||
KZ7SG+VENBaj8r038iq1mPzcWwKBwQDcvJg75LfVuKX+cWMrTO2+MFVcEFiZ/NB/
|
||||
gh7mgL6lCleROVa9P6iR2Wn6vHq8nP5BkChehm/rXEG78fgXEMoArimF7FrrICfI
|
||||
4yB0opDJz/tWrE/62impN7OR8Ce+RQThFj4RTnibQEEVt++JMUXFiMKLdWDSpC2i
|
||||
tNWnlTOb7d89bk0yk62IoLElCZK/MIMxkCHBKW6YgrmvlPJKQwpA6Z3wQbUpE6Rb
|
||||
9f8xJfxZGEJPH0s3Ds9A0CVuEt8OOXcCgcEA1hXTHhhgmb2gIUJgIcvrpkDmiLux
|
||||
EG6ZoyLt6h5QwzScS6KKU1mcoJyVDd0wlt7mEXrPYYHWUWPuvpTQ8/4ZGMw7FCZe
|
||||
bakhnwRbw36FlLwRG35wCF6nQO1XFBKRGto15ivfTyDvMpJBdtNpET5NwT/ifDF3
|
||||
OWS7t6TGhtcfnvBad5S1AgGoAq+q/huFiBGpDbxJ+1xh0lNL5Z8nVypvPWomNpde
|
||||
rpLuwRPEIb+GBfQ9Hp5AjRXVsPjKnkHsnl2NAoHBAJMoZX1DJTklw/72Qhzd89Qg
|
||||
OOgK5bv94FUBae8Afxixj7YmOdN/xbaQ8VHS/H29/tZgGumu9UeS1n1L+roLMVXJ
|
||||
cQPy50dqxTCXavhsYIaKp48diqc8G8YlImFKxSmDWJYO1AuJpbzVgLklSlt2LoOw
|
||||
gbJOQIxtc8HN48UOImfz6ij0M3cNHlsVy24GYdTLAiEKwStw9GWse8pjTDGCBtXx
|
||||
E/WBI3C3wuf5VMtuqDtlgYoU3M9fNNXgGPQMlLQmTwKBwQCOuTdpZZW708AWLEAW
|
||||
h/Ju1e8F0nYK9GZswfPxaYsszb2HwbGM5mhrEw4JPiBklJlg/IpBATmLl/R/DeCi
|
||||
qWYQiCdixD7zxhZqAufXqa5jKAtnqaAFlG+AnjoNYbYR5s6ZcpTfa0ohttZPN5tg
|
||||
1DPWKpb9dk97mH0lGIRZ5L+/Sub6YyNWq8VXH8dUElkFYRtefYankuvhjN1Dv2+P
|
||||
cZ9+RsQkZOnJt0nWDS1r1QQD+Ci/FCsIuTkgpdxpgUhpk7MCgcEAkfkmaBDb7DG2
|
||||
Kc39R6ZZuPnV10w+WOpph7ugwcguG/E0wGq+jFWv6HFckCPeHT4BNtOk8Dem/kPp
|
||||
teF51eAuFWEefj2tScvlSBBPcnla+WzMWXrlxVnajTt73w+oT2Ql//WhgREpsNfx
|
||||
SvU80YPVu4GJfl+hhxBifLx+0FM20OESW93qFRc3p040bNrDY9JIZuly/y5zaiBa
|
||||
mRZF9H8P+x3Lu5AJpdXQEOMZ/XJ/xkoWWjbTojkmgOmmZSMLd5Te
|
||||
-----END RSA PRIVATE KEY-----
|
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <string>
|
||||
#include "sgx_trts.h"
|
||||
#include "sgx_utils.h"
|
||||
#include "EnclaveMessageExchange.h"
|
||||
#include "sgx_eid.h"
|
||||
#include "error_codes.h"
|
||||
#include "sgx_ecp_types.h"
|
||||
#include "sgx_thread.h"
|
||||
#include "dh_session_protocol.h"
|
||||
#include "sgx_dh.h"
|
||||
#include "sgx_tcrypto.h"
|
||||
#include "EnclaveInitiator_t.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t message_exchange_response_generator(char* decrypted_data, char** resp_buffer, size_t* resp_length);
|
||||
uint32_t verify_peer_enclave_trust(sgx_dh_session_enclave_identity_t* peer_enclave_identity);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_SESSION_COUNT 16
|
||||
|
||||
//number of open sessions
|
||||
uint32_t g_session_count = 0;
|
||||
|
||||
ATTESTATION_STATUS generate_session_id(uint32_t *session_id);
|
||||
ATTESTATION_STATUS end_session(sgx_enclave_id_t src_enclave_id);
|
||||
|
||||
//Array of open session ids
|
||||
session_id_tracker_t *g_session_id_tracker[MAX_SESSION_COUNT];
|
||||
|
||||
//Create a session with the destination enclave
|
||||
ATTESTATION_STATUS create_session(dh_session_t *session_info)
|
||||
{
|
||||
sgx_dh_msg1_t dh_msg1; //Diffie-Hellman Message 1
|
||||
sgx_key_128bit_t dh_aek; // Session Key
|
||||
sgx_dh_msg2_t dh_msg2; //Diffie-Hellman Message 2
|
||||
sgx_dh_msg3_t dh_msg3; //Diffie-Hellman Message 3
|
||||
uint32_t session_id;
|
||||
uint32_t retstatus;
|
||||
sgx_status_t status = SGX_SUCCESS;
|
||||
sgx_dh_session_t sgx_dh_session;
|
||||
sgx_dh_session_enclave_identity_t responder_identity;
|
||||
|
||||
if(!session_info)
|
||||
{
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
|
||||
memset(&dh_msg1, 0, sizeof(sgx_dh_msg1_t));
|
||||
memset(&dh_msg2, 0, sizeof(sgx_dh_msg2_t));
|
||||
memset(&dh_msg3, 0, sizeof(sgx_dh_msg3_t));
|
||||
memset(session_info, 0, sizeof(dh_session_t));
|
||||
|
||||
//Intialize the session as a session initiator
|
||||
status = sgx_dh_init_session(SGX_DH_SESSION_INITIATOR, &sgx_dh_session);
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
//Ocall to request for a session with the destination enclave and obtain session id and Message 1 if successful
|
||||
status = session_request_ocall(&retstatus, &dh_msg1, &session_id);
|
||||
if (status == SGX_SUCCESS)
|
||||
{
|
||||
if ((ATTESTATION_STATUS)retstatus != SUCCESS)
|
||||
return ((ATTESTATION_STATUS)retstatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ATTESTATION_SE_ERROR;
|
||||
}
|
||||
//Process the message 1 obtained from desination enclave and generate message 2
|
||||
status = sgx_dh_initiator_proc_msg1(&dh_msg1, &dh_msg2, &sgx_dh_session);
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
//Send Message 2 to Destination Enclave and get Message 3 in return
|
||||
status = exchange_report_ocall(&retstatus, &dh_msg2, &dh_msg3, session_id);
|
||||
if (status == SGX_SUCCESS)
|
||||
{
|
||||
if ((ATTESTATION_STATUS)retstatus != SUCCESS)
|
||||
return ((ATTESTATION_STATUS)retstatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ATTESTATION_SE_ERROR;
|
||||
}
|
||||
|
||||
//Process Message 3 obtained from the destination enclave
|
||||
status = sgx_dh_initiator_proc_msg3(&dh_msg3, &sgx_dh_session, &dh_aek, &responder_identity);
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
// Verify the identity of the destination enclave
|
||||
if(verify_peer_enclave_trust(&responder_identity) != SUCCESS)
|
||||
{
|
||||
return INVALID_SESSION;
|
||||
}
|
||||
|
||||
memcpy(session_info->active.AEK, &dh_aek, sizeof(sgx_key_128bit_t));
|
||||
session_info->session_id = session_id;
|
||||
session_info->active.counter = 0;
|
||||
session_info->status = ACTIVE;
|
||||
memset(&dh_aek,0, sizeof(sgx_key_128bit_t));
|
||||
return status;
|
||||
}
|
||||
|
||||
//Request for the response size, send the request message to the destination enclave and receive the response message back
|
||||
ATTESTATION_STATUS send_request_receive_response(dh_session_t *session_info,
|
||||
char *inp_buff,
|
||||
size_t inp_buff_len,
|
||||
size_t max_out_buff_size,
|
||||
char **out_buff,
|
||||
size_t* out_buff_len)
|
||||
{
|
||||
const uint8_t* plaintext;
|
||||
uint32_t plaintext_length;
|
||||
sgx_status_t status;
|
||||
uint32_t retstatus;
|
||||
secure_message_t* req_message;
|
||||
secure_message_t* resp_message;
|
||||
uint8_t *decrypted_data;
|
||||
uint32_t decrypted_data_length;
|
||||
uint32_t plain_text_offset;
|
||||
uint8_t l_tag[TAG_SIZE];
|
||||
size_t max_resp_message_length;
|
||||
plaintext = (const uint8_t*)(" ");
|
||||
plaintext_length = 0;
|
||||
|
||||
if(!session_info || !inp_buff)
|
||||
{
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
//Check if the nonce for the session has not exceeded 2^32-2 if so end session and start a new session
|
||||
if(session_info->active.counter == ((uint32_t) - 2))
|
||||
{
|
||||
close_session(session_info);
|
||||
create_session(session_info);
|
||||
}
|
||||
|
||||
//Allocate memory for the AES-GCM request message
|
||||
req_message = (secure_message_t*)malloc(sizeof(secure_message_t)+ inp_buff_len);
|
||||
if(!req_message)
|
||||
return MALLOC_ERROR;
|
||||
memset(req_message, 0, sizeof(secure_message_t)+ inp_buff_len);
|
||||
|
||||
const uint32_t data2encrypt_length = (uint32_t)inp_buff_len;
|
||||
|
||||
//Set the payload size to data to encrypt length
|
||||
req_message->message_aes_gcm_data.payload_size = data2encrypt_length;
|
||||
|
||||
//Use the session nonce as the payload IV
|
||||
memcpy(req_message->message_aes_gcm_data.reserved, &session_info->active.counter, sizeof(session_info->active.counter));
|
||||
|
||||
//Set the session ID of the message to the current session id
|
||||
req_message->session_id = session_info->session_id;
|
||||
|
||||
//Prepare the request message with the encrypted payload
|
||||
status = sgx_rijndael128GCM_encrypt(&session_info->active.AEK, (uint8_t*)inp_buff, data2encrypt_length,
|
||||
reinterpret_cast<uint8_t *>(&(req_message->message_aes_gcm_data.payload)),
|
||||
reinterpret_cast<uint8_t *>(&(req_message->message_aes_gcm_data.reserved)),
|
||||
sizeof(req_message->message_aes_gcm_data.reserved), plaintext, plaintext_length,
|
||||
&(req_message->message_aes_gcm_data.payload_tag));
|
||||
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
return status;
|
||||
}
|
||||
|
||||
//Allocate memory for the response payload to be copied
|
||||
*out_buff = (char*)malloc(max_out_buff_size);
|
||||
if(!*out_buff)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
return MALLOC_ERROR;
|
||||
}
|
||||
memset(*out_buff, 0, max_out_buff_size);
|
||||
|
||||
//Allocate memory for the response message
|
||||
resp_message = (secure_message_t*)malloc(sizeof(secure_message_t)+ max_out_buff_size);
|
||||
if(!resp_message)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
return MALLOC_ERROR;
|
||||
}
|
||||
|
||||
memset(resp_message, 0, sizeof(secure_message_t)+ max_out_buff_size);
|
||||
|
||||
//Ocall to send the request to the Destination Enclave and get the response message back
|
||||
status = send_request_ocall(&retstatus, session_info->session_id, req_message,
|
||||
(sizeof(secure_message_t)+ inp_buff_len), max_out_buff_size,
|
||||
resp_message, (sizeof(secure_message_t)+ max_out_buff_size));
|
||||
if (status == SGX_SUCCESS)
|
||||
{
|
||||
if ((ATTESTATION_STATUS)retstatus != SUCCESS)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(resp_message);
|
||||
return ((ATTESTATION_STATUS)retstatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(resp_message);
|
||||
return ATTESTATION_SE_ERROR;
|
||||
}
|
||||
|
||||
max_resp_message_length = sizeof(secure_message_t)+ max_out_buff_size;
|
||||
|
||||
if(sizeof(resp_message) > max_resp_message_length)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(resp_message);
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
//Code to process the response message from the Destination Enclave
|
||||
|
||||
decrypted_data_length = resp_message->message_aes_gcm_data.payload_size;
|
||||
plain_text_offset = decrypted_data_length;
|
||||
decrypted_data = (uint8_t*)malloc(decrypted_data_length);
|
||||
if(!decrypted_data)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(resp_message);
|
||||
return MALLOC_ERROR;
|
||||
}
|
||||
memset(&l_tag, 0, 16);
|
||||
|
||||
memset(decrypted_data, 0, decrypted_data_length);
|
||||
|
||||
//Decrypt the response message payload
|
||||
status = sgx_rijndael128GCM_decrypt(&session_info->active.AEK, resp_message->message_aes_gcm_data.payload,
|
||||
decrypted_data_length, decrypted_data,
|
||||
reinterpret_cast<uint8_t *>(&(resp_message->message_aes_gcm_data.reserved)),
|
||||
sizeof(resp_message->message_aes_gcm_data.reserved), &(resp_message->message_aes_gcm_data.payload[plain_text_offset]), plaintext_length,
|
||||
&resp_message->message_aes_gcm_data.payload_tag);
|
||||
|
||||
if(SGX_SUCCESS != status)
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(decrypted_data);
|
||||
SAFE_FREE(resp_message);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Verify if the nonce obtained in the response is equal to the session nonce + 1 (Prevents replay attacks)
|
||||
if(*(resp_message->message_aes_gcm_data.reserved) != (session_info->active.counter + 1 ))
|
||||
{
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(resp_message);
|
||||
SAFE_FREE(decrypted_data);
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
//Update the value of the session nonce in the source enclave
|
||||
session_info->active.counter = session_info->active.counter + 1;
|
||||
|
||||
memcpy(out_buff_len, &decrypted_data_length, sizeof(decrypted_data_length));
|
||||
memcpy(*out_buff, decrypted_data, decrypted_data_length);
|
||||
|
||||
SAFE_FREE(decrypted_data);
|
||||
SAFE_FREE(req_message);
|
||||
SAFE_FREE(resp_message);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
//Close a current session
|
||||
ATTESTATION_STATUS close_session(dh_session_t *session_info)
|
||||
{
|
||||
sgx_status_t status;
|
||||
uint32_t retstatus;
|
||||
|
||||
if(!session_info)
|
||||
{
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
|
||||
//Ocall to ask the destination enclave to end the session
|
||||
status = end_session_ocall(&retstatus, session_info->session_id);
|
||||
if (status == SGX_SUCCESS)
|
||||
{
|
||||
if ((ATTESTATION_STATUS)retstatus != SUCCESS)
|
||||
return ((ATTESTATION_STATUS)retstatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ATTESTATION_SE_ERROR;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
//Returns a new sessionID for the source destination session
|
||||
ATTESTATION_STATUS generate_session_id(uint32_t *session_id)
|
||||
{
|
||||
ATTESTATION_STATUS status = SUCCESS;
|
||||
|
||||
if(!session_id)
|
||||
{
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
}
|
||||
//if the session structure is untintialized, set that as the next session ID
|
||||
for (int i = 0; i < MAX_SESSION_COUNT; i++)
|
||||
{
|
||||
if (g_session_id_tracker[i] == NULL)
|
||||
{
|
||||
*session_id = i;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = NO_AVAILABLE_SESSION_ERROR;
|
||||
|
||||
return status;
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "sgx_eid.h"
|
||||
#include "sgx_trts.h"
|
||||
#include "dh_session_protocol.h"
|
||||
|
||||
#ifndef LOCALATTESTATION_H_
|
||||
#define LOCALATTESTATION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t SGXAPI create_session(dh_session_t *p_session_info);
|
||||
uint32_t SGXAPI send_request_receive_response(dh_session_t *p_session_info, char *inp_buff, size_t inp_buff_len, size_t max_out_buff_size, char **out_buff, size_t* out_buff_len);
|
||||
uint32_t SGXAPI close_session(dh_session_t *p_session_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
133
demos/local_attestation/EnclaveInitiator/Makefile
Normal file
133
demos/local_attestation/EnclaveInitiator/Makefile
Normal file
@ -0,0 +1,133 @@
|
||||
#
|
||||
# Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#
|
||||
|
||||
include ../buildenv.mk
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
Trts_Library_Name := sgx_trts_sim
|
||||
Service_Library_Name := sgx_tservice_sim
|
||||
else
|
||||
Trts_Library_Name := sgx_trts
|
||||
Service_Library_Name := sgx_tservice
|
||||
endif
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
Urts_Library_Name := sgx_urts_sim
|
||||
else
|
||||
Urts_Library_Name := sgx_urts
|
||||
endif
|
||||
|
||||
Crypto_Library_Name := sgx_tcrypto
|
||||
|
||||
ENCLAVE_NAME := libenclave_initiator.so
|
||||
SIGNED_ENCLAVE_NAME := libenclave_initiator.signed.so
|
||||
|
||||
$(SIGNED_ENCLAVE_NAME) : $(ENCLAVE_NAME)
|
||||
@$(SGX_ENCLAVE_SIGNER) sign -key EnclaveInitiator_private.pem -enclave $(ENCLAVE_NAME) -out $@ -config EnclaveInitiator.config.xml
|
||||
@cp $(SIGNED_ENCLAVE_NAME) $(TOPDIR)/$(OUTDIR)/
|
||||
@echo "SIGN => $@"
|
||||
|
||||
# Enable the security flags
|
||||
Enclave_Security_Link_Flags := -Wl,-z,relro,-z,now,-z,noexecstack
|
||||
|
||||
# To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries:
|
||||
# 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options,
|
||||
# so that the whole content of trts is included in the enclave.
|
||||
# 2. For other libraries, you just need to pull the required symbols.
|
||||
# Use `--start-group' and `--end-group' to link these libraries.
|
||||
# Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options.
|
||||
# Otherwise, you may get some undesirable errors.
|
||||
ENCLAVE_LINK_FLAGS := $(Enclave_Security_Link_Flags) \
|
||||
-Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
|
||||
-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
|
||||
-Wl,--start-group -l$(Urts_Library_Name) -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
|
||||
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
|
||||
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
|
||||
-Wl,--defsym,__ImageBase=0 -Wl,--gc-sections \
|
||||
-Wl,--version-script=EnclaveInitiator.lds
|
||||
|
||||
SGX_COMMON_FLAGS += -Wall -Wextra -Winit-self -Wpointer-arith -Wreturn-type \
|
||||
-Waddress -Wsequence-point -Wformat-security \
|
||||
-Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \
|
||||
-Wcast-align -Wconversion -Wredundant-decls
|
||||
|
||||
SGX_COMMON_CFLAGS := $(SGX_COMMON_FLAGS) -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants
|
||||
SGX_COMMON_CXXFLAGS := $(SGX_COMMON_FLAGS) -Wnon-virtual-dtor -std=c++11
|
||||
|
||||
Enclave_Include_Paths := -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/libcxx -I../Include
|
||||
|
||||
Enclave_C_Flags := $(Enclave_Include_Paths) -nostdinc -fvisibility=hidden -fpie -ffunction-sections -fdata-sections
|
||||
CC_BELOW_4_9 := $(shell expr "`$(CC) -dumpversion`" \< "4.9")
|
||||
ifeq ($(CC_BELOW_4_9), 1)
|
||||
Enclave_C_Flags += -fstack-protector
|
||||
else
|
||||
Enclave_C_Flags += -fstack-protector-strong
|
||||
endif
|
||||
Enclave_Cpp_Flags := $(Enclave_C_Flags) -nostdinc++
|
||||
|
||||
ifeq ($(LAv2), 1)
|
||||
Enclave_C_Flags += -DSGX_USE_LAv2_INITIATOR
|
||||
Enclave_Cpp_Flags += -DSGX_USE_LAv2_INITIATOR
|
||||
endif
|
||||
|
||||
Enclave_Cpp_Files := $(wildcard *.cpp)
|
||||
ENCLAVE_CPP_OBJECTS := $(Enclave_Cpp_Files:.cpp=.o)
|
||||
|
||||
.PHONY = all clean target
|
||||
|
||||
target = $(SIGNED_ENCLAVE_NAME)
|
||||
|
||||
all:
|
||||
@make target
|
||||
|
||||
clean:
|
||||
@rm -f $(ENCLAVE_NAME) $(SIGNED_ENCLAVE_NAME) *.o *_t.c *_t.h *_u.c *_u.h
|
||||
|
||||
$(ENCLAVE_NAME):EnclaveInitiator_t.o $(ENCLAVE_CPP_OBJECTS)
|
||||
@$(CXX) $^ -o $@ $(ENCLAVE_LINK_FLAGS)
|
||||
@echo "LINK => $@"
|
||||
|
||||
######## Enclave Objects ########
|
||||
|
||||
EnclaveInitiator_t.h: $(SGX_EDGER8R) EnclaveInitiator.edl
|
||||
@$(SGX_EDGER8R) --trusted EnclaveInitiator.edl --search-path $(SGX_SDK)/include
|
||||
@echo "GEN => $@"
|
||||
|
||||
EnclaveInitiator_t.c: EnclaveInitiator_t.h
|
||||
|
||||
EnclaveInitiator_t.o: EnclaveInitiator_t.c
|
||||
@$(CC) $(SGX_COMMON_CFLAGS) $(Enclave_C_Flags) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
%.o: %.cpp EnclaveInitiator_t.h
|
||||
@$(CXX) $(SGX_COMMON_CXXFLAGS) $(Enclave_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sgx_eid.h"
|
||||
#include "EnclaveMessageExchange.h"
|
||||
#include "error_codes.h"
|
||||
#include "Utility_EnclaveInitiator.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
uint32_t marshal_input_parameters_e2_foo1(uint32_t target_fn_id, uint32_t msg_type, uint32_t var1, uint32_t var2, char** marshalled_buff, size_t* marshalled_buff_len)
|
||||
{
|
||||
ms_in_msg_exchange_t *ms;
|
||||
size_t param_len, ms_len;
|
||||
char *temp_buff;
|
||||
|
||||
param_len = sizeof(var1)+sizeof(var2);
|
||||
temp_buff = (char*)malloc(param_len);
|
||||
if(!temp_buff)
|
||||
return MALLOC_ERROR;
|
||||
|
||||
memcpy(temp_buff,&var1,sizeof(var1));
|
||||
memcpy(temp_buff+sizeof(var1),&var2,sizeof(var2));
|
||||
ms_len = sizeof(ms_in_msg_exchange_t) + param_len;
|
||||
ms = (ms_in_msg_exchange_t *)malloc(ms_len);
|
||||
if(!ms)
|
||||
{
|
||||
SAFE_FREE(temp_buff);
|
||||
return MALLOC_ERROR;
|
||||
}
|
||||
ms->msg_type = msg_type;
|
||||
ms->target_fn_id = target_fn_id;
|
||||
ms->inparam_buff_len = (uint32_t)param_len;
|
||||
memcpy(&ms->inparam_buff, temp_buff, param_len);
|
||||
*marshalled_buff = (char*)ms;
|
||||
*marshalled_buff_len = ms_len;
|
||||
SAFE_FREE(temp_buff);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t unmarshal_retval_and_output_parameters_e2_foo1(char* out_buff, char** retval)
|
||||
{
|
||||
size_t retval_len;
|
||||
ms_out_msg_exchange_t *ms;
|
||||
if(!out_buff)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
ms = (ms_out_msg_exchange_t *)out_buff;
|
||||
retval_len = ms->retval_len;
|
||||
*retval = (char*)malloc(retval_len);
|
||||
if(!*retval)
|
||||
return MALLOC_ERROR;
|
||||
|
||||
memcpy(*retval, ms->ret_outparam_buff, retval_len);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t unmarshal_input_parameters_e1_foo1(external_param_struct_t *pstruct, ms_in_msg_exchange_t* ms)
|
||||
{
|
||||
char* buff;
|
||||
size_t len;
|
||||
if(!pstruct || !ms)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
|
||||
buff = ms->inparam_buff;
|
||||
len = ms->inparam_buff_len;
|
||||
if(len != (sizeof(pstruct->var1)+sizeof(pstruct->var2)+sizeof(pstruct->p_internal_struct->ivar1)+sizeof(pstruct->p_internal_struct->ivar2)))
|
||||
return ATTESTATION_ERROR;
|
||||
|
||||
memcpy(&pstruct->var1, buff, sizeof(pstruct->var1));
|
||||
memcpy(&pstruct->var2, buff + sizeof(pstruct->var1), sizeof(pstruct->var2));
|
||||
memcpy(&pstruct->p_internal_struct->ivar1, buff+(sizeof(pstruct->var1)+sizeof(pstruct->var2)), sizeof(pstruct->p_internal_struct->ivar1));
|
||||
memcpy(&pstruct->p_internal_struct->ivar2, buff+(sizeof(pstruct->var1)+sizeof(pstruct->var2)+sizeof(pstruct->p_internal_struct->ivar1)), sizeof(pstruct->p_internal_struct->ivar2));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t marshal_retval_and_output_parameters_e1_foo1(char** resp_buffer, size_t* resp_length, uint32_t retval, external_param_struct_t *p_struct_var, size_t len_data, size_t len_ptr_data)
|
||||
{
|
||||
ms_out_msg_exchange_t *ms;
|
||||
size_t param_len, ms_len, ret_param_len;;
|
||||
char *temp_buff;
|
||||
int* addr;
|
||||
char* struct_data;
|
||||
size_t retval_len;
|
||||
|
||||
if(!resp_length || !p_struct_var)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
|
||||
retval_len = sizeof(retval);
|
||||
struct_data = (char*)p_struct_var;
|
||||
param_len = len_data + len_ptr_data;
|
||||
ret_param_len = param_len + retval_len;
|
||||
addr = *(int **)(struct_data + len_data);
|
||||
temp_buff = (char*)malloc(ret_param_len);
|
||||
if(!temp_buff)
|
||||
return MALLOC_ERROR;
|
||||
|
||||
memcpy(temp_buff, &retval, sizeof(retval));
|
||||
memcpy(temp_buff + sizeof(retval), struct_data, len_data);
|
||||
memcpy(temp_buff + sizeof(retval) + len_data, addr, len_ptr_data);
|
||||
ms_len = sizeof(ms_out_msg_exchange_t) + ret_param_len;
|
||||
ms = (ms_out_msg_exchange_t *)malloc(ms_len);
|
||||
if(!ms)
|
||||
{
|
||||
SAFE_FREE(temp_buff);
|
||||
return MALLOC_ERROR;
|
||||
}
|
||||
ms->retval_len = (uint32_t)retval_len;
|
||||
ms->ret_outparam_buff_len = (uint32_t)ret_param_len;
|
||||
memcpy(&ms->ret_outparam_buff, temp_buff, ret_param_len);
|
||||
*resp_buffer = (char*)ms;
|
||||
*resp_length = ms_len;
|
||||
|
||||
SAFE_FREE(temp_buff);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t marshal_message_exchange_request(uint32_t target_fn_id, uint32_t msg_type, uint32_t secret_data, char** marshalled_buff, size_t* marshalled_buff_len)
|
||||
{
|
||||
ms_in_msg_exchange_t *ms;
|
||||
size_t secret_data_len, ms_len;
|
||||
if(!marshalled_buff_len)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
secret_data_len = sizeof(secret_data);
|
||||
ms_len = sizeof(ms_in_msg_exchange_t) + secret_data_len;
|
||||
ms = (ms_in_msg_exchange_t *)malloc(ms_len);
|
||||
if(!ms)
|
||||
return MALLOC_ERROR;
|
||||
|
||||
ms->msg_type = msg_type;
|
||||
ms->target_fn_id = target_fn_id;
|
||||
ms->inparam_buff_len = (uint32_t)secret_data_len;
|
||||
memcpy(&ms->inparam_buff, &secret_data, secret_data_len);
|
||||
*marshalled_buff = (char*)ms;
|
||||
*marshalled_buff_len = ms_len;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t umarshal_message_exchange_request(uint32_t* inp_secret_data, ms_in_msg_exchange_t* ms)
|
||||
{
|
||||
char* buff;
|
||||
size_t len;
|
||||
if(!inp_secret_data || !ms)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
buff = ms->inparam_buff;
|
||||
len = ms->inparam_buff_len;
|
||||
if(len != sizeof(uint32_t))
|
||||
return ATTESTATION_ERROR;
|
||||
|
||||
memcpy(inp_secret_data, buff, sizeof(uint32_t));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t marshal_message_exchange_response(char** resp_buffer, size_t* resp_length, uint32_t secret_response)
|
||||
{
|
||||
ms_out_msg_exchange_t *ms;
|
||||
size_t secret_response_len, ms_len;
|
||||
size_t retval_len, ret_param_len;
|
||||
if(!resp_length)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
secret_response_len = sizeof(secret_response);
|
||||
retval_len = secret_response_len;
|
||||
ret_param_len = secret_response_len;
|
||||
ms_len = sizeof(ms_out_msg_exchange_t) + ret_param_len;
|
||||
ms = (ms_out_msg_exchange_t *)malloc(ms_len);
|
||||
if(!ms)
|
||||
return MALLOC_ERROR;
|
||||
|
||||
ms->retval_len = (uint32_t)retval_len;
|
||||
ms->ret_outparam_buff_len = (uint32_t)ret_param_len;
|
||||
memcpy(&ms->ret_outparam_buff, &secret_response, secret_response_len);
|
||||
*resp_buffer = (char*)ms;
|
||||
*resp_length = ms_len;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t umarshal_message_exchange_response(char* out_buff, char** secret_response)
|
||||
{
|
||||
size_t retval_len;
|
||||
ms_out_msg_exchange_t *ms;
|
||||
if(!out_buff)
|
||||
return INVALID_PARAMETER_ERROR;
|
||||
ms = (ms_out_msg_exchange_t *)out_buff;
|
||||
retval_len = ms->retval_len;
|
||||
*secret_response = (char*)malloc(retval_len);
|
||||
if(!*secret_response)
|
||||
{
|
||||
return MALLOC_ERROR;
|
||||
}
|
||||
memcpy(*secret_response, ms->ret_outparam_buff, retval_len);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UTILITY_E1_H__
|
||||
#define UTILITY_E1_H__
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct _internal_param_struct_t
|
||||
{
|
||||
uint32_t ivar1;
|
||||
uint32_t ivar2;
|
||||
} internal_param_struct_t;
|
||||
|
||||
typedef struct _external_param_struct_t
|
||||
{
|
||||
uint32_t var1;
|
||||
uint32_t var2;
|
||||
internal_param_struct_t *p_internal_struct;
|
||||
} external_param_struct_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t marshal_input_parameters_e2_foo1(uint32_t target_fn_id, uint32_t msg_type, uint32_t var1, uint32_t var2, char** marshalled_buff, size_t* marshalled_buff_len);
|
||||
uint32_t unmarshal_retval_and_output_parameters_e2_foo1(char* out_buff, char** retval);
|
||||
uint32_t unmarshal_input_parameters_e1_foo1(external_param_struct_t *pstruct, ms_in_msg_exchange_t* ms);
|
||||
uint32_t marshal_retval_and_output_parameters_e1_foo1(char** resp_buffer, size_t* resp_length, uint32_t retval, external_param_struct_t *p_struct_var, size_t len_data, size_t len_ptr_data);
|
||||
uint32_t marshal_message_exchange_request(uint32_t target_fn_id, uint32_t msg_type, uint32_t secret_data, char** marshalled_buff, size_t* marshalled_buff_len);
|
||||
uint32_t umarshal_message_exchange_request(uint32_t* inp_secret_data, ms_in_msg_exchange_t* ms);
|
||||
uint32_t marshal_message_exchange_response(char** resp_buffer, size_t* resp_length, uint32_t secret_response);
|
||||
uint32_t umarshal_message_exchange_response(char* out_buff, char** secret_response);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
46
demos/local_attestation/Makefile
Normal file
46
demos/local_attestation/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
OPENSSL ?= $(CUR_DIR)/deps/openssl
|
||||
SGX_SDK ?= /opt/intel/sgxsdk
|
||||
|
||||
BIN_DIR := bin
|
||||
APP := $(BIN_DIR)/appinitiator
|
||||
SGX_MODE ?= HW
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
OCCLUM_LIB := /opt/occlum/build_sim/lib
|
||||
else
|
||||
OCCLUM_LIB := /opt/occlum/build/lib
|
||||
endif
|
||||
|
||||
occlum_=$(CUR_DIR)/../..
|
||||
|
||||
.PHONY: all build_src test clean
|
||||
|
||||
all: occlum_context
|
||||
|
||||
occlum_context: build_src
|
||||
@mkdir -p occlum_context
|
||||
@cd occlum_context && \
|
||||
occlum init && \
|
||||
cp $(CUR_DIR)/AppResponder/responder image/bin/ && \
|
||||
cp $(OPENSSL)/libcrypto.so.1.1 image/lib/ && \
|
||||
cp $(CUR_DIR)/DiffieHellmanLibrary/libecdh.so image/lib/ && \
|
||||
occlum build
|
||||
@cp -r occlum_context/.occlum .occlum
|
||||
|
||||
build_src:
|
||||
@$(MAKE) --no-print-directory -C DiffieHellmanLibrary
|
||||
@$(MAKE) --no-print-directory -C AppInitiator
|
||||
@$(MAKE) --no-print-directory -C AppResponder
|
||||
@$(MAKE) --no-print-directory -C EnclaveInitiator
|
||||
|
||||
test: build_src
|
||||
LD_LIBRARY_PATH=$(OCCLUM_LIB):$(SGX_SDK)/sdk_libs RUST_BACKTRACE=1 \
|
||||
./$(APP)
|
||||
|
||||
clean:
|
||||
@$(MAKE) --no-print-directory -C AppInitiator clean
|
||||
@$(MAKE) --no-print-directory -C AppResponder clean
|
||||
@$(MAKE) --no-print-directory -C EnclaveInitiator clean
|
||||
@$(MAKE) --no-print-directory -C DiffieHellmanLibrary clean
|
||||
@rm -rf .occlum occlum_context bin
|
38
demos/local_attestation/README.md
Normal file
38
demos/local_attestation/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Occlum Local Attestation Demo
|
||||
|
||||
This project demonstrates how an SGX SDK enclave can do local attestation with and establish a secure connection to an Occlum enclave, where a trusted app running upon the Occlum LibOS.
|
||||
|
||||
## Introduction
|
||||
|
||||
This project consists of four components:
|
||||
|
||||
1. **EnclaveInitiator**: an SGX SDK enclave that initiates requests for local attestation;
|
||||
2. **AppInitiator**: an untrusted app that hosts the enclave of EnclaveInitiator and sends the enclave's requests to a responder enclave through socket.
|
||||
3. **AppResponder**: a trusted socket server hosted by Occlum LibOS in another enclave, which responses to the requests initiated by EnclaveInitator and sent by AppInitiator;
|
||||
4. **DiffieHellmanLibrary**: a library used by AppResponder that implements an Attestation-based, Diffie-Hellman Key Exchange protocol.
|
||||
|
||||
## Interopability
|
||||
|
||||
To do local attestation and establish a secure channel between two enclaves, they must talk in the same protocol. The protocol chosen and implemented by Intel SGX SDK is an Attestation-based, Diffie-Hellman Key Exchange protocol, whose APIs are defined in `sgx_dh.h` and used by the local attestation demo shipped with Intel SGX SDK.
|
||||
|
||||
To achieve interoperability with SGX SDK-based enclaves, an Occlum enclave must also talk in this protocol. But apps hosted by Occlum LibOS do not and may not use Intel SGX SDK (at least directly), thus no access to the protocol APIs exposed in `sgx_dh.h`. To resolve this problem, we build DiffieHellmanLibrary, which provides the same set of APIs as `sgx_dh.h`. And to ensure the full compatibility with Intel SGX SDK, DiffieHellmanLibrary actually reuses the code of Intel SGX SDK as much as possible. This is why EnclaveInitiator and AppResponder can talk to and negotiate with each other.
|
||||
|
||||
## Local Attestation through Ioctls
|
||||
|
||||
In the same vein as remote attestation, Occlum LibOS itself only provides three minimal APIs regarding local attestation and leaves most of the work to the user space. The three APIs are exposed to the user space through ioctls on device `/dev/sgx`. We offer a user-space library (i.e., DiffieHellmanLibrary) to hide the low-level details of ioctls and provide a high-level, user-friendly APIs. This design achieves both the easy-of-use of high-level APIs and the flexibility of low-level APIs.
|
||||
|
||||
## How to Build and Run
|
||||
|
||||
**Step 1.** Get prerequisites
|
||||
```shell
|
||||
./download_src_and_build_deps.sh
|
||||
```
|
||||
which downloads some source code and build dependencies (e.g., OpenSSL).
|
||||
|
||||
**Step 2.** Build and run the demo
|
||||
```shell
|
||||
make
|
||||
make test
|
||||
```
|
||||
|
||||
To run the demo in the SGX simulation mode, do `export SGX_MODE=SIM` before running the commands above.
|
157
demos/local_attestation/buildenv.mk
Normal file
157
demos/local_attestation/buildenv.mk
Normal file
@ -0,0 +1,157 @@
|
||||
#
|
||||
# Copyright (C) 2011-2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Function : parent-dir
|
||||
# Arguments: 1: path
|
||||
# Returns : Parent dir or path of $1, with final separator removed.
|
||||
# -------------------------------------------------------------------
|
||||
parent-dir = $(patsubst %/,%,$(dir $(1:%/=%)))
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Macro : my-dir
|
||||
# Returns : the directory of the current Makefile
|
||||
# Usage : $(my-dir)
|
||||
# ------------------------------------------------------------------
|
||||
my-dir = $(realpath $(call parent-dir,$(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
ROOT_DIR := $(call my-dir)
|
||||
ifneq ($(words $(subst :, ,$(ROOT_DIR))), 1)
|
||||
$(error main directory cannot contain spaces nor colons)
|
||||
endif
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# User needs to install SGX SDK installer before compiling this project.
|
||||
# -------------------------------------------------------------------
|
||||
ifeq ($(SGX_SDK),)
|
||||
$(warning "import SGX SDK environment variable")
|
||||
export SGX_SDK=/opt/intel/sgxsdk/
|
||||
endif
|
||||
|
||||
SGX_SDK_PATH ?= $(SGX_SDK)
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# This is the output folder.
|
||||
#-------------------------------------------------------------------
|
||||
BIN_DIR := bin
|
||||
TOPDIR = $(ROOT_DIR)
|
||||
OUTDIR := $(BIN_DIR)
|
||||
|
||||
CP = cp
|
||||
CC ?= gcc
|
||||
CXX ?= g++
|
||||
|
||||
# turn on cet
|
||||
CC_GREAT_EQUAL_8 := $(shell expr "`$(CC) -dumpversion`" \>= "8")
|
||||
ifeq ($(CC_GREAT_EQUAL_8), 1)
|
||||
COMMON_FLAGS += -fcf-protection
|
||||
endif
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Define common variables
|
||||
# ------------------------------------------------------------------
|
||||
SGX_MODE ?= HW
|
||||
SGX_ARCH ?= x64
|
||||
SGX_DEBUG ?= 1
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Define common compile flags used for GCC and G++
|
||||
#-------------------------------------------------------------------
|
||||
COMMON_FLAGS = -ffunction-sections -fdata-sections
|
||||
|
||||
COMMON_FLAGS += -Wall -Wextra -Wchar-subscripts -Wno-coverage-mismatch -Winit-self \
|
||||
-Wpointer-arith -Wreturn-type -Waddress -Wsequence-point -Wformat-security \
|
||||
-Wmissing-include-dirs -Wfloat-equal -Wundef -Wshadow \
|
||||
-Wcast-align -Wconversion -Wredundant-decls
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
ifeq ($(SGX_PRERELEASE), 1)
|
||||
$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
COMMON_FLAGS += -ggdb -DDEBUG
|
||||
COMMON_FLAGS += -DDEBUG_LEVEL=TRACE_DEBUG
|
||||
else
|
||||
COMMON_FLAGS += -o2 -UDEBUG
|
||||
endif
|
||||
|
||||
CFLAGS = $(COMMON_FLAGS)
|
||||
CXXFLAGS = $(COMMON_FLAGS)
|
||||
|
||||
# additional warnings flags for C
|
||||
CFLAGS += -Wjump-misses-init -Wstrict-prototypes -Wunsuffixed-float-constants
|
||||
|
||||
# additional warnings flags for C++
|
||||
CXXFLAGS += -Wnon-virtual-dtor -std=c++11
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Define common link options
|
||||
# ----------------------------------------------------------------
|
||||
COMMON_LDFLAGS := -Wl,-z,relro,-z,now,-z,noexecstack
|
||||
|
||||
# Compiler and linker options for an Enclave
|
||||
#
|
||||
# We are using '--export-dynamic' so that `g_global_data_sim' etc.
|
||||
# will be exported to dynamic symbol table.
|
||||
#
|
||||
# When `pie' is enabled, the linker (both BFD and Gold) under Ubuntu 14.04
|
||||
# will hide all symbols from dynamic symbol table even if they are marked
|
||||
# as `global' in the LD version script.
|
||||
ENCLAVE_CFLAGS = -ffreestanding -nostdinc -fvisibility=hidden -fpie
|
||||
ifeq ($(CC_GREAT_EQUAL_8), 1)
|
||||
ENCLAVE_CFLAGS += -fcf-protection
|
||||
endif
|
||||
ENCLAVE_CXXFLAGS = $(ENCLAVE_CFLAGS) -nostdinc++
|
||||
ENCLAVE_LDFLAGS = $(COMMON_LDFLAGS)
|
||||
|
||||
RM = rm -f
|
||||
|
||||
ifeq ($(shell getconf LONG_BIT), 32)
|
||||
SGX_ARCH := x86
|
||||
else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
|
||||
SGX_ARCH := x86
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_ARCH), x86)
|
||||
SGX_COMMON_FLAGS := -m32
|
||||
SGX_LIBRARY_PATH := $(SGX_SDK)/lib
|
||||
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
|
||||
SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
|
||||
else
|
||||
SGX_COMMON_FLAGS := -m64
|
||||
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
|
||||
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
|
||||
SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
|
||||
endif
|
||||
|
||||
SGX_COMMON_FLAGS += $(COMMON_FLAGS)
|
85
demos/local_attestation/download_src_and_build_deps.sh
Executable file
85
demos/local_attestation/download_src_and_build_deps.sh
Executable file
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export CC=occlum-gcc
|
||||
export CXX=occlum-g++
|
||||
|
||||
THISDIR="$(dirname $(readlink -f $0))"
|
||||
INSTALLDIR="/usr/local/occlum/x86_64-linux-musl"
|
||||
DEPSDIR="$THISDIR/deps"
|
||||
TARGET_SO="$DEPSDIR/openssl/libcrypto.so"
|
||||
|
||||
mkdir -p $DEPSDIR || exit 1
|
||||
|
||||
# Download OpenSSL 1.1.1
|
||||
OPENSSLDIR="${DEPSDIR}/openssl"
|
||||
if [ ! -d "$OPENSSLDIR" ] ; then
|
||||
echo "Downloading openssl ..."
|
||||
cd "$DEPSDIR" && \
|
||||
wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1.tar.gz && \
|
||||
tar -xvzf OpenSSL_1_1_1.tar.gz && \
|
||||
mv openssl-OpenSSL_1_1_1 openssl && \
|
||||
echo "Download openssl successfully" || exit 1
|
||||
else
|
||||
echo "The openssl code is already existent"
|
||||
fi
|
||||
|
||||
# Build openssl
|
||||
if [ ! -f "$TARGET_SO" ] ; then
|
||||
echo "Building openssl ..."
|
||||
cd "$OPENSSLDIR" && \
|
||||
CC=occlum-gcc ./config \
|
||||
--prefix=$INSTALLDIR \
|
||||
--openssldir=/usr/local/occlum/ssl \
|
||||
--with-rand-seed=rdcpu \
|
||||
no-zlib no-async no-tests && \
|
||||
make -j${nproc} && \
|
||||
echo "Build openssl successfully" || exit 1
|
||||
else
|
||||
echo "The openssl library is aleady existent"
|
||||
fi
|
||||
|
||||
SGX_VER=2.8
|
||||
# Download SGX SDK
|
||||
SGX_SDK="${DEPSDIR}/linux-sgx-sdk"
|
||||
if [ ! -d "$SGX_SDK" ] ; then
|
||||
echo "Downloading linux-sgx-sdk ..."
|
||||
cd "$DEPSDIR" && \
|
||||
wget https://github.com/intel/linux-sgx/archive/sgx_$SGX_VER.tar.gz && \
|
||||
tar -xvzf "sgx_$(SGX_VER).tar.gz" && \
|
||||
mv linux-sgx-sgx_$SGX_VER linux-sgx-sdk && \
|
||||
echo "Download sgx-sdk successfully" || exit 1
|
||||
else
|
||||
echo "The sgx-sdk code is already existent"
|
||||
fi
|
||||
|
||||
# Copy files to DiffieHellmanLibrary dir
|
||||
DH_DIR=$THISDIR/DiffieHellmanLibrary
|
||||
DH_PATCH=DiffieHellmanLibrary.patch
|
||||
mkdir -p $DH_DIR/include
|
||||
|
||||
cp $SGX_SDK/{sdk/ec_dh_lib/sgx_dh_internal.h,\
|
||||
common/inc/internal/ecp_interface.h,\
|
||||
common/inc/internal/ssl_wrapper.h\
|
||||
} $DH_DIR/include
|
||||
|
||||
cp $SGX_SDK/{psw/ae/aesm_service/source/utils/crypto_aes_gcm.cpp,\
|
||||
sdk/ec_dh_lib/ec_dh.cpp,\
|
||||
sdk/tlibcrypto/sgxssl/sgx_cmac128.cpp,\
|
||||
sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp,\
|
||||
sdk/tlibcrypto/sgxssl/sgx_sha256_msg.cpp\
|
||||
} $DH_DIR
|
||||
|
||||
cd $DH_DIR && git apply $DH_PATCH >/dev/null 2>&1 || git apply $DH_PATCH -R --check
|
||||
cd - >/dev/null 2>&1
|
||||
|
||||
echo "DiffieHellmanLibrary is ready"
|
||||
|
||||
# Copy header files from linux-sgx-sdk local attestation demo
|
||||
mkdir -p Include
|
||||
cp $SGX_SDK/SampleCode/LocalAttestation/Include/{datatypes.h,\
|
||||
dh_session_protocol.h,\
|
||||
error_codes.h,\
|
||||
fifo_def.h\
|
||||
} Include
|
||||
|
||||
echo "Include is ready"
|
@ -163,7 +163,7 @@ static int do_SGXIOC_CREATE_AND_VERIFY_REPORT(int sgx_fd) {
|
||||
if (ioctl(sgx_fd, SGXIOC_SELF_TARGET, &target_info) < 0) {
|
||||
THROW_ERROR("failed to ioctl /dev/sgx");
|
||||
}
|
||||
sgx_report_t report_data;
|
||||
sgx_report_data_t report_data;
|
||||
sgx_report_t report;
|
||||
|
||||
sgxioc_create_report_arg_t args[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user