From 8b7f1839b1981554979af1aa2e5e8b58ad63fe77 Mon Sep 17 00:00:00 2001 From: Andrey Rys Date: Sat, 16 Mar 2019 17:02:42 +0700 Subject: [PATCH] Support loading tfcrypt_defs.h variables from file. --- VERSION | 2 +- tfc_conf.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tfc_error.c | 2 ++ tfc_skein.c | 3 +- tfcrypt.c | 13 ++++++- tfcrypt.h | 5 +++ xstrlcat.c | 19 ++++++++++ 7 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 tfc_conf.c create mode 100644 xstrlcat.c diff --git a/VERSION b/VERSION index 8351c19..60d3b2f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -14 +15 diff --git a/tfc_conf.c b/tfc_conf.c new file mode 100644 index 0000000..bd2b112 --- /dev/null +++ b/tfc_conf.c @@ -0,0 +1,102 @@ +/* + * tfcrypt -- high security Threefish encryption tool. + * + * tfcrypt is copyrighted: + * Copyright (C) 2012-2018 Andrey Rys. All rights reserved. + * + * tfcrypt is licensed to you under the terms of std. MIT/X11 license: + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "tfcrypt.h" + +void read_defaults(const char *path, tfc_yesno noerr) +{ + static char ln[4096]; + char *s, *d, *t, *stoi; + FILE *f; + tfc_yesno valid = NO; + + f = fopen(path, "r"); + if (!f) { + if (noerr == YES) return; + xerror(NO, NO, YES, "%s", path); + } + + while (1) { + memset(ln, 0, sizeof(ln)); + if (xfgets(ln, sizeof(ln), f) != YES) break; + + if (valid == NO) { + if (!strcmp(ln, "# tfcrypt.defs")) valid = YES; + continue; + } + + if (str_empty(ln) || ln[0] == '#') continue; + + s = ln; + d = strchr(s, '='); + if (!d) continue; + *d = 0; d++; + + /* yay! GOTO hell! You'll "like" it! */ +_spc1: t = strchr(s, ' '); + if (!t) goto _spc2; + *t = 0; goto _spc1; +_spc2: t = strchr(d, ' '); + if (!t) goto _nspc; + *t = 0; d = t+1; goto _spc2; +_nspc: + if (!strcmp(s, "nr_turns")) { + nr_turns = sksum_turns = strtoul(d, &stoi, 10); + if (!str_empty(stoi)) xerror(NO, YES, YES, "[%s] nr_turns=%s: invalid number of turns", path, d); + } + else if (!strcmp(s, "ctr_mode")) { + if (!strcasecmp(d, "ctr")) + ctr_mode = TFC_MODE_CTR; + else if (!strcasecmp(d, "stream")) + ctr_mode = TFC_MODE_STREAM; + else if (!strcasecmp(d, "cbc")) + ctr_mode = TFC_MODE_CBC; + else if (!strcasecmp(d, "ecb")) + ctr_mode = TFC_MODE_ECB; + else if (!strcasecmp(d, "xts")) + ctr_mode = TFC_MODE_XTS; + else if (!strcasecmp(d, "ocb")) + ctr_mode = TFC_MODE_OCB; + else xerror(NO, YES, YES, "[%s] ctr_mode=%s: invalid mode of operation", path, d); + } + else if (!strcmp(s, "tfc_salt")) { + memset(tfc_salt, 0, TFC_MAX_SALT); + tfc_saltsz = base64_decode((char *)tfc_salt, TFC_MAX_SALT, d, strlen(d)); + } + else if (!strcmp(s, "macbits")) { + macbits = strtoul(d, &stoi, 10); + if (macbits == 0 || !str_empty(stoi) || macbits < 8 + || macbits > TF_MAX_BITS || macbits % 8) + xerror(NO, YES, YES, "[%s] macbits=%s: invalid MAC bits setting", path, d); + } + else xerror(NO, YES, YES, "[%s] %s: unknown keyword", path, s); + } + + memset(ln, 0, sizeof(ln)); + fclose(f); +} diff --git a/tfc_error.c b/tfc_error.c index cb8ee05..6e2dabf 100644 --- a/tfc_error.c +++ b/tfc_error.c @@ -151,6 +151,8 @@ void usage(void) tfc_say("convert encrypted data into ASCII format to ease transmission."); tfc_say("\n"); tfc_say(" -e, -d: encrypt, decrypt (it maybe required)."); + tfc_say(" -L : load tfcrypt defsults from file."); + tfc_say(" defaults is text file which defines salt, nr_turns and default mode."); tfc_say(" -s : load tfcrypt salt from file."); tfc_say(" -s disable: disable key salting at all."); tfc_say(" -p: instead of using key, ask for password."); diff --git a/tfc_skein.c b/tfc_skein.c index 5d457de..4eb6f92 100644 --- a/tfc_skein.c +++ b/tfc_skein.c @@ -204,8 +204,7 @@ _dothat: while (1) { memset(sksblk, 0, sizeof(sksblk)); - x = xfgets(sksblk, sizeof(sksblk), f); - if (x == 0) break; + if (xfgets(sksblk, sizeof(sksblk), f) != YES) break; s = d = sksblk; t = NULL; shash = fname = NULL; diff --git a/tfcrypt.c b/tfcrypt.c index 4724c0f..2390516 100644 --- a/tfcrypt.c +++ b/tfcrypt.c @@ -62,9 +62,20 @@ int main(int argc, char **argv) if (!isatty(2)) do_statline_dynamic = NO; + s = (char *)srcblk; + d = getenv("HOME"); + if (!d) d = ""; + xstrlcat(s, d, PATH_MAX > sizeof(srcblk) ? sizeof(srcblk) : PATH_MAX); + xstrlcat(s, "/.tfcrypt.defs", PATH_MAX > sizeof(srcblk) ? sizeof(srcblk) : PATH_MAX); + read_defaults(s, YES); + memset(s, 0, PATH_MAX > sizeof(srcblk) ? sizeof(srcblk) : PATH_MAX); + opterr = 0; - while ((c = getopt(argc, argv, "s: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; diff --git a/tfcrypt.h b/tfcrypt.h index fddb1ae..649fc06 100644 --- a/tfcrypt.h +++ b/tfcrypt.h @@ -119,6 +119,9 @@ int xmhexdump(int to, const void *data, size_t szdata, int hgroup, int hexstr, i #define mhexdump(data, szdata, group, newline) xmhexdump(1, data, szdata, group, do_full_hexdump, newline) #define mehexdump(data, szdata, group, newline) xmhexdump(2, data, szdata, group, do_full_hexdump, newline) +size_t xstrlcpy(char *dst, const char *src, size_t size); +size_t xstrlcat(char *dst, const char *src, size_t size); + extern size_t nr_turns; extern int ctr_mode; extern size_t macbits; @@ -203,6 +206,8 @@ void skein(void *hash, size_t bits, const void *key, const void *data, size_t sz void tf_key_tweak_compat(void *key); tfc_yesno skeinfd(void *hash, size_t bits, const void *key, int fd, tfc_fsize offset, tfc_fsize readto); +void read_defaults(const char *path, tfc_yesno noerr); + void gen_write_bytes(const char *foutname, tfc_fsize offset, tfc_fsize nrbytes); void do_edbase64(char **fargv); void do_sksum(char *spec, char **fargv); diff --git a/xstrlcat.c b/xstrlcat.c new file mode 100644 index 0000000..341b048 --- /dev/null +++ b/xstrlcat.c @@ -0,0 +1,19 @@ +#include + +size_t xstrlcpy(char *dst, const char *src, size_t size) +{ + size_t len, srclen; + srclen = strlen(src); + if (size-- <= 0) return srclen; + len = (size < srclen) ? size : srclen; + memmove(dst, src, len); + dst[len] = '\0'; + return srclen; +} + +size_t xstrlcat(char *dst, const char *src, size_t size) +{ + size_t dstlen = strnlen(dst, size); + if (dstlen == size) return dstlen + strlen(src); + return dstlen + xstrlcpy(dst+dstlen, src, size-dstlen); +} -- 2.31.1