Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a5aec7dce |
6
Makefile
6
Makefile
@@ -5,19 +5,17 @@ LIBS_STATIC = -static -lm
|
|||||||
TARGET = otp
|
TARGET = otp
|
||||||
SOURCE = otp.c
|
SOURCE = otp.c
|
||||||
CHACHA20_SOURCE = nostr_chacha20.c
|
CHACHA20_SOURCE = nostr_chacha20.c
|
||||||
VERSION_SOURCE = src/version.c
|
|
||||||
|
|
||||||
# Default build target
|
# Default build target
|
||||||
$(TARGET): $(SOURCE)
|
$(TARGET): $(SOURCE)
|
||||||
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(VERSION_SOURCE) $(LIBS)
|
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(LIBS)
|
||||||
|
|
||||||
# Static linking target
|
# Static linking target
|
||||||
static: $(SOURCE)
|
static: $(SOURCE)
|
||||||
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(VERSION_SOURCE) $(LIBS_STATIC)
|
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(LIBS_STATIC)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGET) *.pad *.state
|
rm -f $(TARGET) *.pad *.state
|
||||||
rm -f src/version.h src/version.c VERSION
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
sudo cp $(TARGET) /usr/local/bin/
|
sudo cp $(TARGET) /usr/local/bin/
|
||||||
|
|||||||
244
otp.c
244
otp.c
@@ -13,7 +13,6 @@
|
|||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "src/version.h"
|
|
||||||
#include "nostr_chacha20.h"
|
#include "nostr_chacha20.h"
|
||||||
|
|
||||||
// Custom base64 character set
|
// Custom base64 character set
|
||||||
@@ -125,6 +124,12 @@ int add_entropy_to_pad(const char* pad_chksum, const unsigned char* entropy_data
|
|||||||
size_t entropy_size, int show_progress);
|
size_t entropy_size, int show_progress);
|
||||||
int handle_add_entropy_to_pad(const char* pad_chksum);
|
int handle_add_entropy_to_pad(const char* pad_chksum);
|
||||||
|
|
||||||
|
// Enhanced entropy system helper functions
|
||||||
|
int filter_unused_pads(char unused_pads[][65], int max_pads);
|
||||||
|
int update_pad_checksum_after_entropy(const char* old_chksum, char* new_chksum);
|
||||||
|
int rename_pad_files_safely(const char* old_chksum, const char* new_chksum);
|
||||||
|
int is_pad_unused(const char* pad_chksum);
|
||||||
|
|
||||||
// Directory management
|
// Directory management
|
||||||
int ensure_pads_directory(void);
|
int ensure_pads_directory(void);
|
||||||
void get_pad_path(const char* chksum, char* pad_path, char* state_path);
|
void get_pad_path(const char* chksum, char* pad_path, char* state_path);
|
||||||
@@ -450,7 +455,7 @@ int interactive_mode(void) {
|
|||||||
|
|
||||||
void show_main_menu(void) {
|
void show_main_menu(void) {
|
||||||
|
|
||||||
printf("\n\n\n\n=========================== Main Menu - OTP %s ===========================\n\n", get_version() );
|
printf("\n\n\n\n=========================== Main Menu - OTP v1.0.0 ===========================\n\n");
|
||||||
|
|
||||||
printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT
|
printf(" \033[4mT\033[0mext encrypt\n"); //TEXT ENCRYPT
|
||||||
printf(" \033[4mF\033[0mile encrypt\n"); //FILE ENCRYPT
|
printf(" \033[4mF\033[0mile encrypt\n"); //FILE ENCRYPT
|
||||||
@@ -1320,6 +1325,24 @@ int add_entropy_to_pad(const char* pad_chksum, const unsigned char* entropy_data
|
|||||||
printf("✓ Pad integrity maintained\n");
|
printf("✓ Pad integrity maintained\n");
|
||||||
printf("✓ %zu bytes of entropy distributed across entire pad\n", entropy_size);
|
printf("✓ %zu bytes of entropy distributed across entire pad\n", entropy_size);
|
||||||
printf("✓ Pad restored to read-only mode\n");
|
printf("✓ Pad restored to read-only mode\n");
|
||||||
|
|
||||||
|
// Update checksum after entropy addition
|
||||||
|
printf("\n🔄 Updating pad checksum...\n");
|
||||||
|
char new_chksum[65];
|
||||||
|
int checksum_result = update_pad_checksum_after_entropy(pad_chksum, new_chksum);
|
||||||
|
|
||||||
|
if (checksum_result == 0) {
|
||||||
|
printf("✓ Pad checksum updated successfully\n");
|
||||||
|
printf(" Old checksum: %.16s...\n", pad_chksum);
|
||||||
|
printf(" New checksum: %.16s...\n", new_chksum);
|
||||||
|
printf("✓ Pad files renamed to new checksum\n");
|
||||||
|
} else if (checksum_result == 2) {
|
||||||
|
printf("ℹ Checksum unchanged (unusual but not an error)\n");
|
||||||
|
} else {
|
||||||
|
printf("⚠ Warning: Checksum update failed (entropy was added successfully)\n");
|
||||||
|
printf(" You may need to manually handle the checksum update\n");
|
||||||
|
return 1; // Report error despite successful entropy addition
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2156,13 +2179,8 @@ int collect_entropy_with_feedback(unsigned char* entropy_buffer, size_t target_b
|
|||||||
state.unique_keys++;
|
state.unique_keys++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No key available, add timing entropy
|
// No key available, just sleep and wait for keystrokes
|
||||||
clock_gettime(CLOCK_MONOTONIC, ×tamp);
|
usleep(10000); // 10ms delay - wait for keystrokes, don't add timing entropy
|
||||||
if (state.collected_bytes + 12 < MAX_ENTROPY_BUFFER) {
|
|
||||||
memcpy(entropy_buffer + state.collected_bytes, ×tamp, 12);
|
|
||||||
state.collected_bytes += 12;
|
|
||||||
}
|
|
||||||
usleep(1000); // 1ms delay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-complete at target if enabled
|
// Auto-complete at target if enabled
|
||||||
@@ -2875,6 +2893,125 @@ int derive_chacha20_params(const unsigned char* entropy_data, size_t entropy_siz
|
|||||||
return 0; // Success
|
return 0; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enhanced entropy system helper functions
|
||||||
|
|
||||||
|
// Check if a pad is unused (0% usage)
|
||||||
|
int is_pad_unused(const char* pad_chksum) {
|
||||||
|
uint64_t used_bytes;
|
||||||
|
if (read_state_offset(pad_chksum, &used_bytes) != 0) {
|
||||||
|
return 0; // Error reading state, assume used
|
||||||
|
}
|
||||||
|
return (used_bytes <= 32); // Only reserved bytes used (32 bytes for checksum encryption)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter pads to only return unused ones
|
||||||
|
int filter_unused_pads(char unused_pads[][65], int max_pads) {
|
||||||
|
DIR* dir = opendir(current_pads_dir);
|
||||||
|
if (!dir) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent* entry;
|
||||||
|
int unused_count = 0;
|
||||||
|
|
||||||
|
while ((entry = readdir(dir)) != NULL && unused_count < max_pads) {
|
||||||
|
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) {
|
||||||
|
// Extract checksum from filename
|
||||||
|
char chksum[65];
|
||||||
|
strncpy(chksum, entry->d_name, 64);
|
||||||
|
chksum[64] = '\0';
|
||||||
|
|
||||||
|
// Check if pad is unused
|
||||||
|
if (is_pad_unused(chksum)) {
|
||||||
|
strcpy(unused_pads[unused_count], chksum);
|
||||||
|
unused_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
return unused_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safely rename pad files (pad and state) from old to new checksum
|
||||||
|
int rename_pad_files_safely(const char* old_chksum, const char* new_chksum) {
|
||||||
|
char old_pad_path[1024], new_pad_path[1024];
|
||||||
|
char old_state_path[1024], new_state_path[1024];
|
||||||
|
|
||||||
|
// Construct file paths
|
||||||
|
snprintf(old_pad_path, sizeof(old_pad_path), "%s/%s.pad", current_pads_dir, old_chksum);
|
||||||
|
snprintf(new_pad_path, sizeof(new_pad_path), "%s/%s.pad", current_pads_dir, new_chksum);
|
||||||
|
snprintf(old_state_path, sizeof(old_state_path), "%s/%s.state", current_pads_dir, old_chksum);
|
||||||
|
snprintf(new_state_path, sizeof(new_state_path), "%s/%s.state", current_pads_dir, new_chksum);
|
||||||
|
|
||||||
|
// Check if new files would conflict with existing files
|
||||||
|
if (access(new_pad_path, F_OK) == 0) {
|
||||||
|
printf("Error: New pad file already exists: %s\n", new_pad_path);
|
||||||
|
return 1; // Conflict
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename pad file
|
||||||
|
if (rename(old_pad_path, new_pad_path) != 0) {
|
||||||
|
printf("Error: Failed to rename pad file from %s to %s\n", old_pad_path, new_pad_path);
|
||||||
|
return 2; // Pad rename failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename state file (if it exists)
|
||||||
|
if (access(old_state_path, F_OK) == 0) {
|
||||||
|
if (rename(old_state_path, new_state_path) != 0) {
|
||||||
|
printf("Warning: Failed to rename state file, but pad file was renamed successfully\n");
|
||||||
|
// Try to rollback pad file rename
|
||||||
|
rename(new_pad_path, old_pad_path);
|
||||||
|
return 3; // State rename failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update pad checksum after entropy addition
|
||||||
|
int update_pad_checksum_after_entropy(const char* old_chksum, char* new_chksum) {
|
||||||
|
char pad_path[1024];
|
||||||
|
snprintf(pad_path, sizeof(pad_path), "%s/%s.pad", current_pads_dir, old_chksum);
|
||||||
|
|
||||||
|
// Calculate new checksum of the modified pad
|
||||||
|
if (calculate_checksum(pad_path, new_chksum) != 0) {
|
||||||
|
printf("Error: Cannot calculate new pad checksum\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if checksum actually changed
|
||||||
|
if (strcmp(old_chksum, new_chksum) == 0) {
|
||||||
|
printf("Warning: Pad checksum unchanged after entropy addition\n");
|
||||||
|
return 2; // Checksum didn't change (unusual but not fatal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename pad files to use new checksum
|
||||||
|
if (rename_pad_files_safely(old_chksum, new_chksum) != 0) {
|
||||||
|
return 3; // Rename failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update default pad preference if this was the default pad
|
||||||
|
char* current_default = get_default_pad_path();
|
||||||
|
if (current_default) {
|
||||||
|
// Check if the old pad was the default
|
||||||
|
if (strstr(current_default, old_chksum)) {
|
||||||
|
// Update to new checksum
|
||||||
|
char new_default_path[1024];
|
||||||
|
snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, new_chksum);
|
||||||
|
|
||||||
|
if (set_default_pad_path(new_default_path) != 0) {
|
||||||
|
printf("Warning: Failed to update default pad preference\n");
|
||||||
|
} else {
|
||||||
|
printf("Updated default pad to new checksum: %.16s...\n", new_chksum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(current_default);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// UNIVERSAL CORE FUNCTIONS FOR CODE CONSOLIDATION
|
// UNIVERSAL CORE FUNCTIONS FOR CODE CONSOLIDATION
|
||||||
@@ -3045,7 +3182,7 @@ int generate_ascii_armor(const char* chksum, uint64_t offset, const unsigned cha
|
|||||||
strcpy(*ascii_output, "-----BEGIN OTP MESSAGE-----\n");
|
strcpy(*ascii_output, "-----BEGIN OTP MESSAGE-----\n");
|
||||||
|
|
||||||
char temp_line[256];
|
char temp_line[256];
|
||||||
snprintf(temp_line, sizeof(temp_line), "Version: %s\n", get_version());
|
snprintf(temp_line, sizeof(temp_line), "Version: v1.0.0\n");
|
||||||
strcat(*ascii_output, temp_line);
|
strcat(*ascii_output, temp_line);
|
||||||
|
|
||||||
snprintf(temp_line, sizeof(temp_line), "Pad-ChkSum: %s\n", chksum);
|
snprintf(temp_line, sizeof(temp_line), "Pad-ChkSum: %s\n", chksum);
|
||||||
@@ -3958,6 +4095,7 @@ int handle_pads_menu(void) {
|
|||||||
|
|
||||||
printf("\nActions:\n");
|
printf("\nActions:\n");
|
||||||
printf(" \033[4mG\033[0menerate new pad\n");
|
printf(" \033[4mG\033[0menerate new pad\n");
|
||||||
|
printf(" \033[4mA\033[0mdd entropy to pad\n");
|
||||||
printf(" \033[4mS\033[0met default pad\n");
|
printf(" \033[4mS\033[0met default pad\n");
|
||||||
printf(" E\033[4mx\033[0mit\n");
|
printf(" E\033[4mx\033[0mit\n");
|
||||||
printf("\nSelect pad (by prefix) or action: ");
|
printf("\nSelect pad (by prefix) or action: ");
|
||||||
@@ -3977,6 +4115,88 @@ int handle_pads_menu(void) {
|
|||||||
return handle_pads_menu();
|
return handle_pads_menu();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
} else if (toupper(input[0]) == 'A') {
|
||||||
|
// Add entropy to pad - filter for unused pads only
|
||||||
|
char unused_pads[100][65];
|
||||||
|
int unused_count = filter_unused_pads(unused_pads, 100);
|
||||||
|
|
||||||
|
if (unused_count == 0) {
|
||||||
|
printf("\nNo unused pads available for entropy addition.\n");
|
||||||
|
printf("Entropy can only be added to pads with 0%% usage (only reserved bytes used).\n");
|
||||||
|
printf("Use existing pads for encryption/decryption or generate new pads.\n");
|
||||||
|
printf("\nPress Enter to continue...");
|
||||||
|
getchar();
|
||||||
|
return handle_pads_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nUnused pads available for entropy addition:\n");
|
||||||
|
printf("%-4s %-20s %-12s %-12s\n", "No.", "ChkSum", "Size", "Location");
|
||||||
|
printf("%-4s %-20s %-12s %-12s\n", "---", "-------------------", "----------", "----------");
|
||||||
|
|
||||||
|
// Display unused pads with their details
|
||||||
|
for (int i = 0; i < unused_count; i++) {
|
||||||
|
// Find the pad info from our main list
|
||||||
|
for (int j = 0; j < pad_count; j++) {
|
||||||
|
if (strcmp(unused_pads[i], pads[j].chksum) == 0) {
|
||||||
|
printf("%-4d %-20.16s %-12s %-12s\n",
|
||||||
|
i + 1,
|
||||||
|
pads[j].chksum,
|
||||||
|
pads[j].size_str,
|
||||||
|
pads[j].location);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nSelect pad to add entropy to (by number or prefix): ");
|
||||||
|
char pad_input[MAX_HASH_LENGTH];
|
||||||
|
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
|
||||||
|
printf("Error: Failed to read input\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pad_input[strcspn(pad_input, "\n")] = 0;
|
||||||
|
|
||||||
|
// Find matching pad by number or prefix (from unused pads only)
|
||||||
|
char* selected_chksum = NULL;
|
||||||
|
|
||||||
|
// Check if input is a number
|
||||||
|
char* endptr;
|
||||||
|
int selection = strtol(pad_input, &endptr, 10);
|
||||||
|
if (*endptr == '\0' && selection >= 1 && selection <= unused_count) {
|
||||||
|
// Valid number selection
|
||||||
|
selected_chksum = unused_pads[selection - 1];
|
||||||
|
} else {
|
||||||
|
// Try prefix matching in unused pads
|
||||||
|
int match_count = 0;
|
||||||
|
char* matched_chksum = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < unused_count; i++) {
|
||||||
|
if (strncmp(pad_input, unused_pads[i], strlen(pad_input)) == 0) {
|
||||||
|
matched_chksum = unused_pads[i];
|
||||||
|
match_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_count == 1) {
|
||||||
|
selected_chksum = matched_chksum;
|
||||||
|
} else if (match_count > 1) {
|
||||||
|
printf("Ambiguous prefix. Multiple matches found in unused pads.\n");
|
||||||
|
return handle_pads_menu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selected_chksum) {
|
||||||
|
printf("No unused pad found matching '%s'\n", pad_input);
|
||||||
|
return handle_pads_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add entropy to the selected unused pad
|
||||||
|
int result = handle_add_entropy_to_pad(selected_chksum);
|
||||||
|
if (result == 0) {
|
||||||
|
// Return to pads menu after successful entropy addition
|
||||||
|
return handle_pads_menu();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} else if (toupper(input[0]) == 'S') {
|
} else if (toupper(input[0]) == 'S') {
|
||||||
// Set default pad
|
// Set default pad
|
||||||
printf("\nSelect pad to set as default (by prefix): ");
|
printf("\nSelect pad to set as default (by prefix): ");
|
||||||
@@ -4326,8 +4546,8 @@ int handle_add_entropy_to_pad(const char* pad_chksum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void print_usage(const char* program_name) {
|
void print_usage(const char* program_name) {
|
||||||
printf("OTP Cipher - One Time Pad Implementation %s\n", get_version());
|
printf("OTP Cipher - One Time Pad Implementation v1.0.0\n");
|
||||||
printf("%s\n", get_build_info());
|
printf("Built for testing entropy system\n");
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
printf(" %s - Interactive mode\n", program_name);
|
printf(" %s - Interactive mode\n", program_name);
|
||||||
printf(" %s generate|-g <size> - Generate new pad\n", program_name);
|
printf(" %s generate|-g <size> - Generate new pad\n", program_name);
|
||||||
|
|||||||
Reference in New Issue
Block a user