tfc_signal: add elapsed time counter.
[tfcrypt.git] / tfcrypt.c
index 5ed5bbf1979cad49d5ee15bc876495b82ebc822a..d673d386e7757cf739ffc35fbf35283476b39e3b 100644 (file)
--- a/tfcrypt.c
+++ b/tfcrypt.c
@@ -2,7 +2,7 @@
  * tfcrypt -- high security Threefish encryption tool.
  *
  * tfcrypt is copyrighted:
- * Copyright (C) 2012-2018 Andrey Rys. All rights reserved.
+ * Copyright (C) 2012-2019 Andrey Rys. All rights reserved.
  *
  * tfcrypt is licensed to you under the terms of std. MIT/X11 license:
  *
@@ -83,6 +83,30 @@ static int getps_plain_hex_filter(struct getpasswd_state *getps, char chr, size_
        return 1;
 }
 
+static void make_hint(void *hint, size_t szhint, const void *data, size_t szdata)
+{
+       char t[TF_FROM_BITS(TF_MAX_BITS)];
+
+       skein(t, TF_MAX_BITS, NULL, data, szdata);
+       xor_shrink(hint, szhint, t, sizeof(t));
+       memset(t, 0, sizeof(t));
+}
+
+static void raw_say_hint(void *hint, size_t szhint, const void *data, size_t szdata, const char *prompt)
+{
+       make_hint(hint, szhint, data, szdata);
+       if (prompt) tfc_nfsay(stderr, "%s: ", prompt);
+       mehexdump(hint, szhint, szhint, 1);
+       memset(hint, 0, szhint);
+}
+
+static void say_hint(const void *data, size_t szdata, const char *prompt)
+{
+       char t[TF_SIZE_UNIT];
+       raw_say_hint(t, TF_SIZE_UNIT, data, szdata, prompt);
+       /* t[] is erased (automatically) */
+}
+
 int main(int argc, char **argv)
 {
        int c;
@@ -125,6 +149,29 @@ _baddfname:
                                        counter_opt = TFC_CTR_RAND;
                                else if (!strcasecmp(optarg, "zero"))
                                        counter_opt = TFC_CTR_ZERO;
+                               else if (strchr(optarg, ':')) {
+                                       char *ss, chr;
+
+                                       counter_opt = TFC_CTR_SSET;
+                                       n = sizeof(ctr);
+
+                                       s = d = optarg; t = NULL;
+                                       while ((s = strtok_r(d, ",", &t))) {
+                                               if (d) d = NULL;
+
+                                               if (n == 0) break;
+                                               ss = strchr(s, ':');
+                                               if (!ss) continue;
+                                               *ss = 0; ss++;
+                                               chr = (char)strtoul(s, &stoi, 16);
+                                               if (!str_empty(stoi)) continue;
+                                               x = (size_t)strtoul(ss, &stoi, 10);
+                                               if (!str_empty(stoi)) continue;
+                                               if (x > n) x = n;
+                                               memset(ctr+(sizeof(ctr)-n), (int)chr, x);
+                                               n -= x;
+                                       }
+                               }
                                else counter_file = sksum_hashlist_file = optarg;
                                break;
                        case 'C':
@@ -376,6 +423,17 @@ _baddfname:
                                                if (counter_opt == TFC_CTR_HEAD)
                                                        maxlen += TF_BLOCK_SIZE;
                                        }
+                                       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);
+                                               }
+                                               else ftrunc_dfd = tfc_modifysize(ftrunc_dfd, strchr(s, ':'));
+                                       }
                                        else if (!strncmp(s, "xkey", 4) && *(s+4) == '=') {
                                                s += 5;
                                                maxkeylen = tfc_humanfsize(s, &stoi);
@@ -477,6 +535,7 @@ _baddfname:
                        case 'q':
                                quiet = YES;
                                verbose = NO;
+                               do_full_hexdump = NO;
                                status_timer = 0;
                                break;
                        case 'v':
@@ -612,14 +671,8 @@ _mkragain:         lio = xread(mkfd, pblk, lrem);
                n = xgetpasswd(&getps);
                if (n == NOSIZE) xerror(NO, NO, YES, "getting MAC password");
                if (n == ((size_t)-2)) xexit(1);
+               if (verbose) say_hint(pwdask, n, "MAC password hint");
                skein(mackey, TF_MAX_BITS, NULL, pwdask, n);
-               if (verbose) {
-                       skein(tmpdata, TF_MAX_BITS, NULL, mackey, TF_FROM_BITS(TF_MAX_BITS));
-                       xor_shrink(tmpdata+TF_FROM_BITS(TF_MAX_BITS), TF_SIZE_UNIT, tmpdata, TF_FROM_BITS(TF_MAX_BITS));
-                       tfc_nfsay(stderr, "MAC password hint: ");
-                       mehexdump(tmpdata+TF_FROM_BITS(TF_MAX_BITS), TF_SIZE_UNIT, TF_SIZE_UNIT, 1);
-                       memset(tmpdata, 0, sizeof(tmpdata));
-               }
        }
 
        
@@ -807,6 +860,7 @@ _xts2keyaskstr:     memset(&getps, 0, sizeof(struct getpasswd_state));
                n = xgetpasswd(&getps);
                if (n == NOSIZE) xerror(NO, NO, YES, "getting string rawkey");
                if (n == ((size_t)-2)) xexit(1);
+               if (verbose) say_hint(pblk, n, "Raw string key hint");
                if (ctr_mode == TFC_MODE_XTS) {
                        if (xtskeyset == NO) {
                                pblk = xtskey; n = sizeof(xtskey);
@@ -837,6 +891,7 @@ _rawkey_hex_again:
                }
                hex2bin(pblk, pwdask);
                memset(pwdask, 0, sizeof(pwdask));
+               if (verbose) say_hint(pblk, n/2, "Raw hex key hint");
                if (ctr_mode == TFC_MODE_XTS) {
                        if (xtskeyset == NO) {
                                pblk = xtskey;
@@ -871,6 +926,7 @@ _pwdagain:  memset(&getps, 0, sizeof(struct getpasswd_state));
                                goto _pwdagain;
                        }
                }
+               if (verbose) say_hint(pwdask, n, "Password hint");
                skein(key, TFC_KEY_BITS, mackey_opt ? mackey : NULL, pwdask, n);
                memset(pwdask, 0, sizeof(pwdask));
                memset(pwdagain, 0, sizeof(pwdagain));
@@ -1277,6 +1333,7 @@ _nomac:
 
        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);
        xclose(dfd);
 
        xexit(exitcode);