Version v0.2.102 - Add entropy
This commit is contained in:
6
Makefile
6
Makefile
@@ -5,19 +5,17 @@ LIBS_STATIC = -static -lm
|
||||
TARGET = otp
|
||||
SOURCE = otp.c
|
||||
CHACHA20_SOURCE = nostr_chacha20.c
|
||||
VERSION_SOURCE = src/version.c
|
||||
|
||||
# Default build target
|
||||
$(TARGET): $(SOURCE)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(VERSION_SOURCE) $(LIBS)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(LIBS)
|
||||
|
||||
# Static linking target
|
||||
static: $(SOURCE)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(VERSION_SOURCE) $(LIBS_STATIC)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(CHACHA20_SOURCE) $(LIBS_STATIC)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) *.pad *.state
|
||||
rm -f src/version.h src/version.c VERSION
|
||||
|
||||
install:
|
||||
sudo cp $(TARGET) /usr/local/bin/
|
||||
|
||||
244
otp.c
244
otp.c
@@ -13,7 +13,6 @@
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include "src/version.h"
|
||||
#include "nostr_chacha20.h"
|
||||
|
||||
// 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);
|
||||
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
|
||||
int ensure_pads_directory(void);
|
||||
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) {
|
||||
|
||||
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[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("✓ %zu bytes of entropy distributed across entire pad\n", entropy_size);
|
||||
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;
|
||||
@@ -2156,13 +2179,8 @@ int collect_entropy_with_feedback(unsigned char* entropy_buffer, size_t target_b
|
||||
state.unique_keys++;
|
||||
}
|
||||
} else {
|
||||
// No key available, add timing entropy
|
||||
clock_gettime(CLOCK_MONOTONIC, ×tamp);
|
||||
if (state.collected_bytes + 12 < MAX_ENTROPY_BUFFER) {
|
||||
memcpy(entropy_buffer + state.collected_bytes, ×tamp, 12);
|
||||
state.collected_bytes += 12;
|
||||
}
|
||||
usleep(1000); // 1ms delay
|
||||
// No key available, just sleep and wait for keystrokes
|
||||
usleep(10000); // 10ms delay - wait for keystrokes, don't add timing entropy
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -3045,7 +3182,7 @@ int generate_ascii_armor(const char* chksum, uint64_t offset, const unsigned cha
|
||||
strcpy(*ascii_output, "-----BEGIN OTP MESSAGE-----\n");
|
||||
|
||||
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);
|
||||
|
||||
snprintf(temp_line, sizeof(temp_line), "Pad-ChkSum: %s\n", chksum);
|
||||
@@ -3958,6 +4095,7 @@ int handle_pads_menu(void) {
|
||||
|
||||
printf("\nActions:\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(" E\033[4mx\033[0mit\n");
|
||||
printf("\nSelect pad (by prefix) or action: ");
|
||||
@@ -3977,6 +4115,88 @@ int handle_pads_menu(void) {
|
||||
return handle_pads_menu();
|
||||
}
|
||||
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') {
|
||||
// Set default pad
|
||||
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) {
|
||||
printf("OTP Cipher - One Time Pad Implementation %s\n", get_version());
|
||||
printf("%s\n", get_build_info());
|
||||
printf("OTP Cipher - One Time Pad Implementation v1.0.0\n");
|
||||
printf("Built for testing entropy system\n");
|
||||
printf("Usage:\n");
|
||||
printf(" %s - Interactive mode\n", program_name);
|
||||
printf(" %s generate|-g <size> - Generate new pad\n", program_name);
|
||||
|
||||
Reference in New Issue
Block a user