ibencrypt.c - 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 ibencrypt.c (7144B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 /* Encryption layer implementation */ Err bitreich.org 70 i 2 #include Err bitreich.org 70 i 3 #include Err bitreich.org 70 i 4 Err bitreich.org 70 i 5 #include Err bitreich.org 70 i 6 #include Err bitreich.org 70 i 7 #include Err bitreich.org 70 i 8 #include Err bitreich.org 70 i 9 #include Err bitreich.org 70 i 10 #include Err bitreich.org 70 i 11 #include Err bitreich.org 70 i 12 #include Err bitreich.org 70 i 13 Err bitreich.org 70 i 14 #include Err bitreich.org 70 i 15 Err bitreich.org 70 i 16 #include "block.h" Err bitreich.org 70 i 17 #include "config.h" Err bitreich.org 70 i 18 #include "misc.h" Err bitreich.org 70 i 19 #include "state.h" Err bitreich.org 70 i 20 Err bitreich.org 70 i 21 extern struct param param; Err bitreich.org 70 i 22 Err bitreich.org 70 i 23 #define EDNONETYPE 0x300 Err bitreich.org 70 i 24 #define EDCHACHATYPE 0x301 Err bitreich.org 70 i 25 #define NONCESIZE crypto_aead_xchacha20poly1305_ietf_NPUBBYTES Err bitreich.org 70 i 26 #define EDSIZE (8 + 8 + NONCESIZE) Err bitreich.org 70 i 27 Err bitreich.org 70 i 28 extern int pack(unsigned char *, char *, ...); Err bitreich.org 70 i 29 extern int unpack(unsigned char *, char *, ...); Err bitreich.org 70 i 30 Err bitreich.org 70 i 31 static int becreat(struct bctx *bctx, char *path, int mode); Err bitreich.org 70 i 32 static int beopen(struct bctx *bctx, char *path, int flags, int mode); Err bitreich.org 70 i 33 static int beput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); Err bitreich.org 70 i 34 static int beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); Err bitreich.org 70 i 35 static int berm(struct bctx *bctx, unsigned char *md); Err bitreich.org 70 i 36 static int begc(struct bctx *bctx); Err bitreich.org 70 i 37 static int besync(struct bctx *bctx); Err bitreich.org 70 i 38 static int beclose(struct bctx *bctx); Err bitreich.org 70 i 39 Err bitreich.org 70 i 40 static struct bops bops = { Err bitreich.org 70 i 41 .creat = becreat, Err bitreich.org 70 i 42 .open = beopen, Err bitreich.org 70 i 43 .put = beput, Err bitreich.org 70 i 44 .get = beget, Err bitreich.org 70 i 45 .rm = berm, Err bitreich.org 70 i 46 .gc = begc, Err bitreich.org 70 i 47 .sync = besync, Err bitreich.org 70 i 48 .close = beclose, Err bitreich.org 70 i 49 }; Err bitreich.org 70 i 50 Err bitreich.org 70 i 51 /* Encryption layer context */ Err bitreich.org 70 i 52 struct ectx { Err bitreich.org 70 i 53 int type; /* encryption algorithm type for new blocks */ Err bitreich.org 70 i 54 }; Err bitreich.org 70 i 55 Err bitreich.org 70 i 56 /* Encryption descriptor */ Err bitreich.org 70 i 57 struct ed { Err bitreich.org 70 i 58 uint16_t type; /* encryption algorithm type */ Err bitreich.org 70 i 59 unsigned char reserved[6]; /* should be set to 0 when writing */ Err bitreich.org 70 i 60 uint64_t size; /* size of encrypted block */ Err bitreich.org 70 i 61 unsigned char nonce[NONCESIZE]; /* unpredictable nonce used when encrypting */ Err bitreich.org 70 i 62 }; Err bitreich.org 70 i 63 Err bitreich.org 70 i 64 /* Unpack encryption descriptor */ Err bitreich.org 70 i 65 static int Err bitreich.org 70 i 66 unpacked(unsigned char *buf, struct ed *ed) Err bitreich.org 70 i 67 { Err bitreich.org 70 i 68 char fmt[BUFSIZ]; Err bitreich.org 70 i 69 int n; Err bitreich.org 70 i 70 Err bitreich.org 70 i 71 snprintf(fmt, sizeof(fmt), "s'6q'%d", NONCESIZE); Err bitreich.org 70 i 72 n = unpack(buf, fmt, Err bitreich.org 70 i 73 &ed->type, Err bitreich.org 70 i 74 ed->reserved, Err bitreich.org 70 i 75 &ed->size, Err bitreich.org 70 i 76 ed->nonce); Err bitreich.org 70 i 77 Err bitreich.org 70 i 78 assert(n == EDSIZE); Err bitreich.org 70 i 79 return n; Err bitreich.org 70 i 80 } Err bitreich.org 70 i 81 Err bitreich.org 70 i 82 /* Pack encryption descriptor */ Err bitreich.org 70 i 83 static int Err bitreich.org 70 i 84 packed(unsigned char *buf, struct ed *ed) Err bitreich.org 70 i 85 { Err bitreich.org 70 i 86 char fmt[BUFSIZ]; Err bitreich.org 70 i 87 int n; Err bitreich.org 70 i 88 Err bitreich.org 70 i 89 snprintf(fmt, sizeof(fmt), "s'6q'%d", NONCESIZE); Err bitreich.org 70 i 90 n = pack(buf, fmt, Err bitreich.org 70 i 91 ed->type, Err bitreich.org 70 i 92 ed->reserved, Err bitreich.org 70 i 93 ed->size, Err bitreich.org 70 i 94 ed->nonce); Err bitreich.org 70 i 95 Err bitreich.org 70 i 96 assert(n == EDSIZE); Err bitreich.org 70 i 97 return n; Err bitreich.org 70 i 98 } Err bitreich.org 70 i 99 Err bitreich.org 70 i 100 static int Err bitreich.org 70 i 101 becreat(struct bctx *bctx, char *path, int mode) Err bitreich.org 70 i 102 { Err bitreich.org 70 i 103 struct ectx *ectx; Err bitreich.org 70 i 104 int type; Err bitreich.org 70 i 105 Err bitreich.org 70 i 106 /* Determine algorithm type */ Err bitreich.org 70 i 107 if (strcasecmp(param.ealgo, "none") == 0) { Err bitreich.org 70 i 108 type = EDNONETYPE; Err bitreich.org 70 i 109 } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) { Err bitreich.org 70 i 110 type = EDCHACHATYPE; Err bitreich.org 70 i 111 } else { Err bitreich.org 70 i 112 seterr("invalid encryption type: %s", param.ealgo); Err bitreich.org 70 i 113 return -1; Err bitreich.org 70 i 114 } Err bitreich.org 70 i 115 Err bitreich.org 70 i 116 /* Ensure a key has been provided if caller requested encryption */ Err bitreich.org 70 i 117 if (type != EDNONETYPE && !param.keyloaded) { Err bitreich.org 70 i 118 seterr("expected encryption key"); Err bitreich.org 70 i 119 return -1; Err bitreich.org 70 i 120 } Err bitreich.org 70 i 121 Err bitreich.org 70 i 122 if (sodium_init() < 0) { Err bitreich.org 70 i 123 seterr("sodium_init: failed"); Err bitreich.org 70 i 124 return -1; Err bitreich.org 70 i 125 } Err bitreich.org 70 i 126 Err bitreich.org 70 i 127 bctx->ectx = calloc(1, sizeof(struct ectx)); Err bitreich.org 70 i 128 if (bctx->ectx == NULL) { Err bitreich.org 70 i 129 seterr("calloc: out of memory"); Err bitreich.org 70 i 130 return -1; Err bitreich.org 70 i 131 } Err bitreich.org 70 i 132 ectx = bctx->ectx; Err bitreich.org 70 i 133 ectx->type = type; Err bitreich.org 70 i 134 Err bitreich.org 70 i 135 if (bstorageops()->creat(bctx, path, mode) < 0) { Err bitreich.org 70 i 136 free(ectx); Err bitreich.org 70 i 137 return -1; Err bitreich.org 70 i 138 } Err bitreich.org 70 i 139 return 0; Err bitreich.org 70 i 140 } Err bitreich.org 70 i 141 Err bitreich.org 70 i 142 static int Err bitreich.org 70 i 143 beopen(struct bctx *bctx, char *path, int flags, int mode) Err bitreich.org 70 i 144 { Err bitreich.org 70 i 145 struct ectx *ectx; Err bitreich.org 70 i 146 int type; Err bitreich.org 70 i 147 Err bitreich.org 70 i 148 /* Determine algorithm type */ Err bitreich.org 70 i 149 if (strcasecmp(param.ealgo, "none") == 0) { Err bitreich.org 70 i 150 type = EDNONETYPE; Err bitreich.org 70 i 151 } else if (strcasecmp(param.ealgo, "XChaCha20-Poly1305") == 0) { Err bitreich.org 70 i 152 type = EDCHACHATYPE; Err bitreich.org 70 i 153 } else { Err bitreich.org 70 i 154 seterr("invalid encryption type: %s", param.ealgo); Err bitreich.org 70 i 155 return -1; Err bitreich.org 70 i 156 } Err bitreich.org 70 i 157 Err bitreich.org 70 i 158 /* Ensure a key has been provided if caller requested encryption */ Err bitreich.org 70 i 159 if (type != EDNONETYPE && !param.keyloaded) { Err bitreich.org 70 i 160 seterr("expected encryption key"); Err bitreich.org 70 i 161 return -1; Err bitreich.org 70 i 162 } Err bitreich.org 70 i 163 Err bitreich.org 70 i 164 if (sodium_init() < 0) { Err bitreich.org 70 i 165 seterr("sodium_init: failed"); Err bitreich.org 70 i 166 return -1; Err bitreich.org 70 i 167 } Err bitreich.org 70 i 168 Err bitreich.org 70 i 169 bctx->ectx = calloc(1, sizeof(struct ectx)); Err bitreich.org 70 i 170 if (bctx->ectx == NULL) { Err bitreich.org 70 i 171 seterr("calloc: out of memory"); Err bitreich.org 70 i 172 return -1; Err bitreich.org 70 i 173 } Err bitreich.org 70 i 174 ectx = bctx->ectx; Err bitreich.org 70 i 175 ectx->type = type; Err bitreich.org 70 i 176 Err bitreich.org 70 i 177 if (bstorageops()->open(bctx, path, flags, mode) < 0) { Err bitreich.org 70 i 178 free(ectx); Err bitreich.org 70 i 179 return -1; Err bitreich.org 70 i 180 } Err bitreich.org 70 i 181 return 0; Err bitreich.org 70 i 182 } Err bitreich.org 70 i 183 Err bitreich.org 70 i 184 static int Err bitreich.org 70 i 185 beput(struct bctx *bctx, void *buf, size_t n, unsigned char *md) Err bitreich.org 70 i 186 { Err bitreich.org 70 i 187 struct ectx *ectx; Err bitreich.org 70 i 188 struct ed ed; Err bitreich.org 70 i 189 unsigned char *ebuf; Err bitreich.org 70 i 190 unsigned long long elen; Err bitreich.org 70 i 191 size_t en; Err bitreich.org 70 i 192 Err bitreich.org 70 i 193 /* Calculate size of encrypted block */ Err bitreich.org 70 i 194 ectx = bctx->ectx; Err bitreich.org 70 i 195 switch (ectx->type) { Err bitreich.org 70 i 196 case EDNONETYPE: Err bitreich.org 70 i 197 en = n; Err bitreich.org 70 i 198 break; Err bitreich.org 70 i 199 case EDCHACHATYPE: Err bitreich.org 70 i 200 en = n + crypto_aead_xchacha20poly1305_ietf_ABYTES; Err bitreich.org 70 i 201 break; Err bitreich.org 70 i 202 } Err bitreich.org 70 i 203 Err bitreich.org 70 i 204 ebuf = malloc(EDSIZE + en); Err bitreich.org 70 i 205 if (ebuf == NULL) { Err bitreich.org 70 i 206 seterr("malloc: out of memory"); Err bitreich.org 70 i 207 return -1; Err bitreich.org 70 i 208 } Err bitreich.org 70 i 209 Err bitreich.org 70 i 210 /* Prepare encryption descriptor */ Err bitreich.org 70 i 211 ed.type = ectx->type; Err bitreich.org 70 i 212 memset(ed.reserved, 0, sizeof(ed.reserved)); Err bitreich.org 70 i 213 ed.size = en; Err bitreich.org 70 i 214 Err bitreich.org 70 i 215 /* Fill nonce buffer */ Err bitreich.org 70 i 216 switch (ectx->type) { Err bitreich.org 70 i 217 case EDNONETYPE: Err bitreich.org 70 i 218 memset(ed.nonce, 0, sizeof(ed.nonce)); Err bitreich.org 70 i 219 break; Err bitreich.org 70 i 220 case EDCHACHATYPE: Err bitreich.org 70 i 221 randombytes_buf(ed.nonce, sizeof(ed.nonce)); Err bitreich.org 70 i 222 break; Err bitreich.org 70 i 223 } Err bitreich.org 70 i 224 Err bitreich.org 70 i 225 /* Prepend encryption descriptor */ Err bitreich.org 70 i 226 packed(ebuf, &ed); Err bitreich.org 70 i 227 Err bitreich.org 70 i 228 /* Encrypt block */ Err bitreich.org 70 i 229 switch (ectx->type) { Err bitreich.org 70 i 230 case EDNONETYPE: Err bitreich.org 70 i 231 memcpy(&ebuf[EDSIZE], buf, en); Err bitreich.org 70 i 232 break; Err bitreich.org 70 i 233 case EDCHACHATYPE: Err bitreich.org 70 i 234 crypto_aead_xchacha20poly1305_ietf_encrypt(&ebuf[EDSIZE], &elen, Err bitreich.org 70 i 235 buf, n, ebuf, EDSIZE, NULL, Err bitreich.org 70 i 236 ed.nonce, param.key); Err bitreich.org 70 i 237 assert(elen == en); Err bitreich.org 70 i 238 break; Err bitreich.org 70 i 239 } Err bitreich.org 70 i 240 Err bitreich.org 70 i 241 if (bstorageops()->put(bctx, ebuf, EDSIZE + en, md) < 0) { Err bitreich.org 70 i 242 free(ebuf); Err bitreich.org 70 i 243 return -1; Err bitreich.org 70 i 244 } Err bitreich.org 70 i 245 Err bitreich.org 70 i 246 free(ebuf); Err bitreich.org 70 i 247 return ed.size; Err bitreich.org 70 i 248 } Err bitreich.org 70 i 249 Err bitreich.org 70 i 250 static int Err bitreich.org 70 i 251 beget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n) Err bitreich.org 70 i 252 { Err bitreich.org 70 i 253 struct ed ed; Err bitreich.org 70 i 254 struct ectx *ectx; Err bitreich.org 70 i 255 unsigned char *ebuf; Err bitreich.org 70 i 256 unsigned long long dlen; Err bitreich.org 70 i 257 size_t dn, size; Err bitreich.org 70 i 258 Err bitreich.org 70 i 259 /* Calculate maximum size of encrypted block */ Err bitreich.org 70 i 260 size = EDSIZE + *n + crypto_aead_xchacha20poly1305_ietf_ABYTES; Err bitreich.org 70 i 261 Err bitreich.org 70 i 262 ebuf = malloc(size); Err bitreich.org 70 i 263 if (ebuf == NULL) { Err bitreich.org 70 i 264 seterr("malloc: out of memory"); Err bitreich.org 70 i 265 return -1; Err bitreich.org 70 i 266 } Err bitreich.org 70 i 267 Err bitreich.org 70 i 268 if (bstorageops()->get(bctx, md, ebuf, &size) < 0) { Err bitreich.org 70 i 269 free(ebuf); Err bitreich.org 70 i 270 return -1; Err bitreich.org 70 i 271 } Err bitreich.org 70 i 272 Err bitreich.org 70 i 273 unpacked(ebuf, &ed); Err bitreich.org 70 i 274 Err bitreich.org 70 i 275 /* Decrypt block */ Err bitreich.org 70 i 276 ectx = bctx->ectx; Err bitreich.org 70 i 277 switch (ed.type) { Err bitreich.org 70 i 278 case EDNONETYPE: Err bitreich.org 70 i 279 dn = ed.size; Err bitreich.org 70 i 280 if (*n < dn) { Err bitreich.org 70 i 281 free(ebuf); Err bitreich.org 70 i 282 seterr("buffer too small"); Err bitreich.org 70 i 283 return -1; Err bitreich.org 70 i 284 } Err bitreich.org 70 i 285 memcpy(buf, &ebuf[EDSIZE], dn); Err bitreich.org 70 i 286 break; Err bitreich.org 70 i 287 case EDCHACHATYPE: Err bitreich.org 70 i 288 dn = ed.size - crypto_aead_xchacha20poly1305_ietf_ABYTES; Err bitreich.org 70 i 289 if (*n < dn) { Err bitreich.org 70 i 290 free(ebuf); Err bitreich.org 70 i 291 seterr("buffer too small"); Err bitreich.org 70 i 292 return -1; Err bitreich.org 70 i 293 } Err bitreich.org 70 i 294 Err bitreich.org 70 i 295 if (crypto_aead_xchacha20poly1305_ietf_decrypt(buf, &dlen, Err bitreich.org 70 i 296 NULL, Err bitreich.org 70 i 297 &ebuf[EDSIZE], ed.size, Err bitreich.org 70 i 298 ebuf, EDSIZE, Err bitreich.org 70 i 299 ed.nonce, param.key) < 0) { Err bitreich.org 70 i 300 free(ebuf); Err bitreich.org 70 i 301 seterr("authentication failed"); Err bitreich.org 70 i 302 return -1; Err bitreich.org 70 i 303 } Err bitreich.org 70 i 304 Err bitreich.org 70 i 305 assert(dn == dlen); Err bitreich.org 70 i 306 break; Err bitreich.org 70 i 307 } Err bitreich.org 70 i 308 Err bitreich.org 70 i 309 free(ebuf); Err bitreich.org 70 i 310 *n = dn; Err bitreich.org 70 i 311 return 0; Err bitreich.org 70 i 312 } Err bitreich.org 70 i 313 Err bitreich.org 70 i 314 static int Err bitreich.org 70 i 315 berm(struct bctx *bctx, unsigned char *md) Err bitreich.org 70 i 316 { Err bitreich.org 70 i 317 return bstorageops()->rm(bctx, md); Err bitreich.org 70 i 318 } Err bitreich.org 70 i 319 Err bitreich.org 70 i 320 static int Err bitreich.org 70 i 321 begc(struct bctx *bctx) Err bitreich.org 70 i 322 { Err bitreich.org 70 i 323 return bstorageops()->gc(bctx); Err bitreich.org 70 i 324 } Err bitreich.org 70 i 325 Err bitreich.org 70 i 326 static int Err bitreich.org 70 i 327 besync(struct bctx *bctx) Err bitreich.org 70 i 328 { Err bitreich.org 70 i 329 return bstorageops()->sync(bctx); Err bitreich.org 70 i 330 } Err bitreich.org 70 i 331 Err bitreich.org 70 i 332 static int Err bitreich.org 70 i 333 beclose(struct bctx *bctx) Err bitreich.org 70 i 334 { Err bitreich.org 70 i 335 struct ectx *ectx = bctx->ectx; Err bitreich.org 70 i 336 Err bitreich.org 70 i 337 free(ectx); Err bitreich.org 70 i 338 return bstorageops()->close(bctx); Err bitreich.org 70 i 339 } Err bitreich.org 70 i 340 Err bitreich.org 70 i 341 struct bops * Err bitreich.org 70 i 342 bencryptops(void) Err bitreich.org 70 i 343 { Err bitreich.org 70 i 344 return &bops; Err bitreich.org 70 i 345 } Err bitreich.org 70 .