BSD 4_4_Lite2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Tue, 2 Jan 1990 03:46:37 +0000 (19:46 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Tue, 2 Jan 1990 03:46:37 +0000 (19:46 -0800)
Work on file Domestic/src/kerberosIV/des/cbc_encrypt.c
Work on file usr/src/kerberosIV/des/cbc_encrypt.c
Work on file Domestic/src/kerberosIV/des/cksum.c
Work on file usr/src/kerberosIV/des/cksum.c
Work on file Domestic/src/kerberosIV/des/pcbc_encrypt.c
Work on file usr/src/kerberosIV/des/pcbc_encrypt.c
Work on file Domestic/src/kerberosIV/des/quad_cksum.c
Work on file usr/src/kerberosIV/des/quad_cksum.c

Synthesized-from: CSRG/cd3/4.4BSD-Lite2

Domestic/src/kerberosIV/des/cbc_encrypt.c [new file with mode: 0644]
Domestic/src/kerberosIV/des/cksum.c [new file with mode: 0644]
Domestic/src/kerberosIV/des/pcbc_encrypt.c [new file with mode: 0644]
Domestic/src/kerberosIV/des/quad_cksum.c [new file with mode: 0644]
usr/src/kerberosIV/des/cbc_encrypt.c [new file with mode: 0644]
usr/src/kerberosIV/des/cksum.c [new file with mode: 0644]
usr/src/kerberosIV/des/pcbc_encrypt.c [new file with mode: 0644]
usr/src/kerberosIV/des/quad_cksum.c [new file with mode: 0644]

diff --git a/Domestic/src/kerberosIV/des/cbc_encrypt.c b/Domestic/src/kerberosIV/des/cbc_encrypt.c
new file mode 100644 (file)
index 0000000..5d27e9f
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/cbc_encrypt.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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.
+ *
+ * These routines form the library interface to the DES facilities.
+ *
+ * Originally written 8/85 by Steve Miller, MIT Project Athena.
+ */
+
+#ifndef        lint
+static char rcsid_cbc_encrypt_c[] =
+"$Id: cbc_encrypt.c,v 4.10 90/01/02 13:46:14 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <des.h>
+
+extern int des_debug;
+extern int des_debug_print();
+
+/*
+ * This routine performs DES cipher-block-chaining operation, either
+ * encrypting from cleartext to ciphertext, if encrypt != 0 or
+ * decrypting from ciphertext to cleartext, if encrypt == 0.
+ *
+ * The key schedule is passed as an arg, as well as the cleartext or
+ * ciphertext. The cleartext and ciphertext should be in host order.
+ *
+ * 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.
+ */
+
+int
+des_cbc_encrypt(in,out,length,key,iv,encrypt)
+    des_cblock *in;            /* >= length bytes of input text */
+    des_cblock *out;           /* >= length bytes of output text */
+    register long length;      /* in bytes */
+    int encrypt;               /* 0 ==> decrypt, else encrypt */
+    des_key_schedule key;              /* precomputed key schedule */
+    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;
+
+    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;
+
+    t_in_p = (unsigned char *) t_input;
+    if (encrypt) {
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++, (char *)&t_output[0], sizeof(t_output[0]));
+           bcopy((char *)ivec, (char *)&t_output[1], sizeof(t_output[1]));
+       }
+       else
+#endif
+       {
+           t_output[0] = *ivec++;
+           t_output[1] = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
+           }
+           else
+#endif
+           {
+               t_input[0] = *input++;
+               t_input[1] = *input++;
+           }
+
+           /* zero pad */
+           if (length < 8)
+               for (j = length; j <= 7; j++)
+                   *(t_in_p+j)= 0;
+
+#ifdef DEBUG
+           if (des_debug)
+               des_debug_print("clear",length,t_input[0],t_input[1]);
+#endif
+           /* do the xor for cbc into the temp */
+           t_input[0] ^= t_output[0];
+           t_input[1] ^= t_output[1];
+           /* encrypt */
+           (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
+           /* copy temp output and save it for cbc */
+#ifdef MUSTALIGN
+           if ((long) output & 3) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     sizeof(t_output[1]));
+           }
+           else
+#endif
+           {
+               *output++ = t_output[0];
+               *output++ = t_output[1];
+           }
+
+#ifdef DEBUG
+           if (des_debug) {
+               des_debug_print("xor'ed",i,t_input[0],t_input[1]);
+               des_debug_print("cipher",i,t_output[0],t_output[1]);
+           }
+#endif
+       }
+       return 0;
+    }
+
+    else {
+       /* decrypt */
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
+           bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
+       }
+       else
+#endif
+       {
+           xor_0 = *ivec++;
+           xor_1 = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[0]));
+           }
+           else
+#endif
+           {
+               t_input[0] = *input++;
+               t_input[1] = *input++;
+           }
+
+           /* no padding for decrypt */
+#ifdef DEBUG
+           if (des_debug)
+               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 (des_debug)
+               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) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     sizeof(t_output[1]));
+           }
+           else
+#endif
+           {
+               *output++ = t_output[0];
+               *output++ = t_output[1];
+           }
+
+           /* save xor value for next round */
+           xor_0 = t_input[0];
+           xor_1 = t_input[1];
+#ifdef DEBUG
+           if (des_debug)
+               des_debug_print("clear",i,t_output[0],t_output[1]);
+#endif
+       }
+       return 0;
+    }
+}
diff --git a/Domestic/src/kerberosIV/des/cksum.c b/Domestic/src/kerberosIV/des/cksum.c
new file mode 100644 (file)
index 0000000..069a685
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/cksum.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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.
+ * 
+ * These routines form the library interface to the DES facilities.
+ *
+ *     spm     8/85    MIT project athena
+ */
+
+#ifndef        lint
+static char rcsid_cksum_c[] =
+"$Id: cksum.c,v 4.10 90/01/02 13:46:25 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <des.h>
+#include "des_internal.h"
+
+extern int des_debug;
+extern int des_debug_print();
+
+/*
+ * This routine performs DES cipher-block-chaining checksum operation,
+ * a.k.a.  Message Authentication Code.  It ALWAYS encrypts from input
+ * to a single 64 bit output MAC checksum.
+ *
+ * The key schedule is passed as an arg, as well as the cleartext or
+ * ciphertext. The cleartext and ciphertext should be in host order.
+ *
+ * NOTE-- the output is ALWAYS 8 bytes long.  If not enough space was
+ * provided, your program will get trashed.
+ *
+ * The input is null padded, at the end (highest addr), to an integral
+ * multiple of eight bytes.
+ */
+
+unsigned long
+des_cbc_cksum(in,out,length,key,iv)
+    des_cblock *in;            /* >= length bytes of inputtext */
+    des_cblock *out;           /* >= length bytes of outputtext */
+    register long length;      /* in bytes */
+    des_key_schedule key;              /* precomputed key schedule */
+    des_cblock *iv;            /* 8 bytes of ivec */
+{
+    register unsigned long *input = (unsigned long *) in;
+    register unsigned long *output = (unsigned long *) out;
+    unsigned long *ivec = (unsigned long *) iv;
+
+    unsigned long i,j;
+    static unsigned long t_input[2];
+    static unsigned long t_output[8];
+    static unsigned char *t_in_p;
+
+    t_in_p = (unsigned char *) t_input;
+#ifdef MUSTALIGN
+    if ((long) ivec & 3) {
+       bcopy((char *)ivec++,(char *)&t_output[0],sizeof(t_output[0]));
+       bcopy((char *)ivec,(char *)&t_output[1],sizeof(t_output[1]));
+    }
+    else
+#endif
+    {
+       t_output[0] = *ivec++;
+       t_output[1] = *ivec;
+    }
+
+    for (i = 0; length > 0; i++, length -= 8) {
+       /* get input */
+#ifdef MUSTALIGN
+       if ((long) input & 3) {
+           bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+           bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
+       }
+       else
+#endif
+       {
+           t_input[0] = *input++;
+           t_input[1] = *input++;
+       }
+
+       /* zero pad */
+       if (length < 8)
+           for (j = length; j <= 7; j++)
+               *(t_in_p+j)= 0;
+
+#ifdef DEBUG
+       if (des_debug)
+           des_debug_print("clear",length,t_input[0],t_input[1]);
+#endif
+       /* do the xor for cbc into the temp */
+       t_input[0] ^= t_output[0] ;
+       t_input[1] ^= t_output[1] ;
+       /* encrypt */
+       (void) des_ecb_encrypt(t_input,t_output,key,1);
+#ifdef DEBUG
+       if (des_debug) {
+           des_debug_print("xor'ed",i,t_input[0],t_input[1]);
+           des_debug_print("cipher",i,t_output[0],t_output[1]);
+       }
+#else
+#ifdef lint
+       i = i;
+#endif
+#endif
+    }
+    /* copy temp output and save it for checksum */
+#ifdef MUSTALIGN
+    if ((long) output & 3) {
+       bcopy((char *)&t_output[0],(char *)output++,sizeof(t_output[0]));
+       bcopy((char *)&t_output[1],(char *)output,sizeof(t_output[1]));
+    }
+    else
+#endif
+    {
+       *output++ = t_output[0];
+       *output = t_output[1];
+    }
+
+    return (unsigned long) t_output[1];
+}
diff --git a/Domestic/src/kerberosIV/des/pcbc_encrypt.c b/Domestic/src/kerberosIV/des/pcbc_encrypt.c
new file mode 100644 (file)
index 0000000..147d3f1
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/pcbc_encrypt.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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
+ */
+
+#ifndef        lint
+static char rcsid_pcbc_encrypt_c[] =
+"$Id: pcbc_encrypt.c,v 4.11 90/01/02 13:46:30 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <des.h>
+#include "des_internal.h"
+
+extern int des_debug;
+extern int 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.
+ *
+ */
+
+int
+des_pcbc_encrypt(in,out,length,key,iv,encrypt)
+    des_cblock *in;            /* >= length bytes of inputtext */
+    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 */
+    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;
+
+    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;
+
+    t_in_p = (unsigned char *) t_input;
+    if (encrypt) {
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
+           bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
+       }
+       else
+#endif
+       {
+           xor_0 = *ivec++;
+           xor_1 = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)(input+1),(char *)&t_input[1],sizeof(t_input[1]));
+           }
+           else
+#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 (des_debug)
+               des_debug_print("clear",length,t_input[0],t_input[1]);
+#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) {
+               bcopy((char *)input++,(char *)&xor_0,sizeof(xor_0));
+               xor_0 ^= t_output[0];
+               bcopy((char *)input++,(char *)&xor_1,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) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     sizeof(t_output[1]));
+           }
+           else
+#endif
+           {
+               *output++ = t_output[0];
+               *output++ = t_output[1];
+           }
+
+#ifdef DEBUG
+           if (des_debug) {
+               des_debug_print("xor'ed",i,t_input[0],t_input[1]);
+               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;
+    }
+
+    else {
+       /* decrypt */
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
+           bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
+       }
+       else
+#endif
+       {
+           xor_0 = *ivec++;
+           xor_1 = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
+           }
+           else
+#endif
+           {
+               t_input[0] = *input++;
+               t_input[1] = *input++;
+           }
+
+           /* no padding for decrypt */
+#ifdef DEBUG
+           if (des_debug)
+               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 (des_debug)
+               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) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     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 (des_debug)
+               des_debug_print("clear",i,t_output[0],t_output[1]);
+#endif
+       }
+       return 0;
+    }
+}
diff --git a/Domestic/src/kerberosIV/des/quad_cksum.c b/Domestic/src/kerberosIV/des/quad_cksum.c
new file mode 100644 (file)
index 0000000..e27f1d9
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/quad_cksum.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Quadratic Congruential Manipulation Dectection Code
+ *
+ * ref: "Message Authentication"
+ *             R.R. Jueneman, S. M. Matyas, C.H. Meyer
+ *             IEEE Communications Magazine,
+ *             Sept 1985 Vol 23 No 9 p 29-40
+ *
+ * This routine, part of the Athena DES library built for the Kerberos
+ * authentication system, calculates a manipulation detection code for
+ * a message.  It is a much faster alternative to the DES-checksum
+ * method. No guarantees are offered for its security. Refer to the
+ * paper noted above for more information
+ *
+ * Implementation for 4.2bsd
+ * by S.P. Miller      Project Athena/MIT
+ */
+
+/*
+ * Algorithm (per paper):
+ *             define:
+ *             message to be composed of n m-bit blocks X1,...,Xn
+ *             optional secret seed S in block X1
+ *             MDC in block Xn+1
+ *             prime modulus N
+ *             accumulator Z
+ *             initial (secret) value of accumulator C
+ *             N, C, and S are known at both ends
+ *             C and , optionally, S, are hidden from the end users
+ *             then
+ *                     (read array references as subscripts over time)
+ *                     Z[0] = c;
+ *                     for i = 1...n
+ *                             Z[i] = (Z[i+1] + X[i])**2 modulo N
+ *                     X[n+1] = Z[n] = MDC
+ *
+ *             Then pick
+ *                     N = 2**31 -1
+ *                     m = 16
+ *                     iterate 4 times over plaintext, also use Zn
+ *                     from iteration j as seed for iteration j+1,
+ *                     total MDC is then a 128 bit array of the four
+ *                     Zn;
+ *
+ *                     return the last Zn and optionally, all
+ *                     four as output args.
+ *
+ * Modifications:
+ *     To inhibit brute force searches of the seed space, this
+ *     implementation is modified to have
+ *     Z       = 64 bit accumulator
+ *     C       = 64 bit C seed
+ *     N       = 2**63 - 1
+ *  S  = S seed is not implemented here
+ *     arithmetic is not quite real double integer precision, since we
+ *     cant get at the carry or high order results from multiply,
+ *     but nontheless is 64 bit arithmetic.
+ */
+
+#ifndef        lint
+static char rcsid_quad_cksum_c[] =
+"$Id: quad_cksum.c,v 4.13 90/01/02 13:46:34 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+
+/* System include files */
+#include <stdio.h>
+#include <errno.h>
+
+/* Application include files */
+#include <des.h>
+#include "des_internal.h"
+/* Definitions for byte swapping */
+
+#ifdef LSBFIRST
+#ifdef MUSTALIGN
+static unsigned long vaxtohl();
+static unsigned short vaxtohs();
+#else /* ! MUSTALIGN */
+#define vaxtohl(x) *((unsigned long *)(x))
+#define vaxtohs(x) *((unsigned short *)(x))
+#endif /* MUSTALIGN */
+#else /* !LSBFIRST */
+static unsigned long four_bytes_vax_to_nets();
+#define vaxtohl(x) four_bytes_vax_to_nets((char *)(x))
+static unsigned short two_bytes_vax_to_nets();
+#define vaxtohs(x) two_bytes_vax_to_nets((char *)(x))
+#endif
+
+/* Externals */
+extern char *errmsg();
+extern int errno;
+extern int des_debug;
+
+/*** Routines ***************************************************** */
+
+unsigned long
+des_quad_cksum(in,out,length,out_count,c_seed)
+    des_cblock *c_seed;                /* secret seed, 8 bytes */
+    unsigned char *in;         /* input block */
+    unsigned long *out;                /* optional longer output */
+    int out_count;             /* number of iterations */
+    long length;               /* original length in bytes */
+{
+
+    /*
+     * this routine both returns the low order of the final (last in
+     * time) 32bits of the checksum, and if "out" is not a null
+     * pointer, a longer version, up to entire 32 bytes of the
+     * checksum is written unto the address pointed to.
+     */
+
+    register unsigned long z;
+    register unsigned long z2;
+    register unsigned long x;
+    register unsigned long x2;
+    register unsigned char *p;
+    register long len;
+    register int i;
+
+    /* use all 8 bytes of seed */
+
+    z = vaxtohl(c_seed);
+    z2 = vaxtohl((char *)c_seed+4);
+    if (out == NULL)
+       out_count = 1;          /* default */
+
+    /* This is repeated n times!! */
+    for (i = 1; i <=4 && i<= out_count; i++) {
+       len = length;
+       p = in;
+       while (len) {
+           if (len > 1) {
+               x = (z + vaxtohs(p));
+               p += 2;
+               len -= 2;
+           }
+           else {
+               x = (z + *(char *)p++);
+               len = 0;
+           }
+           x2 = z2;
+           z  = ((x * x) + (x2 * x2)) % 0x7fffffff;
+           z2 = (x * (x2+83653421))   % 0x7fffffff; /* modulo */
+           if (des_debug & 8)
+               printf("%d %d\n",z,z2);
+       }
+
+       if (out != NULL) {
+           *out++ = z;
+           *out++ = z2;
+       }
+    }
+    /* return final z value as 32 bit version of checksum */
+    return z;
+}
+#ifdef MSBFIRST
+
+static unsigned short two_bytes_vax_to_nets(p)
+    char *p;
+{
+    union {
+       char pieces[2];
+       unsigned short result;
+    } short_conv;
+
+    short_conv.pieces[0] = p[1];
+    short_conv.pieces[1] = p[0];
+    return(short_conv.result);
+}
+
+static unsigned long four_bytes_vax_to_nets(p)
+    char *p;
+{
+    static union {
+       char pieces[4];
+       unsigned long result;
+    } long_conv;
+
+    long_conv.pieces[0] = p[3];
+    long_conv.pieces[1] = p[2];
+    long_conv.pieces[2] = p[1];
+    long_conv.pieces[3] = p[0];
+    return(long_conv.result);
+}
+
+#endif
+#ifdef LSBFIRST
+#ifdef MUSTALIGN
+static unsigned long vaxtohl(x)
+char *x;
+{
+    unsigned long val;
+    bcopy(x, (char *)&val, sizeof(val));
+    return(val);
+} 
+
+static unsigned short vaxtohs(x)
+char *x;
+{
+    unsigned short val;
+    bcopy(x, (char *)&val, sizeof(val));
+    return(val);
+} 
+#endif /* MUSTALIGN */
+#endif /* LSBFIRST */
diff --git a/usr/src/kerberosIV/des/cbc_encrypt.c b/usr/src/kerberosIV/des/cbc_encrypt.c
new file mode 100644 (file)
index 0000000..5d27e9f
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/cbc_encrypt.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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.
+ *
+ * These routines form the library interface to the DES facilities.
+ *
+ * Originally written 8/85 by Steve Miller, MIT Project Athena.
+ */
+
+#ifndef        lint
+static char rcsid_cbc_encrypt_c[] =
+"$Id: cbc_encrypt.c,v 4.10 90/01/02 13:46:14 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <des.h>
+
+extern int des_debug;
+extern int des_debug_print();
+
+/*
+ * This routine performs DES cipher-block-chaining operation, either
+ * encrypting from cleartext to ciphertext, if encrypt != 0 or
+ * decrypting from ciphertext to cleartext, if encrypt == 0.
+ *
+ * The key schedule is passed as an arg, as well as the cleartext or
+ * ciphertext. The cleartext and ciphertext should be in host order.
+ *
+ * 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.
+ */
+
+int
+des_cbc_encrypt(in,out,length,key,iv,encrypt)
+    des_cblock *in;            /* >= length bytes of input text */
+    des_cblock *out;           /* >= length bytes of output text */
+    register long length;      /* in bytes */
+    int encrypt;               /* 0 ==> decrypt, else encrypt */
+    des_key_schedule key;              /* precomputed key schedule */
+    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;
+
+    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;
+
+    t_in_p = (unsigned char *) t_input;
+    if (encrypt) {
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++, (char *)&t_output[0], sizeof(t_output[0]));
+           bcopy((char *)ivec, (char *)&t_output[1], sizeof(t_output[1]));
+       }
+       else
+#endif
+       {
+           t_output[0] = *ivec++;
+           t_output[1] = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
+           }
+           else
+#endif
+           {
+               t_input[0] = *input++;
+               t_input[1] = *input++;
+           }
+
+           /* zero pad */
+           if (length < 8)
+               for (j = length; j <= 7; j++)
+                   *(t_in_p+j)= 0;
+
+#ifdef DEBUG
+           if (des_debug)
+               des_debug_print("clear",length,t_input[0],t_input[1]);
+#endif
+           /* do the xor for cbc into the temp */
+           t_input[0] ^= t_output[0];
+           t_input[1] ^= t_output[1];
+           /* encrypt */
+           (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
+           /* copy temp output and save it for cbc */
+#ifdef MUSTALIGN
+           if ((long) output & 3) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     sizeof(t_output[1]));
+           }
+           else
+#endif
+           {
+               *output++ = t_output[0];
+               *output++ = t_output[1];
+           }
+
+#ifdef DEBUG
+           if (des_debug) {
+               des_debug_print("xor'ed",i,t_input[0],t_input[1]);
+               des_debug_print("cipher",i,t_output[0],t_output[1]);
+           }
+#endif
+       }
+       return 0;
+    }
+
+    else {
+       /* decrypt */
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
+           bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
+       }
+       else
+#endif
+       {
+           xor_0 = *ivec++;
+           xor_1 = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[0]));
+           }
+           else
+#endif
+           {
+               t_input[0] = *input++;
+               t_input[1] = *input++;
+           }
+
+           /* no padding for decrypt */
+#ifdef DEBUG
+           if (des_debug)
+               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 (des_debug)
+               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) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     sizeof(t_output[1]));
+           }
+           else
+#endif
+           {
+               *output++ = t_output[0];
+               *output++ = t_output[1];
+           }
+
+           /* save xor value for next round */
+           xor_0 = t_input[0];
+           xor_1 = t_input[1];
+#ifdef DEBUG
+           if (des_debug)
+               des_debug_print("clear",i,t_output[0],t_output[1]);
+#endif
+       }
+       return 0;
+    }
+}
diff --git a/usr/src/kerberosIV/des/cksum.c b/usr/src/kerberosIV/des/cksum.c
new file mode 100644 (file)
index 0000000..069a685
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/cksum.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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.
+ * 
+ * These routines form the library interface to the DES facilities.
+ *
+ *     spm     8/85    MIT project athena
+ */
+
+#ifndef        lint
+static char rcsid_cksum_c[] =
+"$Id: cksum.c,v 4.10 90/01/02 13:46:25 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <des.h>
+#include "des_internal.h"
+
+extern int des_debug;
+extern int des_debug_print();
+
+/*
+ * This routine performs DES cipher-block-chaining checksum operation,
+ * a.k.a.  Message Authentication Code.  It ALWAYS encrypts from input
+ * to a single 64 bit output MAC checksum.
+ *
+ * The key schedule is passed as an arg, as well as the cleartext or
+ * ciphertext. The cleartext and ciphertext should be in host order.
+ *
+ * NOTE-- the output is ALWAYS 8 bytes long.  If not enough space was
+ * provided, your program will get trashed.
+ *
+ * The input is null padded, at the end (highest addr), to an integral
+ * multiple of eight bytes.
+ */
+
+unsigned long
+des_cbc_cksum(in,out,length,key,iv)
+    des_cblock *in;            /* >= length bytes of inputtext */
+    des_cblock *out;           /* >= length bytes of outputtext */
+    register long length;      /* in bytes */
+    des_key_schedule key;              /* precomputed key schedule */
+    des_cblock *iv;            /* 8 bytes of ivec */
+{
+    register unsigned long *input = (unsigned long *) in;
+    register unsigned long *output = (unsigned long *) out;
+    unsigned long *ivec = (unsigned long *) iv;
+
+    unsigned long i,j;
+    static unsigned long t_input[2];
+    static unsigned long t_output[8];
+    static unsigned char *t_in_p;
+
+    t_in_p = (unsigned char *) t_input;
+#ifdef MUSTALIGN
+    if ((long) ivec & 3) {
+       bcopy((char *)ivec++,(char *)&t_output[0],sizeof(t_output[0]));
+       bcopy((char *)ivec,(char *)&t_output[1],sizeof(t_output[1]));
+    }
+    else
+#endif
+    {
+       t_output[0] = *ivec++;
+       t_output[1] = *ivec;
+    }
+
+    for (i = 0; length > 0; i++, length -= 8) {
+       /* get input */
+#ifdef MUSTALIGN
+       if ((long) input & 3) {
+           bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+           bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
+       }
+       else
+#endif
+       {
+           t_input[0] = *input++;
+           t_input[1] = *input++;
+       }
+
+       /* zero pad */
+       if (length < 8)
+           for (j = length; j <= 7; j++)
+               *(t_in_p+j)= 0;
+
+#ifdef DEBUG
+       if (des_debug)
+           des_debug_print("clear",length,t_input[0],t_input[1]);
+#endif
+       /* do the xor for cbc into the temp */
+       t_input[0] ^= t_output[0] ;
+       t_input[1] ^= t_output[1] ;
+       /* encrypt */
+       (void) des_ecb_encrypt(t_input,t_output,key,1);
+#ifdef DEBUG
+       if (des_debug) {
+           des_debug_print("xor'ed",i,t_input[0],t_input[1]);
+           des_debug_print("cipher",i,t_output[0],t_output[1]);
+       }
+#else
+#ifdef lint
+       i = i;
+#endif
+#endif
+    }
+    /* copy temp output and save it for checksum */
+#ifdef MUSTALIGN
+    if ((long) output & 3) {
+       bcopy((char *)&t_output[0],(char *)output++,sizeof(t_output[0]));
+       bcopy((char *)&t_output[1],(char *)output,sizeof(t_output[1]));
+    }
+    else
+#endif
+    {
+       *output++ = t_output[0];
+       *output = t_output[1];
+    }
+
+    return (unsigned long) t_output[1];
+}
diff --git a/usr/src/kerberosIV/des/pcbc_encrypt.c b/usr/src/kerberosIV/des/pcbc_encrypt.c
new file mode 100644 (file)
index 0000000..147d3f1
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/pcbc_encrypt.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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
+ */
+
+#ifndef        lint
+static char rcsid_pcbc_encrypt_c[] =
+"$Id: pcbc_encrypt.c,v 4.11 90/01/02 13:46:30 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <des.h>
+#include "des_internal.h"
+
+extern int des_debug;
+extern int 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.
+ *
+ */
+
+int
+des_pcbc_encrypt(in,out,length,key,iv,encrypt)
+    des_cblock *in;            /* >= length bytes of inputtext */
+    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 */
+    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;
+
+    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;
+
+    t_in_p = (unsigned char *) t_input;
+    if (encrypt) {
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
+           bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
+       }
+       else
+#endif
+       {
+           xor_0 = *ivec++;
+           xor_1 = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)(input+1),(char *)&t_input[1],sizeof(t_input[1]));
+           }
+           else
+#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 (des_debug)
+               des_debug_print("clear",length,t_input[0],t_input[1]);
+#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) {
+               bcopy((char *)input++,(char *)&xor_0,sizeof(xor_0));
+               xor_0 ^= t_output[0];
+               bcopy((char *)input++,(char *)&xor_1,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) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     sizeof(t_output[1]));
+           }
+           else
+#endif
+           {
+               *output++ = t_output[0];
+               *output++ = t_output[1];
+           }
+
+#ifdef DEBUG
+           if (des_debug) {
+               des_debug_print("xor'ed",i,t_input[0],t_input[1]);
+               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;
+    }
+
+    else {
+       /* decrypt */
+#ifdef MUSTALIGN
+       if ((long) ivec & 3) {
+           bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
+           bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
+       }
+       else
+#endif
+       {
+           xor_0 = *ivec++;
+           xor_1 = *ivec;
+       }
+
+       for (i = 0; length > 0; i++, length -= 8) {
+           /* get input */
+#ifdef MUSTALIGN
+           if ((long) input & 3) {
+               bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
+               bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
+           }
+           else
+#endif
+           {
+               t_input[0] = *input++;
+               t_input[1] = *input++;
+           }
+
+           /* no padding for decrypt */
+#ifdef DEBUG
+           if (des_debug)
+               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 (des_debug)
+               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) {
+               bcopy((char *)&t_output[0],(char *)output++,
+                     sizeof(t_output[0]));
+               bcopy((char *)&t_output[1],(char *)output++,
+                     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 (des_debug)
+               des_debug_print("clear",i,t_output[0],t_output[1]);
+#endif
+       }
+       return 0;
+    }
+}
diff --git a/usr/src/kerberosIV/des/quad_cksum.c b/usr/src/kerberosIV/des/quad_cksum.c
new file mode 100644 (file)
index 0000000..e27f1d9
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/quad_cksum.c,v $
+ * $Author: jtkohl $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Quadratic Congruential Manipulation Dectection Code
+ *
+ * ref: "Message Authentication"
+ *             R.R. Jueneman, S. M. Matyas, C.H. Meyer
+ *             IEEE Communications Magazine,
+ *             Sept 1985 Vol 23 No 9 p 29-40
+ *
+ * This routine, part of the Athena DES library built for the Kerberos
+ * authentication system, calculates a manipulation detection code for
+ * a message.  It is a much faster alternative to the DES-checksum
+ * method. No guarantees are offered for its security. Refer to the
+ * paper noted above for more information
+ *
+ * Implementation for 4.2bsd
+ * by S.P. Miller      Project Athena/MIT
+ */
+
+/*
+ * Algorithm (per paper):
+ *             define:
+ *             message to be composed of n m-bit blocks X1,...,Xn
+ *             optional secret seed S in block X1
+ *             MDC in block Xn+1
+ *             prime modulus N
+ *             accumulator Z
+ *             initial (secret) value of accumulator C
+ *             N, C, and S are known at both ends
+ *             C and , optionally, S, are hidden from the end users
+ *             then
+ *                     (read array references as subscripts over time)
+ *                     Z[0] = c;
+ *                     for i = 1...n
+ *                             Z[i] = (Z[i+1] + X[i])**2 modulo N
+ *                     X[n+1] = Z[n] = MDC
+ *
+ *             Then pick
+ *                     N = 2**31 -1
+ *                     m = 16
+ *                     iterate 4 times over plaintext, also use Zn
+ *                     from iteration j as seed for iteration j+1,
+ *                     total MDC is then a 128 bit array of the four
+ *                     Zn;
+ *
+ *                     return the last Zn and optionally, all
+ *                     four as output args.
+ *
+ * Modifications:
+ *     To inhibit brute force searches of the seed space, this
+ *     implementation is modified to have
+ *     Z       = 64 bit accumulator
+ *     C       = 64 bit C seed
+ *     N       = 2**63 - 1
+ *  S  = S seed is not implemented here
+ *     arithmetic is not quite real double integer precision, since we
+ *     cant get at the carry or high order results from multiply,
+ *     but nontheless is 64 bit arithmetic.
+ */
+
+#ifndef        lint
+static char rcsid_quad_cksum_c[] =
+"$Id: quad_cksum.c,v 4.13 90/01/02 13:46:34 jtkohl Exp $";
+#endif lint
+
+#include <mit-copyright.h>
+
+/* System include files */
+#include <stdio.h>
+#include <errno.h>
+
+/* Application include files */
+#include <des.h>
+#include "des_internal.h"
+/* Definitions for byte swapping */
+
+#ifdef LSBFIRST
+#ifdef MUSTALIGN
+static unsigned long vaxtohl();
+static unsigned short vaxtohs();
+#else /* ! MUSTALIGN */
+#define vaxtohl(x) *((unsigned long *)(x))
+#define vaxtohs(x) *((unsigned short *)(x))
+#endif /* MUSTALIGN */
+#else /* !LSBFIRST */
+static unsigned long four_bytes_vax_to_nets();
+#define vaxtohl(x) four_bytes_vax_to_nets((char *)(x))
+static unsigned short two_bytes_vax_to_nets();
+#define vaxtohs(x) two_bytes_vax_to_nets((char *)(x))
+#endif
+
+/* Externals */
+extern char *errmsg();
+extern int errno;
+extern int des_debug;
+
+/*** Routines ***************************************************** */
+
+unsigned long
+des_quad_cksum(in,out,length,out_count,c_seed)
+    des_cblock *c_seed;                /* secret seed, 8 bytes */
+    unsigned char *in;         /* input block */
+    unsigned long *out;                /* optional longer output */
+    int out_count;             /* number of iterations */
+    long length;               /* original length in bytes */
+{
+
+    /*
+     * this routine both returns the low order of the final (last in
+     * time) 32bits of the checksum, and if "out" is not a null
+     * pointer, a longer version, up to entire 32 bytes of the
+     * checksum is written unto the address pointed to.
+     */
+
+    register unsigned long z;
+    register unsigned long z2;
+    register unsigned long x;
+    register unsigned long x2;
+    register unsigned char *p;
+    register long len;
+    register int i;
+
+    /* use all 8 bytes of seed */
+
+    z = vaxtohl(c_seed);
+    z2 = vaxtohl((char *)c_seed+4);
+    if (out == NULL)
+       out_count = 1;          /* default */
+
+    /* This is repeated n times!! */
+    for (i = 1; i <=4 && i<= out_count; i++) {
+       len = length;
+       p = in;
+       while (len) {
+           if (len > 1) {
+               x = (z + vaxtohs(p));
+               p += 2;
+               len -= 2;
+           }
+           else {
+               x = (z + *(char *)p++);
+               len = 0;
+           }
+           x2 = z2;
+           z  = ((x * x) + (x2 * x2)) % 0x7fffffff;
+           z2 = (x * (x2+83653421))   % 0x7fffffff; /* modulo */
+           if (des_debug & 8)
+               printf("%d %d\n",z,z2);
+       }
+
+       if (out != NULL) {
+           *out++ = z;
+           *out++ = z2;
+       }
+    }
+    /* return final z value as 32 bit version of checksum */
+    return z;
+}
+#ifdef MSBFIRST
+
+static unsigned short two_bytes_vax_to_nets(p)
+    char *p;
+{
+    union {
+       char pieces[2];
+       unsigned short result;
+    } short_conv;
+
+    short_conv.pieces[0] = p[1];
+    short_conv.pieces[1] = p[0];
+    return(short_conv.result);
+}
+
+static unsigned long four_bytes_vax_to_nets(p)
+    char *p;
+{
+    static union {
+       char pieces[4];
+       unsigned long result;
+    } long_conv;
+
+    long_conv.pieces[0] = p[3];
+    long_conv.pieces[1] = p[2];
+    long_conv.pieces[2] = p[1];
+    long_conv.pieces[3] = p[0];
+    return(long_conv.result);
+}
+
+#endif
+#ifdef LSBFIRST
+#ifdef MUSTALIGN
+static unsigned long vaxtohl(x)
+char *x;
+{
+    unsigned long val;
+    bcopy(x, (char *)&val, sizeof(val));
+    return(val);
+} 
+
+static unsigned short vaxtohs(x)
+char *x;
+{
+    unsigned short val;
+    bcopy(x, (char *)&val, sizeof(val));
+    return(val);
+} 
+#endif /* MUSTALIGN */
+#endif /* LSBFIRST */