I'm trying to implement a virtual UART using socat command for send and receive a string that is encrypted using XOR cipher on sending and decrypted while receiving using C program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define BUFFER_SIZE 256
#define UART_DEVICE_TX "./ttyV0" // Transmit end
#define UART_DEVICE_RX "./ttyV1" // Receive end
// XOR cipher for encryption and decryption
void xor_cipher(char *data, size_t length, char key) {
for (size_t i = 0; i < length; ++i) {
data[i] ^= key;
}
}
// Configure the UART device
int configure_uart(const char *device) {
int uart_fd = open(device, O_RDWR | O_NOCTTY);
if (uart_fd < 0) {
perror("Failed to open UART device");
return -1;
}
struct termios options;
tcgetattr(uart_fd, &options);
// Set baud rate to 9600, 8 data bits, no parity, 1 stop bit
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
options.c_cflag = (options.c_cflag & ~CSIZE) | CS8; // 8 data bits
options.c_cflag |= (CLOCAL | CREAD); // Enable receiver
options.c_cflag &= ~(PARENB | CSTOPB); // No parity, 1 stop bit
options.c_iflag &= ~(IXON | IXOFF | IXANY); // Disable flow control
options.c_lflag = 0; // Raw input mode
options.c_oflag = 0; // Raw output mode
tcsetattr(uart_fd, TCSANOW, &options);
return uart_fd;
}
int main() {
const char key = 0x5A; // XOR encryption key
char original_message[] = "Hello, UART!"; // Original message
char encrypted_message[BUFFER_SIZE];
char received_message[BUFFER_SIZE];
printf("Original message: %s\n", original_message);
// Copy the original message and encrypt it
strcpy(encrypted_message, original_message);
xor_cipher(encrypted_message, strlen(encrypted_message), key);
// Configure UART devices
int uart_fd_tx = configure_uart(UART_DEVICE_TX); // Transmit end
int uart_fd_rx = configure_uart(UART_DEVICE_RX); // Receive end
if (uart_fd_tx < 0 || uart_fd_rx < 0) {
return EXIT_FAILURE;
}
// Send the encrypted message to the TX port (master)
write(uart_fd_tx, encrypted_message, strlen(encrypted_message));
printf("Encrypted message sent: %s\n", encrypted_message);
// Receive the encrypted message from the RX port (slave)
memset(received_message, 0, BUFFER_SIZE);
int bytes_read = read(uart_fd_rx, received_message, BUFFER_SIZE - 1);
if (bytes_read < 0) {
perror("Failed to read from UART device");
close(uart_fd_tx);
close(uart_fd_rx);
return EXIT_FAILURE;
}
// Decrypt the received message
xor_cipher(received_message, bytes_read, key);
printf("Decrypted message: %s\n", received_message);
// Check if the original and decrypted messages match
if (strcmp(original_message, received_message) == 0) {
printf("Decryption successful: Messages match.\n");
} else {
printf("Decryption failed: Messages do not match.\n");
}
// Clean up
close(uart_fd_tx);
close(uart_fd_rx);
return EXIT_SUCCESS;
}
for creating virtual uart driver in the working directory i used this command:
socat -d -d PTY,link=./ttyV0,raw,echo=0 PTY,link=./ttyV1,raw,echo=0
after compilation and running the c file the encryption parting running and iam getting the encrypted data on tty1(cat ./ttyV1
)
but the decryption part is not working.. i need help to figure this out.
when i tried without looking on the devices its working fine
Original message: Hello, UART!
Encrypted message sent: ?665vz
Encrypted message received: ?665vz
Decrypted message: Hello, UART!
Decryption successful: Messages match.
when i start cat ./ttyV1 in one terminal and run the program it will display like this
Original message: Hello, UART!
Encrypted message sent: ?665vz
not doing the decryption part
but the key can be seen in the other terminal that runs cat ./ttyV1
why this happening?
When an open TTY receives data, it is held in a buffer until it has been read by one of the processes that has the TTY open. Once it has been read by a process (or thread), it is discarded and is no longer available for the other processes (or threads) to read. The same thing happens if multiple processes are trying to read from the receive end of a pipe, FIFO (named pipe), or socket, whether or not the file descriptors are freshly opened, duplicated, or inherited.