Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/lf-lang/reactor-c into encl…
Browse files Browse the repository at this point in the history
…aves2
  • Loading branch information
erlingrj committed Jul 13, 2023
2 parents 3cb0c24 + df0f4a5 commit 804f25a
Show file tree
Hide file tree
Showing 12 changed files with 272 additions and 501 deletions.
110 changes: 54 additions & 56 deletions core/federated/RTI/rti_remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,11 @@ lf_mutex_t rti_mutex;
lf_cond_t received_start_times;
lf_cond_t sent_start_time;

/**
* Enter a critical section where logical time and the event queue are guaranteed
* to not change unless they are changed within the critical section.
* this can be implemented by disabling interrupts.
* Users of this function must ensure that lf_init_critical_sections() is
* called first and that lf_critical_section_exit() is called later.
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_enter() {
extern int lf_critical_section_enter(environment_t* env) {
return lf_mutex_lock(&rti_mutex);
}

/**
* Exit the critical section entered with lf_lock_time().
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_exit() {
extern int lf_critical_section_exit(environment_t* env) {
return lf_mutex_unlock(&rti_mutex);
}

Expand Down Expand Up @@ -315,7 +303,7 @@ void handle_port_absent_message(federate_info_t* sending_federate, unsigned char
tag_t tag = extract_tag(&(buffer[1 + 2 * sizeof(uint16_t)]));

if (rti_remote->base.tracing_enabled) {
tracepoint_rti_from_federate(rti_remote->base.trace, receive_PORT_ABS, federate_id, &tag);
tracepoint_rti_from_federate(rti_remote->base.trace, receive_PORT_ABS, sending_federate->enclave.id, &tag);
}

// Need to acquire the mutex lock to ensure that the thread handling
Expand Down Expand Up @@ -1388,57 +1376,67 @@ int receive_udp_message_and_set_up_clock_sync(int socket_id, uint16_t fed_id) {

#ifdef __RTI_AUTH__
bool authenticate_federate(int socket) {
// Buffer for message type and federation RTI nonce.
size_t message_length = 1 + NONCE_LENGTH;
unsigned char rti_hello_buffer[message_length];
rti_hello_buffer[0] = MSG_TYPE_RTI_NONCE;
unsigned char rti_nonce[NONCE_LENGTH];
RAND_bytes(rti_nonce, NONCE_LENGTH);
memcpy(rti_hello_buffer + 1, rti_nonce, NONCE_LENGTH);
// Send RTI hello with RTI's random nonce.
write_to_socket(socket, message_length, rti_hello_buffer);

// Check HMAC of received FED_RESPONSE message.
// Wait for MSG_TYPE_FED_NONCE from federate.
size_t fed_id_length = sizeof(uint16_t);
unsigned char buffer[1 + fed_id_length + NONCE_LENGTH];
read_from_socket_errexit(socket, 1 + fed_id_length + NONCE_LENGTH, buffer,
"Failed to read MSG_TYPE_FED_NONCE");
if (buffer[0] != MSG_TYPE_FED_NONCE) {
lf_print_error_and_exit(
"Received unexpected response %u from the FED (see net_common.h).",
buffer[0]);
}
unsigned int hmac_length = SHA256_HMAC_LENGTH;
size_t federation_id_length = strnlen(rti_remote->federation_id, 255);
size_t fed_id_length = sizeof(uint16_t);

unsigned char received[1 + NONCE_LENGTH + fed_id_length + hmac_length];
read_from_socket_errexit(socket, 1 + NONCE_LENGTH + fed_id_length + hmac_length, received, "Failed to read RTI response.");
// HMAC tag is created with MSG_TYPE, federate ID, received federate nonce.
unsigned char mac_buf[1 + fed_id_length + NONCE_LENGTH];
mac_buf[0] = MSG_TYPE_RTI_RESPONSE;
memcpy(&mac_buf[1], &buffer[1], fed_id_length);
memcpy(&mac_buf[1 + fed_id_length], &buffer[1 + fed_id_length], NONCE_LENGTH);
unsigned char hmac_tag[hmac_length];
unsigned char * ret = HMAC(EVP_sha256(), rti_remote->federation_id,
federation_id_length, mac_buf, 1 + fed_id_length + NONCE_LENGTH,
hmac_tag, &hmac_length);
if (ret == NULL) {
lf_print_error_and_exit("HMAC construction failed for MSG_TYPE_RTI_RESPONSE.");
}
// Make buffer for message type, RTI's nonce, and HMAC tag.
unsigned char sender[1 + NONCE_LENGTH + hmac_length];
sender[0] = MSG_TYPE_RTI_RESPONSE;
unsigned char rti_nonce[NONCE_LENGTH];
RAND_bytes(rti_nonce, NONCE_LENGTH);
memcpy(&sender[1], rti_nonce, NONCE_LENGTH);
memcpy(&sender[1 + NONCE_LENGTH], hmac_tag, hmac_length);
write_to_socket(socket, 1 + NONCE_LENGTH + hmac_length, sender);

// Wait for MSG_TYPE_FED_RESPONSE
unsigned char received[1 + hmac_length];
read_from_socket_errexit(socket, 1 + hmac_length, received,
"Failed to read federate response.");
if (received[0] != MSG_TYPE_FED_RESPONSE) {
lf_print_error("Received unexpected response %u from the FED (see net_common.h).",
received[0]);
lf_print_error_and_exit(
"Received unexpected response %u from the federate (see net_common.h).",
received[0]);
return false;
}

// Create tag to compare to received tag.
unsigned char buf_to_check[1 + fed_id_length + NONCE_LENGTH];
buf_to_check[0] = MSG_TYPE_FED_RESPONSE;
memcpy(&buf_to_check[1], &received[1 + NONCE_LENGTH], fed_id_length);
memcpy(&buf_to_check[1 + fed_id_length], rti_nonce, NONCE_LENGTH);
// HMAC tag is created with MSG_TYPE_FED_RESPONSE and RTI's nonce.
unsigned char mac_buf2[1 + NONCE_LENGTH];
mac_buf2[0] = MSG_TYPE_FED_RESPONSE;
memcpy(&mac_buf2[1], rti_nonce, NONCE_LENGTH);
unsigned char rti_tag[hmac_length];
HMAC(EVP_sha256(), rti_remote->federation_id, federation_id_length, buf_to_check, 1 + fed_id_length + NONCE_LENGTH,
rti_tag, &hmac_length);

ret = HMAC(EVP_sha256(), rti_remote->federation_id, federation_id_length,
mac_buf2, 1 + NONCE_LENGTH, rti_tag, &hmac_length);
if (ret == NULL) {
lf_print_error_and_exit("HMAC construction failed for MSG_TYPE_FED_RESPONSE.");
}
// Compare received tag and created tag.
if (memcmp(&received[1 + fed_id_length + NONCE_LENGTH], rti_tag, hmac_length) != 0) {
if (memcmp(&received[1], rti_tag, hmac_length) != 0) {
// Federation IDs do not match. Send back a HMAC_DOES_NOT_MATCH message.
lf_print_warning("HMAC authentication failed. Rejecting the federate.");
send_reject(socket, HMAC_DOES_NOT_MATCH);
return false;
}
else{
LF_PRINT_LOG("HMAC verified.");
// HMAC tag is created with MSG_TYPE and received federate nonce.
unsigned char mac_buf[1 + NONCE_LENGTH];
mac_buf[0] = MSG_TYPE_RTI_RESPONSE;
memcpy(&mac_buf[1], &received[1], NONCE_LENGTH);
// Buffer for message type and HMAC tag.
unsigned char sender[1 + hmac_length];
sender[0] = MSG_TYPE_RTI_RESPONSE;
HMAC(EVP_sha256(), rti_remote->federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH,
&sender[1], &hmac_length);
write_to_socket(socket, 1 + hmac_length, sender);
} else {
LF_PRINT_LOG("Federate's HMAC verified.");
return true;
}
}
Expand All @@ -1465,7 +1463,7 @@ void connect_to_federates(int socket_descriptor) {
}
}

// Send RTI hello when RTI -a option is on.
// Wait for the first message from the federate when RTI -a option is on.
#ifdef __RTI_AUTH__
if (rti_remote->authentication_enabled) {
if (!authenticate_federate(socket_id)) {
Expand Down
6 changes: 4 additions & 2 deletions core/federated/RTI/rti_remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,17 @@ typedef struct rti_remote_t {
* this can be implemented by disabling interrupts.
* Users of this function must ensure that lf_init_critical_sections() is
* called first and that lf_critical_section_exit() is called later.
* @param env Ignored (present for compatibility).
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_enter();
extern int lf_critical_section_enter(environment_t* env);

/**
* Exit the critical section entered with lf_lock_time().
* @param env Ignored (present for compatibility).
* @return 0 on success, platform-specific error number otherwise.
*/
extern int lf_critical_section_exit();
extern int lf_critical_section_exit(environment_t* env);

/**
* Create a server and enable listening for socket connections.
Expand Down
96 changes: 41 additions & 55 deletions core/federated/federate.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,65 +914,40 @@ void connect_to_federate(uint16_t remote_federate_id) {
* @param rti_socket TCP socket for connection with the RTI.
*/
void perform_hmac_authentication(int rti_socket) {
unsigned char buffer[1 + NONCE_LENGTH];
read_from_socket_errexit(rti_socket, 1 + NONCE_LENGTH, buffer,
"Failed to read RTI hello.");
if (buffer[0] != MSG_TYPE_RTI_NONCE) {
lf_print_error_and_exit(
"Received unexpected response %u from the RTI (see net_common.h).",
buffer[0]);
}

// Send buffer including message type, federate ID, federate's nonce.
size_t fed_id_length = sizeof(uint16_t);
size_t message_length = 1 + fed_id_length + NONCE_LENGTH;
unsigned char fed_hello_buf[message_length];
fed_hello_buf[0] = MSG_TYPE_FED_NONCE;
encode_uint16((uint16_t)_lf_my_fed_id, &fed_hello_buf[1]);
unsigned char fed_nonce[NONCE_LENGTH];
RAND_bytes(fed_nonce, NONCE_LENGTH);
memcpy(&fed_hello_buf[1 + fed_id_length], fed_nonce, NONCE_LENGTH);
write_to_socket(rti_socket, message_length, fed_hello_buf);

// Check HMAC of received FED_RESPONSE message.
unsigned int hmac_length = SHA256_HMAC_LENGTH;
size_t federation_id_length = strnlen(federation_metadata.federation_id, 255);
// HMAC tag is created with MSG_TYPE, federate ID, received rti nonce.
unsigned char mac_buf[1 + sizeof(uint16_t) + NONCE_LENGTH];
mac_buf[0] = MSG_TYPE_FED_RESPONSE;
encode_uint16((uint16_t)_lf_my_fed_id, &mac_buf[1]);
memcpy(&mac_buf[1 + sizeof(uint16_t)], &buffer[1], NONCE_LENGTH);
unsigned char hmac_tag[hmac_length];
unsigned char * ret = HMAC(EVP_sha256(), federation_metadata.federation_id,
federation_id_length, mac_buf, 1 + sizeof(uint16_t) + NONCE_LENGTH,
hmac_tag, &hmac_length);
if (ret == NULL) {
lf_print_error_and_exit("HMAC failure for MSG_TYPE_FED_RESPONSE.");
}

// Buffer for message type, federate's nonce, federate ID, and HMAC tag.
unsigned char sender[1 + NONCE_LENGTH + sizeof(uint16_t) + hmac_length];
sender[0] = MSG_TYPE_FED_RESPONSE;
unsigned char federate_nonce[NONCE_LENGTH];
RAND_bytes(federate_nonce, NONCE_LENGTH);
int num_bytes = 1;
memcpy(&sender[num_bytes], federate_nonce, NONCE_LENGTH);
num_bytes += NONCE_LENGTH;
encode_uint16((uint16_t)_lf_my_fed_id, &sender[num_bytes]);
num_bytes += sizeof(uint16_t);
memcpy(&sender[num_bytes], hmac_tag, hmac_length);
num_bytes += hmac_length;
write_to_socket(rti_socket, num_bytes, sender);

// Received MSG_TYPE_RTI_RESPONSE
unsigned char received[1 + hmac_length];
read_from_socket_errexit(rti_socket, 1 + hmac_length, received,
"Failed to read RTI response.");

unsigned char received[1 + NONCE_LENGTH + hmac_length];
read_from_socket_errexit(rti_socket, 1 + NONCE_LENGTH + hmac_length, received, "Failed to read RTI response.");
if (received[0] != MSG_TYPE_RTI_RESPONSE) {
lf_print_error_and_exit(
"Received unexpected response %u from the RTI (see net_common.h).",
received[0]);
}
// HMAC tag is created with MSG_TYPE and federate nonce.
unsigned char mac_buf2[1 + NONCE_LENGTH];
mac_buf2[0] = MSG_TYPE_RTI_RESPONSE;
memcpy(&mac_buf2[1], federate_nonce, NONCE_LENGTH);
lf_print_error("Received unexpected response %u from the RTI (see net_common.h).",
received[0]);
}
// Create tag to compare to received tag.
unsigned char buf_to_check[1 + fed_id_length + NONCE_LENGTH];
buf_to_check[0] = MSG_TYPE_RTI_RESPONSE;
encode_uint16((uint16_t)_lf_my_fed_id, &buf_to_check[1]);
memcpy(&buf_to_check[1 + fed_id_length], fed_nonce, NONCE_LENGTH);
unsigned char fed_tag[hmac_length];
ret = HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length,
mac_buf2, 1 + NONCE_LENGTH, fed_tag, &hmac_length);
if (ret == NULL) {
lf_print_error_and_exit("HMAC failure for MSG_TYPE_RTI_RESPONSE.");
}
HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, buf_to_check, 1 + fed_id_length + NONCE_LENGTH,
fed_tag, &hmac_length);

// Compare received tag and created tag.
if (memcmp(&received[1], fed_tag, hmac_length) != 0) {
// Federation IDs do not match. Send back a MSG_TYPE_REJECT message.
if (memcmp(&received[1 + NONCE_LENGTH], fed_tag, hmac_length) != 0) {
// HMAC does not match. Send back a MSG_TYPE_REJECT message.
lf_print_error("HMAC authentication failed.");
unsigned char response[2];
response[0] = MSG_TYPE_REJECT;
Expand All @@ -981,8 +956,19 @@ void perform_hmac_authentication(int rti_socket) {
rti_socket, 2, response,
"Federate failed to write MSG_TYPE_REJECT message on the socket.");
close(rti_socket);
} else {
}
else {
LF_PRINT_LOG("HMAC verified.");
// HMAC tag is created with MSG_TYPE_FED_RESPONSE and received federate nonce.
unsigned char mac_buf[1 + NONCE_LENGTH];
mac_buf[0] = MSG_TYPE_FED_RESPONSE;
memcpy(&mac_buf[1], &received[1], NONCE_LENGTH);
// Buffer for message type and HMAC tag.
unsigned char sender[1 + hmac_length];
sender[0] = MSG_TYPE_FED_RESPONSE;
HMAC(EVP_sha256(), federation_metadata.federation_id, federation_id_length, mac_buf, 1 + NONCE_LENGTH,
&sender[1], &hmac_length);
write_to_socket(rti_socket, 1 + hmac_length, sender);
}
}
#endif
Expand Down
Loading

0 comments on commit 804f25a

Please sign in to comment.