occlum/demos/local_attestation/AppResponder/session.c
2020-03-09 04:17:41 +00:00

196 lines
5.7 KiB
C

#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;
}