iEncrypt/authenticate snapshot metadata - dedup - deduplicating backup program Err bitreich.org 70
hgit clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ URL:git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ bitreich.org 70
1Log /scm/dedup/log.gph bitreich.org 70
1Files /scm/dedup/files.gph bitreich.org 70
1Refs /scm/dedup/refs.gph bitreich.org 70
1Tags /scm/dedup/tag bitreich.org 70
1README /scm/dedup/file/README.gph bitreich.org 70
1LICENSE /scm/dedup/file/LICENSE.gph bitreich.org 70
i--- Err bitreich.org 70
1commit 72ba1a8a75b1990156ec209538cc00498efcb43d /scm/dedup/commit/72ba1a8a75b1990156ec209538cc00498efcb43d.gph bitreich.org 70
1parent 9c6cdcc42dc9b0def23ed2839cb528f3867f9cfb /scm/dedup/commit/9c6cdcc42dc9b0def23ed2839cb528f3867f9cfb.gph bitreich.org 70
hAuthor: sin <sin@2f30.org> URL:mailto:sin@2f30.org bitreich.org 70
iDate: Sun, 12 May 2019 15:24:55 +0100 Err bitreich.org 70
i Err bitreich.org 70
iEncrypt/authenticate snapshot metadata Err bitreich.org 70
i Err bitreich.org 70
iDiffstat: Err bitreich.org 70
i M bencrypt.c | 2 +- Err bitreich.org 70
i M snap.c | 197 +++++++++++++++++++++++++------ Err bitreich.org 70
i Err bitreich.org 70
i2 files changed, 160 insertions(+), 39 deletions(-) Err bitreich.org 70
i--- Err bitreich.org 70
1diff --git a/bencrypt.c b/bencrypt.c /scm/dedup/file/bencrypt.c.gph bitreich.org 70
i@@ -112,7 +112,7 @@ becreat(struct bctx *bctx, char *path, int mode) Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i- /* Ensure that if caller requested encryption, a key was provided */ Err bitreich.org 70
i+ /* Ensure a key has been provided if caller requested encryption */ Err bitreich.org 70
i if (type != EDNONETYPE && !param.keyloaded) { Err bitreich.org 70
i seterr("expected encryption key"); Err bitreich.org 70
i return -1; Err bitreich.org 70
1diff --git a/snap.c b/snap.c /scm/dedup/file/snap.c.gph bitreich.org 70
i@@ -10,6 +10,7 @@ Err bitreich.org 70
i #include <stdio.h> Err bitreich.org 70
i #include <stdlib.h> Err bitreich.org 70
i #include <string.h> Err bitreich.org 70
i+#include <strings.h> Err bitreich.org 70
i #include <unistd.h> Err bitreich.org 70
i Err bitreich.org 70
i #include <sodium.h> Err bitreich.org 70
i@@ -18,6 +19,7 @@ Err bitreich.org 70
i #include "misc.h" Err bitreich.org 70
i #include "queue.h" Err bitreich.org 70
i #include "snap.h" Err bitreich.org 70
i+#include "state.h" Err bitreich.org 70
i Err bitreich.org 70
i /* snapshot header constants */ Err bitreich.org 70
i #define SHDRMAGIC "SNAPSNAPPYSNOOP" Err bitreich.org 70
i@@ -29,7 +31,9 @@ Err bitreich.org 70
i #define VMAJSHIFT 8 Err bitreich.org 70
i #define VMAJMASK 0xff Err bitreich.org 70
i Err bitreich.org 70
i-#define SHDRSIZE (NSHDRMAGIC + 24 + 24 + 8 + 8) Err bitreich.org 70
i+#define SHDRSIZE (NSHDRMAGIC + 24 + 8 + 8) Err bitreich.org 70
i+ Err bitreich.org 70
i+extern struct param param; Err bitreich.org 70
i Err bitreich.org 70
i /* misc helpers */ Err bitreich.org 70
i extern int pack(unsigned char *, char *, ...); Err bitreich.org 70
i@@ -38,7 +42,6 @@ extern int unpack(unsigned char *, char *, ...); Err bitreich.org 70
i /* Snapshot header structure */ Err bitreich.org 70
i struct shdr { Err bitreich.org 70
i char magic[NSHDRMAGIC]; /* magic number for file(1) */ Err bitreich.org 70
i- unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES]; Err bitreich.org 70
i unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; Err bitreich.org 70
i uint64_t flags; /* version number */ Err bitreich.org 70
i uint64_t nbd; /* number of block hashes */ Err bitreich.org 70
i@@ -52,6 +55,7 @@ struct mdnode { Err bitreich.org 70
i struct sctx { Err bitreich.org 70
i TAILQ_HEAD(mdhead, mdnode) mdhead; /* list of hashes contained in snapshot */ Err bitreich.org 70
i struct mdnode *mdnext; /* next hash to be returned via sget() */ Err bitreich.org 70
i+ int crypto; /* when set, snapshots are encrypted */ Err bitreich.org 70
i int fd; /* underlying snapshot file descriptor */ Err bitreich.org 70
i int rdonly; /* when set, ssync() is a no-op */ Err bitreich.org 70
i struct shdr shdr; /* snapshot header */ Err bitreich.org 70
i@@ -69,9 +73,8 @@ unpackshdr(int fd, struct shdr *shdr) Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i- n = unpack(buf, "'16'24'24qq", Err bitreich.org 70
i+ n = unpack(buf, "'16'24qq", Err bitreich.org 70
i shdr->magic, Err bitreich.org 70
i- shdr->nonce, Err bitreich.org 70
i shdr->header, Err bitreich.org 70
i &shdr->flags, Err bitreich.org 70
i &shdr->nbd); Err bitreich.org 70
i@@ -87,9 +90,8 @@ packshdr(int fd, struct shdr *shdr) Err bitreich.org 70
i unsigned char buf[SHDRSIZE]; Err bitreich.org 70
i int n; Err bitreich.org 70
i Err bitreich.org 70
i- n = pack(buf, "'16'24'24qq", Err bitreich.org 70
i+ n = pack(buf, "'16'24qq", Err bitreich.org 70
i shdr->magic, Err bitreich.org 70
i- shdr->nonce, Err bitreich.org 70
i shdr->header, Err bitreich.org 70
i shdr->flags, Err bitreich.org 70
i shdr->nbd); Err bitreich.org 70
i@@ -103,52 +105,99 @@ packshdr(int fd, struct shdr *shdr) Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i static int Err bitreich.org 70
i-loadmd(struct sctx *sctx) Err bitreich.org 70
i+initmdhead(struct sctx *sctx) Err bitreich.org 70
i { Err bitreich.org 70
i- struct mdnode *mdnode; Err bitreich.org 70
i+ unsigned char ad[SHDRSIZE]; Err bitreich.org 70
i+ struct shdr *shdr; Err bitreich.org 70
i+ uint64_t i; Err bitreich.org 70
i Err bitreich.org 70
i- mdnode = calloc(1, sizeof(*mdnode)); Err bitreich.org 70
i- if (mdnode == NULL) { Err bitreich.org 70
i- seterr("calloc: %s", strerror(errno)); Err bitreich.org 70
i+ if (lseek(sctx->fd, 0, SEEK_SET) < 0) { Err bitreich.org 70
i+ seterr("lseek: %s", strerror(errno)); Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i- if (xread(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) { Err bitreich.org 70
i- free(mdnode); Err bitreich.org 70
i- seterr("failed to read block hash: %s", strerror(errno)); Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (xread(sctx->fd, ad, sizeof(ad)) != sizeof(ad)) { Err bitreich.org 70
i+ seterr("failed to read snapshot header: %s\n", strerror(errno)); Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i- TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e); Err bitreich.org 70
i- return 0; Err bitreich.org 70
i-} Err bitreich.org 70
i- Err bitreich.org 70
i-static int Err bitreich.org 70
i-initmdhead(struct sctx *sctx) Err bitreich.org 70
i-{ Err bitreich.org 70
i- struct shdr *shdr; Err bitreich.org 70
i- uint64_t i; Err bitreich.org 70
i Err bitreich.org 70
i shdr = &sctx->shdr; Err bitreich.org 70
i- for (i = 0; i < shdr->nbd; i++) { Err bitreich.org 70
i- if (loadmd(sctx) == 0) Err bitreich.org 70
i- continue; Err bitreich.org 70
i+ if (sctx->crypto) { Err bitreich.org 70
i+ crypto_secretstream_xchacha20poly1305_state state; Err bitreich.org 70
i+ struct shdr *shdr; Err bitreich.org 70
i+ Err bitreich.org 70
i+ shdr = &sctx->shdr; Err bitreich.org 70
i+ if (crypto_secretstream_xchacha20poly1305_init_pull(&state, Err bitreich.org 70
i+ shdr->header, Err bitreich.org 70
i+ param.key) != 0) { Err bitreich.org 70
i+ seterr("invalid crypto header"); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i Err bitreich.org 70
i- /* Cleanup */ Err bitreich.org 70
i- while (!TAILQ_EMPTY(&sctx->mdhead)) { Err bitreich.org 70
i+ for (i = 0; i < shdr->nbd; i++) { Err bitreich.org 70
i+ unsigned char buf[MDSIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; Err bitreich.org 70
i+ unsigned char md[MDSIZE]; Err bitreich.org 70
i+ struct mdnode *mdnode; Err bitreich.org 70
i+ unsigned char tag; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (xread(sctx->fd, buf, sizeof(buf)) != sizeof(buf)) { Err bitreich.org 70
i+ seterr("failed to read block hash: %s", strerror(errno)); Err bitreich.org 70
i+ goto err0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (crypto_secretstream_xchacha20poly1305_pull(&state, md, NULL, &tag, Err bitreich.org 70
i+ buf, sizeof(buf), Err bitreich.org 70
i+ ad, sizeof(ad)) != 0) { Err bitreich.org 70
i+ seterr("authentication failed"); Err bitreich.org 70
i+ goto err0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ mdnode = calloc(1, sizeof(*mdnode)); Err bitreich.org 70
i+ if (mdnode == NULL) { Err bitreich.org 70
i+ seterr("calloc: %s", strerror(errno)); Err bitreich.org 70
i+ goto err0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ memcpy(mdnode->md, md, MDSIZE); Err bitreich.org 70
i+ TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ for (i = 0; i < shdr->nbd; i++) { Err bitreich.org 70
i+ unsigned char md[MDSIZE]; Err bitreich.org 70
i struct mdnode *mdnode; Err bitreich.org 70
i Err bitreich.org 70
i- mdnode = TAILQ_FIRST(&sctx->mdhead); Err bitreich.org 70
i- TAILQ_REMOVE(&sctx->mdhead, mdnode, e); Err bitreich.org 70
i- free(mdnode); Err bitreich.org 70
i+ if (xread(sctx->fd, md, MDSIZE) != MDSIZE) { Err bitreich.org 70
i+ seterr("failed to read block hash: %s", strerror(errno)); Err bitreich.org 70
i+ goto err0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ mdnode = calloc(1, sizeof(*mdnode)); Err bitreich.org 70
i+ if (mdnode == NULL) { Err bitreich.org 70
i+ seterr("calloc: %s", strerror(errno)); Err bitreich.org 70
i+ goto err0; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ memcpy(mdnode->md, md, MDSIZE); Err bitreich.org 70
i+ TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e); Err bitreich.org 70
i } Err bitreich.org 70
i- return -1; Err bitreich.org 70
i } Err bitreich.org 70
i return 0; Err bitreich.org 70
i+ Err bitreich.org 70
i+err0: Err bitreich.org 70
i+ /* Cleanup */ Err bitreich.org 70
i+ while (!TAILQ_EMPTY(&sctx->mdhead)) { Err bitreich.org 70
i+ struct mdnode *mdnode; Err bitreich.org 70
i+ Err bitreich.org 70
i+ mdnode = TAILQ_FIRST(&sctx->mdhead); Err bitreich.org 70
i+ TAILQ_REMOVE(&sctx->mdhead, mdnode, e); Err bitreich.org 70
i+ free(mdnode); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i int Err bitreich.org 70
i screat(char *path, int mode, struct sctx **sctx) Err bitreich.org 70
i { Err bitreich.org 70
i struct shdr *shdr; Err bitreich.org 70
i+ int crypto; Err bitreich.org 70
i int fd; Err bitreich.org 70
i Err bitreich.org 70
i if (path == NULL || sctx == NULL) { Err bitreich.org 70
i@@ -156,6 +205,22 @@ screat(char *path, int mode, struct sctx **sctx) Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i+ /* Determine algorithm type */ Err bitreich.org 70
i+ if (strcasecmp(param.ealgo, "none") == 0) { Err bitreich.org 70
i+ crypto = 0; Err bitreich.org 70
i+ } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) { Err bitreich.org 70
i+ crypto = 1; Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ seterr("invalid encryption type: %s", param.ealgo); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* Ensure a key has been provided if caller requested encryption */ Err bitreich.org 70
i+ if (crypto && !param.keyloaded) { Err bitreich.org 70
i+ seterr("expected encryption key"); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i if (sodium_init() < 0) { Err bitreich.org 70
i seterr("sodium_init: failed"); Err bitreich.org 70
i return -1; Err bitreich.org 70
i@@ -176,6 +241,7 @@ screat(char *path, int mode, struct sctx **sctx) Err bitreich.org 70
i Err bitreich.org 70
i TAILQ_INIT(&(*sctx)->mdhead); Err bitreich.org 70
i (*sctx)->mdnext = NULL; Err bitreich.org 70
i+ (*sctx)->crypto = crypto; Err bitreich.org 70
i (*sctx)->fd = fd; Err bitreich.org 70
i Err bitreich.org 70
i shdr = &(*sctx)->shdr; Err bitreich.org 70
i@@ -196,6 +262,7 @@ int Err bitreich.org 70
i sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70
i { Err bitreich.org 70
i struct shdr *shdr; Err bitreich.org 70
i+ int crypto; Err bitreich.org 70
i int fd; Err bitreich.org 70
i Err bitreich.org 70
i if (path == NULL || sctx == NULL) { Err bitreich.org 70
i@@ -209,6 +276,16 @@ sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i+ /* Determine algorithm type */ Err bitreich.org 70
i+ if (strcasecmp(param.ealgo, "none") == 0) { Err bitreich.org 70
i+ crypto = 0; Err bitreich.org 70
i+ } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) { Err bitreich.org 70
i+ crypto = 1; Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ seterr("invalid encryption type: %s", param.ealgo); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i if (sodium_init() < 0) { Err bitreich.org 70
i seterr("sodium_init: failed"); Err bitreich.org 70
i return -1; Err bitreich.org 70
i@@ -229,6 +306,7 @@ sopen(char *path, int flags, int mode, struct sctx **sctx) Err bitreich.org 70
i Err bitreich.org 70
i TAILQ_INIT(&(*sctx)->mdhead); Err bitreich.org 70
i (*sctx)->mdnext = NULL; Err bitreich.org 70
i+ (*sctx)->crypto = crypto; Err bitreich.org 70
i (*sctx)->fd = fd; Err bitreich.org 70
i (*sctx)->rdonly = 1; Err bitreich.org 70
i Err bitreich.org 70
i@@ -340,16 +418,59 @@ ssync(struct sctx *sctx) Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i shdr = &sctx->shdr; Err bitreich.org 70
i- if (packshdr(sctx->fd, shdr) < 0) Err bitreich.org 70
i- return -1; Err bitreich.org 70
i- TAILQ_FOREACH(mdnode, &sctx->mdhead, e) { Err bitreich.org 70
i- if (xwrite(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) { Err bitreich.org 70
i- seterr("failed to write block hash: %s", Err bitreich.org 70
i- strerror(errno)); Err bitreich.org 70
i+ if (sctx->crypto) { Err bitreich.org 70
i+ unsigned char ad[SHDRSIZE]; Err bitreich.org 70
i+ crypto_secretstream_xchacha20poly1305_state state; Err bitreich.org 70
i+ Err bitreich.org 70
i+ crypto_secretstream_xchacha20poly1305_init_push(&state, Err bitreich.org 70
i+ shdr->header, Err bitreich.org 70
i+ param.key); Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (packshdr(sctx->fd, shdr) < 0) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (lseek(sctx->fd, 0, SEEK_SET) < 0) { Err bitreich.org 70
i+ seterr("lseek: %s", strerror(errno)); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (xread(sctx->fd, ad, sizeof(ad)) != sizeof(ad)) { Err bitreich.org 70
i+ seterr("failed to read snapshot header: %s\n", strerror(errno)); Err bitreich.org 70
i return -1; Err bitreich.org 70
i } Err bitreich.org 70
i+ Err bitreich.org 70
i+ TAILQ_FOREACH(mdnode, &sctx->mdhead, e) { Err bitreich.org 70
i+ unsigned char buf[MDSIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; Err bitreich.org 70
i+ unsigned char tag; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (TAILQ_LAST(&sctx->mdhead, mdhead) == mdnode) Err bitreich.org 70
i+ tag = crypto_secretstream_xchacha20poly1305_TAG_FINAL; Err bitreich.org 70
i+ else Err bitreich.org 70
i+ tag = 0; Err bitreich.org 70
i+ Err bitreich.org 70
i+ crypto_secretstream_xchacha20poly1305_push(&state, Err bitreich.org 70
i+ buf, NULL, Err bitreich.org 70
i+ mdnode->md, MDSIZE, Err bitreich.org 70
i+ ad, sizeof(ad), tag); Err bitreich.org 70
i+ if (xwrite(sctx->fd, buf, sizeof(buf)) != sizeof(buf)) { Err bitreich.org 70
i+ seterr("failed to write block hash: %s", Err bitreich.org 70
i+ strerror(errno)); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ if (packshdr(sctx->fd, shdr) < 0) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ TAILQ_FOREACH(mdnode, &sctx->mdhead, e) { Err bitreich.org 70
i+ if (xwrite(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) { Err bitreich.org 70
i+ seterr("failed to write block hash: %s", Err bitreich.org 70
i+ strerror(errno)); Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ } Err bitreich.org 70
i } Err bitreich.org 70
i fsync(sctx->fd); Err bitreich.org 70
i+ Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
.
Response:
text/plain