moochacha
Code Issues 2 Releases Activity
No description
10 commits 1 branch 0 tags 70 KiB
- C 70.3%
- Shell 21.8%
- Makefile 7.9%
main
HTTPS
Download ZIP Download TAR.GZ Download BUNDLE Open with VS Code Open with VSCodium Open with Intellij IDEA
| Repository files (latest commit first) | Filename | Latest commit message | Latest commit date |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ------------------ |
| Mark Dascher 0b50f03a7c
Add openssl.sh script to validate cryptographic primitives... Also reserve the real domain separation prefix for RELEASE builds only, since this sort of testing is risky. | 2023-02-28 22:52:17 -05:00 | | |
| .gitignore | Initial commit | 2022-11-06 13:23:02 -05:00 | |
| check.log | Add openssl.sh script to validate cryptographic primitives | 2023-02-28 22:52:17 -05:00 | |
| checker.sh | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| checks.sh | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| derive.c | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| derive.h | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| die.c | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| die.h | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| echo.c | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| echo.h | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| encrypt.c | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| encrypt.h | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| frama-fix.c | Add -k KEYFILE and -m MEMLIMIT command-line options | 2023-01-15 20:37:05 -05:00 | |
| frama.c | Explicitly disable buffering and prevent nonce overflow | 2023-02-13 21:19:55 -05:00 | |
| frama.log | Add openssl.sh script to validate cryptographic primitives | 2023-02-28 22:52:17 -05:00 | |
| io.c | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| io.h | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| LICENSE | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| main.c | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| main.h | Add openssl.sh script to validate cryptographic primitives | 2023-02-28 22:52:17 -05:00 | |
| Makefile | Add openssl.sh script to validate cryptographic primitives | 2023-02-28 22:52:17 -05:00 | |
| openssl.sh | Add openssl.sh script to validate cryptographic primitives | 2023-02-28 22:52:17 -05:00 | |
| padmoo.c | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| password.c | Add openssl.sh script to validate cryptographic primitives | 2023-02-28 22:52:17 -05:00 | |
| password.h | Add -k KEYFILE and -m MEMLIMIT command-line options | 2023-01-15 20:37:05 -05:00 | |
| README.md | Add padmoo proof-of-concept | 2023-02-20 12:53:37 -05:00 | |
| wrap.c | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
| wrap.h | Use IETF ChaCha20-Poly1305 AEAD | 2023-01-07 09:29:20 -05:00 | |
moochacha
WARNING: This is a personal project, unsafe for real data. Don't use it.
Encrypt files using a random keyfile, like enchive without public keys. Plain 256-bit encryption satisfies even the most paranoid quantum computing fears.
Each file's encryption key derives from a common keyfile plus a 256-bit random seed. Keep the keyfile secret. Its passphrase discourages only casual snooping, given that passphrases can be discovered by brute-force or hidden camera.
Currently uses Argon2id, BLAKE2b, and ChaCha20-Poly1305 from libsodium.
License
Copyright 2022-2023 Mark Dascher Licensed under the ISC License.
Specification
WARNING: All details are still subject to change.
Argon2id makes two passes of 1 GiB by default. The memory limit is adjustable between 1 MiB and 512 GiB, but only in even powers of two. Therefore, there are only 20 possibilities to try when the correct value is inevitably forgotten.
ChaCha20-Poly1305 refers to the IETF/TLS variant, having a 96-bit nonce. Here the nonce is treated as a single little-endian integer consisting of 12 bytes.
salt = 16 random bytes
keyP = Argon2id(salt, "ADIOS MOOCHACHA" || 0 || password)
keyW = 32 random bytes
wrap = ChaCha20-Poly1305(keyP, nonce=0, msg=keyW)
keyfile = (salt, wrap)After creating or unlocking the keyfile, encryption of plaintext can begin. The maximum file size is 2^108 + 8191 = 324,518,553,658,426,726,783,156,020,584,447 bytes which...ought to be enough for anybody?
A sequential 96-bit ChaCha20 nonce is exactly as safe as a random 192-bit XChaCha20 nonce, even without overflow checking. Still, go ahead and check for nonce overflow if you want, since it's mathematically the weakest point.
plaintext = (p0, p1, ..., pN); where p0 is 12288 bytes,
each inner p is 4096 bytes,
and pN is 0-4095 bytes.
or (p0); where p0 is 0-12287 bytes.seed = 32 random bytes
keyF = BLAKE2b-256(keyW, msg=seed)
c0 = ChaCha20-Poly1305(keyF, nonce=0, msg=p0)
c1 = ChaCha20-Poly1305(keyF, nonce=1, msg=p1)
...
cN = ChaCha20-Poly1305(keyF, nonce=N, msg=pN)
ciphertext = (seed, c0, c1, ..., cN); where c0 is 12304 bytes,
each inner c is 4112 bytes,
and cN is 16-4111 bytes.
or (seed, c0); where c0 is 16-12303 bytes.
When decrypting, the sequential nonce protects against reordering. To protect against truncation, confirm that pN < 4096 bytes or p0 < 12288 bytes.
Threat model
Suppose a cloud provider, criminal organization, or government quietly retains encrypted files for decades, waiting until decryption is feasible. Can we encrypt uploads safely enough to resist theoretical quantum attacks?
Of course, a government has plenty of old-fashioned tools to capture the common keyfile from your computer, but those require actual effort and target specific individuals. The goal is merely to protect against automated mass surveillance. The main exception involves malware, which can efficiently steal data and keys.
The 128-bit Poly1305 MAC might not resist future attacks, but that's not fatal as long as those attacks don't reveal or weaken the encryption key. If Poly1305 is broken, simply delete this program and never use it again.
Weaknesses
An adversary who manages to unlock the keyfile can decrypt every file ever encrypted. That's unavoidable for offline storage. An online protocol should rather exchange keys interactively, to achieve backward and forward secrecy.
Avoiding public-key cryptography is a tradeoff, since there's no way to take a private key offline. On the other hand, that's not always as useful as it sounds. For example, encrypted backups should be tested periodically to make sure the decryption key works. If there's a dedicated machine to validate backups, then why not encrypt the backups on that same machine?
Still, definitely consider that there may be a better tool for the job.
Static analysis and testing
All C code passes analysis using Cppcheck, Frama-C's Eva plugin, and Infer. There's also a custom test suite with full branch coverage. For details, see checker.sh, frama.log, and the Makefile.
TODO
This tool is incomplete and unsafe. A partial list of what's still needed:
The code is full of global variables and other anti-patterns, just for fun.
Usage
Build moochacha
The Makefile supports GCC and MSVC directly. To use Clang instead, delete `-fanalyzer` and `-flto-partition=none` from CFLAGS.
Before building on Linux, install `libsodium-dev` (Debian/Ubuntu), `libsodium-devel` (Fedora/RHEL), or a similar package.
## Linux
make lint
make
make checkBefore building on Windows, download and extract the libsodium MSVC pre-built library. Place the extracted `include` folder and dynamic `libsodium.lib` for your MSVC version into this project's root folder, along with `libsodium.dll`.
:: Windows
nmakeEncrypt a file
Encrypting uses an existing keyfile if available. Provide the passphrase when prompted. The default keyfile is `moochacha.key`.
Otherwise it creates a new keyfile and prompts for a passphrase. Every future encryption and decryption will ask for the same passphrase.
## Linux
moochacha <secret.txt >secret.txt.moo && rm secret.txt:: Windows
moochacha <secret.txt >secret.txt.moo && del secret.txtDecrypt a file
Decrypting requires the same keyfile used during encryption. Provide the passphrase when prompted.
## Linux
moochacha -d <secret.txt.moo >secret.txt && rm secret.txt.moo:: Windows
moochacha -d <secret.txt.moo >secret.txt && del secret.txt.mooOptions
The `-k` option selects a keyfile other than the default `moochacha.key`.
## Linux
moochacha -k ~/moochacha.key >secret.txt.moo
moochacha -dk ~/moochacha.key <secret.txt.moo:: Windows
moochacha -k "%USERPROFILE%\moochacha.key" >secret.txt.moo
moochacha -dk "%USERPROFILE%\moochacha.key" <secret.txt.mooThe `-m` option adjusts the Argon2 memory limit, 1 GiB by default. Stick with the default unless it needs to run on less RAM. A longer passphrase does more for security than any Argon2 settings. There are 20 possibilities:
1M 2M 4M 8M 16M 32M 64M 128M 256M 512M
1G 2G 4G 8G 16G 32G 64G 128G 256G 512GPadding
No padding is added by default. To conceal file sizes, add padding first. The included padmoo proof-of-concept adds a specific amount of padding to a plaintext file. Then, when that padded file is encrypted, the encrypted output matches one of the legal Padmé sizes.
This could be built into moochacha itself, but keeping it separate may protect against timing attacks. Besides, Padmé is just one possible padding scheme.
# Run padmoo before encrypting.
padmoo secret.txt
moochacha <secret.txt >secret.txt.moo && rm secret.txtRun padmoo after successfully decrypting, to remove the padding.
moochacha -d <secret.txt.moo >secret.txt && rm secret.txt.moo
padmoo secret.txt