51 broke -E logic completely, rewise it
[tfcrypt.git] / tfc_error.c
1 /*
2  * tfcrypt -- high security Threefish encryption tool.
3  *
4  * tfcrypt is copyrighted:
5  * Copyright (C) 2012-2019 Andrey Rys. All rights reserved.
6  *
7  * tfcrypt is licensed to you under the terms of std. MIT/X11 license:
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  */
28
29 #include "tfcrypt.h"
30
31 void xerror(tfc_yesno noexit, tfc_yesno noerrno, tfc_yesno nostats, const char *fmt, ...)
32 {
33         va_list ap;
34         char *s;
35
36         if (quiet) goto _do_sil_exit;
37
38         va_start(ap, fmt);
39
40         if (noexit == YES && (statline_was_shown == YES && do_statline_dynamic == YES)) tfc_esay("\n");
41
42         tfc_nfsay(stderr, "%s: ", tfc_format_pid(progname));
43         tfc_vfsay(stderr, NO, fmt, ap);
44         if (errno && noerrno == NO) {
45                 s = strerror(errno);
46                 tfc_esay(": %s", s);
47         }
48         else tfc_esay("\n");
49
50         va_end(ap);
51
52         if (nostats == NO) {
53                 print_crypt_status(TFC_SIGERR);
54         }
55
56 _do_sil_exit:
57         if (noexit == YES) {
58                 errno = 0;
59                 return;
60         }
61
62         xexit(2);
63 }
64
65 void xexit(int status)
66 {
67         if (status > 1) goto _do_clean_and_exit;
68
69         if (do_ftrunc > TFC_NO_FTRUNC) {
70                 if (do_ftrunc == TFC_FTRUNC_TAIL) ftrunc_dfd = total_processed_dst;
71                 if (ftruncate(dfd, (off_t)ftrunc_dfd) == -1) xerror(YES, NO, YES, "ftruncate(%d)", dfd);
72         }
73         if (do_preserve_time) fcopy_matime(dfd, &s_stat);
74
75 _do_clean_and_exit:
76         xclose(sfd);
77         xclose(dfd);
78
79         memset(srcblk, 0, sizeof(srcblk));
80         memset(dstblk, 0, sizeof(dstblk));
81
82         memset(key, 0, sizeof(key));
83         memset(ctr, 0, sizeof(ctr));
84         memset(mackey, 0, sizeof(mackey));
85         memset(xtskey, 0, sizeof(xtskey));
86         memset(tweak, 0, sizeof(tweak));
87         memset(&sk, 0, sizeof(struct skein));
88         memset(&tfe, 0, sizeof(struct tfe_stream));
89
90         tfc_finirandom();
91
92         memset(macvrfy, 0, sizeof(macvrfy));
93         memset(macresult, 0, sizeof(macresult));
94
95         memset(tmpdata, 0, sizeof(tmpdata));
96         memset(&getps, 0, sizeof(struct getpasswd_state));
97         memset(pwdask, 0, sizeof(pwdask));
98         memset(pwdagain, 0, sizeof(pwdagain));
99
100         exit(status);
101 }
102
103 void usage(void)
104 {
105         tfc_yesno is_embedded_prog = NO;
106
107         if (optopt == 'V') {
108                 tfc_say("tfcrypt toolkit, version %s.", _TFCRYPT_VERSION);
109                 if (do_edcrypt != TFC_DO_PLAIN) {
110                         char shash[64];
111
112                         hash_defaults(shash, sizeof(shash));
113                         tfc_say("Defaults hash: %s", shash);
114                         memset(shash, 0, sizeof(shash));
115                 }
116                 xexit(0);
117         }
118
119         if (!strcmp(progname, "iotool")) {
120                 is_embedded_prog = YES;
121                 tfc_say("usage: %s [-E how] [-l length] [-O opts] [-aqvw] [-V secs] [source] [output]", progname);
122                 tfc_say("\n");
123                 tfc_say("%s: do dd-like input/output, writing source to output whole or partially.", progname);
124                 tfc_say("  -E how: how to behave on I/O errors (both src or dst):");
125                 tfc_say("    exit: print error if not quiet, then exit,");
126                 tfc_say("    cont: print error if not quiet, then continue,");
127                 tfc_say("      no action to pad missing data is attempted.");
128                 tfc_say("      may be dangerous when working with block devices.");
129                 tfc_say("    sync: print error if not quiet, then continue,");
130                 tfc_say("      pad missing data block with zeroes.");
131                 tfc_say("    lsync: same as sync, but does not use SEEK_SET logic,");
132                 tfc_say("      lsync uses only relative seek operations, and does not prequery");
133                 tfc_say("      the current file position for exact offsets, which maybe unsafe.");
134                 tfc_say("      For this reason, it is HIGHLY recommended to use sync instead!");
135                 tfc_say("      Note that both sync and lsync work only with read errors!");
136                 tfc_say("  default error action is exit with printing status if not quiet.");
137                 tfc_say("  -E xall: turn on error actions above for all errors, not just EIO errors.");
138                 tfc_say("  -E xseek: ignore positioning and other seek related errors.");
139                 tfc_say("    Multiple -E specifiers may be given in separate options.");
140                 tfc_say("  -a: shortcut of -O xtime.");
141                 tfc_say("  -l length: read only these first bytes of source.");
142                 tfc_say("  -O opts: set options (comma separated list):");
143                 tfc_say("    ro: open all files only for reading, even those intended for writing,");
144                 tfc_say("    sync: request a synchronous I/O for a output,");
145                 tfc_say("    fsync: on each write() call a corresponding fsync(fd),");
146                 tfc_say("    trunc: open(O_WRONLY) will truncate output file to zero size.");
147                 tfc_say("    append: open(O_APPEND) will append data to output file.");
148                 tfc_say("    pad: pad incomplete (l.t. %u bytes) block with zeroes.", TFC_U(TF_BLOCK_SIZE));
149                 tfc_say("    xtime: copy timestamps from source to destination files.");
150                 tfc_say("    gibsize: use SI units of size: 1k = 1000. Applies only to size prefixes.");
151                 tfc_say("    Computers convention is to use 1024, whereas SI/hdd measure in 1000.");
152                 tfc_say("    plainstats: force status line to be plain: no fancy dynamic stuff.");
153                 tfc_say("    Dynamic line works well only on VT100 compatible ttys, and");
154                 tfc_say("    when the whole status line width is smaller than tty width.");
155                 tfc_say("    statless: emit less information in status line (only processed data).");
156                 tfc_say("    iobs=val: set IO block size value. Must not exceed %u bytes.", TFC_U(TFC_BLKSIZE));
157                 tfc_say("    nobuf: disable IO buffering, write as soon as data received (only for stream ciphers!)");
158                 tfc_say("    iseek=val: seek source file/device by these val bytes.");
159                 tfc_say("    oseek=val: seek destination file/device by these val bytes.");
160                 tfc_say("    ioseek=val: seek both source and destination.");
161                 tfc_say("    ioseek is equal to iseek and oseek.");
162                 tfc_say("    count=val: process only these val bytes, both input and output.");
163                 tfc_say("    ftrunc=val: truncate output file to these val bytes before closing it.");
164                 tfc_say("    ftrunc=tail: truncate output's tail, leaving only processed data.");
165                 tfc_say("  -w: overwrite source file. If not file, ignored.");
166                 tfc_say("  -q: always be quiet, never tell anything (except when signaled).");
167                 tfc_say("  -v: print number of read and written encrypted bytes, and explain stages.");
168                 tfc_say("  -V seconds: activate timer that will repeatedly print statistics to stderr.");
169                 tfc_say("\n");
170         }
171         else if ((strlen(progname) <= 9)
172         && ((!strcmp(progname, "sksum"))
173         || ((!memcmp(progname, "sk", 2))
174         && (!memcmp(progname+3, "sum", 3)
175         || !memcmp(progname+4, "sum", 3)
176         || !memcmp(progname+5, "sum", 3)
177         || !memcmp(progname+6, "sum", 3))))) {
178                 is_embedded_prog = YES;
179                 tfc_say("usage: %s [-AW] [-D BITS] [-n TURNS] [-l length] [-c <file>] [-U <file>] [source] ...", progname);
180                 tfc_say("\n");
181                 tfc_say("%s: calculate and print Skein hashsum of stream.", progname);
182                 tfc_say("  -D BITS: specify bits as it was skBITSsum.");
183                 tfc_say("  -n TURNS: number of turns to perform in Skein function.");
184                 tfc_say("    sksum defaults to just one in all modes.");
185                 tfc_say("  -A: format checksum in base64 rather than in binary hex.");
186                 tfc_say("  -W: output raw binary checksum and remove filename(s) from output.");
187                 tfc_say("  -H: output small hexdump (hex string and ASCII printable characters).");
188                 tfc_say("  -l length: read only these first bytes of source.");
189                 tfc_say("  -c <file>: read hashes list from file and check them.");
190                 tfc_say("  -U <file>: read Skein MAC key from file.");
191                 tfc_say("multiple sources can be given in cmdline, and if one of");
192                 tfc_say("them is specified as \"-\", then reads are performed from stdin.");
193                 tfc_say("\n");
194         }
195         else if (!strcmp(progname, "base64")) {
196                 is_embedded_prog = YES;
197                 tfc_say("usage: %s [-ed] [source] [output]", progname);
198                 tfc_say("\n");
199                 tfc_say("tfcrypt embedded base64 encoder/decoder.");
200                 tfc_say("  -e: encode stream into base64.");
201                 tfc_say("  -d: decode base64 stream.");
202                 tfc_say("no error checking is performed.");
203                 tfc_say("\n");
204         }
205         else if (!strcmp(progname, "xor")) {
206                 is_embedded_prog = YES;
207                 tfc_say("usage: %s [sourceX] [sourceY] [output]", progname);
208                 tfc_say("\n");
209                 tfc_say("tfcrypt embedded high performance XOR tool.");
210                 tfc_say("It does XOR (multiply modulo 2) of each byte from sourceX");
211                 tfc_say("each byte of sourceY and writes output.");
212                 tfc_say("If filenames omitted, it is assumed to operate over");
213                 tfc_say("standard in to standard out.");
214                 tfc_say("If any of source files is shorter than another,");
215                 tfc_say("then output is truncated to length of the shortest one.");
216                 tfc_say("\n");
217                 tfc_say("No error checking is performed.");
218                 tfc_say("Please use iotool options there.");
219                 tfc_say("\n");
220         }
221         else if (!strcmp(progname, "tfbench")) {
222                 is_embedded_prog = YES;
223                 tfc_say("usage: %s seconds", progname);
224                 tfc_say("do an in-memory random data benchmark of Threefish.");
225                 tfc_say("\n");
226         }
227
228         if (is_embedded_prog) {
229                 tfc_say("This program is physical part of tfcrypt toolkit.");
230                 tfc_say("(see it's version with %s -V)", progname);
231                 tfc_say("Please note that other tfcrypt options are either ignored there,");
232                 tfc_say("or result of using them is undefined and it's not a bug.");
233
234                 xexit(1);
235         }
236
237         tfc_say("usage: %s [opts] [--] [key] [source] [output]", progname);
238         tfc_say("\n");
239         tfc_say("tfcrypt toolkit: encrypt streams with Threefish in CTR mode,");
240         tfc_say("calculate and check Skein hashsums, generate CSPRNG quality random data,");
241         tfc_say("convert encrypted data into ASCII format to ease transmission.");
242         tfc_say("\n");
243         tfc_say("  -e, -d: encrypt, decrypt (it maybe required).");
244         tfc_say("  -L <file>: load tfcrypt defaults from file.");
245         tfc_say("    defaults is text file which defines salt, nr_turns and default mode.");
246         tfc_say("  -s <file>: load tfcrypt salt from file.");
247         tfc_say("  -s disable: disable key salting at all.");
248         tfc_say("  -p: instead of using key, ask for password.");
249         tfc_say("  -k: use raw (%u byte) key instead of deriving it from arbitrary data.", TFC_U(TF_KEY_SIZE));
250         tfc_say("  -z: ask for key in plain C string form through password asker.");
251         tfc_say("  -x: ask for key in hex string form through password asker.");
252         tfc_say("  -K <file>: generate key from keyfile or password and write it to file.");
253         tfc_say("  -t <file>: use (raw) tweak from file.");
254         tfc_say("  -w: overwrite source file. If not file, ignored.");
255         tfc_say("  -n TURNS: number of turns to perform in Skein function.");
256         tfc_say("    Default is always defined when building tfcrypt.");
257         tfc_say("  -C mode: mode of operation: CTR, STREAM, XTS, ECB, CBC.");
258         tfc_say("    Default encryption mode can be changed when building tfcrypt.");
259         tfc_say("  -c opt: initial CTR value initialisation mode:");
260         tfc_say("    show: do default action, then dump CTR value to stderr,");
261         tfc_say("    head: when decrypting, read CTR from beginning of stream,");
262         tfc_say("    rand: generate random CTR and write it to beginning of stream,");
263         tfc_say("    zero: assume zero CTR is used, do not read from and write it to stream,");
264         tfc_say("    hexc:nr[,hexc:nr,...]: construct counter from given pattern.");
265         tfc_say("      Example: \"ff:124,08:2,80:2\" will fill counter first with 124 0xff bytes,");
266         tfc_say("      then with 2 0x08 bytes, then 2 0x80 bytes. To fill with zeroes, it is");
267         tfc_say("      simple to specify just a \"0:128\" as a pattern. Note that bytes that");
268         tfc_say("      exceed CTR space will be just dropped, and any unused bytes are set to zeroes.");
269         tfc_say("    <file>: read CTR from given file (both when encrypting/decrypting).");
270         tfc_say("      default is to derive CTR from user provided password or keyfile with");
271         tfc_say("      a single Skein function turn over derived, %u byte raw key", TFC_U(TF_KEY_SIZE));
272         tfc_say("  -q: always be quiet, never tell anything (except when signaled).");
273         tfc_say("  -v: print number of read and written encrypted bytes, and explain stages.");
274         tfc_say("  -V seconds: activate timer that will repeatedly print statistics to stderr.");
275         tfc_say("  -a: shortcut of -O xtime.");
276         tfc_say("  -g: same as '-e -C stream -c rand' or '-d -C stream -c head', depending on mode.");
277         tfc_say("  -j: same as '-e -C ctr -c rand' or '-d -C ctr -c head', depending on mode.");
278         tfc_say("  -l length: read only these first bytes of source.");
279         tfc_say("  -r <file>: specify random source instead of /dev/urandom.");
280         tfc_say("  -R nr_bytes: generate nr_bytes of random bytes suitable for use as key data.");
281         tfc_say("    -R also supports these aliases specified instead of nr_bytes:");
282         tfc_say("    cbs: output fixed maximum crypt block size (%u bytes),", TFC_U(TF_BLOCK_SIZE));
283         tfc_say("    ks: output fixed maximum crypt key size (%u bytes)", TFC_U(TF_KEY_SIZE));
284         tfc_say("    xks: output fixed maximum crypt XTS key size (%u bytes)", TFC_U(TF_KEY_SIZE*2));
285         tfc_say("    iobs: output %s builtin block size TFC_BLKSIZE (%u bytes),", progname, TFC_U(TFC_BLKSIZE));
286         tfc_say("    if nr_bytes is not a valid number or alias, this string will be");
287         tfc_say("    used to attempt to open it as file, and examine it's size.");
288         tfc_say("    Then this examined size will be set as nr_bytes to output.");
289         tfc_say("  -Z nr_bytes: like -R, but emit zero stream instead of random.");
290         tfc_say("  -D MACBITS: specify bit width of a MAC signature.");
291         tfc_say("  -U key/pwd/<file>: read Skein MAC key from file.");
292         tfc_say("    key: use primary encryption rawkey as a MAC key.");
293         tfc_say("    pwd: ask for password string that will be used as MAC key.");
294         tfc_say("  -S MAC: append MAC signature to end of file:");
295         tfc_say("    MAC: embed MAC signature into file itself at the end,");
296         tfc_say("    <file>: write a detached MAC signature into separate <file>,");
297         tfc_say("    -: write a detached MAC signature to stdout.");
298         tfc_say("    useful only with variable length files! For block devices,");
299         tfc_say("    specify a separate file name to save signature to: -S file.");
300         tfc_say("  -A: format raw binary data, like MAC signature or Skein hash, in base64.");
301         tfc_say("  -W: output pure binary data, and disable any strings addition in Skein.");
302         tfc_say("  -H: output small hexdump (hex string and ASCII printable characters).");
303         tfc_say("  -M MAC: verify attached MAC signature when decrypting a file:");
304         tfc_say("    MAC: embed MAC signature into file itself at the end,");
305         tfc_say("    <file>: write a detached MAC signature into separate <file>,");
306         tfc_say("    -: read a detached MAC signature from stdin,");
307         tfc_say("    drop: do not verify attached MAC, if any, and drop it from output.");
308         tfc_say("  -m: just verify MAC provided with -M. Do not write output file.");
309         tfc_say("  -u: almost same as -m, but turns on MAC pre-test mode, when verified");
310         tfc_say("    signature enables writing output file. It is useful when decrypting small texts.");
311         tfc_say("    The source must be a seekable file, otherwise this mode will be disabled.");
312         tfc_say("    In this mode, decryption is done twice and verification done once.");
313         tfc_say("    Both -m and -u options must be specified after -M.");
314         tfc_say("  -E how: how to behave on I/O errors (both src or dst):");
315         tfc_say("    exit: print error if not quiet, then exit,");
316         tfc_say("    cont: print error if not quiet, then continue,");
317         tfc_say("      no action to pad missing data is attempted.");
318         tfc_say("      may be dangerous when working with block devices.");
319         tfc_say("    sync: print error if not quiet, then continue,");
320         tfc_say("      pad missing data block with zeroes.");
321         tfc_say("    lsync: same as sync, but does not use SEEK_SET logic,");
322         tfc_say("      lsync uses only relative seek operations, and does not prequery");
323         tfc_say("      the current file position for exact offsets, which maybe unsafe.");
324         tfc_say("      For this reason, it is HIGHLY recommended to use sync instead!");
325         tfc_say("      Note that both sync and lsync work only with read errors!");
326         tfc_say("  default error action is exit with printing status if not quiet.");
327         tfc_say("  -E xall: turn on error actions above for all errors, not just EIO errors.");
328         tfc_say("  -E xseek: ignore positioning and other seek related errors.");
329         tfc_say("    Multiple -E specifiers may be given in separate options.");
330         tfc_say("  -o logfile: redirect all messages to logfile instead of stderr.");
331         tfc_say("  -O opts: set options (comma separated list):");
332         tfc_say("    ro: open all files only for reading, even those intended for writing,");
333         tfc_say("    sync: request a synchronous I/O for a output,");
334         tfc_say("    fsync: on each write() call a corresponding fsync(fd),");
335         tfc_say("    trunc: open(O_WRONLY) will truncate output file to zero size.");
336         tfc_say("    append: open(O_APPEND) will append data to output file.");
337         tfc_say("    pad: pad incomplete (l.t. %u bytes) block with zeroes.", TFC_U(TF_BLOCK_SIZE));
338         tfc_say("    xtime: copy timestamps from source to destination files.");
339         tfc_say("    gibsize: use SI units of size: 1k = 1000. Applies only to size prefixes.");
340         tfc_say("    Computers convention is to use 1024, whereas SI/hdd measure in 1000.");
341         tfc_say("    plainstats: force status line to be plain: no fancy dynamic stuff.");
342         tfc_say("    Dynamic line works well only on VT100 compatible ttys, and");
343         tfc_say("    when the whole status line width is smaller than tty width.");
344         tfc_say("    statless: emit less information in status line (only processed data).");
345         tfc_say("    norepeat: do not ask for any possible password confirmations.");
346         tfc_say("    showsecrets: show passwords in plaintext instead of masking them.");
347         tfc_say("    finished: add \"finished\" word before status line when work is finished.");
348         tfc_say("    pid: show %s's process id near it's name in error messages, logs etc.", progname);
349         tfc_say("    readloops=val: when seekable source ends, reading continues from it's beginning again.");
350         tfc_say("    prompt=str: set main password prompts to this string.");
351         tfc_say("    macprompt=str: set MAC password prompts to this string.");
352         tfc_say("    shorthex: with -H, do not print printable characters, dump only hex string.");
353         tfc_say("    logfile: (same as -o) redirect all messages to logfile instead of stderr.");
354         tfc_say("    iobs=val: set IO block size value. Must not exceed %u bytes.", TFC_U(TFC_BLKSIZE));
355         tfc_say("    nobuf: disable IO buffering, write as soon as data received (only for stream ciphers!)");
356         tfc_say("    xtsblocks=val: use these nr of TF blocks per XTS block. Default is %u.", TFC_U(TFC_XTSBLOCKS));
357         tfc_say("    iseek=val: seek source file/device by these val bytes.");
358         tfc_say("    Initial counter is adjusted automatically.");
359         tfc_say("    ixseek=val: rawseek source file/device by these val bytes.");
360         tfc_say("    Do not adjust initial counter automatically.");
361         tfc_say("    ictr=val: Increment initial counter by this val blocks.");
362         tfc_say("    The size of each block is %u bytes.", TFC_U(TF_BLOCK_SIZE));
363         tfc_say("    ictr option is valid only for CTR and CTR like modes.");
364         tfc_say("    ixctr=val: Increment initial counter by this val bytes.");
365         tfc_say("    Internally this number is translated into number of %u byte blocks.", TFC_U(TF_BLOCK_SIZE));
366         tfc_say("    oseek=val: seek destination file/device by these val bytes.");
367         tfc_say("    ioseek=val: seek both source and destination.");
368         tfc_say("    ioseek is equal to iseek and oseek.");
369         tfc_say("    count=val: process only these val bytes, both input and output.");
370         tfc_say("    ftrunc=val: truncate output file to these val bytes before closing it.");
371         tfc_say("    ftrunc=tail: truncate output's tail, leaving only processed data.");
372         tfc_say("    xkey=val: take only val bytes from user keyfile.");
373         tfc_say("    okey=val: seek the key before reading it (usually a device).");
374         tfc_say("    xctr=val: specify size in bytes of initial counter prepended or read.");
375         tfc_say("    fullkey: occupy tweak space by key space, extending key size by 256 bits.");
376         tfc_say("  -P: plain IO mode: disable encryption/decryption code at all.");
377         tfc_say("  -X: XOR IO mode: same as -P but do XOR of two streams.");
378         tfc_say("\n");
379         tfc_say("Default is to ask for password, then encrypt stdin into stdout.");
380         tfc_say("Some cmdline parameters may be mutually exclusive, or they can");
381         tfc_say("generate errors or behave abnormally. Please understand that some");
382         tfc_say("dumb mode error checking may be not performed well, and please read");
383         tfc_say("the README included within package and this help text carefully.");
384         tfc_say("\n");
385
386         xexit(1);
387 }