Skip to content

Instantly share code, notes, and snippets.

@jedisct1
Last active November 9, 2017 13:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedisct1/16c8b56ebd4624526b7665c47dcd0aca to your computer and use it in GitHub Desktop.
Save jedisct1/16c8b56ebd4624526b7665c47dcd0aca to your computer and use it in GitHub Desktop.
secretstream example
#include <stdio.h>
#include <sodium.h>
#define CHUNK_SIZE 4096
static int
encrypt(const char *target_file, const char *source_file,
const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES])
{
unsigned char buf_in[CHUNK_SIZE];
unsigned char buf_out[CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
crypto_secretstream_xchacha20poly1305_state st;
FILE *fp_t, *fp_s;
unsigned long long out_len;
size_t rlen;
int eof;
unsigned char tag;
fp_s = fopen(source_file, "rb");
fp_t = fopen(target_file, "wb");
crypto_secretstream_xchacha20poly1305_init_push(&st, header, key);
fwrite(header, 1, sizeof header, fp_t);
do {
rlen = fread(buf_in, 1, sizeof buf_in, fp_s);
eof = feof(fp_s);
tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
crypto_secretstream_xchacha20poly1305_push(&st, buf_out, &out_len, buf_in, rlen,
NULL, 0, tag);
fwrite(buf_out, 1, (size_t) out_len, fp_t);
} while (! eof);
fclose(fp_t);
fclose(fp_s);
return 0;
}
static int
decrypt(const char *target_file, const char *source_file,
const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES])
{
unsigned char buf_in[CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
unsigned char buf_out[CHUNK_SIZE];
unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
crypto_secretstream_xchacha20poly1305_state st;
FILE *fp_t, *fp_s;
unsigned long long out_len;
size_t rlen;
int eof;
int ret = -1;
unsigned char tag;
fp_s = fopen(source_file, "rb");
fp_t = fopen(target_file, "wb");
fread(header, 1, sizeof header, fp_s);
if (crypto_secretstream_xchacha20poly1305_init_pull(&st, header, key) != 0) {
goto ret;
}
do {
rlen = fread(buf_in, 1, sizeof buf_in, fp_s);
eof = feof(fp_s);
if (crypto_secretstream_xchacha20poly1305_pull(&st, buf_out, &out_len, &tag,
buf_in, rlen, NULL, 0) != 0) {
goto ret; /* corrupted chunk */
}
if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL && ! eof) {
goto ret; /* premature end */
}
fwrite(buf_out, 1, (size_t) out_len, fp_t);
} while (! eof);
ret = 0;
ret:
fclose(fp_t);
fclose(fp_s);
return ret;
}
int
main(void)
{
unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
if (sodium_init() != 0) {
return 1;
}
crypto_secretstream_xchacha20poly1305_keygen(key);
if (encrypt("/tmp/encrypted", "/tmp/original", key) != 0) {
return 1;
}
if (decrypt("/tmp/decrypted", "/tmp/encrypted", key) != 0) {
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment