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
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
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));
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];
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;
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);
}
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));
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;
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);
#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)
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);
--- /dev/null
+#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];
+}