Add Propagating CBC (PCBC) mode
[tfcrypt.git] / tfcrypt.c
index 7da9e99e550623fdce783b84d4ee420161d2383c..45438cb2bde7dc46cdc05ea0fba5b20d7ca7eebf 100644 (file)
--- a/tfcrypt.c
+++ b/tfcrypt.c
@@ -30,6 +30,7 @@
 
 static tfc_byte svctr[TF_BLOCK_SIZE];
 static tfc_fsize rwd, do_read_loops, loopcnt;
+static tfc_yesno unbuffered;
 
 static void open_log(const char *logfile)
 {
@@ -208,12 +209,12 @@ _baddfname:
                                        ctr_mode = TFC_MODE_STREAM;
                                else if (!strcasecmp(optarg, "cbc"))
                                        ctr_mode = TFC_MODE_CBC;
+                               else if (!strcasecmp(optarg, "pcbc"))
+                                       ctr_mode = TFC_MODE_PCBC;
                                else if (!strcasecmp(optarg, "ecb"))
                                        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':
@@ -348,6 +349,12 @@ _baddfname:
                                                show_when_done = YES;
                                        else if (!strcmp(s, "pid"))
                                                show_pid = YES;
+                                       else if (!strcmp(s, "nobuf")) {
+                                               if (!tfc_is_freestream(ctr_mode)) xerror(NO, YES, YES,
+                                                       "cannot activate unbuffered mode for non-stream cipher mode %s!",
+                                                       tfc_modename(ctr_mode));
+                                               else unbuffered = YES;
+                                       }
                                        else if (!strncmp(s, "readloops", 9) && *(s+9) == '=') {
                                                do_read_loops = tfc_humanfsize(s+10, &stoi);
                                                if (!str_empty(stoi)) do_read_loops = NOSIZE;
@@ -364,7 +371,7 @@ _baddfname:
                                                        "%s: invalid block size value", s);
                                                }
                                                else blksize = (size_t)tfc_modifysize((tfc_fsize)blksize, strchr(s, ':'));
-                                               if (blksize < TF_BLOCK_SIZE) xerror(NO, YES, YES,
+                                               if (!tfc_is_freestream(ctr_mode) && blksize < TF_BLOCK_SIZE) xerror(NO, YES, YES,
                                                        "%s: block size is lesser than TF_BLOCK_SIZE (%u bytes)", s, TFC_U(TF_BLOCK_SIZE));
                                                if (blksize > TFC_BLKSIZE) xerror(NO, YES, YES,
                                                        "%s: block size exceeds %u bytes",
@@ -765,7 +772,7 @@ _mkragain:          lio = xread(mkfd, pblk, lrem);
        || !memcmp(progname+5, "sum", 3)
        || !memcmp(progname+6, "sum", 3)))))
                do_sksum(progname, argv+optind);
-       if (!strcmp(progname, "tfbase64")) do_edbase64(argv+optind);
+       if (!strcmp(progname, "base64")) do_edbase64(argv+optind);
 
        idx = optind;
 
@@ -1052,12 +1059,10 @@ _xts2genkey:    if (xwrite(krfd, pblk, TF_FROM_BITS(TFC_KEY_BITS)) == NOSIZE) xerro
 
        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) {
@@ -1213,7 +1218,7 @@ _ragain:  lio = xread(sfd, pblk, lrem);
                                default: xerror(NO, NO, NO, "%s", srcfname); break;
                        }
                }
-               if (lio && lio < lrem) {
+               if (unbuffered == NO && lio && lio < lrem) {
                        pblk += lio;
                        lrem -= lio;
                        goto _ragain;
@@ -1227,8 +1232,7 @@ _ragain:  lio = xread(sfd, pblk, lrem);
                        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);
@@ -1244,17 +1248,15 @@ _ragain:        lio = xread(sfd, pblk, lrem);
                        tf_cbc_encrypt(key, ctr, 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_PCBC && do_edcrypt == TFC_DO_ENCRYPT)
+                       tf_pcbc_encrypt(key, ctr, dstblk, srcblk, ldone);
+               else if (ctr_mode == TFC_MODE_PCBC && do_edcrypt == TFC_DO_DECRYPT)
+                       tf_pcbc_decrypt(key, ctr, dstblk, srcblk, ldone);
 
                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;
@@ -1337,15 +1339,14 @@ _macragain:             lio = xread(sfd, pblk, lrem);
                        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);
+               else if (ctr_mode == TFC_MODE_PCBC) tf_pcbc_decrypt(key, ctr, tmpdata, macvrfy, TF_FROM_BITS(macbits));
 
                if (!memcmp(tmpdata, macresult, TF_FROM_BITS(macbits))) {
                        if (quiet == NO) {
@@ -1376,15 +1377,14 @@ _shortmac:      memset(macvrfy, 0, sizeof(macvrfy));
                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);
+               else if (ctr_mode == TFC_MODE_PCBC) tf_pcbc_encrypt(key, ctr, tmpdata, macresult, TF_FROM_BITS(macbits));
                memset(macresult, 0, sizeof(macresult));
 
                if (!do_mac_file) {