diff --git a/cmd/carp/README.md b/cmd/carp/README.md deleted file mode 100644 index 116de6c..0000000 --- a/cmd/carp/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# Carp: Secure Your Data with Ease - -**Carp** is a versatile tool for encryption, decryption, and secure file wiping. Designed with simplicity and security in mind. -This uses chacha20poly1305 cipher and scrypt [library](https://github.com/8ff/cipherbox). - -## Features -- **Encrypt** (`e`): Secure your data with strong encryption. (Requires `CKEY` environment variable) -- **Decrypt** (`d`): Decrypt your data to restore it to its original form. (Requires `CKEY` environment variable) -- **Wipe** (`w`,`wipe`): Permanently and securely erase files, leaving no trace behind. - -## Installation -Download the latest release of Carp from the [GitHub Releases](https://github.com/8ff/cipherbox/releases/tag/latest). - -1. Download the binary for your platform. -2. Make it executable: - - ```bash - chmod +x carp - ``` - -3. Run the binary from the download location or place it in your system PATH for easy access. - -## Usage - -### Encrypting Data -To encrypt a file, ensure the `CKEY` environment variable is set with a 32-byte key. If the key is shorter, it will be padded using a Fibonacci sequence, which is not secure. It is highly recommended to use a key of the correct length. - -```bash -CKEY="your-32-byte-key" ./carp e < plaintext.txt > encrypted.txt -``` - -### Decrypting Data -Decrypt your previously encrypted files with the correct key: - -```bash -CKEY="your-32-byte-key" ./carp d < encrypted.txt > plaintext.txt -``` - -### Securely Wiping Files -To securely delete a file, use the wipe command: - -```bash -./carp wipe /path/to/your/file.txt -``` -### Dont prompt for confirmation -```bash -FORCE_WIPE=true ./carp wipe /path/to/your/file.txt -``` - -### Help -For assistance and a summary of available commands: - -```bash -./carp help -``` - -## Key Length Requirement -Your encryption key must be exactly 32 bytes long. If it's shorter, it will be padded using a Fibonacci sequence, which is not recommended for secure encryption. Ensure your key is the correct length to maintain the highest level of security. - -## Contributing -Contributions are welcome. If you encounter any issues or have suggestions for improvements, please open an issue or submit a pull request. diff --git a/cmd/carp/carp.go b/cmd/carp/carp.go deleted file mode 100644 index 5aeea0a..0000000 --- a/cmd/carp/carp.go +++ /dev/null @@ -1,156 +0,0 @@ -package main - -import ( - "fmt" - "log" - "os" - "path/filepath" - - cipher "github.com/8ff/cipherbox/pkg/cc2p1305_scrypt" - "github.com/8ff/cipherbox/pkg/wipe" -) - -const ( - expectedKeyLength = 32 // Adjust based on your encryption algorithm's requirements - fibonacciIterations = 10000 // Number of Fibonacci iterations to generate -) - -func main() { - defer handlePanic() // Ensure key is wiped even on panic - - // Display help menu if no arguments are provided or if help is requested - if len(os.Args) < 2 || os.Args[1] == "help" || os.Args[1] == "--help" || os.Args[1] == "-h" { - showUsageAndExit() - } - - // Handle the command - switch os.Args[1] { - case "e", "d": - key := getKeyFromEnv("CKEY") - c, err := cipher.Init(cipher.Params{KeySize: len(key), Key: key}) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to initialize cipher: %v", err) - os.Exit(1) - } - defer wipeKey(&key) // Securely wipe the key from memory after usage - - if os.Args[1] == "e" { - if err := c.StreamEncrypt(os.Stdin, os.Stdout, 1024); err != nil { - fmt.Fprintf(os.Stderr, "Failed to encrypt data: %v\n", err) - os.Exit(1) - } - } else { - if err := c.StreamDecrypt(os.Stdin, os.Stdout, 1024); err != nil { - fmt.Fprintf(os.Stderr, "Failed to decrypt data: %v\n", err) - os.Exit(1) - } - } - - case "w", "wipe": - if len(os.Args) != 3 { - fmt.Fprintf(os.Stderr, "Usage: %s wipe \n", filepath.Base(os.Args[0])) - os.Exit(1) - } - wipePath := os.Args[2] - handleWipeCommand(wipePath) - - default: - showUsageAndExit() - } -} - -func getKeyFromEnv(envVar string) []byte { - key := []byte(os.Getenv(envVar)) - if len(key) == 0 { - log.Fatalf("%s env var not set", envVar) - } - if len(key) < expectedKeyLength { - key = extendKeyWithFibonacci(key, expectedKeyLength) - } - if len(key) != expectedKeyLength { - log.Fatalf("Invalid key length: expected %d bytes, got %d", expectedKeyLength, len(key)) - } - return key -} - -func extendKeyWithFibonacci(key []byte, desiredLength int) []byte { - fib := fibonacciSequence(fibonacciIterations) - extraLength := desiredLength - len(key) - - // Take the last `extraLength` bytes from the Fibonacci sequence - for i := len(fib) - extraLength; i < len(fib); i++ { - key = append(key, byte(fib[i]%256)) - } - return key -} - -func fibonacciSequence(n int) []int { - fib := make([]int, n) - if n > 0 { - fib[0] = 1 - } - if n > 1 { - fib[1] = 1 - } - for i := 2; i < n; i++ { - fib[i] = fib[i-1] + fib[i-2] - } - return fib -} - -func wipeKey(data *[]byte) { - if data != nil { - for i := range *data { - (*data)[i] = 0 - } - } -} - -func handlePanic() { - if r := recover(); r != nil { - fmt.Println("Recovered from panic, ensuring data is wiped") - var key []byte - wipeKey(&key) - } -} - -func handleWipeCommand(wipePath string) { - if _, err := os.Stat(wipePath); os.IsNotExist(err) { - fmt.Fprintf(os.Stderr, "Path does not exist: %s\n", wipePath) - os.Exit(1) - } - - // If env var FORCE_WIPE is set, wipe the path without confirmation - var confirm string - if os.Getenv("FORCE_WIPE") != "true" { - fmt.Printf("WARNING! Are you sure you want to wipe [%s]?\nType \"y\" to confirm\n", wipePath) - fmt.Scanln(&confirm) - } else { - confirm = "y" - } - if confirm == "y" { - if err := wipe.Wipe(wipePath, 10); err != nil { - fmt.Fprintf(os.Stderr, "Failed to wipe the path: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println("Action cancelled!") - os.Exit(1) - } - os.Exit(0) -} - -func showUsageAndExit() { - binaryName := filepath.Base(os.Args[0]) - fmt.Fprintf(os.Stderr, "Usage: %s [options]\n", binaryName) - fmt.Fprintf(os.Stderr, "Commands:\n") - fmt.Fprintf(os.Stderr, " e Encrypt data from stdin to stdout (requires CKEY env var)\n") - fmt.Fprintf(os.Stderr, " d Decrypt data from stdin to stdout (requires CKEY env var)\n") - fmt.Fprintf(os.Stderr, " wipe Securely wipe the specified file\n") - fmt.Fprintf(os.Stderr, " help Display this help menu\n") - fmt.Fprintf(os.Stderr, "Examples:\n") - fmt.Fprintf(os.Stderr, " %s e < inputfile > outputfile Encrypt inputfile and save to outputfile\n", binaryName) - fmt.Fprintf(os.Stderr, " %s d < inputfile > outputfile Decrypt inputfile and save to outputfile\n", binaryName) - fmt.Fprintf(os.Stderr, " %s wipe /path/to/file Securely wipe the specified file\n", binaryName) - os.Exit(1) -} diff --git a/cmd/carp/testValidity.sh b/cmd/carp/testValidity.sh deleted file mode 100755 index fa25720..0000000 --- a/cmd/carp/testValidity.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -function fail { - echo "Test failed: $1" - exit 1 -} - -dd if=/dev/urandom of=randomData bs=1M count=1000 2>/dev/null || fail "Failed to generate random data" -CKEY=test go run carp.go e < randomData > encryptedData || fail "Failed to encrypt data" -CKEY=test go run carp.go d < encryptedData > decryptedData || fail "Failed to decrypt data" -# Check if on macOS, use md5 instead of md5sum -if [ "$(uname)" == "Darwin" ]; then - md5 randomData decryptedData || fail "Decrypted data does not match original data" -else - md5sum randomData decryptedData || fail "Decrypted data does not match original data" -fi -rm randomData encryptedData decryptedData || fail "Failed to clean up" \ No newline at end of file