Compare commits

...

1 Commits

Author SHA1 Message Date
2a5aec7dce Version v0.2.102 - Add entropy 2025-08-29 09:10:39 -04:00
2 changed files with 234 additions and 16 deletions

View File

@@ -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
View File

@@ -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, &timestamp); 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, &timestamp, 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);