if (optopt == 'V') {
tfc_say("tfcrypt toolkit, version %s.", _TFCRYPT_VERSION);
- if (ctr_mode != TFC_MODE_PLAIN) {
+ if (do_edcrypt != TFC_DO_PLAIN) {
char shash[64];
hash_defaults(shash, sizeof(shash));
tfc_say("no error checking is performed.");
tfc_say("\n");
}
+ else if (!strcmp(progname, "xor")) {
+ is_embedded_prog = YES;
+ tfc_say("usage: %s [sourceX] [sourceY] [output]", progname);
+ tfc_say("\n");
+ tfc_say("tfcrypt embedded high performance XOR tool.");
+ tfc_say("It does XOR (multiply modulo 2) of each byte from sourceX");
+ tfc_say("each byte of sourceY and writes output.");
+ tfc_say("If filenames omitted, it is assumed to operate over");
+ tfc_say("standard in to standard out.");
+ tfc_say("If any of source files is shorter than another,");
+ tfc_say("then output is truncated to length of the shortest one.");
+ tfc_say("\n");
+ tfc_say("No error checking is performed.");
+ tfc_say("Please use iotool options there.");
+ tfc_say("\n");
+ }
else if (!strcmp(progname, "tfbench")) {
is_embedded_prog = YES;
tfc_say("usage: %s seconds", progname);
tfc_say(" xctr=val: specify size in bytes of initial counter prepended or read.");
tfc_say(" fullkey: occupy tweak space by key space, extending key size by 256 bits.");
tfc_say(" -P: plain IO mode: disable encryption/decryption code at all.");
+ tfc_say(" -X: XOR IO mode: same as -P but do XOR of two streams.");
tfc_say("\n");
tfc_say("Default is to ask for password, then encrypt stdin into stdout.");
tfc_say("Some cmdline parameters may be mutually exclusive, or they can");
int main(int argc, char **argv)
{
+ tfc_yesno flipfd;
int c;
double td;
char *s, *d, *t, *stoi;
if (!strcmp(progname, "iotool")) {
do_edcrypt = TFC_DO_PLAIN;
- password = YES;
ctr_mode = TFC_MODE_PLAIN;
}
+ if (!strcmp(progname, "xor")) {
+ do_edcrypt = TFC_DO_PLAIN;
+ ctr_mode = TFC_MODE_XOR;
+ /* xor: default to stdin if invoked without args */
+ kfd = 0;
+ }
+
opterr = 0;
- while ((c = getopt(argc, argv, "L:s:aU:C:r:K:t:Pkzxc:l:qedn:vV:pwE:o:O:S:AmuM:R:Z:WHD:")) != -1) {
+ while ((c = getopt(argc, argv, "L:s:aU:C:r:K:t:PXkzxc:l:qedn:vV:pwE:o:O:S:AmuM:R:Z:WHD:")) != -1) {
switch (c) {
case 'L':
read_defaults(optarg, NO);
else xerror(NO, YES, YES, "%s: invalid mode of operation", optarg);
break;
case 'P':
+ case 'X':
do_edcrypt = TFC_DO_PLAIN;
- password = YES;
- ctr_mode = TFC_MODE_PLAIN;
+ if (c == 'X') {
+ ctr_mode = TFC_MODE_XOR;
+ /* xor: default to stdin if invoked without args */
+ kfd = 0;
+ }
+ else ctr_mode = TFC_MODE_PLAIN;
break;
case 'e':
if (do_edcrypt != TFC_DO_PLAIN) do_edcrypt = TFC_DO_ENCRYPT;
"%s: invalid iseek value", s);
}
else iseek = tfc_modifysize(iseek, strchr(s, ':'));
- if (ctr_mode != TFC_MODE_PLAIN && iseek % TF_BLOCK_SIZE)
+ if (do_edcrypt != TFC_DO_PLAIN && iseek % TF_BLOCK_SIZE)
xerror(NO, YES, YES,
"%s: not round to TF block size "
"of %u bytes",
"%s: invalid iseek value", s);
}
else iseek = tfc_modifysize(iseek, strchr(s, ':'));
- if (ctr_mode != TFC_MODE_PLAIN && iseek % TF_BLOCK_SIZE)
+ if (do_edcrypt != TFC_DO_PLAIN && iseek % TF_BLOCK_SIZE)
xerror(NO, YES, YES,
"%s: not round to TF block size "
"of %u bytes",
xerror(NO, YES, YES, "Cannot encrypt and read CTR from source!");
if (overwrite_source && counter_opt == TFC_CTR_RAND)
xerror(NO, YES, YES, "Cannot embed a CTR into file when overwriting it!");
- if (ctr_mode == TFC_MODE_PLAIN
- && (do_edcrypt || do_mac || rawkey
- || mackey_opt || counter_opt || counter_file))
+ if (do_edcrypt == TFC_DO_PLAIN
+ && (do_mac || saltf || rawkey || mackey_opt || counter_opt || counter_file))
xerror(NO, YES, YES, "Encryption facility is disabled when in plain IO mode.");
errno = 0;
idx = optind;
if (argv[idx]) {
- if (password || rawkey > TFC_RAWKEY_KEYFILE) goto _nokeyfd;
+ if ((do_edcrypt == TFC_DO_PLAIN && ctr_mode == TFC_MODE_PLAIN)
+ || password
+ || rawkey > TFC_RAWKEY_KEYFILE) goto _nokeyfd;
if (!strcmp(argv[idx], "-")) kfd = 0;
else kfd = xopen(argv[idx], O_RDONLY | O_LARGEFILE);
+ if (do_edcrypt == TFC_DO_PLAIN && ctr_mode == TFC_MODE_XOR) {
+ /* out: don't erase kfname if xor */
+ idx++;
+ goto _nokeyfd;
+ }
+
lio = strnlen(argv[idx], PATH_MAX);
memset(argv[idx], '*', lio);
xerror(ignore_seek_errors, NO, NO, "%s: seek failed", srcfname);
}
- if (ctr_mode == TFC_MODE_PLAIN) goto _plain;
+ if (do_edcrypt == TFC_DO_PLAIN) goto _plain;
if (verbose) tfc_esay("%s: hashing password", tfc_format_pid(progname));
memset(svctr, 0, TF_BLOCK_SIZE);
}
+#define FLFD(x, y) (flipfd ? y : x)
_nodecrypt_again_vrfy2:
loopcnt = 1;
errno = 0;
do_stop = NO;
+ flipfd = NO;
while (1) {
if (do_stop) break;
+ if (ctr_mode == TFC_MODE_XOR) flipfd = NO;
pblk = srcblk;
- ldone = 0;
+_nextblk: ldone = 0;
lrem = lblock = blk_len_adj(maxlen, total_processed_src, blksize);
- if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(sfd);
-_ragain: lio = xread(sfd, pblk, lrem);
+ if (error_action == TFC_ERRACT_SYNC) rdpos = tfc_fdgetpos(FLFD(sfd, kfd));
+_ragain: lio = xread(FLFD(sfd, kfd), pblk, lrem);
if (lio == 0) {
- if ((do_read_loops != 0 && sfd != 0) && (loopcnt < do_read_loops)) {
- lseek(sfd, 0L, SEEK_SET);
+ if ((do_read_loops != 0 && FLFD(sfd, kfd) != 0) && (loopcnt < do_read_loops)) {
+ lseek(FLFD(sfd, kfd), 0L, SEEK_SET);
loopcnt++;
goto _ragain;
}
xerror(YES, NO, NO, "%s", srcfname);
lio = ldone = lrem = lblock;
memset(srcblk, 0, lio);
- if (rdpos == NOFSIZE) lseek(sfd, lio, SEEK_CUR);
- else lseek(sfd, rdpos + lio, SEEK_SET);
+ if (rdpos == NOFSIZE) lseek(FLFD(sfd, kfd), lio, SEEK_CUR);
+ else lseek(FLFD(sfd, kfd), rdpos + lio, SEEK_SET);
break;
default: xerror(NO, NO, NO, "%s", srcfname); break;
}
memset(srcblk+orig, 0, sizeof(srcblk)-orig);
}
+ if (ctr_mode == TFC_MODE_XOR && flipfd == NO) {
+ if (do_stop) blksize = ldone;
+ flipfd = YES;
+ pblk = dstblk;
+ goto _nextblk;
+ }
+
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_PLAIN)
memcpy(dstblk, srcblk, ldone);
+ else if (ctr_mode == TFC_MODE_XOR)
+ xor_block(dstblk, srcblk, ldone);
+
if (do_mac >= TFC_MAC_VRFY) skein_update(&sk, dstblk, ldone);
if (do_mac >= TFC_MAC_JUST_VRFY) goto _nowrite;