6

markdascher/moochacha - moochacha - Codeberg.org

 1 year ago
source link: https://codeberg.org/markdascher/moochacha
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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.

This tool is incomplete and unsafe. A partial list of what's still needed:

  • Add password change feature.
  • Add typical command-line arguments.
  • Finish tweaking file format. Future revisions won't be backward-compatible.
  • Revisit obsolete or unusual techniques.
  • Windows handles CTRL+C inconsistently until bug 334 is fixed.
  • Windows only supports ASCII passwords until bug 4551 is fixed.

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 check

Before 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
nmake

Encrypt 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.txt

Decrypt 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.moo

Options

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.moo

The -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 512G

Padding

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.txt

# Run padmoo after successfully decrypting, to remove the padding.
moochacha -d <secret.txt.moo >secret.txt && rm secret.txt.moo
padmoo secret.txt

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK