From f402e6aa2dd18138ec26e9bfb340dae294637aec Mon Sep 17 00:00:00 2001 From: Andrey Rys Date: Sat, 23 Mar 2019 17:54:53 +0700 Subject: [PATCH] Replace ugly tweak size computation with explicit tweak clean API. --- README | 12 ++++-------- VERSION | 2 +- tfc_error.c | 1 + tfc_skein.c | 10 ---------- tfc_vars.c | 2 +- tfcrypt.c | 10 +++++----- tfcrypt.h | 3 +-- tfdef.h | 8 ++++++++ tftweakapi.c | 23 +++++++++++++++++++++++ 9 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 tftweakapi.c diff --git a/README b/README index f26c346..486307e 100644 --- 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 d6b2404..209e3ef 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -19 +20 diff --git a/tfc_error.c b/tfc_error.c index b90b108..5375367 100644 --- a/tfc_error.c +++ b/tfc_error.c @@ -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)); diff --git a/tfc_skein.c b/tfc_skein.c index 4eb6f92..e05927d 100644 --- a/tfc_skein.c +++ b/tfc_skein.c @@ -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]; diff --git a/tfc_vars.c b/tfc_vars.c index 490193d..e7e7f54 100644 --- a/tfc_vars.c +++ b/tfc_vars.c @@ -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; diff --git a/tfcrypt.c b/tfcrypt.c index 01173fb..aeedd02 100644 --- 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)); diff --git a/tfcrypt.h b/tfcrypt.h index c41f38d..a36cc16 100644 --- 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 463e5fb..72c713d 100644 --- a/tfdef.h +++ b/tfdef.h @@ -59,6 +59,11 @@ #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 index 0000000..5f68fe5 --- /dev/null +++ b/tftweakapi.c @@ -0,0 +1,23 @@ +#include +#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]; +} -- 2.31.1