Compare commits

...

7 Commits

4 changed files with 172 additions and 127 deletions

View File

@@ -1,4 +1,4 @@
# OTP Cipher - One Time Pad Implementation r# OTP Cipher - One Time Pad Implementation
A secure one-time pad (OTP) cipher implementation in C with automatic versioning system. A secure one-time pad (OTP) cipher implementation in C with automatic versioning system.
@@ -199,3 +199,4 @@ When contributing:
1. The version will automatically increment on builds 1. The version will automatically increment on builds
2. For major features, consider manually creating minor version tags 2. For major features, consider manually creating minor version tags
3. Generated version files (`src/version.*`, `VERSION`) should not be committed 3. Generated version files (`src/version.*`, `VERSION`) should not be committed
# Test change

View File

@@ -50,6 +50,32 @@ increment_version() {
print_status "Current version: $LATEST_TAG" print_status "Current version: $LATEST_TAG"
print_status "New version: $NEW_VERSION" print_status "New version: $NEW_VERSION"
# Stage all changes
if git add . 2>/dev/null; then
print_success "Staged all changes"
else
print_warning "Failed to stage changes (maybe not a git repository)"
fi
# Prompt for commit message
echo ""
print_status "Please enter a meaningful commit message for version $NEW_VERSION:"
echo -n "> "
read -r COMMIT_MESSAGE
# Check if user provided a message
if [[ -z "$COMMIT_MESSAGE" ]]; then
print_warning "No commit message provided. Using default message."
COMMIT_MESSAGE="Version $NEW_VERSION - Automatic version increment"
fi
# Commit changes with user-provided message
if git commit -m "Version $NEW_VERSION - $COMMIT_MESSAGE" 2>/dev/null; then
print_success "Committed changes for version $NEW_VERSION"
else
print_warning "Failed to commit changes (maybe no changes to commit or not a git repository)"
fi
# Create new git tag # Create new git tag
if git tag "$NEW_VERSION" 2>/dev/null; then if git tag "$NEW_VERSION" 2>/dev/null; then
print_success "Created new version tag: $NEW_VERSION" print_success "Created new version tag: $NEW_VERSION"

BIN
otp

Binary file not shown.

238
otp.c
View File

@@ -62,20 +62,20 @@ void simple_entropy_mix(unsigned char* urandom_buffer, size_t buffer_size,
// Directory management // Directory management
int ensure_pads_directory(void); int ensure_pads_directory(void);
void get_pad_path(const char* hash, char* pad_path, char* state_path); void get_pad_path(const char* chksum, char* pad_path, char* state_path);
// Utility functions // Utility functions
uint64_t parse_size_string(const char* size_str); uint64_t parse_size_string(const char* size_str);
char* find_pad_by_prefix(const char* prefix); char* find_pad_by_prefix(const char* prefix);
int list_available_pads(void); int list_available_pads(void);
int show_pad_info(const char* hash); int show_pad_info(const char* chksum);
int get_user_choice(int min, int max); int get_user_choice(int min, int max);
void show_progress(uint64_t current, uint64_t total, time_t start_time); void show_progress(uint64_t current, uint64_t total, time_t start_time);
// File operations // File operations
int read_state_offset(const char* pad_hash, uint64_t* offset); int read_state_offset(const char* pad_chksum, uint64_t* offset);
int write_state_offset(const char* pad_hash, uint64_t offset); int write_state_offset(const char* pad_chksum, uint64_t offset);
int calculate_sha256(const char* filename, char* hash_hex); int calculate_checksum(const char* filename, char* checksum_hex);
void xor_checksum_256(const unsigned char* data, size_t len, unsigned char checksum[32]); void xor_checksum_256(const unsigned char* data, size_t len, unsigned char checksum[32]);
char* custom_base64_encode(const unsigned char* input, int length); char* custom_base64_encode(const unsigned char* input, int length);
unsigned char* custom_base64_decode(const char* input, int* output_length); unsigned char* custom_base64_decode(const char* input, int* output_length);
@@ -101,37 +101,46 @@ int interactive_mode(void) {
while (1) { while (1) {
show_main_menu(); show_main_menu();
int choice = get_user_choice(1, 6); char input[10];
if (fgets(input, sizeof(input), stdin)) {
char choice = toupper(input[0]);
switch (choice) { switch (choice) {
case 1: case 'G':
handle_generate_menu(); handle_generate_menu();
break; break;
case 2: case 'E':
handle_encrypt_menu(); handle_encrypt_menu();
break; break;
case 3: case 'D':
handle_decrypt_menu(); handle_decrypt_menu();
break; break;
case 4: case 'L':
list_available_pads(); list_available_pads();
break; break;
case 5: { case 'S': {
printf("Enter pad hash (or prefix): "); printf("Enter pad checksum (or prefix): ");
char input[MAX_HASH_LENGTH]; char input[MAX_HASH_LENGTH];
if (fgets(input, sizeof(input), stdin)) { if (fgets(input, sizeof(input), stdin)) {
input[strcspn(input, "\n")] = 0; input[strcspn(input, "\n")] = 0;
char* hash = find_pad_by_prefix(input); char* chksum = find_pad_by_prefix(input);
if (hash) { if (chksum) {
show_pad_info(hash); show_pad_info(chksum);
free(hash); free(chksum);
} }
} }
break; break;
} }
case 6: case 'X':
printf("Goodbye!\n"); printf("Goodbye!\n");
return 0; return 0;
default:
printf("Invalid option. Please select G, E, D, L, S, or X.\n");
continue;
}
} else {
printf("Error reading input. Please try again.\n");
continue;
} }
printf("\n"); printf("\n");
} }
@@ -153,14 +162,14 @@ int command_line_mode(int argc, char* argv[]) {
} }
else if (strcmp(argv[1], "encrypt") == 0) { else if (strcmp(argv[1], "encrypt") == 0) {
if (argc != 3) { if (argc != 3) {
printf("Usage: %s encrypt <pad_hash_or_prefix>\n", argv[0]); printf("Usage: %s encrypt <pad_chksum_or_prefix>\n", argv[0]);
return 1; return 1;
} }
return encrypt_text(argv[2]); return encrypt_text(argv[2]);
} }
else if (strcmp(argv[1], "decrypt") == 0) { else if (strcmp(argv[1], "decrypt") == 0) {
if (argc != 3) { if (argc != 3) {
printf("Usage: %s decrypt <pad_hash_or_prefix>\n", argv[0]); printf("Usage: %s decrypt <pad_chksum_or_prefix>\n", argv[0]);
return 1; return 1;
} }
return decrypt_text(argv[2]); return decrypt_text(argv[2]);
@@ -176,13 +185,13 @@ int command_line_mode(int argc, char* argv[]) {
void show_main_menu(void) { void show_main_menu(void) {
printf("=== Main Menu ===\n"); printf("=== Main Menu ===\n");
printf("1. Generate new pad\n"); printf("\033[4mG\033[0menerate new pad\n");
printf("2. Encrypt message\n"); printf("\033[4mE\033[0mncrypt message\n");
printf("3. Decrypt message\n"); printf("\033[4mD\033[0mecrypt message\n");
printf("4. List available pads\n"); printf("\033[4mL\033[0mist available pads\n");
printf("5. Show pad information\n"); printf("\033[4mS\033[0mhow pad information\n");
printf("6. Exit\n"); printf("E\033[4mx\033[0mit\n");
printf("\nSelect option (1-6): "); printf("\nSelect option: ");
} }
int handle_generate_menu(void) { int handle_generate_menu(void) {
@@ -233,7 +242,7 @@ int handle_encrypt_menu(void) {
return 1; return 1;
} }
printf("\nEnter pad selection (number, hash, or prefix): "); printf("\nEnter pad selection (number, chksum, or prefix): ");
char input[MAX_HASH_LENGTH]; char input[MAX_HASH_LENGTH];
if (!fgets(input, sizeof(input), stdin)) { if (!fgets(input, sizeof(input), stdin)) {
printf("Error: Failed to read input\n"); printf("Error: Failed to read input\n");
@@ -246,7 +255,7 @@ int handle_encrypt_menu(void) {
int handle_decrypt_menu(void) { int handle_decrypt_menu(void) {
printf("\n=== Decrypt Message ===\n"); printf("\n=== Decrypt Message ===\n");
return decrypt_text(NULL); // No pad selection needed - hash comes from message return decrypt_text(NULL); // No pad selection needed - chksum comes from message
} }
uint64_t parse_size_string(const char* size_str) { uint64_t parse_size_string(const char* size_str) {
@@ -307,7 +316,7 @@ char* find_pad_by_prefix(const char* prefix) {
int current = 0; int current = 0;
rewinddir(dir); rewinddir(dir);
while ((entry = readdir(dir)) != NULL && match_count == 0) { while ((entry = readdir(dir)) != NULL && match_count == 0) {
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) { // 64 char hash + ".pad" if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) { // 64 char chksum + ".pad"
current++; current++;
if (current == selection) { if (current == selection) {
matches[match_count] = malloc(65); matches[match_count] = malloc(65);
@@ -368,15 +377,15 @@ int list_available_pads(void) {
int count = 0; int count = 0;
printf("Available pads:\n"); printf("Available pads:\n");
printf("%-4s %-20s %-12s %-12s %-8s\n", "No.", "Hash (first 16 chars)", "Size", "Used", "% Used"); printf("%-4s %-20s %-12s %-12s %-8s\n", "No.", "ChkSum (first 16 chars)", "Size", "Used", "% Used");
printf("%-4s %-20s %-12s %-12s %-8s\n", "---", "-------------------", "----------", "----------", "------"); printf("%-4s %-20s %-12s %-12s %-8s\n", "---", "-------------------", "----------", "----------", "------");
while ((entry = readdir(dir)) != NULL) { while ((entry = readdir(dir)) != NULL) {
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) { if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) {
count++; count++;
char hash[65]; char chksum[65];
strncpy(hash, entry->d_name, 64); strncpy(chksum, entry->d_name, 64);
hash[64] = '\0'; chksum[64] = '\0';
// Get pad file size // Get pad file size
char full_path[300]; // Increased buffer size to accommodate longer paths char full_path[300]; // Increased buffer size to accommodate longer paths
@@ -385,7 +394,7 @@ int list_available_pads(void) {
if (stat(full_path, &st) == 0) { if (stat(full_path, &st) == 0) {
// Get used bytes from state // Get used bytes from state
uint64_t used_bytes; uint64_t used_bytes;
read_state_offset(hash, &used_bytes); read_state_offset(chksum, &used_bytes);
// Format sizes // Format sizes
char size_str[32], used_str[32]; char size_str[32], used_str[32];
@@ -415,7 +424,7 @@ int list_available_pads(void) {
// Calculate percentage // Calculate percentage
double percentage = (double)used_bytes / st.st_size * 100.0; double percentage = (double)used_bytes / st.st_size * 100.0;
printf("%-4d %-20.16s %-12s %-12s %.1f%%\n", count, hash, size_str, used_str, percentage); printf("%-4d %-20.16s %-12s %-12s %.1f%%\n", count, chksum, size_str, used_str, percentage);
} }
} }
} }
@@ -429,24 +438,24 @@ int list_available_pads(void) {
return count; return count;
} }
int show_pad_info(const char* hash) { int show_pad_info(const char* chksum) {
char pad_filename[MAX_HASH_LENGTH + 10]; char pad_filename[MAX_HASH_LENGTH + 10];
char state_filename[MAX_HASH_LENGTH + 10]; char state_filename[MAX_HASH_LENGTH + 10];
snprintf(pad_filename, sizeof(pad_filename), "%s.pad", hash); snprintf(pad_filename, sizeof(pad_filename), "%s.pad", chksum);
snprintf(state_filename, sizeof(state_filename), "%s.state", hash); snprintf(state_filename, sizeof(state_filename), "%s.state", chksum);
struct stat st; struct stat st;
if (stat(pad_filename, &st) != 0) { if (stat(pad_filename, &st) != 0) {
printf("Pad not found: %s\n", hash); printf("Pad not found: %s\n", chksum);
return 1; return 1;
} }
uint64_t used_bytes; uint64_t used_bytes;
read_state_offset(hash, &used_bytes); read_state_offset(chksum, &used_bytes);
printf("=== Pad Information ===\n"); printf("=== Pad Information ===\n");
printf("Hash: %s\n", hash); printf("ChkSum: %s\n", chksum);
printf("File: %s\n", pad_filename); printf("File: %s\n", pad_filename);
double size_gb = (double)st.st_size / (1024.0 * 1024.0 * 1024.0); double size_gb = (double)st.st_size / (1024.0 * 1024.0 * 1024.0);
@@ -496,7 +505,7 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
char temp_filename[32]; char temp_filename[32];
char pad_filename[MAX_HASH_LENGTH + 10]; char pad_filename[MAX_HASH_LENGTH + 10];
char state_filename[MAX_HASH_LENGTH + 10]; char state_filename[MAX_HASH_LENGTH + 10];
char hash_hex[MAX_HASH_LENGTH]; char chksum_hex[MAX_HASH_LENGTH];
// Create temporary filename // Create temporary filename
snprintf(temp_filename, sizeof(temp_filename), "temp_%ld.pad", time(NULL)); snprintf(temp_filename, sizeof(temp_filename), "temp_%ld.pad", time(NULL));
@@ -559,19 +568,19 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
fclose(urandom); fclose(urandom);
fclose(pad_file); fclose(pad_file);
// Calculate SHA-256 of the pad file // Calculate XOR checksum of the pad file
if (calculate_sha256(temp_filename, hash_hex) != 0) { if (calculate_checksum(temp_filename, chksum_hex) != 0) {
printf("Error: Cannot calculate pad hash\n"); printf("Error: Cannot calculate pad checksum\n");
unlink(temp_filename); unlink(temp_filename);
return 1; return 1;
} }
// Rename file to its hash // Rename file to its chksum
snprintf(pad_filename, sizeof(pad_filename), "%s.pad", hash_hex); snprintf(pad_filename, sizeof(pad_filename), "%s.pad", chksum_hex);
snprintf(state_filename, sizeof(state_filename), "%s.state", hash_hex); snprintf(state_filename, sizeof(state_filename), "%s.state", chksum_hex);
if (rename(temp_filename, pad_filename) != 0) { if (rename(temp_filename, pad_filename) != 0) {
printf("Error: Cannot rename pad file to hash-based name\n"); printf("Error: Cannot rename pad file to chksum-based name\n");
unlink(temp_filename); unlink(temp_filename);
return 1; return 1;
} }
@@ -582,7 +591,7 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
} }
// Initialize state file with offset 0 // Initialize state file with offset 0
if (write_state_offset(hash_hex, 0) != 0) { if (write_state_offset(chksum_hex, 0) != 0) {
printf("Error: Failed to create state file\n"); printf("Error: Failed to create state file\n");
unlink(pad_filename); unlink(pad_filename);
return 1; return 1;
@@ -590,7 +599,7 @@ int generate_pad(uint64_t size_bytes, int display_progress) {
double size_gb = (double)size_bytes / (1024.0 * 1024.0 * 1024.0); double size_gb = (double)size_bytes / (1024.0 * 1024.0 * 1024.0);
printf("Generated pad: %s (%.2f GB)\n", pad_filename, size_gb); printf("Generated pad: %s (%.2f GB)\n", pad_filename, size_gb);
printf("Pad hash: %s\n", hash_hex); printf("Pad chksum: %s\n", chksum_hex);
printf("State file: %s\n", state_filename); printf("State file: %s\n", state_filename);
printf("Pad file set to read-only\n"); printf("Pad file set to read-only\n");
@@ -606,7 +615,7 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
char temp_filename[64]; char temp_filename[64];
char pad_path[MAX_HASH_LENGTH + 20]; char pad_path[MAX_HASH_LENGTH + 20];
char state_path[MAX_HASH_LENGTH + 20]; char state_path[MAX_HASH_LENGTH + 20];
char hash_hex[MAX_HASH_LENGTH]; char chksum_hex[MAX_HASH_LENGTH];
// Create temporary filename // Create temporary filename
snprintf(temp_filename, sizeof(temp_filename), "temp_%ld.pad", time(NULL)); snprintf(temp_filename, sizeof(temp_filename), "temp_%ld.pad", time(NULL));
@@ -743,15 +752,15 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
fclose(urandom); fclose(urandom);
fclose(pad_file); fclose(pad_file);
// Calculate SHA-256 of the pad file // Calculate XOR checksum of the pad file
if (calculate_sha256(temp_filename, hash_hex) != 0) { if (calculate_checksum(temp_filename, chksum_hex) != 0) {
printf("Error: Cannot calculate pad hash\n"); printf("Error: Cannot calculate pad checksum\n");
unlink(temp_filename); unlink(temp_filename);
return 1; return 1;
} }
// Get final paths in pads directory // Get final paths in pads directory
get_pad_path(hash_hex, pad_path, state_path); get_pad_path(chksum_hex, pad_path, state_path);
if (rename(temp_filename, pad_path) != 0) { if (rename(temp_filename, pad_path) != 0) {
printf("Error: Cannot move pad file to pads directory\n"); printf("Error: Cannot move pad file to pads directory\n");
@@ -764,11 +773,11 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
printf("Warning: Cannot set pad file to read-only\n"); printf("Warning: Cannot set pad file to read-only\n");
} }
// Initialize state file with offset 0 // Initialize state file with offset 32 (first 32 bytes used for checksum encryption)
FILE* state_file = fopen(state_path, "wb"); FILE* state_file = fopen(state_path, "wb");
if (state_file) { if (state_file) {
uint64_t zero = 0; uint64_t reserved_bytes = 32;
fwrite(&zero, sizeof(uint64_t), 1, state_file); fwrite(&reserved_bytes, sizeof(uint64_t), 1, state_file);
fclose(state_file); fclose(state_file);
} else { } else {
printf("Error: Failed to create state file\n"); printf("Error: Failed to create state file\n");
@@ -778,7 +787,7 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
double size_gb = (double)size_bytes / (1024.0 * 1024.0 * 1024.0); double size_gb = (double)size_bytes / (1024.0 * 1024.0 * 1024.0);
printf("Generated pad: %s (%.2f GB)\n", pad_path, size_gb); printf("Generated pad: %s (%.2f GB)\n", pad_path, size_gb);
printf("Pad hash: %s\n", hash_hex); printf("Pad checksum: %s\n", chksum_hex);
printf("State file: %s\n", state_path); printf("State file: %s\n", state_path);
if (use_keyboard_entropy) { if (use_keyboard_entropy) {
printf("Enhanced with keyboard entropy!\n"); printf("Enhanced with keyboard entropy!\n");
@@ -789,37 +798,46 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
} }
int encrypt_text(const char* pad_identifier) { int encrypt_text(const char* pad_identifier) {
char* pad_hash = find_pad_by_prefix(pad_identifier); char* pad_chksum = find_pad_by_prefix(pad_identifier);
if (!pad_hash) { if (!pad_chksum) {
return 1; return 1;
} }
char input_text[MAX_INPUT_SIZE]; char input_text[MAX_INPUT_SIZE];
char hash_hex[MAX_HASH_LENGTH]; char chksum_hex[MAX_HASH_LENGTH];
uint64_t current_offset; uint64_t current_offset;
char pad_path[MAX_HASH_LENGTH + 20]; char pad_path[MAX_HASH_LENGTH + 20];
char state_path[MAX_HASH_LENGTH + 20]; char state_path[MAX_HASH_LENGTH + 20];
get_pad_path(pad_hash, pad_path, state_path); get_pad_path(pad_chksum, pad_path, state_path);
// Check if pad file exists // Check if pad file exists
if (access(pad_path, R_OK) != 0) { if (access(pad_path, R_OK) != 0) {
printf("Error: Pad file %s not found\n", pad_path); printf("Error: Pad file %s not found\n", pad_path);
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
// Read current offset // Read current offset
if (read_state_offset(pad_hash, &current_offset) != 0) { if (read_state_offset(pad_chksum, &current_offset) != 0) {
printf("Error: Cannot read state file\n"); printf("Error: Cannot read state file\n");
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
// Calculate SHA-256 of pad file // Ensure we never encrypt before offset 32 (reserved for checksum encryption)
if (calculate_sha256(pad_path, hash_hex) != 0) { if (current_offset < 32) {
printf("Error: Cannot calculate pad hash\n"); printf("Warning: State offset below reserved area, adjusting to 32\n");
free(pad_hash); current_offset = 32;
if (write_state_offset(pad_chksum, current_offset) != 0) {
printf("Warning: Failed to update state file\n");
}
}
// Calculate XOR checksum of pad file
if (calculate_checksum(pad_path, chksum_hex) != 0) {
printf("Error: Cannot calculate pad checksum\n");
free(pad_chksum);
return 1; return 1;
} }
@@ -829,7 +847,7 @@ int encrypt_text(const char* pad_identifier) {
if (fgets(input_text, sizeof(input_text), stdin) == NULL) { if (fgets(input_text, sizeof(input_text), stdin) == NULL) {
printf("Error: Failed to read input\n"); printf("Error: Failed to read input\n");
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
@@ -842,7 +860,7 @@ int encrypt_text(const char* pad_identifier) {
if (input_len == 0) { if (input_len == 0) {
printf("Error: No input provided\n"); printf("Error: No input provided\n");
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
@@ -850,7 +868,7 @@ int encrypt_text(const char* pad_identifier) {
struct stat pad_stat; struct stat pad_stat;
if (stat(pad_path, &pad_stat) != 0) { if (stat(pad_path, &pad_stat) != 0) {
printf("Error: Cannot get pad file size\n"); printf("Error: Cannot get pad file size\n");
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
@@ -858,7 +876,7 @@ int encrypt_text(const char* pad_identifier) {
printf("Error: Not enough pad space remaining\n"); printf("Error: Not enough pad space remaining\n");
printf("Need: %lu bytes, Available: %lu bytes\n", printf("Need: %lu bytes, Available: %lu bytes\n",
input_len, (uint64_t)pad_stat.st_size - current_offset); input_len, (uint64_t)pad_stat.st_size - current_offset);
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
@@ -866,14 +884,14 @@ int encrypt_text(const char* pad_identifier) {
FILE* pad_file = fopen(pad_path, "rb"); FILE* pad_file = fopen(pad_path, "rb");
if (!pad_file) { if (!pad_file) {
printf("Error: Cannot open pad file\n"); printf("Error: Cannot open pad file\n");
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
if (fseek(pad_file, current_offset, SEEK_SET) != 0) { if (fseek(pad_file, current_offset, SEEK_SET) != 0) {
printf("Error: Cannot seek to offset in pad file\n"); printf("Error: Cannot seek to offset in pad file\n");
fclose(pad_file); fclose(pad_file);
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
@@ -882,7 +900,7 @@ int encrypt_text(const char* pad_identifier) {
printf("Error: Cannot read pad data\n"); printf("Error: Cannot read pad data\n");
free(pad_data); free(pad_data);
fclose(pad_file); fclose(pad_file);
free(pad_hash); free(pad_chksum);
return 1; return 1;
} }
fclose(pad_file); fclose(pad_file);
@@ -897,14 +915,14 @@ int encrypt_text(const char* pad_identifier) {
char* base64_cipher = custom_base64_encode(ciphertext, input_len); char* base64_cipher = custom_base64_encode(ciphertext, input_len);
// Update state offset // Update state offset
if (write_state_offset(pad_hash, current_offset + input_len) != 0) { if (write_state_offset(pad_chksum, current_offset + input_len) != 0) {
printf("Warning: Failed to update state file\n"); printf("Warning: Failed to update state file\n");
} }
// Output in ASCII armor format // Output in ASCII armor format
printf("\n-----BEGIN OTP MESSAGE-----\n"); printf("\n\n-----BEGIN OTP MESSAGE-----\n");
printf("Version: %s\n", get_version()); printf("Version: %s\n", get_version());
printf("Pad-Hash: %s\n", hash_hex); printf("Pad-ChkSum: %s\n", chksum_hex);
printf("Pad-Offset: %lu\n", current_offset); printf("Pad-Offset: %lu\n", current_offset);
printf("\n"); printf("\n");
@@ -914,24 +932,24 @@ int encrypt_text(const char* pad_identifier) {
printf("%.64s\n", base64_cipher + i); printf("%.64s\n", base64_cipher + i);
} }
printf("-----END OTP MESSAGE-----\n\n"); printf("-----END OTP MESSAGE-----\n\n\n");
// Cleanup // Cleanup
free(pad_data); free(pad_data);
free(ciphertext); free(ciphertext);
free(base64_cipher); free(base64_cipher);
free(pad_hash); free(pad_chksum);
return 0; return 0;
} }
int decrypt_text(const char* pad_identifier) { int decrypt_text(const char* pad_identifier) {
// For command line mode, pad_identifier is ignored - we'll get the hash from the message // For command line mode, pad_identifier is ignored - we'll get the chksum from the message
(void)pad_identifier; // Suppress unused parameter warning (void)pad_identifier; // Suppress unused parameter warning
char line[MAX_LINE_LENGTH]; char line[MAX_LINE_LENGTH];
char stored_hash[MAX_HASH_LENGTH]; char stored_chksum[MAX_HASH_LENGTH];
char current_hash[MAX_HASH_LENGTH]; char current_chksum[MAX_HASH_LENGTH];
uint64_t pad_offset; uint64_t pad_offset;
char base64_data[MAX_INPUT_SIZE * 2] = {0}; char base64_data[MAX_INPUT_SIZE * 2] = {0};
int in_data_section = 0; int in_data_section = 0;
@@ -954,9 +972,9 @@ int decrypt_text(const char* pad_identifier) {
if (!found_begin) continue; if (!found_begin) continue;
if (strncmp(line, "Pad-Hash: ", 10) == 0) { if (strncmp(line, "Pad-ChkSum: ", 12) == 0) {
strncpy(stored_hash, line + 10, 64); strncpy(stored_chksum, line + 12, 64);
stored_hash[64] = '\0'; stored_chksum[64] = '\0';
} }
else if (strncmp(line, "Pad-Offset: ", 12) == 0) { else if (strncmp(line, "Pad-Offset: ", 12) == 0) {
pad_offset = strtoull(line + 12, NULL, 10); pad_offset = strtoull(line + 12, NULL, 10);
@@ -974,29 +992,29 @@ int decrypt_text(const char* pad_identifier) {
return 1; return 1;
} }
// Now we have the pad hash from the message, construct filename // Now we have the pad chksum from the message, construct filename
char pad_path[MAX_HASH_LENGTH + 20]; char pad_path[MAX_HASH_LENGTH + 20];
char state_path[MAX_HASH_LENGTH + 20]; char state_path[MAX_HASH_LENGTH + 20];
get_pad_path(stored_hash, pad_path, state_path); get_pad_path(stored_chksum, pad_path, state_path);
// Check if we have this pad // Check if we have this pad
if (access(pad_path, R_OK) != 0) { if (access(pad_path, R_OK) != 0) {
printf("Error: Required pad not found: %s\n", stored_hash); printf("Error: Required pad not found: %s\n", stored_chksum);
printf("Available pads:\n"); printf("Available pads:\n");
list_available_pads(); list_available_pads();
return 1; return 1;
} }
// Verify pad integrity // Verify pad integrity
if (calculate_sha256(pad_path, current_hash) != 0) { if (calculate_checksum(pad_path, current_chksum) != 0) {
printf("Error: Cannot calculate current pad hash\n"); printf("Error: Cannot calculate current pad checksum\n");
return 1; return 1;
} }
if (strcmp(stored_hash, current_hash) != 0) { if (strcmp(stored_chksum, current_chksum) != 0) {
printf("Warning: Pad integrity check failed!\n"); printf("Warning: Pad integrity check failed!\n");
printf("Expected: %s\n", stored_hash); printf("Expected: %s\n", stored_chksum);
printf("Current: %s\n", current_hash); printf("Current: %s\n", current_chksum);
printf("Continue anyway? (y/N): "); printf("Continue anyway? (y/N): ");
fflush(stdout); fflush(stdout);
@@ -1060,9 +1078,9 @@ int decrypt_text(const char* pad_identifier) {
return 0; return 0;
} }
int read_state_offset(const char* pad_hash, uint64_t* offset) { int read_state_offset(const char* pad_chksum, uint64_t* offset) {
char state_filename[MAX_HASH_LENGTH + 20]; char state_filename[MAX_HASH_LENGTH + 20];
snprintf(state_filename, sizeof(state_filename), "%s/%s.state", PADS_DIR, pad_hash); snprintf(state_filename, sizeof(state_filename), "%s/%s.state", PADS_DIR, pad_chksum);
FILE* state_file = fopen(state_filename, "rb"); FILE* state_file = fopen(state_filename, "rb");
if (!state_file) { if (!state_file) {
@@ -1080,9 +1098,9 @@ int read_state_offset(const char* pad_hash, uint64_t* offset) {
return 0; return 0;
} }
int write_state_offset(const char* pad_hash, uint64_t offset) { int write_state_offset(const char* pad_chksum, uint64_t offset) {
char state_filename[MAX_HASH_LENGTH + 20]; char state_filename[MAX_HASH_LENGTH + 20];
snprintf(state_filename, sizeof(state_filename), "%s/%s.state", PADS_DIR, pad_hash); snprintf(state_filename, sizeof(state_filename), "%s/%s.state", PADS_DIR, pad_chksum);
FILE* state_file = fopen(state_filename, "wb"); FILE* state_file = fopen(state_filename, "wb");
if (!state_file) { if (!state_file) {
@@ -1098,7 +1116,7 @@ int write_state_offset(const char* pad_hash, uint64_t offset) {
return 0; return 0;
} }
int calculate_sha256(const char* filename, char* hash_hex) { int calculate_checksum(const char* filename, char* checksum_hex) {
FILE* file = fopen(filename, "rb"); FILE* file = fopen(filename, "rb");
if (!file) { if (!file) {
return 1; return 1;
@@ -1142,9 +1160,9 @@ int calculate_sha256(const char* filename, char* hash_hex) {
// Convert to hex string (64 characters) // Convert to hex string (64 characters)
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
sprintf(hash_hex + (i * 2), "%02x", encrypted_checksum[i]); sprintf(checksum_hex + (i * 2), "%02x", encrypted_checksum[i]);
} }
hash_hex[64] = '\0'; checksum_hex[64] = '\0';
return 0; return 0;
} }
@@ -1231,9 +1249,9 @@ int ensure_pads_directory(void) {
return 0; return 0;
} }
void get_pad_path(const char* hash, char* pad_path, char* state_path) { void get_pad_path(const char* chksum, char* pad_path, char* state_path) {
snprintf(pad_path, MAX_HASH_LENGTH + 20, "%s/%s.pad", PADS_DIR, hash); snprintf(pad_path, MAX_HASH_LENGTH + 20, "%s/%s.pad", PADS_DIR, chksum);
snprintf(state_path, MAX_HASH_LENGTH + 20, "%s/%s.state", PADS_DIR, hash); snprintf(state_path, MAX_HASH_LENGTH + 20, "%s/%s.state", PADS_DIR, chksum);
} }
@@ -1329,9 +1347,9 @@ void print_usage(const char* program_name) {
printf("Usage:\n"); printf("Usage:\n");
printf(" %s - Interactive mode\n", program_name); printf(" %s - Interactive mode\n", program_name);
printf(" %s generate <size> - Generate new pad\n", program_name); printf(" %s generate <size> - Generate new pad\n", program_name);
printf(" %s encrypt <pad_hash_prefix> - Encrypt text\n", program_name); printf(" %s encrypt <pad_checksum_prefix> - Encrypt text\n", program_name);
printf(" %s decrypt <pad_hash_prefix> - Decrypt message\n", program_name); printf(" %s decrypt <pad_checksum_prefix> - Decrypt message\n", program_name);
printf(" %s list - List available pads\n", program_name); printf(" %s list - List available pads\n", program_name);
printf("\nSize examples: 1GB, 5TB, 512MB, 2048 (bytes)\n"); printf("\nSize examples: 1GB, 5TB, 512MB, 2048 (bytes)\n");
printf("Pad selection: Full hash, prefix, or number from list\n"); printf("Pad selection: Full chksum, prefix, or number from list\n");
} }