diff --git a/.gitignore b/.gitignore index d0b9488..6f01cd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ pads/ Gemini.md + +# Auto-generated version files +src/version.h +src/version.c +VERSION diff --git a/Makefile b/Makefile index 62ad320..464b285 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,22 @@ CC = gcc CFLAGS = -Wall -Wextra -std=c99 LIBS = -lssl -lcrypto +LIBS_STATIC = -static -lssl -lcrypto -ldl -lpthread TARGET = otp SOURCE = otp.c +VERSION_SOURCE = src/version.c +# Default build target $(TARGET): $(SOURCE) - $(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(LIBS) + $(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(VERSION_SOURCE) $(LIBS) + +# Static linking target +static: $(SOURCE) + $(CC) $(CFLAGS) -o $(TARGET) $(SOURCE) $(VERSION_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/ @@ -16,4 +24,4 @@ install: uninstall: sudo rm -f /usr/local/bin/$(TARGET) -.PHONY: clean install uninstall +.PHONY: clean install uninstall static diff --git a/README.md b/README.md index 817f1cb..7e64982 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,164 @@ -# OTP Cipher v2.0 - Enhanced One Time Pad Implementation +# OTP Cipher - One Time Pad Implementation -A comprehensive and user-friendly One Time Pad (OTP) cryptographic system implemented in C for Linux, supporting massive pad sizes up to 10TB+ with both interactive and command-line interfaces. - -## New in Version 2.0 🚀 - -- **Interactive Menu System** - User-friendly menu-driven interface -- **Smart Size Parsing** - Supports K/KB/M/MB/G/GB/T/TB units -- **Partial Hash Matching** - Use hash prefixes or pad numbers for selection -- **Progress Indicators** - Real-time progress for large pad generation -- **10TB+ Support** - Generate massive pads for external drives -- **Enhanced Pad Management** - List, info, and usage statistics +A secure one-time pad (OTP) cipher implementation in C with automatic versioning system. ## Features -- **Cryptographically secure** random pad generation using `/dev/urandom` -- **ASCII armor format** similar to PGP for encrypted messages -- **Integrity verification** using SHA-256 hashing of pad files -- **State management** to prevent pad reuse -- **Interactive text encryption/decryption** -- **Hash-based file naming** for content verification -- **Read-only pad protection** prevents accidental corruption +- **Perfect Security**: Implements true one-time pad encryption with information-theoretic security +- **Keyboard Entropy**: Optional keyboard entropy collection for enhanced randomness +- **Automatic Versioning**: Built-in semantic versioning with automatic patch increment +- **Multiple Build Options**: Standard and static linking builds +- **Cross-Platform**: Works on Linux and other UNIX-like systems -## Dependencies +## Version Information -- OpenSSL development libraries (`libssl-dev` on Ubuntu/Debian) -- GCC compiler +This project uses an automatic versioning system that: +- Automatically increments the patch version on each build +- Embeds build timestamp, git commit hash, and branch information +- Creates git tags for version tracking +- Generates version header files with detailed build metadata -### Install dependencies on Ubuntu/Debian: -```bash -sudo apt update -sudo apt install libssl-dev build-essential -``` +Current version can be viewed with: `./otp --help` or by running the interactive mode. ## Building +### Prerequisites + +- GCC compiler +- OpenSSL development libraries (`libssl-dev` on Ubuntu/Debian) +- Git (for version tracking) +- Make + +### Build Commands + +Use the included build script for automatic versioning: + ```bash -make +# Standard build (default) +./build.sh build + +# Static linking build +./build.sh static + +# Clean build artifacts +./build.sh clean + +# Generate version files only +./build.sh version + +# Install to system +./build.sh install + +# Remove from system +./build.sh uninstall + +# Show usage +./build.sh help ``` -This will create the `otp` executable. +### Traditional Make -## Usage Modes +You can also use make directly (without automatic versioning): -### Interactive Mode (Recommended) +```bash +make # Standard build +make static # Static linking +make clean # Clean artifacts +make install # Install to /usr/local/bin/ +make uninstall # Remove from system +``` -Simply run the program without arguments: +## Usage +### Interactive Mode ```bash ./otp ``` -This launches a menu-driven interface: +### Command Line Mode +```bash +# Generate a new pad +./otp generate 1GB + +# Encrypt text (interactive input) +./otp encrypt + +# Decrypt message (interactive input) +./otp decrypt + +# List available pads +./otp list ``` -=== OTP Cipher Interactive Mode === -Version: OTP-CIPHER 2.0 + +## Version System Details + +### Automatic Version Increment +Every build automatically increments the patch version: +- v0.1.0 → v0.1.1 → v0.1.2, etc. +- Creates git tags for each version +- Embeds detailed build information + +### Manual Version Control +For major/minor releases, create tags manually: +```bash +# Feature release (minor bump) +git tag v0.2.0 # Next build: v0.2.1 + +# Breaking change (major bump) +git tag v1.0.0 # Next build: v1.0.1 +``` + +### Version Information Available +- Version number (major.minor.patch) +- Git commit hash and branch +- Build date and time +- Full version display with metadata + +### Generated Files +The build system automatically generates: +- `src/version.h` - Version constants and macros +- `src/version.c` - Version API functions +- `VERSION` - Plain text version number + +These files are excluded from git (.gitignore) and regenerated on each build. + +## Security Features + +- Uses `/dev/urandom` for cryptographically secure random number generation +- Optional keyboard entropy mixing using HKDF (Hash-based Key Derivation Function) +- SHA-256 pad integrity verification +- Read-only pad files to prevent accidental modification +- State tracking to prevent pad reuse + +## File Structure + +``` +otp/ +├── build.sh # Build script with automatic versioning +├── Makefile # Traditional make build system +├── otp.c # Main source code +├── README.md # This file +├── .gitignore # Git ignore rules +├── src/ # Generated version files (auto-created) +│ ├── version.h # Version header (generated) +│ └── version.c # Version implementation (generated) +├── pads/ # OTP pad storage directory (created at runtime) +└── VERSION # Plain text version (generated) +``` + +## Examples + +### Build and Version Tracking +```bash +$ ./build.sh build +[INFO] Incrementing version... +[INFO] Current version: v0.1.4 +[INFO] New version: v0.1.5 +[SUCCESS] Created new version tag: v0.1.5 +[SUCCESS] Build completed successfully + +$ ./otp +=== OTP Cipher v0.1.5 === === Main Menu === 1. Generate new pad @@ -62,212 +167,33 @@ Version: OTP-CIPHER 2.0 4. List available pads 5. Show pad information 6. Exit + +$ ./otp --help +OTP Cipher - One Time Pad Implementation v0.1.5 +Built on 2025-08-10 at 08:17:47 from commit 9edfa5f on branch master +Usage: + ./otp - Interactive mode + ... ``` -### Command Line Mode - -For automation and scripting: - +### Version History ```bash -./otp generate # Generate new pad -./otp encrypt # Encrypt text -./otp decrypt # Decrypt message -./otp list # List available pads +$ git tag --list +v0.1.0 +v0.1.1 +v0.1.2 +v0.1.3 +v0.1.4 +v0.1.5 ``` -## Smart Size Parsing +## License -The system intelligently parses size specifications: +This project includes automatic versioning system based on the Generic Automatic Version Increment System. -```bash -./otp generate 1024 # 1024 bytes -./otp generate 5MB # 5 megabytes -./otp generate 2GB # 2 gigabytes -./otp generate 10TB # 10 terabytes -./otp generate 1.5GB # 1.5 gigabytes (decimal supported) -``` +## Contributing -**Supported units:** K, KB, M, MB, G, GB, T, TB (case insensitive) - -## Pad Selection - -Multiple convenient ways to select pads: - -1. **Full hash**: `./otp encrypt a1b2c3d4e5f6789012345678901234567890abcdef...` -2. **Hash prefix**: `./otp encrypt a1b2c3d4` -3. **Pad number**: `./otp encrypt 1` (from list output) - -## Example Workflows - -### Basic Usage -```bash -# Generate a 1GB pad -./otp generate 1GB -Generated pad: a1b2c3d4e5f6789...123456.pad (1.00 GB) -Pad hash: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 - -# List available pads -./otp list -Available pads: -No. Hash (first 16 chars) Size Used ---- ------------------- ---------- ---------- -1 a1b2c3d4e5f67890 1.00GB 0.0MB - -# Encrypt using hash prefix -./otp encrypt a1b2 -Enter text to encrypt: Secret message ------BEGIN OTP MESSAGE----- -Version: OTP-CIPHER 2.0 -Pad-Hash: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 -Pad-Offset: 0 - -U2VjcmV0IG1lc3NhZ2U= ------END OTP MESSAGE----- -``` - -### Large Scale Usage -```bash -# Generate a 5TB pad for external drive -./otp generate 5TB -Progress: 100.0% (85.2 MB/s, ETA: 0s) -Generated pad: f9e8d7c6b5a4932...654321.pad (5.00 TB) - -# Use pad number for quick selection -./otp encrypt 1 -Enter text to encrypt: Classified information -``` - -### Interactive Mode Workflow -```bash -./otp -# Select option 1 to generate -# Enter size: 10GB -# Select option 2 to encrypt -# Choose pad from list -# Enter your message -``` - -## Security Features - -### Perfect Forward Secrecy -Each message uses a unique portion of the pad that is never reused, ensuring perfect forward secrecy. - -### Content-Based Integrity -- **SHA-256 file naming**: Pad files named by their hash ensure content verification -- **Integrity checking**: Embedded hashes detect pad corruption/tampering -- **Read-only protection**: Pad files automatically set to read-only after creation - -### ASCII Armor Format -Messages use a PGP-like ASCII armor format: -``` ------BEGIN OTP MESSAGE----- -Version: OTP-CIPHER 2.0 -Pad-Hash: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 -Pad-Offset: 0 - -U2VjcmV0IG1lc3NhZ2U= ------END OTP MESSAGE----- -``` - -### State Management -- **Automatic tracking**: Prevents pad reuse through state files -- **Portable state**: State stored separately from immutable pad data -- **Usage statistics**: Track pad consumption and remaining capacity - -## File Structure - -**Source Files:** -- `otp.c` - Complete implementation (850+ lines) -- `Makefile` - Build configuration -- `README.md` - This documentation - -**Generated Files:** -- `otp` - Compiled executable -- `.pad` - Pad files (read-only, hash-named) -- `.state` - State files (writable, tracks usage) - -## Advanced Features - -### Progress Indicators -For large pads, see real-time generation progress: -``` -Generating pad... -Progress: 45.2% (78.5 MB/s, ETA: 125s) -``` - -### Pad Information -Detailed statistics for each pad: -```bash -./otp list -No. Hash (first 16 chars) Size Used ---- ------------------- ---------- ---------- -1 a1b2c3d4e5f67890 5.00TB 2.1GB -2 f9e8d7c6b5a49321 1.00GB 0.5GB -``` - -### Multiple Pad Management -- List all available pads -- Show detailed information per pad -- Track usage across multiple pads -- Quick selection by number or prefix - -## Performance - -### Size Limits -- **Theoretical maximum**: 18 exabytes (uint64_t limit) -- **Practical maximum**: Limited by available disk space -- **Tested up to**: 10TB+ on modern systems -- **Generation speed**: ~80-120 MB/s (system dependent) - -### Memory Efficiency -- **Streaming operation**: Constant memory usage regardless of pad size -- **64KB buffers**: Efficient I/O without excessive memory consumption -- **Large file support**: Handles multi-terabyte pads efficiently - -## Security Notes - -⚠️ **Critical Security Requirements:** - -1. **Never reuse pad data** - Automatic prevention through state tracking -2. **Secure pad distribution** - Use secure channels for pad sharing -3. **Physical security** - Protect pad files like encryption keys -4. **Verify integrity** - Always check pad hash verification during decryption -5. **Secure systems** - Generate pads on trusted systems with good entropy - -## Installation - -### Local Installation -```bash -make install # Install to /usr/local/bin -make uninstall # Remove from system -``` - -### Clean Up -```bash -make clean # Remove compiled files and generated pads -``` - -## Technical Specifications - -- **Entropy source**: `/dev/urandom` (cryptographically secure) -- **Hash algorithm**: SHA-256 for integrity verification -- **Encoding**: Base64 for ciphertext representation -- **File format**: ASCII armor with embedded metadata -- **Architecture**: Single C file, ~850 lines -- **Dependencies**: OpenSSL libcrypto -- **Platform**: Linux (easily portable) - -## Theory - -A One Time Pad is theoretically unbreakable when implemented correctly with: -- **Perfect randomness**: Cryptographically secure entropy -- **Key length**: Equal to or greater than message length -- **Single use**: Each pad portion used exactly once -- **Secure distribution**: Pads shared through secure channels - -This implementation satisfies all requirements for perfect cryptographic security while providing modern usability features for practical deployment. - -## Version History - -- **v2.0**: Interactive mode, smart parsing, 10TB+ support, enhanced UX -- **v1.0**: Basic command-line implementation with hash-based naming +When contributing: +1. The version will automatically increment on builds +2. For major features, consider manually creating minor version tags +3. Generated version files (`src/version.*`, `VERSION`) should not be committed diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e2c5b4d --- /dev/null +++ b/build.sh @@ -0,0 +1,227 @@ +#!/bin/bash +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +print_status() { echo -e "${BLUE}[INFO]${NC} $1"; } +print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } +print_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +# Function to automatically increment version +increment_version() { + print_status "Incrementing version..." + + # Check if we're in a git repository + if ! git rev-parse --git-dir > /dev/null 2>&1; then + print_warning "Not in a git repository - skipping version increment" + return 0 + fi + + # Get the highest version tag (not chronologically latest) + LATEST_TAG=$(git tag -l 'v*.*.*' | sort -V | tail -n 1 || echo "v0.1.0") + if [[ -z "$LATEST_TAG" ]]; then + LATEST_TAG="v0.1.0" + fi + + # Extract version components (remove 'v' prefix) + VERSION=${LATEST_TAG#v} + + # Parse major.minor.patch using regex + if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + MAJOR=${BASH_REMATCH[1]} + MINOR=${BASH_REMATCH[2]} + PATCH=${BASH_REMATCH[3]} + else + print_error "Invalid version format in tag: $LATEST_TAG" + print_error "Expected format: v0.1.0" + return 1 + fi + + # Increment patch version + NEW_PATCH=$((PATCH + 1)) + NEW_VERSION="v${MAJOR}.${MINOR}.${NEW_PATCH}" + + print_status "Current version: $LATEST_TAG" + print_status "New version: $NEW_VERSION" + + # Create new git tag + if git tag "$NEW_VERSION" 2>/dev/null; then + print_success "Created new version tag: $NEW_VERSION" + else + print_warning "Tag $NEW_VERSION already exists - using existing version" + NEW_VERSION=$LATEST_TAG + # Re-extract version components for existing tag + VERSION=${NEW_VERSION#v} + if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + MAJOR=${BASH_REMATCH[1]} + MINOR=${BASH_REMATCH[2]} + NEW_PATCH=${BASH_REMATCH[3]} + fi + fi + + # Update VERSION file for compatibility + echo "${NEW_VERSION#v}" > VERSION + print_success "Updated VERSION file to ${NEW_VERSION#v}" + + # Generate version.h header file + mkdir -p src + cat > src/version.h << EOF +/* + * Auto-Generated Version Header + * DO NOT EDIT THIS FILE MANUALLY - Generated by build script + */ + +#ifndef VERSION_H +#define VERSION_H + +#define VERSION_MAJOR ${MAJOR} +#define VERSION_MINOR ${MINOR} +#define VERSION_PATCH ${NEW_PATCH} +#define VERSION_STRING "${MAJOR}.${MINOR}.${NEW_PATCH}" +#define VERSION_TAG "${NEW_VERSION}" + +/* Build information */ +#define BUILD_DATE "$(date +%Y-%m-%d)" +#define BUILD_TIME "$(date +%H:%M:%S)" +#define BUILD_TIMESTAMP "$(date '+%Y-%m-%d %H:%M:%S')" + +/* Git information */ +#define GIT_HASH "$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" +#define GIT_BRANCH "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" + +/* Display versions */ +#define VERSION_DISPLAY "${NEW_VERSION}" +#define VERSION_FULL_DISPLAY "${NEW_VERSION} ($(date '+%Y-%m-%d %H:%M:%S'), $(git rev-parse --short HEAD 2>/dev/null || echo 'unknown'))" + +/* Version API functions */ +const char* get_version(void); +const char* get_version_full(void); +const char* get_build_info(void); + +#endif /* VERSION_H */ +EOF + + # Generate version.c implementation file + cat > src/version.c << EOF +/* + * Auto-Generated Version Implementation + * DO NOT EDIT THIS FILE MANUALLY - Generated by build script + */ + +#include "version.h" + +const char* get_version(void) { + return VERSION_TAG; +} + +const char* get_version_full(void) { + return VERSION_FULL_DISPLAY; +} + +const char* get_build_info(void) { + return "Built on " BUILD_DATE " at " BUILD_TIME " from commit " GIT_HASH " on branch " GIT_BRANCH; +} +EOF + + print_success "Generated version header files" +} + +# Build functions +build_project() { + print_status "Cleaning previous build..." + make clean + increment_version + print_status "Building OTP project..." + make + if [ $? -eq 0 ]; then + print_success "Build completed successfully" + else + print_error "Build failed" + return 1 + fi +} + +build_static() { + print_status "Cleaning previous build..." + make clean + increment_version + print_status "Building OTP project with static linking..." + make static + if [ $? -eq 0 ]; then + print_success "Static build completed successfully" + else + print_error "Static build failed" + return 1 + fi +} + +clean_project() { + print_status "Cleaning build artifacts..." + make clean + rm -f VERSION src/version.h src/version.c + print_success "Clean completed" +} + +install_project() { + print_status "Installing OTP project..." + make install + if [ $? -eq 0 ]; then + print_success "Installation completed" + else + print_error "Installation failed" + return 1 + fi +} + +uninstall_project() { + print_status "Uninstalling OTP project..." + make uninstall + if [ $? -eq 0 ]; then + print_success "Uninstallation completed" + else + print_error "Uninstallation failed" + return 1 + fi +} + +# Main script logic +case "${1:-build}" in + build) + build_project + ;; + static) + build_static + ;; + clean) + clean_project + ;; + install) + install_project + ;; + uninstall) + uninstall_project + ;; + version) + increment_version + print_status "Version information generated" + ;; + *) + echo "OTP Cipher Build Script" + echo "Usage: $0 {build|static|clean|install|uninstall|version}" + echo "" + echo "Commands:" + echo " build - Build project with automatic version increment (default)" + echo " static - Build with static linking" + echo " clean - Clean build artifacts and generated files" + echo " install - Install to system (requires build first)" + echo " uninstall - Remove from system" + echo " version - Generate version files only" + exit 1 + ;; +esac diff --git a/otp b/otp index c1a42a6..fda1b7f 100755 Binary files a/otp and b/otp differ diff --git a/otp.c b/otp.c index b19c645..7d9fb70 100644 --- a/otp.c +++ b/otp.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 200809L +#define _DEFAULT_SOURCE #include #include @@ -17,11 +18,11 @@ #include #include #include +#include "src/version.h" #define MAX_INPUT_SIZE 4096 #define MAX_LINE_LENGTH 1024 #define MAX_HASH_LENGTH 65 -#define VERSION_STRING "OTP-CIPHER 2.0" #define PROGRESS_UPDATE_INTERVAL (64 * 1024 * 1024) // 64MB intervals #define PADS_DIR "pads" #define MAX_ENTROPY_BUFFER 32768 // 32KB entropy buffer @@ -81,8 +82,7 @@ int main(int argc, char* argv[]) { } int interactive_mode(void) { - printf("=== OTP Cipher Interactive Mode ===\n"); - printf("Version: %s\n\n", VERSION_STRING); + printf("=== OTP Cipher %s ===\n\n", get_version()); while (1) { show_main_menu(); @@ -364,7 +364,7 @@ int list_available_pads(void) { hash[64] = '\0'; // Get pad file size - char full_path[MAX_HASH_LENGTH + 20]; + char full_path[300]; // Increased buffer size to accommodate longer paths snprintf(full_path, sizeof(full_path), "%s/%s", PADS_DIR, entry->d_name); struct stat st; if (stat(full_path, &st) == 0) { @@ -639,7 +639,6 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use unsigned char urandom_buffer[64 * 1024]; // 64KB buffer unsigned char output_buffer[64 * 1024]; uint64_t bytes_written = 0; - time_t start_time = time(NULL); if (display_progress) { printf("Generating pad...\n"); @@ -803,7 +802,6 @@ int encrypt_text(const char* pad_identifier) { return 1; } - char pad_filename[MAX_HASH_LENGTH + 10]; char input_text[MAX_INPUT_SIZE]; char hash_hex[MAX_HASH_LENGTH]; uint64_t current_offset; @@ -913,7 +911,7 @@ int encrypt_text(const char* pad_identifier) { // Output in ASCII armor format printf("\n-----BEGIN OTP MESSAGE-----\n"); - printf("Version: %s\n", VERSION_STRING); + printf("Version: %s\n", get_version()); printf("Pad-Hash: %s\n", hash_hex); printf("Pad-Offset: %lu\n", current_offset); printf("\n"); @@ -1334,7 +1332,8 @@ unsigned char* base64_decode(const char* input, int* output_length) { } void print_usage(const char* program_name) { - printf("OTP Cipher - One Time Pad Implementation v2.0\n"); + printf("OTP Cipher - One Time Pad Implementation %s\n", get_version()); + printf("%s\n", get_build_info()); printf("Usage:\n"); printf(" %s - Interactive mode\n", program_name); printf(" %s generate - Generate new pad\n", program_name);