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.
-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
-a single pass crypt and verify, thus, it is faster than other modes when both crypt and verify.
+Supported modes of operation: CTR, ECB, CBC, XTS and arbitrary long keystream.
Additionally, this version provides a way to virtually "extend" key size to 1280 bits,
by enabling "fullkey" option or changing "do_full_key" default setting in tfcrypt_defs.h.
slow on 32 bit systems. This way, it cannot be efficiently used on pure 32 bit machines.
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.
+regular block cipher. To add tweakability, XTS modes of operation is used.
Default wide block size is 4096 bytes.
SKEIN NOTES
tfc_getrandom(ctr, sizeof(ctr));
if (do_mac != NO) {
tfc_getrandom(mackey, sizeof(mackey));
- if (ctr_mode < TFC_MODE_OCB) skein_init_key(&sk, mackey, macbits);
+ skein_init_key(&sk, mackey, macbits);
}
if (ctr_mode == TFC_MODE_STREAM) tfe_init_iv(&tfe, key, ctr);
if (ctr_mode == TFC_MODE_XTS) tfc_getrandom(xtskey, sizeof(xtskey));
lblock = blk_len_adj(NOFSIZE, total_processed_src, blksize);
total_processed_src += lblock;
- if (do_mac != NO && ctr_mode < TFC_MODE_OCB)
- skein_update(&sk, srcblk, lblock);
+ if (do_mac != NO) skein_update(&sk, srcblk, lblock);
if (ctr_mode == TFC_MODE_CTR) tf_ctr_crypt(key, ctr, srcblk, srcblk, lblock);
else if (ctr_mode == TFC_MODE_STREAM) tf_stream_crypt(&tfe, srcblk, srcblk, lblock);
else if (ctr_mode == TFC_MODE_CBC && do_edcrypt == TFC_DO_DECRYPT)
tf_cbc_decrypt(key, ctr, srcblk, srcblk, lblock);
- else if (ctr_mode == TFC_MODE_OCB && do_edcrypt == TFC_DO_ENCRYPT)
- tf_ocb_encrypt(key, ctr, srcblk, do_mac ? macresult : NULL, srcblk, lblock, xtsblocks);
- else if (ctr_mode == TFC_MODE_OCB && do_edcrypt == TFC_DO_DECRYPT)
- tf_ocb_decrypt(key, ctr, srcblk, do_mac ? macresult : NULL, srcblk, lblock, xtsblocks);
-
delta_processed += lblock;
}
}
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")) {
tfc_say(" -w: overwrite source file. If not file, ignored.");
tfc_say(" -n TURNS: number of turns to perform in Skein function.");
tfc_say(" Default is always defined when building tfcrypt.");
- tfc_say(" -C mode: mode of operation: CTR, STREAM, XTS, ECB, CBC, OCB.");
+ tfc_say(" -C mode: mode of operation: CTR, STREAM, XTS, ECB, CBC.");
tfc_say(" Default encryption mode can be changed when building tfcrypt.");
tfc_say(" -c opt: initial CTR value initialisation mode:");
tfc_say(" show: do default action, then dump CTR value to stderr,");
case TFC_MODE_XTS: return "XTS";
case TFC_MODE_ECB: return "ECB";
case TFC_MODE_CBC: return "CBC";
- case TFC_MODE_OCB: return "OCB";
}
return NULL;
ctr_mode = TFC_MODE_ECB;
else if (!strcasecmp(optarg, "xts"))
ctr_mode = TFC_MODE_XTS;
- else if (!strcasecmp(optarg, "ocb"))
- ctr_mode = TFC_MODE_OCB;
else xerror(NO, YES, YES, "%s: invalid mode of operation", optarg);
break;
case 'P':
if (do_mac != NO) {
if (mackey_opt == TFC_MACKEY_RAWKEY) skein(mackey, TF_MAX_BITS, key, key, TF_FROM_BITS(TFC_KEY_BITS));
- if (ctr_mode < TFC_MODE_OCB) {
- if (verbose) tfc_esay("%s: doing MAC calculation, processing speed "
- "will be slower.", tfc_format_pid(progname));
- if (mackey_opt) skein_init_key(&sk, mackey, macbits);
- else skein_init(&sk, macbits);
- }
+ if (verbose) tfc_esay("%s: doing MAC calculation, processing speed "
+ "will be slower.", tfc_format_pid(progname));
+ if (mackey_opt) skein_init_key(&sk, mackey, macbits);
+ else skein_init(&sk, macbits);
}
if (!counter_file && counter_opt <= TFC_CTR_SHOW && ctr_mode != TFC_MODE_ECB) {
memset(srcblk+orig, 0, sizeof(srcblk)-orig);
}
- if (do_mac == TFC_MAC_SIGN && ctr_mode < TFC_MODE_OCB)
- skein_update(&sk, srcblk, ldone);
+ if (do_mac == TFC_MAC_SIGN) skein_update(&sk, srcblk, ldone);
if (ctr_mode == TFC_MODE_CTR) tf_ctr_crypt(key, ctr, dstblk, srcblk, ldone);
else if (ctr_mode == TFC_MODE_STREAM) tf_stream_crypt(&tfe, dstblk, srcblk, ldone);
else if (ctr_mode == TFC_MODE_CBC && do_edcrypt == TFC_DO_DECRYPT)
tf_cbc_decrypt(key, ctr, dstblk, srcblk, ldone);
- else if (ctr_mode == TFC_MODE_OCB && do_edcrypt == TFC_DO_ENCRYPT)
- tf_ocb_encrypt(key, ctr, dstblk, do_mac == TFC_MAC_SIGN ? macresult : NULL, srcblk, ldone, xtsblocks);
- else if (ctr_mode == TFC_MODE_OCB && do_edcrypt == TFC_DO_DECRYPT)
- tf_ocb_decrypt(key, ctr, dstblk, do_mac >= TFC_MAC_VRFY ? macresult : NULL, srcblk, ldone, xtsblocks);
-
else if (ctr_mode == TFC_MODE_PLAIN)
memcpy(dstblk, srcblk, ldone);
- if (do_mac >= TFC_MAC_VRFY && ctr_mode < TFC_MODE_OCB)
- skein_update(&sk, dstblk, ldone);
+ if (do_mac >= TFC_MAC_VRFY) skein_update(&sk, dstblk, ldone);
if (do_mac >= TFC_MAC_JUST_VRFY) goto _nowrite;
pblk = dstblk;
goto _shortmac;
}
- if (ctr_mode < TFC_MODE_OCB) skein_final(macresult, &sk);
- else skein(macresult, macbits, mackey, macresult, TF_FROM_BITS(macbits));
+ skein_final(macresult, &sk);
if (ctr_mode == TFC_MODE_CTR) tf_ctr_crypt(key, ctr, tmpdata, macvrfy, TF_FROM_BITS(macbits));
else if (ctr_mode == TFC_MODE_STREAM) tf_stream_crypt(&tfe, tmpdata, macvrfy, TF_FROM_BITS(macbits));
else if (ctr_mode == TFC_MODE_XTS) tf_xts_decrypt(key, xtskey, ctr, tmpdata, macvrfy, TF_FROM_BITS(macbits), xtsblocks);
else if (ctr_mode == TFC_MODE_ECB) tf_ecb_decrypt(key, tmpdata, macvrfy, TF_FROM_BITS(macbits));
else if (ctr_mode == TFC_MODE_CBC) tf_cbc_decrypt(key, ctr, tmpdata, macvrfy, TF_FROM_BITS(macbits));
- else if (ctr_mode == TFC_MODE_OCB) tf_ocb_decrypt(key, ctr, tmpdata, NULL, macvrfy, TF_FROM_BITS(macbits), xtsblocks);
if (!memcmp(tmpdata, macresult, TF_FROM_BITS(macbits))) {
if (quiet == NO) {
memset(tmpdata, 0, sizeof(tmpdata));
}
else if (do_mac == TFC_MAC_SIGN) {
- if (ctr_mode < TFC_MODE_OCB) skein_final(macresult, &sk);
- else skein(macresult, macbits, mackey, macresult, TF_FROM_BITS(macbits));
+ skein_final(macresult, &sk);
if (ctr_mode == TFC_MODE_CTR) tf_ctr_crypt(key, ctr, tmpdata, macresult, TF_FROM_BITS(macbits));
else if (ctr_mode == TFC_MODE_STREAM) tf_stream_crypt(&tfe, tmpdata, macresult, TF_FROM_BITS(macbits));
else if (ctr_mode == TFC_MODE_XTS) tf_xts_encrypt(key, xtskey, ctr, tmpdata, macresult, TF_FROM_BITS(macbits), xtsblocks);
else if (ctr_mode == TFC_MODE_ECB) tf_ecb_encrypt(key, tmpdata, macresult, TF_FROM_BITS(macbits));
else if (ctr_mode == TFC_MODE_CBC) tf_cbc_encrypt(key, ctr, tmpdata, macresult, TF_FROM_BITS(macbits));
- else if (ctr_mode == TFC_MODE_OCB) tf_ocb_encrypt(key, ctr, tmpdata, NULL, macresult, TF_FROM_BITS(macbits), xtsblocks);
memset(macresult, 0, sizeof(macresult));
if (!do_mac_file) {
enum { TFC_OUTFMT_HEX = 1, TFC_OUTFMT_B64, TFC_OUTFMT_RAW };
enum {
TFC_MODE_SKSUM = -2, TFC_MODE_PLAIN = -1, TFC_MODE_CTR = 1,
- TFC_MODE_STREAM, TFC_MODE_XTS, TFC_MODE_ECB, TFC_MODE_CBC, TFC_MODE_OCB
+ TFC_MODE_STREAM, TFC_MODE_XTS, TFC_MODE_ECB, TFC_MODE_CBC
};
enum { TFC_CTR_SHOW = 1, TFC_CTR_HEAD, TFC_CTR_RAND, TFC_CTR_ZERO, TFC_CTR_SSET };
enum { TFC_NO_FTRUNC, TFC_DO_FTRUNC, TFC_FTRUNC_TAIL };
void tf_cbc_decrypt(const void *key, void *iv, void *out, const void *in, size_t sz);
void tf_xts_encrypt(const void *keyx, const void *keyz, void *ctr, void *out, const void *in, size_t sz, size_t bpi);
void tf_xts_decrypt(const void *keyx, const void *keyz, void *ctr, void *out, const void *in, size_t sz, size_t bpi);
-void tf_ocb_encrypt(const void *key, void *ctr, void *out, void *tag, const void *in, size_t sz, size_t bpi);
-void tf_ocb_decrypt(const void *key, void *ctr, void *out, void *tag, const void *in, size_t sz, size_t bpi);
#endif
+++ /dev/null
-#include <string.h>
-#include "tfdef.h"
-
-static inline void ocb_block(TF_UNIT_TYPE *x, int tag)
-{
- TF_UNIT_TYPE c = (x[0] >> (TF_UNIT_BITS-1));
- size_t i;
-
- if (tag) goto _tag;
- for (i = 0; i < TF_NR_BLOCK_UNITS-1; i++)
- x[i] = ((x[i] << 1) | (x[i+1] >> (TF_UNIT_BITS-1)));
- x[TF_NR_BLOCK_UNITS-1] = ((x[i-1] << 1) ^ (c*IRR_POLY_CONST));
- return;
-
-_tag: for (i = 0; i < TF_NR_BLOCK_UNITS-1; i++)
- x[i] ^= ((x[i] << 1) | (x[i+1] >> (TF_UNIT_BITS-1)));
- x[TF_NR_BLOCK_UNITS-1] ^= ((x[i-1] << 1) ^ (c*IRR_POLY_CONST));
-}
-
-static void ocb_encrypt(const void *key, void *ctr, void *out, void *tag, const void *in, size_t sz)
-{
- const TF_BYTE_TYPE *uin = in;
- TF_BYTE_TYPE *uout = out, *s, *d;
- TF_UNIT_TYPE x[TF_NR_BLOCK_UNITS], y[TF_NR_BLOCK_UNITS];
- TF_UNIT_TYPE tctr[TF_NR_BLOCK_UNITS], c[TF_NR_BLOCK_UNITS];
- TF_UNIT_TYPE *uctr = ctr, *utag = tag;
- const TF_UNIT_TYPE *ukey = key;
- size_t sl = sz, i;
-
- tf_encrypt_rawblk(tctr, uctr, ukey);
- if (tag) {
- memcpy(c, tag, TF_BLOCK_SIZE);
- data_to_words(c, TF_BLOCK_SIZE);
- }
-
- if (sl >= TF_BLOCK_SIZE) {
- do {
- memcpy(x, uin, TF_BLOCK_SIZE);
- uin += TF_BLOCK_SIZE;
- data_to_words(x, TF_BLOCK_SIZE);
-
- ctr_inc(uctr, TF_NR_BLOCK_UNITS);
- ocb_block(tctr, 0);
- if (tag) for (i = 0; i < TF_NR_BLOCK_UNITS; i++) c[i] ^= x[i];
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
- tf_encrypt_rawblk(y, x, ukey);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] ^= tctr[i];
-
- data_to_words(y, TF_BLOCK_SIZE);
- memcpy(uout, y, TF_BLOCK_SIZE);
- uout += TF_BLOCK_SIZE;
- } while ((sl -= TF_BLOCK_SIZE) >= TF_BLOCK_SIZE);
- }
-
- if (sl) {
- ctr_inc(uctr, TF_NR_BLOCK_UNITS);
- ocb_block(tctr, 0);
- memset(x, 0, TF_BLOCK_SIZE);
- x[TF_NR_BLOCK_UNITS-1] = (TF_TO_BITS(sl));
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
- tf_encrypt_rawblk(y, x, ukey);
-
- memcpy(x, uin, sl);
- data_to_words(x, sl);
- s = (TF_BYTE_TYPE *)x; d = (TF_BYTE_TYPE *)y;
- memcpy(s+sl, d+sl, TF_BLOCK_SIZE-sl);
- if (tag) for (i = 0; i < TF_NR_BLOCK_UNITS; i++) c[i] ^= x[i];
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= y[i];
-
- data_to_words(x, sl);
- memcpy(uout, x, sl);
- }
-
- if (!tag) goto _done;
-
- ocb_block(tctr, 1);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] = tctr[i] ^ c[i];
- tf_encrypt_rawblk(y, x, ukey);
- data_to_words(y, TF_BLOCK_SIZE);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) utag[i] ^= y[i];
-
-_done: memset(tctr, 0, TF_BLOCK_SIZE);
- memset(c, 0, TF_BLOCK_SIZE);
- memset(x, 0, TF_BLOCK_SIZE);
- memset(y, 0, TF_BLOCK_SIZE);
-}
-
-void tf_ocb_encrypt(const void *key, void *ctr, void *out, void *tag, const void *in, size_t sz, size_t bpi)
-{
- const TF_BYTE_TYPE *uin = in;
- TF_BYTE_TYPE *uout = out;
- size_t sl = sz, sx = TF_BLOCKS_TO_BYTES(bpi);
-
- if (sl >= sx) {
- do {
- ocb_encrypt(key, ctr, uout, tag, uin, sx);
- uout += sx;
- uin += sx;
- } while ((sl -= sx) >= sx);
- }
-
- if (sl) ocb_encrypt(key, ctr, uout, tag, uin, sl);
-}
-
-static void ocb_decrypt(const void *key, void *ctr, void *out, void *tag, const void *in, size_t sz)
-{
- const TF_BYTE_TYPE *uin = in;
- TF_BYTE_TYPE *uout = out;
- TF_UNIT_TYPE x[TF_NR_BLOCK_UNITS], y[TF_NR_BLOCK_UNITS];
- TF_UNIT_TYPE tctr[TF_NR_BLOCK_UNITS], c[TF_NR_BLOCK_UNITS];
- TF_UNIT_TYPE *uctr = ctr, *utag = tag;
- const TF_UNIT_TYPE *ukey = key;
- size_t sl = sz, i;
-
- tf_encrypt_rawblk(tctr, uctr, ukey);
- if (tag) {
- memcpy(c, tag, TF_BLOCK_SIZE);
- data_to_words(c, TF_BLOCK_SIZE);
- }
-
- if (sl >= TF_BLOCK_SIZE) {
- do {
- memcpy(x, uin, TF_BLOCK_SIZE);
- uin += TF_BLOCK_SIZE;
- data_to_words(x, TF_BLOCK_SIZE);
-
- ctr_inc(uctr, TF_NR_BLOCK_UNITS);
- ocb_block(tctr, 0);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
- tf_decrypt_rawblk(y, x, ukey);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) y[i] ^= tctr[i];
- if (tag) for (i = 0; i < TF_NR_BLOCK_UNITS; i++) c[i] ^= y[i];
-
- data_to_words(y, TF_BLOCK_SIZE);
- memcpy(uout, y, TF_BLOCK_SIZE);
- uout += TF_BLOCK_SIZE;
- } while ((sl -= TF_BLOCK_SIZE) >= TF_BLOCK_SIZE);
- }
-
- if (sl) {
- ctr_inc(uctr, TF_NR_BLOCK_UNITS);
- ocb_block(tctr, 0);
- memset(x, 0, TF_BLOCK_SIZE);
- x[TF_NR_BLOCK_UNITS-1] = (TF_TO_BITS(sl));
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= tctr[i];
- tf_encrypt_rawblk(y, x, ukey);
-
- memset(x, 0, TF_BLOCK_SIZE);
- memcpy(x, uin, sl);
- data_to_words(x, sl);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] ^= y[i];
- if (tag) for (i = 0; i < TF_NR_BLOCK_UNITS; i++) c[i] ^= x[i];
-
- data_to_words(x, sl);
- memcpy(uout, x, sl);
- }
-
- if (!tag) goto _done;
-
- ocb_block(tctr, 1);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) x[i] = tctr[i] ^ c[i];
- tf_encrypt_rawblk(y, x, ukey);
- data_to_words(y, TF_BLOCK_SIZE);
- for (i = 0; i < TF_NR_BLOCK_UNITS; i++) utag[i] ^= y[i];
-
-_done: memset(tctr, 0, TF_BLOCK_SIZE);
- memset(c, 0, TF_BLOCK_SIZE);
- memset(x, 0, TF_BLOCK_SIZE);
- memset(y, 0, TF_BLOCK_SIZE);
-}
-
-void tf_ocb_decrypt(const void *key, void *ctr, void *out, void *tag, const void *in, size_t sz, size_t bpi)
-{
- const TF_BYTE_TYPE *uin = in;
- TF_BYTE_TYPE *uout = out;
- size_t sl = sz, sx = TF_BLOCKS_TO_BYTES(bpi);
-
- if (sl >= sx) {
- do {
- ocb_decrypt(key, ctr, uout, tag, uin, sx);
- uout += sx;
- uin += sx;
- } while ((sl -= sx) >= sx);
- }
-
- if (sl) ocb_decrypt(key, ctr, uout, tag, uin, sl);
-}