Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
kr
*.bak
*.exe
*.o
*.profraw
*.profdata
*~
tmp
test.out
cov
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ AEAD interface of Monocypher to encrypt/decrypt files using
`kr` offers two modes of operation:

- Keyfile-based: a private key is stored on the user's machine and is used to
encrypt and decrypt files.
encrypt and decrypt files.

- Passphrase-based: an encryption/decryption key is generated, on the fly, using
Argon2i (with a random salt).
Expand Down Expand Up @@ -65,7 +65,7 @@ _same_ pair (passphrase, userID) on every invocation. For example:
```
$ kr -guUSERID -p"PASS PHRASE" ~/key.sec
```
Or
Or

```
$ kr -g --uid=USERID --passphrase="PASS PHRASE" ~/key.sec
Expand Down Expand Up @@ -133,7 +133,7 @@ $ kr --decrypt --keyfile ~/.key.sec inputfile outputfile

Instead of using key files, we can use passphrases as follows:

##### Encryption `-e -p`
##### Encryption `-e -p` / `-e -E`

```
$ kr -e -p"PASS PHRASE" inputfile outputfile
Expand All @@ -149,7 +149,15 @@ We can also use the long options:
$ kr --encrypt --passphrase="PASS PHRASE" inputfile outputfile
```

##### Decryption `-d -p`
Alternatively use `-E` / `--envvar` to pick up password from an operating
system environment variable:

```
$ env PASSPHRASE="PASS PHRASE" kr --encrypt -E=PASSPHRASE inputfile outputfile
$ env PASSPHRASE="PASS PHRASE" kr --encrypt --envvar=PASSPHRASE inputfile outputfile
```

##### Decryption `-d -p` / `-d -E`

```
$ kr -d -p"PASS PHRASE" inputfile outputfile
Expand All @@ -165,6 +173,15 @@ Or using the long options:
$ kr --decrypt --passphrase="PASS PHRASE" inputfile outputfile
```

Alternatively use `-E` / `--envvar` to pick up password from an operating
system environment variable:

```
$ env PASSPHRASE="PASS PHRASE" kr --decrypt -E=PASSPHRASE inputfile outputfile
$ env PASSPHRASE="PASS PHRASE" kr --decrypt --envvar=PASSPHRASE inputfile outputfile
```


### Support for streams

`kr` is able to process streams as well. For instance, these examples with
Expand All @@ -173,7 +190,7 @@ pipes:
```
$ echo 'Hello, world!' | kr -epPASS | kr -dpPASS
```
or with keyfiles
or with keyfiles

```
$ echo 'Hello, world!' | kr -ek ~/.key.sec | kr -dk ~/.key.sec
Expand Down
4 changes: 4 additions & 0 deletions kr.1
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ Use the passphrase \fB[pass]\fR for for operations. If the passphrase is not
specified, prompt the user to type it (Twice for encryption and keyfile
generation. Once for decryption).
.TP
\fB\-E\fR, \fB\-\-envvar\fR \fI[pass]\fP
Use the passphrase contained in the operating system environment variable
\fB[pass]\fR for operations.
.TP
\fB\-u\fR, \fB\-\-uid\fR \fI<uid>\fP
Use \fB<uid>\fR for key generation (\fB\-g\fR). Use \fB<uid>\fR for
reproductible key generation (\-g). When used, the program will ask for a
Expand Down
34 changes: 27 additions & 7 deletions src/kr.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
// backward compatibility issues.

#define PROG "kr"
#define PROG_VERSION "0.2" // The program's version.
#define PROG_VERSION "0.3" // The program's version.
#define FILE_VERSION 0 // Encrypted files format version.
#define KEYFILE_VERSION 0 // keyfiles format version.
#define KEY_SIZE 32
Expand Down Expand Up @@ -221,6 +221,10 @@ static const char *usage[] = {
" user to type it (Twice for encryption and",
" keyfile generation. Once for decryption).",
"",
" -E | --envvar=[pass] Use the passphrase contained in the operating",
" system environment variable [pass] for operations.",
" TODO doc priority versus passphrase",
"",
" -u | --uid=<uid> Use <uid> for key generation (-g).",
" When used, the program will ask for a passphrase",
" in order to generate a deterministic key, i.e., ",
Expand Down Expand Up @@ -264,7 +268,7 @@ static enum error encrypt(FILE *in, FILE *out, const uint8_t key[KEY_SIZE],
uint8_t *ad = (eof) ? END_TAG : NULL; // if last chunk, tag it.
size_t adlen = (eof) ? 4 : 0;

// Arguments order:
// Arguments order:
// ctx, cipher_text, mac, ad, ad_size, plain_text, text_size.
// The mac comes after the encrypted chunk, thus:
// - the mac is located at buf_out + len, and
Expand Down Expand Up @@ -318,7 +322,7 @@ static enum error decrypt(FILE *in, FILE *out, const uint8_t key[KEY_SIZE],
uint8_t *ad = (eof) ? END_TAG : 0; // last chunk should've been tagged.
size_t adlen = (eof) ? 4 : 0;

// Arguments order:
// Arguments order:
// ctx, plain_text, mac, ad, ad_size, cipher_text, text_size.
// The read 'len' bytes from 'in' already includes the mac, thus:
// - the mac is located at buf_in + len - MAC_SIZE, and
Expand All @@ -343,7 +347,7 @@ static enum error decrypt(FILE *in, FILE *out, const uint8_t key[KEY_SIZE],
}

// Generate a key_size bytes key from a passphrase and a salt (random)
// using Argon2i (with configuration in 'config', inputs (password and salt)
// using Argon2i (with configuration in 'config', inputs (password and salt)
// data in 'inputs'), and extras (key and ad). This needs a work area that
// has to be allocated. If this allocation fails, securely wipe inputs and
// extras and exit.
Expand Down Expand Up @@ -448,7 +452,7 @@ static enum error read_keyfile(FILE *kf, uint8_t key[KEY_SIZE])
// Inspect the protection-version byte, and get its MSB.
int protected = *version >> 7;
if (!protected) {
// Key is not protected. Copy the last KEY_SIZE bytes.
// Key is not protected. Copy the last KEY_SIZE bytes.
memcpy(key, fkey, KEY_SIZE);
} else {
// Ask the user to provide a passphrase to decrypt the key.
Expand Down Expand Up @@ -581,6 +585,7 @@ int main(int argc, char *argv[])
{"decrypt", 'd', OPTPARSE_NONE},
{"keyfile", 'k', OPTPARSE_REQUIRED},
{"passphrase", 'p', OPTPARSE_OPTIONAL},
{"envvar", 'E', OPTPARSE_OPTIONAL},
{"uid", 'u', OPTPARSE_REQUIRED},
{"keyedit", 'm', OPTPARSE_REQUIRED},
{"help", 'h', OPTPARSE_NONE},
Expand All @@ -602,6 +607,7 @@ int main(int argc, char *argv[])
char *keyfile = NULL;
char *infile = NULL;
char *outfile = NULL;
char *passphrase_env_ptr = NULL;
FILE *kf = NULL;
FILE *in = NULL;
FILE *out = NULL;
Expand Down Expand Up @@ -643,6 +649,20 @@ int main(int argc, char *argv[])
memcpy(passphrase, options.optarg, pwlen);
}
break;
case 'E':
use_passphrase = 1;
if (options.optarg) {
passphrase_env_ptr = getenv(options.optarg);
if (passphrase_env_ptr == NULL) {
BAIL(ERR_PASS_READ_FAIL);
}
pwlen = strlen(passphrase_env_ptr) + 1;
if (pwlen > MAXPASS) {
BAIL(ERR_PASS_TOO_BIG);
}
memcpy(passphrase, passphrase_env_ptr, pwlen);
}
break;
case 'u':
use_passphrase = 1;
if (options.optarg) {
Expand Down Expand Up @@ -722,7 +742,7 @@ int main(int argc, char *argv[])
BAIL(ERR_NO_RANDOM);
}
// If the key to be generated depends on a uid and a passphrase,
// generate a deterministic one with the same value when given
// generate a deterministic one with the same value when given
// the same uid and passphrase.
if (use_passphrase) {
// Hash the uid to use it as a salt for key derivation.
Expand Down Expand Up @@ -830,7 +850,7 @@ int main(int argc, char *argv[])
}

// Clean everything and exit.
bail:
bail:
// Safely wipe sensitive info.
crypto_wipe(key, KEY_SIZE);
crypto_wipe(passphrase, MAXPASS);
Expand Down
4 changes: 2 additions & 2 deletions tests/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ static int p_encrypt_decrypt(void)
fsize = 0;
}
if (DEBUG) {
printf(YELLOW "\tFile size:" BLUE " %lu bytes\n", fsize);
printf(YELLOW "\tFile size:" BLUE " %" PRIu64 " bytes\n", fsize);
}
fillrand(data, fsize);
fillrand(key, KEY_SIZE);
Expand Down Expand Up @@ -428,7 +428,7 @@ int p_password_enc_dec(void)
}

if (DEBUG) {
printf(YELLOW "\tFile size:" BLUE " %lu bytes\n", fsize);
printf(YELLOW "\tFile size:" BLUE " %" PRIu64 " bytes\n", fsize);
}

fillrand(data, fsize);
Expand Down