Version v0.3.21 - Fixing errors with adding entropy to file

This commit is contained in:
2025-12-18 08:34:52 -04:00
parent 33b34bf5a5
commit 05f5d6ca4f
13 changed files with 201 additions and 4 deletions
+1
View File
@@ -208,6 +208,7 @@ int collect_dice_entropy(unsigned char* entropy_buffer, size_t target_bytes, siz
// File entropy collection functions
int get_file_entropy_info(char* file_path, size_t max_path_len, size_t* file_size, int display_progress);
int collect_file_entropy(unsigned char* entropy_buffer, size_t target_bytes, size_t* collected_bytes, int display_progress);
int add_file_entropy_streaming(const char* pad_chksum, const char* file_path, size_t file_size, int display_progress);
// Unified entropy collection interface (updated to match implementation)
int collect_entropy_by_source(entropy_source_t source, unsigned char* entropy_buffer, size_t target_bytes, size_t* collected_bytes, int display_progress);
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+125
View File
@@ -560,6 +560,131 @@ int collect_file_entropy(unsigned char* entropy_buffer, size_t target_bytes,
return 0; // Success
}
// Add file entropy directly to pad using streaming (for large files)
int add_file_entropy_streaming(const char* pad_chksum, const char* file_path, size_t file_size, int display_progress) {
// Get pad file path
char pad_path[1024];
char state_path[1024];
get_pad_path(pad_chksum, pad_path, state_path);
// Check if pad exists and get size
struct stat pad_stat;
if (stat(pad_path, &pad_stat) != 0) {
printf("Error: Pad file not found: %s\n", pad_path);
return 1;
}
uint64_t pad_size = pad_stat.st_size;
// Open entropy file for reading
FILE* entropy_file = fopen(file_path, "rb");
if (!entropy_file) {
printf("Error: Cannot open entropy file '%s' for reading\n", file_path);
return 1;
}
// Open pad file for read/write
FILE* pad_file = fopen(pad_path, "r+b");
if (!pad_file) {
printf("Error: Cannot open pad file for modification: %s\n", pad_path);
fclose(entropy_file);
return 1;
}
if (display_progress) {
printf("Adding entropy to pad using streaming direct XOR...\n");
printf("Pad size: %.2f GB (%lu bytes)\n", (double)pad_size / (1024.0*1024.0*1024.0), pad_size);
printf("Entropy file: %.2f GB (%zu bytes)\n", (double)file_size / (1024.0*1024.0*1024.0), file_size);
}
// Process in chunks
unsigned char pad_buffer[64 * 1024];
unsigned char entropy_buffer[64 * 1024];
uint64_t offset = 0;
size_t entropy_offset = 0;
time_t start_time = time(NULL);
while (offset < pad_size) {
size_t chunk_size = sizeof(pad_buffer);
if (pad_size - offset < chunk_size) {
chunk_size = pad_size - offset;
}
// Read current pad data
if (fread(pad_buffer, 1, chunk_size, pad_file) != chunk_size) {
printf("Error: Cannot read pad data at offset %lu\n", offset);
fclose(entropy_file);
fclose(pad_file);
return 1;
}
// Read entropy data (wrap around if file smaller than pad)
size_t entropy_read = 0;
while (entropy_read < chunk_size) {
size_t to_read = chunk_size - entropy_read;
if (to_read > sizeof(entropy_buffer)) {
to_read = sizeof(entropy_buffer);
}
size_t read_bytes = fread(entropy_buffer, 1, to_read, entropy_file);
if (read_bytes == 0) {
// Reached end of entropy file, wrap around
fseek(entropy_file, 0, SEEK_SET);
entropy_offset = 0;
read_bytes = fread(entropy_buffer, 1, to_read, entropy_file);
if (read_bytes == 0) {
printf("Error: Cannot read from entropy file\n");
fclose(entropy_file);
fclose(pad_file);
return 1;
}
}
// XOR this chunk
for (size_t i = 0; i < read_bytes; i++) {
pad_buffer[entropy_read + i] ^= entropy_buffer[i];
}
entropy_read += read_bytes;
entropy_offset += read_bytes;
}
// Seek back and write modified data
if (fseek(pad_file, offset, SEEK_SET) != 0) {
printf("Error: Cannot seek to offset %lu\n", offset);
fclose(entropy_file);
fclose(pad_file);
return 1;
}
if (fwrite(pad_buffer, 1, chunk_size, pad_file) != chunk_size) {
printf("Error: Cannot write modified pad data\n");
fclose(entropy_file);
fclose(pad_file);
return 1;
}
offset += chunk_size;
// Show progress for large pads
if (display_progress && offset % (64 * 1024 * 1024) == 0) {
show_progress(offset, pad_size, start_time);
}
}
fclose(entropy_file);
fclose(pad_file);
if (display_progress) {
show_progress(pad_size, pad_size, start_time);
printf("\n✓ Entropy successfully added to pad using streaming direct XOR\n");
printf("✓ Pad integrity maintained\n");
printf("✓ %zu bytes of entropy distributed across entire pad\n", file_size);
}
return 0;
}
// Collect entropy by source type with unified interface
int collect_entropy_by_source(entropy_source_t source, unsigned char* entropy_buffer,
size_t target_bytes, size_t* collected_bytes, int display_progress) {
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+75 -4
View File
@@ -83,13 +83,37 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
return 1;
}
// Check available disk space before starting
const char* pads_dir = get_current_pads_dir();
struct statvfs stat;
if (statvfs(pads_dir, &stat) == 0) {
uint64_t available_bytes = stat.f_bavail * stat.f_frsize;
double available_gb = (double)available_bytes / (1024.0 * 1024.0 * 1024.0);
double required_gb = (double)size_bytes / (1024.0 * 1024.0 * 1024.0);
if (available_bytes < size_bytes) {
printf("\n⚠ WARNING: Insufficient disk space!\n");
printf(" Required: %.2f GB\n", required_gb);
printf(" Available: %.2f GB\n", available_gb);
printf(" Shortfall: %.2f GB\n", required_gb - available_gb);
printf("\nContinue anyway? (y/N): ");
char response[10];
if (!fgets(response, sizeof(response), stdin) ||
(toupper(response[0]) != 'Y')) {
printf("Pad generation cancelled.\n");
return 1;
}
printf("\n");
}
}
char temp_filename[1024];
char pad_path[MAX_HASH_LENGTH + 20];
char state_path[MAX_HASH_LENGTH + 20];
char chksum_hex[MAX_HASH_LENGTH];
// Create temporary filename in the pads directory to avoid cross-filesystem issues
const char* pads_dir = get_current_pads_dir();
snprintf(temp_filename, sizeof(temp_filename), "%s/temp_%ld.pad", pads_dir, time(NULL));
FILE* urandom = fopen("/dev/urandom", "rb");
@@ -1175,9 +1199,56 @@ int handle_add_entropy_to_pad(const char* pad_chksum) {
// Smart method selection based on file size vs pad size
if (file_size >= pad_size) {
printf("✓ Using Direct XOR method (file ≥ pad size)\n");
printf(" Method: Direct XOR - entropy file will be distributed across entire pad\n");
target_bytes = file_size; // Use entire file
printf("✓ Using Streaming Direct XOR method (file ≥ pad size)\n");
printf(" Method: Streaming XOR - entropy file will be distributed across entire pad\n");
printf(" Processing: File will be streamed in chunks (no memory limit)\n");
// Store original permissions and make pad temporarily writable
mode_t original_mode;
if (make_pad_temporarily_writable(pad_path, &original_mode) != 0) {
printf("Error: Cannot make pad file writable for entropy addition\n");
return 1;
}
// Use streaming method for large files
int result = add_file_entropy_streaming(pad_chksum, file_path, file_size, 1);
if (result != 0) {
printf("Error: Failed to add file entropy to pad\n");
restore_pad_permissions(pad_path, original_mode);
return 1;
}
// 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");
// Restore permissions on the new pad file
char new_pad_path[1024];
const char* pads_dir = get_current_pads_dir();
snprintf(new_pad_path, sizeof(new_pad_path), "%s/%s.pad", pads_dir, new_chksum);
restore_pad_permissions(new_pad_path, original_mode);
} else if (checksum_result == 2) {
printf("ℹ Checksum unchanged (unusual but not an error)\n");
restore_pad_permissions(pad_path, original_mode);
} else {
printf("⚠ Warning: Checksum update failed (entropy was added successfully)\n");
printf(" You may need to manually handle the checksum update\n");
restore_pad_permissions(pad_path, original_mode);
return 1;
}
printf("\n🎉 SUCCESS! Your pad now has enhanced randomness from the entropy file!\n");
print_centered_header("Entropy Enhancement Complete", 1);
return 0; // Success - exit early, don't continue to buffer-based method
} else {
printf("✓ Using ChaCha20 method (file < pad size)\n");
printf(" Method: ChaCha20 - entropy will be expanded to fill entire pad\n");
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.