Skip to content

Conversation

@yaelhoma
Copy link

Adds random number exchange to handshake protocol integrated with all sec-types.

@yaelhoma yaelhoma force-pushed the handshake_security branch 3 times, most recently from 62160ef to af8eccb Compare September 26, 2025 22:03
uint64_t rand_num, uuid_num;

//random number file
FILE *random_file = fopen("/dev/random", "r");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest using linux's getrandom() call (which wraps reading of /dev/urandom), which looks to be the preferred way to do this.

fclose(uuid_file);
return -1;
}
if (fread(&uuid_num, sizeof(uuid_num), 1, uuid_file) != 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A) The /proc/sys/kernel/random/uuid file returns and ASCII encoded number, but this is reading it like a binary number.
B) If we're doing a read/fread of random data we need to handle the EINTR return codes

time_t now = time(NULL);

// Combine timestamp,random number, uuid
*unique_value = now ^ rand_num ^ uuid_num;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to xor the data together. We're essentially xor'ing a random number with a partially-random number with a non-random number. I don't think that produces anything interesting. The goal is to make a unique number. I think we could do that by concat'ing into 128 bits (or fill in multiple 64-bit fields) with a random number, session id, and a counter.

@yaelhoma yaelhoma force-pushed the handshake_security branch from 24d684c to e8201ab Compare October 3, 2025 19:50
static unsigned int saved_key_len;
static connection_info_t *saved_conninfo;
static int timeout_seconds = 0;
uint32_t local_global_countr = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a static variable: 'static uint32_t local_global_countr'
That keeps it scope limited to this file.

Also suggest a more descriptive name for what it does, i.e., unique_number_counter

/**
* Decrypt their packet with their random number
**/
debug_printf("Decrypting their random number packet\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading comment and printf. This is decrypting the main handshake packet (which does contain the initial random number). But it is not the random number packet, which this comment implies.


static int compare_packets(handshake_packet_t *expected_packet,
handshake_packet_t *recvd_packet)
static int compare_packets(handshake_packet_t *expected_packet, handshake_packet_t *recvd_packet,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's break this into two functions: compare_handshake_packets() and compare_random_number_packets().
Then compare_handshake_packets() after the first exchange, but before doing the random packet exchange.
Then compare_random_number_packets() after the random packet exchange.

Two reasons for this. A) It's a common occurrence for two different spindle sessions to connect to each other and realize they are the wrong sessions (the HSHAKE_DROP_CONNECTION test below). Let's get those dropped quickly before sending the other packets. B) No reason to be signing and sending those other packets when we can do an earlier test for common cases..

return_result = result;
goto done;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below about splitting up compare_packet(). The compare_handshake_packet() would go here.

//encrypt random number packet that they are expecting
random_number_packet.random_number = recvd_packet.random_number;
random_number_packet.signature = packet.signature;
result = encrypt_packet(hdata, &random_number_packet, sizeof(random_number_packet_t), &packet_buffer, &packet_buffer_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a memory leak on packet_buffer here. Before this commit packet_buffer was allocated and free'd once at the exit to this function. Now it's allocated twice and free'd once at the end of the function. It needs to be free'd before being passed to encryp_packet.

result = getrandom((void*) &rand_num->random_number,sizeof(rand_num->random_number),GRND_RANDOM|GRND_NONBLOCK);
if (result<0) {
local_errno = errno;
if (local_errno == EAGAIN){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to handle EINTR here.

Also we don't want EAGAIN to be a fatal error (nor EINTR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants