X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=tfcrypt.c;h=3fdf9c65ad893d4b78513ccd6a615101dffeaa26;hb=d2e7d8aede7d69caffd59e4b0fa60e0c4b245201;hp=6e30bc6e46ad06b2e8edc39fac635a8d12410add;hpb=87d683181cc464de9b1d48483b72533aa9166cd3;p=tfcrypt.git diff --git a/tfcrypt.c b/tfcrypt.c index 6e30bc6..3fdf9c6 100644 --- a/tfcrypt.c +++ b/tfcrypt.c @@ -62,9 +62,25 @@ int main(int argc, char **argv) if (!isatty(2)) do_statline_dynamic = NO; + s = (char *)srcblk; + d = getenv("HOME"); + if (!d) d = ""; + n = PATH_MAX > sizeof(srcblk) ? sizeof(srcblk) : PATH_MAX; + if (xstrlcpy(s, d, n) >= n) goto _baddfname; + if (xstrlcat(s, "/.tfcrypt.defs", n) >= n) goto _baddfname; + read_defaults(s, YES); +_baddfname: + memset(s, 0, n); + opterr = 0; - while ((c = getopt(argc, argv, "aU:C:r:K:t:TPkzxc:l:qedn:vV:pwE:O:S:AmM:R:Z:WHD:")) != -1) { + while ((c = getopt(argc, argv, "L:s:aU:C:r:K:t:TPkzxc:l:qedn:vV:pwE:O:S:AmM:R:Z:WHD:")) != -1) { switch (c) { + case 'L': + read_defaults(optarg, NO); + break; + case 's': + saltf = optarg; + break; case 'r': randsource = optarg; break; @@ -75,6 +91,8 @@ int main(int argc, char **argv) counter_opt = TFC_CTR_HEAD; else if (!strcasecmp(optarg, "rand")) counter_opt = TFC_CTR_RAND; + else if (!strcasecmp(optarg, "zero")) + counter_opt = TFC_CTR_ZERO; else counter_file = sksum_hashlist_file = optarg; break; case 'C': @@ -141,9 +159,11 @@ int main(int argc, char **argv) break; case 't': tweakf = optarg; + do_full_key = NO; break; case 'T': - do_tfcrypt1 = YES; + tfc_saltsz = 0; + do_full_key = NO; break; case 'l': if (maxlen != NOFSIZE) break; @@ -167,12 +187,18 @@ int main(int argc, char **argv) catch_all_errors = YES; break; } + if (!strcmp(optarg, "xseek")) { + ignore_seek_errors = YES; + break; + } if (!strcmp(optarg, "exit")) error_action = TFC_ERRACT_EXIT; else if (!strncmp(optarg, "cont", 4)) error_action = TFC_ERRACT_CONT; else if (!strcmp(optarg, "sync")) error_action = TFC_ERRACT_SYNC; + else if (!strcmp(optarg, "lsync")) + error_action = TFC_ERRACT_LSYNC; else xerror(NO, YES, YES, "invalid error action %s specified", optarg); break; case 'O': @@ -322,13 +348,25 @@ int main(int argc, char **argv) s += 5; maxkeylen = tfc_humanfsize(s, &stoi); if (!str_empty(stoi)) { - maxkeylen = (size_t)tfc_fnamesize(s, YES); - maxkeylen = (size_t)tfc_modifysize((tfc_fsize)maxkeylen, strchr(s, ':')); + maxkeylen = tfc_fnamesize(s, YES); + maxkeylen = tfc_modifysize(maxkeylen, strchr(s, ':')); if (maxkeylen == NOSIZE) xerror(NO, YES, YES, "%s: invalid key length value", s); } - else maxkeylen = (size_t)tfc_modifysize((tfc_fsize)maxkeylen, strchr(s, ':')); + else maxkeylen = tfc_modifysize(maxkeylen, strchr(s, ':')); + } + else if (!strncmp(s, "okey", 4) && *(s+4) == '=') { + s += 5; + keyoffset = tfc_humanfsize(s, &stoi); + if (!str_empty(stoi)) { + keyoffset = tfc_fnamesize(s, YES); + keyoffset = tfc_modifysize(keyoffset, strchr(s, ':')); + if (keyoffset == NOFSIZE) + xerror(NO, YES, YES, + "%s: invalid key offset value", s); + } + else keyoffset = tfc_modifysize(keyoffset, strchr(s, ':')); } else if (!strncmp(s, "xctr", 4) && *(s+4) == '=') { s += 5; @@ -456,8 +494,6 @@ int main(int argc, char **argv) xerror(NO, YES, YES, "Cannot encrypt and read CTR from source!"); if (overwrite_source && counter_opt == TFC_CTR_RAND) xerror(NO, YES, YES, "Cannot embed a CTR into file when overwriting it!"); - if (tweakf && do_tfcrypt1 == NO) - xerror(NO, YES, YES, "Use -T with -t tweakfile to enable old tfcrypt mode!"); if (ctr_mode == TFC_MODE_PLAIN && (do_edcrypt || do_mac || rawkey || mackey_opt || counter_opt || counter_file)) @@ -466,6 +502,23 @@ int main(int argc, char **argv) errno = 0; do_stop = NO; + if (saltf) { + int saltfd; + + memset(tfc_salt, 0, TFC_MAX_SALT); + tfc_saltsz = 0; + if (!strcasecmp(saltf, "disable")) goto _nosalt; + + if (!strcmp(saltf, "-")) saltfd = 0; + else saltfd = open(saltf, O_RDONLY | O_LARGEFILE); + if (saltfd == -1) xerror(NO, NO, YES, "%s", saltf); + lio = xread(saltfd, tfc_salt, TFC_MAX_SALT - TF_FROM_BITS(TFC_KEY_BITS)); + if (lio == NOSIZE) xerror(NO, NO, YES, "%s", saltf); + tfc_saltsz = lio; + xclose(saltfd); + } + +_nosalt: if (mackey_opt == TFC_MACKEY_FILE && mackeyf) { int mkfd = -1; tfc_yesno do_stop; @@ -482,7 +535,8 @@ int main(int argc, char **argv) pblk = tmpdata; ldone = 0; lrem = lblock = sizeof(tmpdata); -_mkragain: lio = read(mkfd, pblk, lrem); + if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(mkfd); +_mkragain: lio = xread(mkfd, pblk, lrem); if (lio == 0) do_stop = YES; if (lio != NOSIZE) ldone += lio; else { @@ -491,10 +545,12 @@ _mkragain: lio = read(mkfd, pblk, lrem); switch (error_action) { case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", mackeyf); goto _mkragain; break; case TFC_ERRACT_SYNC: + case TFC_ERRACT_LSYNC: xerror(YES, NO, NO, "%s", mackeyf); lio = ldone = lrem = lblock; memset(tmpdata, 0, lio); - lseek(mkfd, lio, SEEK_CUR); + if (rdpos == NOFSIZE) lseek(mkfd, lio, SEEK_CUR); + else lseek(mkfd, rdpos + lio, SEEK_SET); break; default: xerror(NO, NO, NO, "%s", mackeyf); break; } @@ -561,16 +617,16 @@ _mkragain: lio = read(mkfd, pblk, lrem); else password = YES; errno = 0; - if (do_tfcrypt1 == YES && tweakf) { + if (do_full_key == NO && tweakf) { int twfd; if (!strcmp(tweakf, "-")) twfd = 0; else twfd = open(tweakf, O_RDONLY | O_LARGEFILE); if (twfd == -1) xerror(NO, NO, YES, "%s", tweakf); - lio = ldone = read(twfd, key+TF_FROM_BITS(TF_MAX_BITS)+TF_SIZE_UNIT, 2*TF_SIZE_UNIT); + lio = ldone = xread(twfd, tweak, TF_TWEAK_SIZE); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", tweakf); - if (ldone < 2*TF_SIZE_UNIT) - xerror(NO, NO, YES, "%s: %zu bytes tweak required", tweakf, 2*TF_SIZE_UNIT); + if (ldone < TF_TWEAK_SIZE) + xerror(NO, NO, YES, "%s: %zu bytes tweak required", tweakf, TF_TWEAK_SIZE); xclose(twfd); } @@ -616,7 +672,7 @@ _nokeyfd: if (!strcmp(counter_file, "-")) ctrfd = 0; else ctrfd = open(counter_file, O_RDONLY | O_LARGEFILE); if (ctrfd == -1) xerror(NO, NO, YES, "%s", counter_file); - lio = read(ctrfd, ctr, ctrsz); + lio = xread(ctrfd, ctr, ctrsz); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", counter_file); if (lio < ctrsz) xerror(NO, YES, YES, "counter file is too small (%zu)!", lio); xclose(ctrfd); @@ -625,7 +681,8 @@ _nokeyfd: pblk = ctr; ldone = 0; lrem = lblock = ctrsz; -_ctrragain: lio = read(sfd, pblk, lrem); + if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); +_ctrragain: lio = xread(sfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -633,10 +690,12 @@ _ctrragain: lio = read(sfd, pblk, lrem); switch (error_action) { case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", srcfname); goto _ctrragain; break; case TFC_ERRACT_SYNC: + case TFC_ERRACT_LSYNC: xerror(YES, NO, NO, "%s", srcfname); lio = ldone = lrem = lblock; memset(ctr, 0, lio); - lseek(sfd, lio, SEEK_CUR); + if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR); + else lseek(sfd, rdpos + lio, SEEK_SET); break; default: xerror(NO, NO, NO, "%s", srcfname); break; } @@ -654,7 +713,7 @@ _ctrskip1: if (counter_opt == TFC_CTR_HEAD && ctr_mode != TFC_MODE_ECB) iseek += ctrsz; if (lseek(sfd, iseek, SEEK_SET) == -1) - xerror(YES, NO, NO, "%s: seek failed", srcfname); + xerror(ignore_seek_errors, NO, NO, "%s: seek failed", srcfname); } if (ctr_mode == TFC_MODE_PLAIN) goto _plain; @@ -667,7 +726,8 @@ _ctrskip1: pblk = key; _xts2key: ldone = 0; lrem = lblock = TF_FROM_BITS(TFC_KEY_BITS); -_keyragain: lio = read(kfd, pblk, lrem); + if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(kfd); +_keyragain: lio = xread(kfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -675,10 +735,12 @@ _keyragain: lio = read(kfd, pblk, lrem); switch (error_action) { case TFC_ERRACT_CONT: xerror(YES, NO, NO, "reading key"); goto _keyragain; break; case TFC_ERRACT_SYNC: + case TFC_ERRACT_LSYNC: xerror(YES, NO, NO, "reading key"); lio = ldone = lrem = lblock; memset(key, 0, lio); - lseek(kfd, lio, SEEK_CUR); + if (rdpos == NOFSIZE) lseek(kfd, lio, SEEK_CUR); + else lseek(kfd, rdpos + lio, SEEK_SET); break; default: xerror(NO, NO, NO, "reading key"); break; } @@ -782,13 +844,18 @@ _pwdagain: memset(&getps, 0, sizeof(struct getpasswd_state)); memset(pwdagain, 0, sizeof(pwdagain)); } else { - if (skeinfd(key, TFC_KEY_BITS, mackey_opt ? mackey : NULL, kfd, maxkeylen) != YES) + if (skeinfd(key, TFC_KEY_BITS, mackey_opt ? mackey : NULL, kfd, keyoffset, maxkeylen) != YES) xerror(NO, NO, YES, "hashing key"); } - if (nr_turns > 1 && rawkey == NO) { - for (x = 0; x < nr_turns; x++) + if (rawkey == NO) { + if (tfc_saltsz > 0) { + memcpy(tfc_salt+tfc_saltsz, key, TF_FROM_BITS(TFC_KEY_BITS)); + skein(key, TFC_KEY_BITS, mackey_opt ? mackey : NULL, tfc_salt, tfc_saltsz+TF_FROM_BITS(TFC_KEY_BITS)); + } + if (nr_turns > 1) for (x = 0; x < nr_turns; x++) skein(key, TFC_KEY_BITS, mackey_opt ? mackey : NULL, key, TF_FROM_BITS(TFC_KEY_BITS)); + memset(tfc_salt, 0, TFC_MAX_SALT); } if (ctr_mode == TFC_MODE_XTS && rawkey == NO) { @@ -803,7 +870,7 @@ _pwdagain: memset(&getps, 0, sizeof(struct getpasswd_state)); if (!strcmp(genkeyf, "-")) krfd = 1; else krfd = open(genkeyf, O_WRONLY | O_CREAT | O_LARGEFILE | write_flags, 0666); if (krfd == -1) xerror(NO, NO, YES, "%s", genkeyf); -_xts2genkey: if (write(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == -1) xerror(NO, NO, YES, "%s", genkeyf); +_xts2genkey: if (xwrite(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == NOSIZE) xerror(NO, NO, YES, "%s", genkeyf); if (do_fsync && fsync(krfd) == -1) xerror(NO, NO, YES, "%s", genkeyf); if (verbose && xtskeyset == NO) { tfc_esay("%s: password hashing done", progname); @@ -846,11 +913,10 @@ _xts2genkey: if (write(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == -1) xerror(NO, tf_convkey(key); if (ctr_mode == TFC_MODE_XTS) tf_convkey(xtskey); - if (do_tfcrypt1 == YES) { - if (!tweakf) skein(key+TF_FROM_BITS(TF_MAX_BITS)+TF_SIZE_UNIT, 2*TF_UNIT_BITS, NULL, key, TF_FROM_BITS(TFC_KEY_BITS)); - tf_key_tweak_compat(key); + if (do_full_key == NO) { + if (!tweakf) skein(tweak, TF_NR_TWEAK_BITS, NULL, key, TF_FROM_BITS(TFC_KEY_BITS)); + tf_tweak_set(key, tweak); } - if (ctr_mode == TFC_MODE_STREAM) tfe_init_iv(&tfe, key, ctr); if (ctr_mode == TFC_MODE_ECB) goto _ctrskip2; tfc_data_to_words64(&iseek_blocks, sizeof(iseek_blocks)); tf_ctr_set(ctr, &iseek_blocks, sizeof(iseek_blocks)); @@ -859,11 +925,12 @@ _xts2genkey: if (write(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == -1) xerror(NO, case TFC_CTR_SHOW: switch (do_outfmt) { case TFC_OUTFMT_B64: tfc_printbase64(stderr, ctr, ctrsz, YES); break; - case TFC_OUTFMT_RAW: write(2, ctr, ctrsz); break; + case TFC_OUTFMT_RAW: xwrite(2, ctr, ctrsz); break; case TFC_OUTFMT_HEX: mehexdump(ctr, ctrsz, ctrsz, YES); break; } break; case TFC_CTR_RAND: tfc_getrandom(ctr, ctrsz); break; + case TFC_CTR_ZERO: memset(ctr, 0, ctrsz); break; } _ctrskip2: @@ -889,7 +956,7 @@ _plain: if (oseek) { if (lseek(dfd, oseek, SEEK_SET) == -1) - xerror(YES, NO, NO, "%s: seek failed", dstfname); + xerror(ignore_seek_errors, NO, NO, "%s: seek failed", dstfname); } for (x = 1; x < NSIG; x++) signal(x, SIG_IGN); @@ -923,7 +990,7 @@ _plain: pblk = ctr; lio = lrem = ctrsz; ldone = 0; -_ctrwagain: lio = write(dfd, pblk, lrem); +_ctrwagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", dstfname); if (do_fsync && fsync(dfd) == -1) xerror(NO, NO, NO, "%s", dstfname); @@ -936,6 +1003,8 @@ _ctrwagain: lio = write(dfd, pblk, lrem); delta_processed += ldone; } + if (ctr_mode == TFC_MODE_STREAM) tfe_init_iv(&tfe, key, ctr); + errno = 0; do_stop = NO; while (1) { @@ -943,7 +1012,8 @@ _ctrwagain: lio = write(dfd, pblk, lrem); pblk = srcblk; ldone = 0; lrem = lblock = blk_len_adj(maxlen, total_processed_src, blksize); -_ragain: lio = read(sfd, pblk, lrem); + if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); +_ragain: lio = xread(sfd, pblk, lrem); if (lio == 0) do_stop = TFC_STOP_BEGAN; if (lio != NOSIZE) ldone += lio; else { @@ -952,10 +1022,12 @@ _ragain: lio = read(sfd, pblk, lrem); switch (error_action) { case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", srcfname); goto _ragain; break; case TFC_ERRACT_SYNC: + case TFC_ERRACT_LSYNC: xerror(YES, NO, NO, "%s", srcfname); lio = ldone = lrem = lblock; memset(srcblk, 0, lio); - lseek(sfd, lio, SEEK_CUR); + if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR); + else lseek(sfd, rdpos + lio, SEEK_SET); break; default: xerror(NO, NO, NO, "%s", srcfname); break; } @@ -1007,7 +1079,7 @@ _ragain: lio = read(sfd, pblk, lrem); pblk = dstblk; lrem = ldone; ldone = 0; -_wagain: lio = write(dfd, pblk, lrem); +_wagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", dstfname); if (do_fsync && fsync(dfd) == -1) xerror(NO, NO, NO, "%s", dstfname); @@ -1030,7 +1102,8 @@ _nowrite: total_processed_dst += ldone; pblk = macvrfy; ldone = 0; lrem = lblock = TF_FROM_BITS(macbits); -_macragain: lio = read(sfd, pblk, lrem); + if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd); +_macragain: lio = xread(sfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -1038,10 +1111,12 @@ _macragain: lio = read(sfd, pblk, lrem); switch (error_action) { case TFC_ERRACT_CONT: xerror(YES, NO, NO, "%s", srcfname); goto _macragain; break; case TFC_ERRACT_SYNC: + case TFC_ERRACT_LSYNC: xerror(YES, NO, NO, "%s", srcfname); lio = ldone = lrem = lblock; memset(macvrfy, 0, lio); - lseek(sfd, lio, SEEK_CUR); + if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR); + else lseek(sfd, rdpos + lio, SEEK_SET); break; default: xerror(NO, NO, NO, "%s", srcfname); break; } @@ -1059,7 +1134,7 @@ _macragain: lio = read(sfd, pblk, lrem); if (!strcmp(do_mac_file, "-")) mfd = 0; else mfd = open(do_mac_file, O_RDONLY | O_LARGEFILE); if (mfd == -1) xerror(YES, NO, NO, "%s", do_mac_file); - lio = ldone = read(mfd, tmpdata, sizeof(tmpdata)); + lio = ldone = xread(mfd, tmpdata, sizeof(tmpdata)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", do_mac_file); if (!memcmp(tmpdata, TFC_ASCII_TFC_MAC_FOURCC, TFC_ASCII_TFC_MAC_FOURCC_LEN)) { memmove(tmpdata, tmpdata+TFC_ASCII_TFC_MAC_FOURCC_LEN, @@ -1124,7 +1199,7 @@ _shortmac: memset(macvrfy, 0, sizeof(macvrfy)); pblk = tmpdata; lio = lrem = TF_FROM_BITS(macbits); ldone = 0; -_macwagain: lio = write(dfd, pblk, lrem); +_macwagain: lio = xwrite(dfd, pblk, lrem); if (lio != NOSIZE) ldone += lio; else xerror(NO, NO, NO, "%s", dstfname); if (do_fsync && fsync(dfd) == -1) xerror(NO, NO, NO, "%s", dstfname); @@ -1152,9 +1227,9 @@ _macwagain: lio = write(dfd, pblk, lrem); tmpdata[lrem] = '\n'; lrem++; } - lio = write(mfd, tmpdata, lrem); + lio = xwrite(mfd, tmpdata, lrem); } - else lio = write(mfd, tmpdata, TF_FROM_BITS(macbits)); + else lio = xwrite(mfd, tmpdata, TF_FROM_BITS(macbits)); if (lio == NOSIZE) xerror(NO, NO, YES, "%s", do_mac_file); if (do_fsync && fsync(mfd) == -1) xerror(NO, NO, YES, "%s", do_mac_file); xclose(mfd);