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
 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
 
 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.
 
 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
 
 
 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(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));
 
        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);
 }
 
        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];
 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;
 
 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;
 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);
                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 (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);
        }
 
                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) {
        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));
        }
        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 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;
 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 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);
 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_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)
 #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_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);
 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];
+}