* pcbc_encrypt.c: moved from f_pcbc.c in lib/crypto/des, and
authorMark Eichin <eichin@mit.edu>
Thu, 3 Nov 1994 23:31:51 +0000 (23:31 +0000)
committerMark Eichin <eichin@mit.edu>
Thu, 3 Nov 1994 23:31:51 +0000 (23:31 +0000)
inlined proper des.h to avoid confusion in names.
* Makefile.in: add -I to CFLAGS to get f_tables.h from
lib/crypto/des as well.

this shouldn't have been in lib/crypto/des in the first place, and the old
version here was nonportable.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4626 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/des425/ChangeLog
src/lib/des425/Makefile.in
src/lib/des425/pcbc_encrypt.c

index d2fc93f3dbde56f10310c44f2cf17c53daf2ac49..cf76d7637252e719c679a0b1c381f814e505598e 100644 (file)
@@ -1,3 +1,10 @@
+Thu Nov  3 18:29:10 1994  Mark Eichin  (eichin@cygnus.com)
+
+       * pcbc_encrypt.c: moved from f_pcbc.c in lib/crypto/des, and
+       inlined proper des.h to avoid confusion in names.
+       * Makefile.in: add -I to CFLAGS to get f_tables.h from
+       lib/crypto/des as well.
+
 Wed Oct 26 14:23:36 1994    (tytso@rsx-11)
 
        * Makefile.in (check): 
index 389a379a7b55bcfdfe0a0cf091f3a00478a8dd62..650c8dded25b3d25cc900f1d7aa34c26a664e6f9 100644 (file)
@@ -1,4 +1,4 @@
-CFLAGS = $(CCOPTS) $(DEFS)
+CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../crypto/des
 LDFLAGS = -g
 
 all:: $(OBJS)
index 00d9644ee1264bbb47db775b95945efd625c1e0a..45de20bc053d059052d6428a72eac618526b8b91 100644 (file)
 /*
  * lib/des425/pcbc_encrypt.c
- *
- * Copyright 1985, 1986, 1987, 1988,1990 by the Massachusetts Institute
- * of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- *   require a specific license from the United States Government.
- *   It is the responsibility of any person or organization contemplating
- *   export to obtain such a license before exporting.
- * 
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission.  M.I.T. makes no representations about the suitability of
- * this software for any purpose.  It is provided "as is" without express
- * or implied warranty.
- * 
- *
- * These routines perform encryption and decryption using the DES
- * private key algorithm, or else a subset of it-- fewer inner loops.
- * ( AUTH_DES_ITER defaults to 16, may be less)
- *
- * Under U.S. law, this software may not be exported outside the US
- * without license from the U.S. Commerce department.
- *
- * The key schedule is passed as an arg, as well as the cleartext or
- * ciphertext.  The cleartext and ciphertext should be in host order.
- *
- * These routines form the library interface to the des facilities.
- *
- * spm 8/85    MIT project athena
  */
 
-
-#include <stdio.h>
-#include "des.h"
-
-extern int mit_des_debug;
-extern int mit_des_debug_print();
-
 /*
- * pcbc_encrypt is an "error propagation chaining" encrypt operation
- * for DES, similar to CBC, but that, on encryption, "xor"s the
- * plaintext of block N with the ciphertext resulting from block N,
- * then "xor"s that result with the plaintext of block N+1 prior to
- * encrypting block N+1. (decryption the appropriate inverse.  This
- * "pcbc" mode propagates a single bit error anywhere in either the
- * cleartext or ciphertext chain all the way through to the end. In
- * contrast, CBC mode limits a single bit error in the ciphertext to
- * affect only the current (8byte) block and the subsequent block.
- *
- * performs pcbc error-propagation chaining operation by xor-ing block
- * N+1 with both the plaintext (block N) and the ciphertext from block
- * N.  Either encrypts from cleartext to ciphertext, if encrypt != 0
- * or decrypts from ciphertext to cleartext, if encrypt == 0
- *
- * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
- * enough space was provided, your program will get trashed.
- *
- * For encryption, the cleartext string is null padded, at the end, to
- * an integral multiple of eight bytes.
- *
- * For decryption, the ciphertext will be used in integral multiples
- * of 8 bytes, but only the first "length" bytes returned into the
- * cleartext.
- *
- * This is NOT a standard mode of operation.
+ * Copyright (c) 1990 Dennis Ferguson.  All rights reserved.
  *
+ * Commercial use is permitted only if products which are derived from
+ * or include this software are made available for purchase and/or use
+ * in Canada.  Otherwise, redistribution and use in source and binary
+ * forms are permitted.
  */
 
-int
-des_pcbc_encrypt(in,out,length,key,iv,encrypt)
-    mit_des_cblock *in;                /* >= length bytes of inputtext */
-    mit_des_cblock *out;               /* >= length bytes of outputtext */
-    register long length;      /* in bytes */
-    int encrypt;               /* 0 ==> decrypt, else encrypt */
-    des_key_schedule key;              /* precomputed key schedule */
-    mit_des_cblock *iv;                /* 8 bytes of ivec */
-{
-    register unsigned long *input = (unsigned long *) in;
-    register unsigned long *output = (unsigned long *) out;
-    register unsigned long *ivec = (unsigned long *) iv;
+/*
+ * des_pcbc_encrypt.c - encrypt a string of characters in error propagation mode
+ */
 
-    unsigned long i,j;
-    static unsigned long t_input[2];
-    static unsigned long t_output[2];
-    static unsigned char *t_in_p;
-    static unsigned long xor_0, xor_1;
+/* 
+ * copy of include/des.h to avoid collision with local one
+ */
+#include <kerberosIV/mit-copyright.h>
+#include <krb5/osconf.h>
 
-    t_in_p = (unsigned char *) t_input;
-    if (encrypt) {
-#ifdef MUSTALIGN
-       if ((long) ivec & 3) {
-           memcpy((char *)&xor_0, (char *)ivec++,sizeof(xor_0));
-           memcpy((char *)&xor_1, (char *)ivec,  sizeof(xor_1));
-       }
-       else
+#ifndef KRB_INT32
+#define KRB_INT32 long
 #endif
-       {
-           xor_0 = *ivec++;
-           xor_1 = *ivec;
-       }
-
-       for (i = 0; length > 0; i++, length -= 8) {
-           /* get input */
-#ifdef MUSTALIGN
-           if ((long) input & 3) {
-               memcpy((char *)&t_input[0], (char *)input,    sizeof(t_input[0]));
-               memcpy((char *)&t_input[1], (char *)(input+1),sizeof(t_input[1]));
-           }
-           else
+#ifndef KRB_UINT32
+#define KRB_UINT32 unsigned KRB_INT32
 #endif
-           {
-               t_input[0] = *input;
-               t_input[1] = *(input+1);
-           }
-
-           /* zero pad */
-           if (length < 8) {
-               for (j = length; j <= 7; j++)
-                   *(t_in_p+j)= 0;
-           }
 
-#ifdef DEBUG
-           if (mit_des_debug)
-               mit_des_debug_print("clear",length,t_input[0],t_input[1]);
+typedef unsigned char des_cblock[8];   /* crypto-block size */
+/* Key schedule */
+typedef struct des_ks_struct { union { KRB_INT32 pad; des_cblock _;} __; } des_key_schedule[16];
+
+#define DES_KEY_SZ     (sizeof(des_cblock))
+#define DES_ENCRYPT    1
+#define DES_DECRYPT    0
+
+#ifndef NCOMPAT
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define key_sched des_key_sched
+#define cbc_encrypt des_cbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define C_Block_print des_cblock_print
+#define quad_cksum des_quad_cksum
+typedef struct des_ks_struct bit_64;
 #endif
-           /* do the xor for cbc into the temp */
-           t_input[0] ^= xor_0 ;
-           t_input[1] ^= xor_1 ;
-           /* encrypt */
-           (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
 
-           /*
-            * We want to XOR with both the plaintext and ciphertext
-            * of the previous block, before we write the output, in
-            * case both input and output are the same space.
-            */
-#ifdef MUSTALIGN
-           if ((long) input & 3) {
-               memcpy((char *)&xor_0, (char *)input++, sizeof(xor_0));
-               xor_0 ^= t_output[0];
-               memcpy((char *)&xor_1, (char *)input++, sizeof(xor_1));
-               xor_1 ^= t_output[1];
-           }
-           else
-#endif
-           {
-               xor_0 = *input++ ^ t_output[0];
-               xor_1 = *input++ ^ t_output[1];
-           }
-
-
-           /* copy temp output and save it for cbc */
-#ifdef MUSTALIGN
-           if ((long) output & 3) {
-               memcpy((char *)output++, (char *)&t_output[0],
-                      sizeof(t_output[0]));
-               memcpy((char *)output++, (char *)&t_output[1],
-                      sizeof(t_output[1]));
-           }
-           else
-#endif
-           {
-               *output++ = t_output[0];
-               *output++ = t_output[1];
-           }
+#define des_cblock_print(x) des_cblock_print_file(x, stdout)
 
-#ifdef DEBUG
-           if (mit_des_debug) {
-               mit_des_debug_print("xor'ed",i,t_input[0],t_input[1]);
-               mit_des_debug_print("cipher",i,t_output[0],t_output[1]);
-           }
-#endif
-       }
-       t_output[0] = 0;
-       t_output[1] = 0;
-       xor_0 = 0;
-       xor_1 = 0;
-       return 0;
-    }
+#include "f_tables.h"
 
-    else {
-       /* decrypt */
-#ifdef MUSTALIGN
-       if ((long) ivec & 3) {
-           memcpy((char *)&xor_0, (char *)ivec++,sizeof(xor_0));
-           memcpy((char *)&xor_1, (char *)ivec,  sizeof(xor_1));
-       }
-       else
-#endif
-       {
-           xor_0 = *ivec++;
-           xor_1 = *ivec;
+/*
+ * des_pcbc_encrypt - {en,de}crypt a stream in PCBC mode
+ */
+int
+des_pcbc_encrypt(in, out, length, schedule, ivec, encrypt)
+       des_cblock *in;
+       des_cblock *out;
+       long length;
+       des_key_schedule schedule;
+       des_cblock ivec;
+       int encrypt;
+{
+       register unsigned KRB_INT32 left, right;
+       register unsigned KRB_INT32 temp;
+       register unsigned KRB_INT32 *kp;
+       register unsigned char *ip, *op;
+
+       /*
+        * Copy the key pointer, just once
+        */
+       kp = (unsigned KRB_INT32 *)schedule;
+
+       /*
+        * Deal with encryption and decryption separately.
+        */
+       if (encrypt) {
+               register unsigned KRB_INT32 plainl;
+               register unsigned KRB_INT32 plainr;
+
+               /*
+                * Initialize left and right with the contents of the initial
+                * vector.
+                */
+               ip = (unsigned char *)ivec;
+               GET_HALF_BLOCK(left, ip);
+               GET_HALF_BLOCK(right, ip);
+
+               /*
+                * Suitably initialized, now work the length down 8 bytes
+                * at a time.
+                */
+               ip = (unsigned char *)in;
+               op = (unsigned char *)out;
+               while (length > 0) {
+                       /*
+                        * Get block of input.  If the length is
+                        * greater than 8 this is straight
+                        * forward.  Otherwise we have to fart around.
+                        */
+                       if (length > 8) {
+                               GET_HALF_BLOCK(plainl, ip);
+                               GET_HALF_BLOCK(plainr, ip);
+                               left ^= plainl;
+                               right ^= plainr;
+                               length -= 8;
+                       } else {
+                               /*
+                                * Oh, shoot.  We need to pad the
+                                * end with zeroes.  Work backwards
+                                * to do this.  We know this is the
+                                * last block, though, so we don't have
+                                * to save the plain text.
+                                */
+                               ip += (int) length;
+                               switch(length) {
+                               case 8:
+                                       right ^= *(--ip) & 0xff;
+                               case 7:
+                                       right ^= (*(--ip) & 0xff) << 8;
+                               case 6:
+                                       right ^= (*(--ip) & 0xff) << 16;
+                               case 5:
+                                       right ^= (*(--ip) & 0xff) << 24;
+                               case 4:
+                                       left ^= *(--ip) & 0xff;
+                               case 3:
+                                       left ^= (*(--ip) & 0xff) << 8;
+                               case 2:
+                                       left ^= (*(--ip) & 0xff) << 16;
+                               case 1:
+                                       left ^= (*(--ip) & 0xff) << 24;
+                                       break;
+                               }
+                               length = 0;
+                       }
+
+                       /*
+                        * Encrypt what we have
+                        */
+                       DES_DO_ENCRYPT(left, right, temp, kp);
+
+                       /*
+                        * Copy the results out
+                        */
+                       PUT_HALF_BLOCK(left, op);
+                       PUT_HALF_BLOCK(right, op);
+
+                       /*
+                        * Xor with the old plain text
+                        */
+                       left ^= plainl;
+                       right ^= plainr;
+               }
+       } else {
+               /*
+                * Decrypting is harder than encrypting because of
+                * the necessity of remembering a lot more things.
+                * Should think about this a little more...
+                */
+               unsigned KRB_INT32 ocipherl, ocipherr;
+               unsigned KRB_INT32 cipherl, cipherr;
+
+               if (length <= 0)
+                       return 0;
+
+               /*
+                * Prime the old cipher with ivec.
+                */
+               ip = (unsigned char *)ivec;
+               GET_HALF_BLOCK(ocipherl, ip);
+               GET_HALF_BLOCK(ocipherr, ip);
+
+               /*
+                * Now do this in earnest until we run out of length.
+                */
+               ip = (unsigned char *)in;
+               op = (unsigned char *)out;
+               for (;;) {              /* check done inside loop */
+                       /*
+                        * Read a block from the input into left and
+                        * right.  Save this cipher block for later.
+                        */
+                       GET_HALF_BLOCK(left, ip);
+                       GET_HALF_BLOCK(right, ip);
+                       cipherl = left;
+                       cipherr = right;
+
+                       /*
+                        * Decrypt this.
+                        */
+                       DES_DO_DECRYPT(left, right, temp, kp);
+
+                       /*
+                        * Xor with the old cipher to get plain
+                        * text.  Output 8 or less bytes of this.
+                        */
+                       left ^= ocipherl;
+                       right ^= ocipherr;
+                       if (length > 8) {
+                               length -= 8;
+                               PUT_HALF_BLOCK(left, op);
+                               PUT_HALF_BLOCK(right, op);
+                               /*
+                                * Save current cipher block here
+                                */
+                               ocipherl = cipherl ^ left;
+                               ocipherr = cipherr ^ right;
+                       } else {
+                               /*
+                                * Trouble here.  Start at end of output,
+                                * work backwards.
+                                */
+                               op += (int) length;
+                               switch(length) {
+                               case 8:
+                                       *(--op) = right & 0xff;
+                               case 7:
+                                       *(--op) = (right >> 8) & 0xff;
+                               case 6:
+                                       *(--op) = (right >> 16) & 0xff;
+                               case 5:
+                                       *(--op) = (right >> 24) & 0xff;
+                               case 4:
+                                       *(--op) = left & 0xff;
+                               case 3:
+                                       *(--op) = (left >> 8) & 0xff;
+                               case 2:
+                                       *(--op) = (left >> 16) & 0xff;
+                               case 1:
+                                       *(--op) = (left >> 24) & 0xff;
+                                       break;
+                               }
+                               break;          /* we're done */
+                       }
+               }
        }
 
-       for (i = 0; length > 0; i++, length -= 8) {
-           /* get input */
-#ifdef MUSTALIGN
-           if ((long) input & 3) {
-               memcpy((char *)&t_input[0],(char *)input++,sizeof(t_input[0]));
-               memcpy((char *)&t_input[1],(char *)input++,sizeof(t_input[1]));
-           }
-           else
-#endif
-           {
-               t_input[0] = *input++;
-               t_input[1] = *input++;
-           }
-
-           /* no padding for decrypt */
-#ifdef DEBUG
-           if (mit_des_debug)
-               mit_des_debug_print("cipher",i,t_input[0],t_input[1]);
-#else
-#ifdef lint
-           i = i;
-#endif
-#endif
-           /* encrypt */
-           (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
-#ifdef DEBUG
-           if (mit_des_debug)
-               mit_des_debug_print("out pre xor",i,t_output[0],t_output[1]);
-#endif
-           /* do the xor for cbc into the output */
-           t_output[0] ^= xor_0 ;
-           t_output[1] ^= xor_1 ;
-           /* copy temp output */
-#ifdef MUSTALIGN
-           if ((long) output & 3) {
-               memcpy((char *)output++, (char *)&t_output[0],
-                      sizeof(t_output[0]));
-               memcpy((char *)output++, (char *)&t_output[1],
-                      sizeof(t_output[1]));
-           }
-           else
-#endif
-           {
-               *output++ = t_output[0];
-               *output++ = t_output[1];
-           }
-
-           /* save xor value for next round */
-           xor_0 = t_output[0] ^ t_input[0];
-           xor_1 = t_output[1] ^ t_input[1];
-
-#ifdef DEBUG
-           if (mit_des_debug)
-               mit_des_debug_print("clear",i,t_output[0],t_output[1]);
-#endif
-       }
+       /*
+        * Done, return nothing.
+        */
        return 0;
-    }
 }