commit da5196be59c4f03fd81127900dd1b1afdbdfa34f
parent 1c0530ef5bf190a62ca8ce7c9b3ae14702b44a7f
Author: sin <sin@2f30.org>
Date: Tue, 14 May 2019 13:33:06 +0300
Split initmdhead() into plaintext/encrypted variants
Diffstat:
M | snap.c | | | 143 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 76 insertions(+), 67 deletions(-)
diff --git a/snap.c b/snap.c
@@ -94,84 +94,93 @@ packshdr(unsigned char *buf, struct shdr *shdr)
}
static int
+loadmdnone(struct sctx *sctx, int first)
+{
+ struct mdnode *mdnode;
+
+ mdnode = calloc(1, sizeof(*mdnode));
+ if (mdnode == NULL) {
+ seterr("calloc: %s", strerror(errno));
+ return -1;
+ }
+
+ if (xread(sctx->fd, mdnode->md, MDSIZE) != MDSIZE) {
+ seterr("failed to read block hash: %s", strerror(errno));
+ return -1;
+ }
+
+ TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e);
+ return 0;
+}
+
+static int
+loadmdcrypto(struct sctx *sctx, int first)
+{
+ unsigned char buf[MDSIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
+ unsigned char hdr[SHDRSIZE];
+ static crypto_secretstream_xchacha20poly1305_state state;
+ struct mdnode *mdnode;
+ struct shdr *shdr;
+
+ shdr = &sctx->shdr;
+ packshdr(hdr, shdr);
+ if (first && crypto_secretstream_xchacha20poly1305_init_pull(&state,
+ shdr->header,
+ param.key) < 0) {
+ seterr("invalid crypto header");
+ return -1;
+ }
+
+ if (xread(sctx->fd, buf, sizeof(buf)) != sizeof(buf)) {
+ seterr("failed to read block hash: %s", strerror(errno));
+ return -1;
+ }
+
+ mdnode = calloc(1, sizeof(*mdnode));
+ if (mdnode == NULL) {
+ seterr("calloc: %s", strerror(errno));
+ return -1;
+ }
+
+ if (crypto_secretstream_xchacha20poly1305_pull(&state, mdnode->md, NULL,
+ NULL, buf, sizeof(buf),
+ hdr, sizeof(hdr)) < 0) {
+ free(mdnode);
+ seterr("authentication failed");
+ return -1;
+ }
+
+ TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e);
+ return 0;
+}
+
+static int
initmdhead(struct sctx *sctx)
{
struct shdr *shdr;
+ int (*fn)(struct sctx *, int);
uint64_t i;
+ if (!sctx->crypto)
+ fn = loadmdnone;
+ else
+ fn = loadmdcrypto;
+
shdr = &sctx->shdr;
- if (sctx->crypto) {
- unsigned char ad[SHDRSIZE];
- crypto_secretstream_xchacha20poly1305_state state;
- struct shdr *shdr;
-
- shdr = &sctx->shdr;
- packshdr(ad, shdr);
-
- if (crypto_secretstream_xchacha20poly1305_init_pull(&state,
- shdr->header,
- param.key) < 0) {
- seterr("invalid crypto header");
- return -1;
- }
+ for (i = 0; i < shdr->nbd; i++) {
+ if ((*fn)(sctx, i == 0) == 0)
+ continue;
- for (i = 0; i < shdr->nbd; i++) {
- unsigned char buf[MDSIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
- unsigned char md[MDSIZE];
- struct mdnode *mdnode;
- unsigned char tag;
-
- if (xread(sctx->fd, buf, sizeof(buf)) != sizeof(buf)) {
- seterr("failed to read block hash: %s", strerror(errno));
- goto err0;
- }
-
- if (crypto_secretstream_xchacha20poly1305_pull(&state, md, NULL, &tag,
- buf, sizeof(buf),
- ad, sizeof(ad)) < 0) {
- seterr("authentication failed");
- goto err0;
- }
-
- mdnode = calloc(1, sizeof(*mdnode));
- if (mdnode == NULL) {
- seterr("calloc: %s", strerror(errno));
- goto err0;
- }
- memcpy(mdnode->md, md, MDSIZE);
- TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e);
- }
- } else {
- for (i = 0; i < shdr->nbd; i++) {
- unsigned char md[MDSIZE];
+ while (!TAILQ_EMPTY(&sctx->mdhead)) {
struct mdnode *mdnode;
- if (xread(sctx->fd, md, MDSIZE) != MDSIZE) {
- seterr("failed to read block hash: %s", strerror(errno));
- goto err0;
- }
-
- mdnode = calloc(1, sizeof(*mdnode));
- if (mdnode == NULL) {
- seterr("calloc: %s", strerror(errno));
- goto err0;
- }
- memcpy(mdnode->md, md, MDSIZE);
- TAILQ_INSERT_TAIL(&sctx->mdhead, mdnode, e);
+ mdnode = TAILQ_FIRST(&sctx->mdhead);
+ TAILQ_REMOVE(&sctx->mdhead, mdnode, e);
+ free(mdnode);
}
+ return -1;
}
return 0;
-
-err0:
- /* Cleanup */
- while (!TAILQ_EMPTY(&sctx->mdhead)) {
- struct mdnode *mdnode;
-
- mdnode = TAILQ_FIRST(&sctx->mdhead);
- TAILQ_REMOVE(&sctx->mdhead, mdnode, e);
- free(mdnode);
- }
- return -1;
}
int
@@ -486,7 +495,7 @@ sclose(struct sctx *sctx)
if (ssync(sctx) < 0)
return -1;
- /* Cleanup */
+ /* Free block hash list */
while (!TAILQ_EMPTY(&sctx->mdhead)) {
struct mdnode *mdnode;