occlum/demos/local_attestation/AppResponder/session.c
2023-04-18 13:12:37 +08:00

179 lines
5.8 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 corresponding 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 {
//Retrieve 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;
}