2 * tfcrypt -- high security Threefish encryption tool.
4 * tfcrypt is copyrighted:
5 * Copyright (C) 2012-2019 Andrey Rys. All rights reserved.
7 * tfcrypt is licensed to you under the terms of std. MIT/X11 license:
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:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
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.
31 size_t blk_len_adj(tfc_fsize filelen, tfc_fsize read_already, size_t blklen)
33 if (filelen == NOFSIZE) return blklen;
34 return ((filelen - read_already) >= blklen) ? blklen : (filelen - read_already);
37 tfc_yesno xor_shrink(void *dst, size_t szdst, const void *src, size_t szsrc)
39 unsigned char *udst = dst;
40 const unsigned char *usrc = src;
43 if ((szsrc % szdst) != 0) return NO;
46 memmove(dst, src, szsrc);
52 memset(dst, 0, szdst);
53 for (x = 0; x < (szsrc / szdst); x++) {
54 for (y = 0; y < szdst; y++) udst[y] ^= usrc[(x*szdst)+y];
60 tfc_yesno str_empty(const char *str)
62 if (!*str) return YES;
66 int xxopen(tfc_yesno noerr, const char *pathname, int flags)
70 if ((flags & O_WRONLY || flags & O_RDWR)) {
71 if (read_only == YES) flags = O_RDONLY;
72 else flags |= write_flags;
76 r = open(pathname, flags, 0666);
77 if (noerr == NO && r == -1) xerror(NO, NO, YES, "%s", pathname);
81 int xopen(const char *pathname, int flags)
83 return xxopen(NO, pathname, flags);
89 if (close(fd) == -1) xerror(YES, NO, NO, "close(%d)", fd);
92 const char *tfc_modename(int mode)
95 case TFC_MODE_CTR: return "CTR";
96 case TFC_MODE_STREAM: return "STREAM";
97 case TFC_MODE_XTS: return "XTS";
98 case TFC_MODE_ECB: return "ECB";
99 case TFC_MODE_CBC: return "CBC";
105 tfc_yesno tfc_is_freestream(int mode)
109 case TFC_MODE_STREAM: return YES;
115 void tfc_getcurtime(tfc_useconds *tx)
118 memset(&t, 0, sizeof(t));
120 clock_gettime(CLOCK_MONOTONIC, &t);
121 *tx = (tfc_useconds)t.tv_sec * 1000000 + (t.tv_nsec / 1000);
123 memset(&t, 0, sizeof(t));
126 char *tfc_format_time(tfc_useconds t)
128 tfc_useconds secs, dsecs;
129 unsigned days, hours, minutes, seconds;
132 secs = (tfc_useconds)TFC_UTODSECS(t);
133 dsecs = (tfc_useconds)(t - (secs * 1000000));
136 hours = (secs / 3600) % 24;
137 minutes = (secs / 60) % 60;
140 if (days > 0) sprintf(r, "%ud,%02u:%02u:%02u.%04u", days, hours, minutes, seconds, (unsigned)(dsecs / 100));
141 else if (hours > 0) sprintf(r, "%02u:%02u:%02u.%04u", hours, minutes, seconds, (unsigned)(dsecs / 100));
142 else if (minutes > 0) sprintf(r, "%02u:%02u.%04u", minutes, seconds, (unsigned)(dsecs / 100));
143 else sprintf(r, "%02u.%04u", seconds, (unsigned)(dsecs / 100));
148 char *tfc_format_pid(const char *str)
153 n = xstrlcpy(r, str, sizeof(r));
154 if (show_pid == YES && sizeof(r)-n >= 22) sprintf(r+n, "[%lu]", (unsigned long)progpid);
159 tfc_fsize tfc_fdsize(int fd)
163 cur = lseek(fd, 0L, SEEK_CUR);
164 l = lseek(fd, 0L, SEEK_SET);
165 if (l == -1) return NOFSIZE;
166 l = lseek(fd, 0L, SEEK_END);
167 if (l == -1) return NOFSIZE;
168 lseek(fd, cur, SEEK_SET);
173 tfc_fsize tfc_fdgetpos(int fd)
177 t = lseek(fd, 0L, SEEK_CUR);
178 if (t == (off_t)-1) return NOFSIZE;
182 tfc_fsize tfc_fnamesize(char *fname, tfc_yesno noexit)
188 if (!fname) return 0;
190 s = strchr(fname, ':');
191 if (s && s[1] && (s[1] == '+' || s[1] == '-' || s[1] == '*' || s[1] == '/')) {
196 fnmfd = xxopen(YES, fname, O_RDONLY);
197 if (s) memcpy(s, T, 2);
199 xerror(noexit, NO, YES, "%s", fname);
202 ret = tfc_fdsize(fnmfd);
203 if (ret == NOFSIZE) {
204 xerror(noexit, NO, YES, "%s: not a seekable file", fname);
212 tfc_fsize tfc_modifysize(tfc_fsize szmodify, const char *szspec)
218 if (szmodify == NOFSIZE) return NOFSIZE;
219 if (!szspec) return szmodify;
222 if (*s != ':') return szmodify;
224 if (!(*s == '+' || *s == '-' || *s == '*' || *s == '/')) return szmodify;
227 if (strchr(s, '/') || strchr(s, '.')) return szmodify;
229 t = tfc_humanfsize(s, &stoi);
230 if (!str_empty(stoi)) return szmodify;
233 case '+': szmodify += t; break;
234 case '-': szmodify -= t; break;
235 case '*': szmodify *= t; break;
236 case '/': szmodify /= t; break;
243 void fcopy_matime(int fd, const struct stat *st)
245 struct timeval times[2];
247 times[1].tv_sec = times[0].tv_sec = st->st_mtime;
248 times[1].tv_usec = times[0].tv_usec = 0;
249 if (futimes(fd, times) == -1) xerror(YES, NO, YES, "futimes(%d)", fd);
252 static void char_to_nul(char *s, size_t l, int c)
254 while (*s && l) { if (*s == c) { *s = 0; break; } s++; l--; }
257 tfc_yesno xfgets(char *s, size_t n, FILE *f)
261 if (fgets(s, (int)n, f) == s) {
262 char_to_nul(s, n, '\n');
269 tfc_yesno isbase64(const char *s)
272 if (*s >= 'g' && *s <= 'z') return YES;
273 if (*s >= 'G' && *s <= 'Z') return YES;
274 if (*s == '+' || *s == '/' || *s == '=') return YES;
280 static int chrbin(char x)
282 if (x >= '0' && x <= '9')
284 if (x >= 'A' && x <= 'F')
286 if (x >= 'a' && x <= 'f')
291 void hex2bin(void *d, const char *s)
299 x = (x << 4) ^ chrbin(*s);