Replace ugly tweak size computation with explicit tweak clean API.
authorAndrey Rys <rys@lynxlynx.ru>
Sat, 23 Mar 2019 10:54:53 +0000 (17:54 +0700)
committerAndrey Rys <rys@lynxlynx.ru>
Sat, 23 Mar 2019 10:54:53 +0000 (17:54 +0700)
README
VERSION
tfc_error.c
tfc_skein.c
tfc_vars.c
tfcrypt.c
tfcrypt.h
tfdef.h
tftweakapi.c [new file with mode: 0644]

diff --git a/README b/README
index f26c3461c4d2fb4cd106c0181519bd8f910f7dd1..486307ef2d19eff9762b14da4baffbf90f6e5ab8 100644 (file)
--- a/README
+++ b/README
@@ -15,9 +15,9 @@ with Skein hash function. Default key length is 1280 bits (160 bytes).
 This program is incompatible with older, "tf1024" tfcrypt version. This version aims to
 provide a portable encryption tool to encrypt fixed media such as disks and archive files,
 as well as to provide decades long privacy for encrypted data. That's why it uses 1024 bit
-encryption and, unlike older version, extends key size to 1280 bits, eliminates tweak feature
-from Threefish and uses either XTS (by default) or OCB modes of operation instead,
-to encrypt fixed media in a secure undetectable way.
+encryption and, unlike older version, virtually extends key size to 1280 bits by
+removing tweak feature from Threefish and uses either XTS (by default) or OCB modes of
+operation instead, to encrypt fixed media in a secure undetectable way.
 
 Supported modes of operation: CTR, ECB, CBC, XTS, OCB and arbitrary long keystream.
 OCB mode does not use Skein hash function to hash and verify message, instead, it does
@@ -30,11 +30,7 @@ slow on 32 bit systems. This way, it cannot be efficiently used on pure 32 bit m
 
 Threefish contained here is stripped off of it's tweak property, thus, it is turned into a
 regular block cipher. To add tweakability, either XTS or OCB modes of operation are used.
-Default wide block size is 4096 bytes. Author strongly believes that Threefish _may_ be subject
-to related key attacks when used in a tweaked mode, so this property is easy to remove.
-Because tweak occupied another 192 bits of key material, these 192 bits are added to effective
-key length. Another key word is extracted from the sum of all the user key words, thus,
-another 64 bits. Total +256 additional bits of key = 1280 key bits.
+Default wide block size is 4096 bytes.
 
 SKEIN NOTES
 
diff --git a/VERSION b/VERSION
index d6b24041cf04154f8f902651969675021f4d93a5..209e3ef4b6247ce746048d5711befda46206d235 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-19
+20
index b90b1087f659d4d656490c639b71586b713319ad..53753674915966d88e635d8500fd723a23c9bd64 100644 (file)
@@ -69,6 +69,7 @@ void xexit(int status)
        memset(ctr, 0, sizeof(ctr));
        memset(mackey, 0, sizeof(mackey));
        memset(xtskey, 0, sizeof(xtskey));
+       memset(tweak, 0, sizeof(tweak));
        memset(&sk, 0, sizeof(struct skein));
        memset(&tfe, 0, sizeof(struct tfe_stream));
 
index 4eb6f92d7734695d45558f028f5613742974aaf5..e05927da18385375aa61ea314737b65e9f2890be 100644 (file)
@@ -39,16 +39,6 @@ void skein(void *hash, size_t bits, const void *key, const void *data, size_t sz
        skein_final(hash, &sk);
 }
 
-void tf_key_tweak_compat(void *key)
-{
-       TF_UNIT_TYPE *ukey = key, c = THREEFISH_CONST;
-       size_t x;
-
-       for (x = 0; x < TF_NR_BLOCK_UNITS; x++) c ^= ukey[x];
-       ukey[x] = c;
-       ukey[TF_TWEAK_WORD3] = ukey[TF_TWEAK_WORD1] ^ ukey[TF_TWEAK_WORD2];
-}
-
 tfc_yesno skeinfd(void *hash, size_t bits, const void *key, int fd, tfc_fsize offset, tfc_fsize readto)
 {
        static tfc_byte skblk[TFC_BLKSIZE];
index 490193dc26013ddd7c59f0097c904530ef55ee74..e7e7f540f7b2529582c9d074cec6abd3687cc0ba 100644 (file)
@@ -32,7 +32,7 @@
 char *progname;
 int exitcode;
 
-tfc_byte key[TF_KEY_SIZE], ctr[TF_BLOCK_SIZE], xtskey[TF_KEY_SIZE], mackey[TF_FROM_BITS(TF_MAX_BITS)];
+tfc_byte key[TF_KEY_SIZE], ctr[TF_BLOCK_SIZE], xtskey[TF_KEY_SIZE], mackey[TF_FROM_BITS(TF_MAX_BITS)], tweak[TF_TWEAK_SIZE];
 struct skein sk;
 struct tfe_stream tfe;
 tfc_byte srcblk[TFC_BLKSIZE], dstblk[TFC_BLKSIZE], *pblk;
index 01173fb691a214f7e666fb0f48552072b4c59756..aeedd02b22f5e04f07867a06564fef092fac25f1 100644 (file)
--- a/tfcrypt.c
+++ b/tfcrypt.c
@@ -624,10 +624,10 @@ _mkragain:                lio = xread(mkfd, pblk, lrem);
                if (!strcmp(tweakf, "-")) twfd = 0;
                else twfd = open(tweakf, O_RDONLY | O_LARGEFILE);
                if (twfd == -1) xerror(NO, NO, YES, "%s", tweakf);
-               lio = ldone = xread(twfd, key+TF_FROM_BITS(TF_MAX_BITS)+TF_SIZE_UNIT, 2*TF_SIZE_UNIT);
+               lio = ldone = xread(twfd, tweak, TF_TWEAK_SIZE);
                if (lio == NOSIZE) xerror(NO, NO, YES, "%s", tweakf);
-               if (ldone < 2*TF_SIZE_UNIT)
-                       xerror(NO, NO, YES, "%s: %zu bytes tweak required", tweakf, 2*TF_SIZE_UNIT);
+               if (ldone < TF_TWEAK_SIZE)
+                       xerror(NO, NO, YES, "%s: %zu bytes tweak required", tweakf, TF_TWEAK_SIZE);
                xclose(twfd);
        }
 
@@ -915,8 +915,8 @@ _xts2genkey:        if (xwrite(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == NOSIZE) xerro
        tf_convkey(key);
        if (ctr_mode == TFC_MODE_XTS) tf_convkey(xtskey);
        if (do_tfcrypt1 == YES) {
-               if (!tweakf) skein(key+TF_FROM_BITS(TF_MAX_BITS)+TF_SIZE_UNIT, 2*TF_UNIT_BITS, NULL, key, TF_FROM_BITS(TFC_KEY_BITS));
-               tf_key_tweak_compat(key);
+               if (!tweakf) skein(tweak, TF_NR_TWEAK_BITS, NULL, key, TF_FROM_BITS(TFC_KEY_BITS));
+               tf_tweak_set(key, tweak);
        }
        if (ctr_mode == TFC_MODE_ECB) goto _ctrskip2;
        tfc_data_to_words64(&iseek_blocks, sizeof(iseek_blocks));
index c41f38d7203dd91db8bdfd6d000529ba5fbbecb1..a36cc16cfb6cd1d06d10dad53d20acd14ff0951f 100644 (file)
--- a/tfcrypt.h
+++ b/tfcrypt.h
@@ -130,7 +130,7 @@ extern tfc_byte tfc_salt[TFC_MAX_SALT];
 
 extern char *progname;
 extern int exitcode;
-extern tfc_byte key[TF_KEY_SIZE], ctr[TF_BLOCK_SIZE], xtskey[TF_KEY_SIZE], mackey[TF_FROM_BITS(TF_MAX_BITS)];
+extern tfc_byte key[TF_KEY_SIZE], ctr[TF_BLOCK_SIZE], xtskey[TF_KEY_SIZE], mackey[TF_FROM_BITS(TF_MAX_BITS)], tweak[TF_TWEAK_SIZE];
 extern struct skein sk;
 extern struct tfe_stream tfe;
 extern tfc_byte srcblk[TFC_BLKSIZE], dstblk[TFC_BLKSIZE], *pblk;
@@ -203,7 +203,6 @@ void change_status_width(int signal);
 void change_status_timer(int signal);
 void setup_next_alarm(tfc_useconds useconds);
 void skein(void *hash, size_t bits, const void *key, const void *data, size_t szdata);
-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);
diff --git a/tfdef.h b/tfdef.h
index 463e5fb7c0f4d83be1549ef8bdaa7b0666c8658c..72c713df4764b331452e311b7c9380c3ec43cf2b 100644 (file)
--- a/tfdef.h
+++ b/tfdef.h
 #define TF_BLOCK_SIZE (TF_SIZE_UNIT * TF_NR_BLOCK_UNITS)
 #define TF_KEY_SIZE (TF_SIZE_UNIT * TF_NR_KEY_UNITS)
 
+#define TF_NR_TWEAK_UNITS 2
+#define TF_NR_TWEAK_BITS 128
+#define TF_TWEAK_SIZE (TF_SIZE_UNIT * TF_NR_TWEAK_UNITS)
+#define TF_TWEAKEY_SIZE (TF_KEY_SIZE - (2 * TF_TWEAK_SIZE))
+#define TF_NR_TWEAKEY_BITS (TF_NR_KEY_BITS - (2 * TF_NR_TWEAK_BITS))
 #define TF_TWEAK_WORD1 (TF_NR_KEY_UNITS-3)
 #define TF_TWEAK_WORD2 (TF_NR_KEY_UNITS-2)
 #define TF_TWEAK_WORD3 (TF_NR_KEY_UNITS-1)
@@ -122,6 +127,9 @@ void tf_decrypt_block(const void *key, void *out, const void *in);
 
 void tf_ctr_set(void *ctr, const void *sctr, size_t sctrsz);
 void tf_ctr_crypt(const void *key, void *ctr, void *out, const void *in, size_t sz);
+
+void tf_tweak_set(void *key, const void *tweak);
+
 void tf_stream_crypt(struct tfe_stream *tfe, void *out, const void *in, size_t sz);
 void tf_ecb_encrypt(const void *key, void *out, const void *in, size_t sz);
 void tf_ecb_decrypt(const void *key, void *out, const void *in, size_t sz);
diff --git a/tftweakapi.c b/tftweakapi.c
new file mode 100644 (file)
index 0000000..5f68fe5
--- /dev/null
@@ -0,0 +1,23 @@
+#include <string.h>
+#include "tfdef.h"
+#include "tfcore.h"
+
+void tf_tweak_set(void *key, const void *tweak)
+{
+       TF_UNIT_TYPE *ukey = key;
+       TF_UNIT_TYPE *twe = ukey+TF_TWEAK_WORD1;
+       TF_UNIT_TYPE c = THREEFISH_CONST;
+       size_t x;
+
+       for (x = 0; x < TF_NR_BLOCK_UNITS; x++) c ^= ukey[x];
+       ukey[x] = c;
+
+       if (!tweak) {
+               memset(twe, 0, (TF_NR_TWEAK_UNITS+1)*TF_SIZE_UNIT);
+               return;
+       }
+
+       memcpy(twe, tweak, TF_NR_TWEAK_UNITS*TF_SIZE_UNIT);
+       data_to_words(twe, TF_NR_TWEAK_UNITS*TF_SIZE_UNIT);
+       ukey[TF_TWEAK_WORD3] = ukey[TF_TWEAK_WORD1] ^ ukey[TF_TWEAK_WORD2];
+}