Compare commits

..

3 Commits

4 changed files with 89 additions and 57 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.

View File

@@ -50,6 +50,20 @@ 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
# Commit changes with version message
if git commit -m "Version $NEW_VERSION - Automatic version increment" 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.

90
otp.c
View File

@@ -75,7 +75,7 @@ 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_hash, uint64_t* offset);
int write_state_offset(const char* pad_hash, uint64_t offset); int write_state_offset(const char* pad_hash, 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,23 +101,25 @@ 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;
@@ -129,9 +131,16 @@ int interactive_mode(void) {
} }
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");
} }
@@ -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 (G/E/D/L/S/X): ");
} }
int handle_generate_menu(void) { int handle_generate_menu(void) {
@@ -559,9 +568,9 @@ 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, hash_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;
} }
@@ -743,9 +752,9 @@ 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, hash_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;
} }
@@ -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", hash_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");
@@ -816,9 +825,18 @@ int encrypt_text(const char* pad_identifier) {
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");
current_offset = 32;
if (write_state_offset(pad_hash, current_offset) != 0) {
printf("Warning: Failed to update state file\n");
}
}
// Calculate XOR checksum of pad file
if (calculate_checksum(pad_path, hash_hex) != 0) {
printf("Error: Cannot calculate pad checksum\n");
free(pad_hash); free(pad_hash);
return 1; return 1;
} }
@@ -988,8 +1006,8 @@ int decrypt_text(const char* pad_identifier) {
} }
// Verify pad integrity // Verify pad integrity
if (calculate_sha256(pad_path, current_hash) != 0) { if (calculate_checksum(pad_path, current_hash) != 0) {
printf("Error: Cannot calculate current pad hash\n"); printf("Error: Cannot calculate current pad checksum\n");
return 1; return 1;
} }
@@ -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;
} }
@@ -1329,8 +1347,8 @@ 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 hash, prefix, or number from list\n");