X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=tfcrypt.c;h=6ac7bdceb4da6879c98df6f6483e4cf4d3026559;hb=a2ba0ca55c0bccf3695f9fdfacfbd991a2a73cf1;hp=d673d386e7757cf739ffc35fbf35283476b39e3b;hpb=f761a53231d1a023e2d3e5efcc5591b04a34f98a;p=tfcrypt.git diff --git a/tfcrypt.c b/tfcrypt.c index d673d38..6ac7bdc 100644 --- a/tfcrypt.c +++ b/tfcrypt.c @@ -28,6 +28,8 @@ #include "tfcrypt.h" +static tfc_byte svctr[TF_BLOCK_SIZE]; + static int getps_filter(struct getpasswd_state *getps, char chr, size_t pos) { if (chr == '\x03') { @@ -113,6 +115,7 @@ int main(int argc, char **argv) double td; char *s, *d, *t, *stoi; size_t x, n; + tfc_fsize rwd; progname = basename(argv[0]); @@ -128,8 +131,14 @@ int main(int argc, char **argv) _baddfname: memset(s, 0, n); + if (!strcmp(progname, "iotool")) { + do_edcrypt = TFC_DO_PLAIN; + password = YES; + ctr_mode = TFC_MODE_PLAIN; + } + opterr = 0; - while ((c = getopt(argc, argv, "L:s:aU:C:r:K:t:Pkzxc:l:qedn:vV:pwE:O:S:AmM:R:Z:WHD:")) != -1) { + while ((c = getopt(argc, argv, "L:s:aU:C:r:K:t:Pkzxc:l:qedn:vV:pwE:O:S:AmuM:R:Z:WHD:")) != -1) { switch (c) { case 'L': read_defaults(optarg, NO); @@ -195,10 +204,10 @@ _baddfname: ctr_mode = TFC_MODE_PLAIN; break; case 'e': - do_edcrypt = TFC_DO_ENCRYPT; + if (do_edcrypt != TFC_DO_PLAIN) do_edcrypt = TFC_DO_ENCRYPT; break; case 'd': - do_edcrypt = TFC_DO_DECRYPT; + if (do_edcrypt != TFC_DO_PLAIN) do_edcrypt = TFC_DO_DECRYPT; break; case 'D': macbits = strtoul(optarg, &stoi, 10); @@ -425,14 +434,21 @@ _baddfname: } else if (!strncmp(s, "ftrunc", 6) && *(s+6) == '=') { s += 7; - ftrunc_dfd = tfc_humanfsize(s, &stoi); - if (!str_empty(stoi)) { - ftrunc_dfd = tfc_fnamesize(s, YES); - ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); - if (ftrunc_dfd == NOFSIZE) xerror(NO, YES, YES, - "%s: invalid ftrunc value", s); + if (!strcmp(s, "tail")) { + do_ftrunc = TFC_FTRUNC_TAIL; + ftrunc_dfd = NOFSIZE; + } + else { + do_ftrunc = TFC_DO_FTRUNC; + ftrunc_dfd = tfc_humanfsize(s, &stoi); + if (!str_empty(stoi)) { + ftrunc_dfd = tfc_fnamesize(s, YES); + ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); + if (ftrunc_dfd == NOFSIZE) xerror(NO, YES, YES, + "%s: invalid ftrunc value", s); + } + else ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); } - else ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':')); } else if (!strncmp(s, "xkey", 4) && *(s+4) == '=') { s += 5; @@ -488,9 +504,11 @@ _baddfname: do_mac_file = optarg; break; case 'm': + case 'u': if (do_mac != TFC_MAC_VRFY) xerror(NO, YES, YES, "signature source was not specified"); do_mac = TFC_MAC_JUST_VRFY; + if (c == 'u') do_mac = TFC_MAC_JUST_VRFY2; break; case 'R': case 'Z': @@ -628,7 +646,7 @@ _nosalt: lrem = lblock = sizeof(tmpdata); if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(mkfd); _mkragain: lio = xread(mkfd, pblk, lrem); - if (lio == 0) do_stop = YES; + if (lio == 0 && do_stop == NO) do_stop = YES; if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -1011,6 +1029,7 @@ _xts2genkey: if (xwrite(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == NOSIZE) xerro tfc_data_to_words64(&iseek_blocks, sizeof(iseek_blocks)); tf_ctr_set(ctr, &iseek_blocks, sizeof(iseek_blocks)); + if (do_mac == TFC_MAC_JUST_VRFY2) memcpy(svctr, ctr, TF_BLOCK_SIZE); if (counter_opt == TFC_CTR_SHOW) { switch (do_outfmt) { @@ -1093,6 +1112,24 @@ _ctrwagain: lio = xwrite(dfd, pblk, lrem); if (ctr_mode == TFC_MODE_STREAM) tfe_init_iv(&tfe, key, ctr); + if (do_mac == TFC_MAC_JUST_VRFY2) { + rwd = tfc_fdgetpos(sfd); + if (rwd == NOFSIZE) { + tfc_esay("%s: WARNING: input is not seekable, disabling MAC testing mode", progname); + do_mac = TFC_MAC_VRFY; + } + goto _nodecrypt_again_vrfy2; + +_decrypt_again_vrfy2: + if (lseek(sfd, (off_t)rwd, SEEK_SET) == ((off_t)-1)) { + xerror(ignore_seek_errors, NO, YES, "MAC testing seek failed"); + } + total_processed_src = rwd; + memcpy(ctr, svctr, TF_BLOCK_SIZE); + memset(svctr, 0, TF_BLOCK_SIZE); + } + +_nodecrypt_again_vrfy2: errno = 0; do_stop = NO; while (1) { @@ -1102,7 +1139,7 @@ _ctrwagain: lio = xwrite(dfd, pblk, lrem); lrem = lblock = blk_len_adj(maxlen, total_processed_src, blksize); 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 == 0) do_stop = YES; if (lio != NOSIZE) ldone += lio; else { if (errno != EIO && catch_all_errors != YES) @@ -1162,7 +1199,7 @@ _ragain: lio = xread(sfd, pblk, lrem); if (do_mac >= TFC_MAC_VRFY && ctr_mode < TFC_MODE_OCB) skein_update(&sk, dstblk, ldone); - if (do_mac == TFC_MAC_JUST_VRFY) goto _nowrite; + if (do_mac >= TFC_MAC_JUST_VRFY) goto _nowrite; pblk = dstblk; lrem = ldone; @@ -1176,14 +1213,13 @@ _wagain: lio = xwrite(dfd, pblk, lrem); lrem -= lio; goto _wagain; } + total_written_dst += ldone; _nowrite: total_processed_dst += ldone; delta_processed += ldone; if (maxlen != NOFSIZE && total_processed_src >= maxlen) break; } - if (do_stop == TFC_STOP_FULL) goto _nomac; - errno = 0; if (do_mac >= TFC_MAC_VRFY) { if (!do_mac_file) { @@ -1259,10 +1295,18 @@ _macragain: lio = xread(sfd, pblk, lrem); else mehexdump(macresult, TF_FROM_BITS(macbits), TF_FROM_BITS(macbits), YES); } } + if (do_mac == TFC_MAC_JUST_VRFY2) { + if (verbose) tfc_esay("%s: -u: MAC signature is valid, proceeding with decrypting it again", progname); + do_mac = TFC_MAC_DROP; + goto _decrypt_again_vrfy2; + } } else { - if (quiet == NO) tfc_esay("%s: signature is BAD: " + if (quiet == NO) { + tfc_esay("%s: signature is BAD: " "wrong password, key, mode, or file is not signed", progname); + if (do_mac == TFC_MAC_JUST_VRFY2) tfc_esay("%s: -u: MAC signature is invalid, not decrypting it again", progname); + } exitcode = 1; } @@ -1328,12 +1372,14 @@ _macwagain: lio = xwrite(dfd, pblk, lrem); memset(tmpdata, 0, sizeof(tmpdata)); } -_nomac: - if (verbose || status_timer || do_stop == TFC_STOP_FULL) print_crypt_status(0); + if (verbose || status_timer || do_stop == YES) print_crypt_status(0); if (do_preserve_time) fcopy_matime(dfd, &s_stat); xclose(sfd); - if (ftrunc_dfd != NOFSIZE) if (ftruncate(dfd, (off_t)ftrunc_dfd) == -1) xerror(YES, NO, YES, "ftruncate(%d)", dfd); + if (do_ftrunc > TFC_NO_FTRUNC) { + if (do_ftrunc == TFC_FTRUNC_TAIL) ftrunc_dfd = total_processed_dst; + if (ftruncate(dfd, (off_t)ftrunc_dfd) == -1) xerror(YES, NO, YES, "ftruncate(%d)", dfd); + } xclose(dfd); xexit(exitcode);