*** empty log message ***
authoredg <edg@mit.edu>
Thu, 10 May 1990 13:27:14 +0000 (13:27 +0000)
committeredg <edg@mit.edu>
Thu, 10 May 1990 13:27:14 +0000 (13:27 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@822 dc483132-0cff-0310-8789-dd5450dbe970

29 files changed:
src/lib/crypto/des/Imakefile [new file with mode: 0644]
src/lib/crypto/des/cbc_cksum.c [new file with mode: 0644]
src/lib/crypto/des/cksum.c [new file with mode: 0644]
src/lib/crypto/des/cs_entry.c [new file with mode: 0644]
src/lib/crypto/des/des.c [new file with mode: 0644]
src/lib/crypto/des/des_int.h [new file with mode: 0644]
src/lib/crypto/des/enc_dec.c [new file with mode: 0644]
src/lib/crypto/des/fin_rndkey.c [new file with mode: 0644]
src/lib/crypto/des/finish_key.c [new file with mode: 0644]
src/lib/crypto/des/init_rkey.c [new file with mode: 0644]
src/lib/crypto/des/key_parity.c [new file with mode: 0644]
src/lib/crypto/des/key_sched.c [new file with mode: 0644]
src/lib/crypto/des/make_e.c [new file with mode: 0644]
src/lib/crypto/des/make_fp.c [new file with mode: 0644]
src/lib/crypto/des/make_ip.c [new file with mode: 0644]
src/lib/crypto/des/make_kp.c [new file with mode: 0644]
src/lib/crypto/des/make_odd.c [new file with mode: 0644]
src/lib/crypto/des/make_p.c [new file with mode: 0644]
src/lib/crypto/des/make_pt.c [new file with mode: 0644]
src/lib/crypto/des/make_s.c [new file with mode: 0644]
src/lib/crypto/des/make_st.c [new file with mode: 0644]
src/lib/crypto/des/misc.c [new file with mode: 0644]
src/lib/crypto/des/new_rn_key.c [new file with mode: 0644]
src/lib/crypto/des/process_ky.c [new file with mode: 0644]
src/lib/crypto/des/random_key.c [new file with mode: 0644]
src/lib/crypto/des/string2key.c [new file with mode: 0644]
src/lib/crypto/des/tables.h [new file with mode: 0644]
src/lib/crypto/des/verify.c [new file with mode: 0644]
src/lib/crypto/des/weak_key.c [new file with mode: 0644]

diff --git a/src/lib/crypto/des/Imakefile b/src/lib/crypto/des/Imakefile
new file mode 100644 (file)
index 0000000..ac49efa
--- /dev/null
@@ -0,0 +1,82 @@
+NormalLibraryObjectRule()
+
+OBJS=  cksum.o         \
+       des.o           \
+       des_cbc_cksum.o \
+       des_cs_ent.o    \
+       des_enc_dec.o   \
+       des_fin_key.o   \
+       des_fnr_key.o   \
+       des_inr_key.o   \
+       des_prc_key.o   \
+       des_ran_key.o   \
+       des_st2_key.o   \
+       key_parity.o    \
+       key_sched.o     \
+       new_rnd_key.o   \
+       weak_key.o
+
+SRCS=  cksum.c         \
+       des.c           \
+       des_cs_ent.c    \
+       des_cbc_cksum.c \
+       des_enc_dec.c   \
+       des_fin_key.c   \
+       des_fnr_key.c   \
+       des_inr_key.c   \
+       des_prc_key.c   \
+       des_ran_key.c   \
+       des_st2_key.c   \
+       key_parity.c    \
+       key_sched.c     \
+       new_rnd_key.c   \
+       weak_key.c
+
+VERIFYOBJ = verify.o
+
+NormalLibraryTarget(des,$(OBJS))
+
+EXTRA_LIBRARIES = $(TOP)/error_tables/libkrberrs.a
+
+NormalProgramTarget(verify, $(VERIFYOBJ), libdes.a, libdes.a, -lcom_err)
+
+NormalProgramTarget(make_e, make_e.o, misc.o, misc.o, )
+
+NormalProgramTarget(make_fp, make_fp.o, misc.o, misc.o, )
+
+fp.c: make_fp
+       ./make_fp fp.c
+
+NormalProgramTarget(make_ip, make_ip.o, misc.o, misc.o, )
+
+ip.c: make_ip
+       ./make_ip ip.c
+
+NormalProgramTarget(make_key_perm, make_key_perm.o, misc.o, misc.o, )
+
+key_perm.h: make_key_perm
+       ./make_key_perm key_perm.h
+
+NormalProgramTarget(make_odd, make_odd.o, misc.o, misc.o, )
+
+odd.h: make_odd
+       ./make_odd odd.h
+
+NormalProgramTarget(make_p, make_p.o, misc.o, misc.o, )
+
+p.c: make_p
+       ./make_p p.c
+
+NormalProgramTarget(make_p_table, make_p_table.o, misc.o, misc.o, )
+
+p_table.h: make_p_table
+       ./make_p_table p_table.h
+
+NormalProgramTarget(make_s, make_s.o, misc.o, misc.o, )
+
+NormalProgramTarget(make_s_table, make_s_table.o, misc.o, misc.o, )
+
+s_table.h: make_s_table
+       ./make_s_table s_table.h
+
+NormalLintTarget($(SRCS))
diff --git a/src/lib/crypto/des/cbc_cksum.c b/src/lib/crypto/des/cbc_cksum.c
new file mode 100644 (file)
index 0000000..206a9f6
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * 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.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_cbc_checksum_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include <krb5/krb5_err.h>
+
+#include <krb5/des.h>
+
+extern void des_cbc_cksum();
+extern int des_key_sched();
+
+/*
+       produces cbc cheksum of sequence "in" of the length "in_length" 
+       with the help of key "key" of size "key_size" (which should be 8);
+       fills out krb5_checksum structure.
+
+       caller is responsible for freeing "contents" element in 
+       krb5_checksum structure.
+
+       returns: errors
+*/
+krb5_error_code des_cbc_checksum(DECLARG(krb5_pointer, in),
+                                DECLARG(size_t, in_length),
+                                DECLARG(krb5_pointer, key),
+                                DECLARG(size_t, key_size),
+                                DECLARG(krb5_checksum *, cksum))
+OLDDECLARG(krb5_pointer, in)
+OLDDECLARG(size_t, in_length)
+OLDDECLARG(krb5_pointer, key)
+OLDDECLARG(size_t, key_size)
+OLDDECLARG(krb5_checksum *, cksum)
+{
+    struct des_ks_struct       *schedule;      /* pointer to key schedules */
+    krb5_octet         *contents;
+
+    if (key_size != sizeof(des_cblock))
+       return -1;
+
+    if (!(schedule = (struct des_ks_struct *) malloc(sizeof(des_key_schedule))))
+        return ENOMEM;
+
+#define cleanup() { bzero((char *)schedule, sizeof(des_key_schedule));\
+                   free( (char *) schedule); }
+
+    switch (des_key_sched ((krb5_octet *)key, schedule)) {
+    case -1:
+        cleanup();
+        return KRB5DES_BAD_KEYPAR;       /* XXX error code-bad key parity */
+
+    case -2:
+        cleanup();
+        return KRB5DES_WEAK_KEY;       /* XXX error code-weak key */
+
+    default:
+        ;
+    }
+
+    if (!(contents = (krb5_octet *) malloc(sizeof(des_cblock))))
+        return ENOMEM;
+
+#define cleanup2() { free( (char *) schedule); }
+
+    des_cbc_cksum((krb5_octet *)in, contents, in_length,
+                 schedule, (krb5_octet *)key);
+
+    cksum->checksum_type = CKSUMTYPE_DESCBC;
+    cksum->length = sizeof(des_cblock);
+    cksum->contents = contents;
+    cleanup();
+
+    return 0;
+}
+    
diff --git a/src/lib/crypto/des/cksum.c b/src/lib/crypto/des/cksum.c
new file mode 100644 (file)
index 0000000..a224944
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * 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
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_cksum_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include "des_internal.h"
+
+extern int des_debug;
+extern int des_debug_print();
+extern int des_ecb_encrypt();
+
+/*
+ * 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.
+ */
+
+void
+des_cbc_cksum(in,out,length,key,iv)
+    krb5_octet  *in;           /* >= length bytes of inputtext */
+    krb5_octet  *out;          /* >= length bytes of outputtext */
+    register long length;      /* in bytes */
+    des_key_schedule key;              /* precomputed key schedule */
+    krb5_octet  *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;
+}
diff --git a/src/lib/crypto/des/cs_entry.c b/src/lib/crypto/des/cs_entry.c
new file mode 100644 (file)
index 0000000..a6862f5
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ * Wrapper for the V4 libdes for use with kerberos V5.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_cs_ent_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/ext-proto.h>
+
+extern krb5_error_code encrypt_func PROTOTYPE((const krb5_pointer,
+                                               krb5_pointer,
+                                               const size_t,
+                                               krb5_encrypt_block *,
+                                              krb5_pointer));
+extern krb5_error_code decrypt_func PROTOTYPE((const krb5_pointer,
+                                               krb5_pointer,
+                                               const size_t,
+                                               krb5_encrypt_block *,
+                                              krb5_pointer));
+extern krb5_error_code process_key PROTOTYPE((krb5_encrypt_block *,
+                                              const krb5_keyblock *));
+extern krb5_error_code finish_key PROTOTYPE((krb5_encrypt_block *));
+extern krb5_error_code string_to_key PROTOTYPE((const krb5_keytype, 
+                                               krb5_keyblock *,
+                                                const krb5_data *,
+                                                const krb5_principal));
+extern krb5_error_code init_random_key PROTOTYPE((const krb5_keyblock *,
+                                                 krb5_pointer *));
+extern krb5_error_code finish_random_key PROTOTYPE((krb5_pointer *));
+extern krb5_error_code random_key PROTOTYPE((krb5_pointer,
+                                            krb5_keyblock **));
+
+krb5_cryptosystem_entry mit_des_cryptosystem_entry = {
+    encrypt_func,
+    decrypt_func, 
+    process_key,
+    finish_key,
+    string_to_key,
+    init_random_key,
+    finish_random_key ,
+    random_key,
+    sizeof(des_cblock),
+    0,
+    sizeof(des_cblock),
+    ETYPE_DES_CBC_CRC,
+    KEYTYPE_DES
+    };
+
+krb5_cs_table_entry krb5_des_cst_entry = {
+    &mit_des_cryptosystem_entry,
+    0
+    };
+extern krb5_error_code des_cbc_checksum PROTOTYPE ((krb5_pointer ,
+                                                   size_t ,
+                                                   krb5_pointer ,
+                                                   size_t ,
+                                                   krb5_checksum * ));
+
+
+krb5_checksum_entry des_cbc_cksumtable_entry = {
+    des_cbc_checksum,
+    sizeof(des_cblock)
+    };
diff --git a/src/lib/crypto/des/des.c b/src/lib/crypto/des/des.c
new file mode 100644 (file)
index 0000000..73e529d
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * 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.
+ *
+ * All registers labeled imply Vax using the Ultrix or 4.2bsd
+ * compiler.
+ *
+ *
+ *     NOTE:  bit and byte numbering:
+ *                     DES algorithm is defined in terms of bits of L
+ *                     followed by bits of R.
+ *             bit 0  ==> lsb of L
+ *             bit 63 ==> msb of R
+ *
+ * Always work in register pairs, FROM L1,R1 TO L2,R2 to make
+ * bookkeeping easier.
+ *
+ * originally written by Steve Miller, MIT Project Athena
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_des_c[] =
+"$Header$";
+#endif /* !lint & !SABER */
+
+#include <mit-copyright.h>
+
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include "des_internal.h"
+#include "s_table.h"
+#include "p_table.h"
+
+#ifdef DEBUG
+#define DBG_PRINT(s) if (des_debug & 2) \
+    des_debug_print(s,i,L1&0xffff,(L1>>16)&0xffff, \
+               R1&0xffff,(R1>>16)&0xffff)
+#else
+#define DBG_PRINT(s)
+#endif
+
+extern int des_debug;
+extern des_cblock_print_file ();
+extern des_debug_print ();
+
+int
+des_ecb_encrypt(clear, cipher, schedule, encrypt)
+    unsigned long *clear;
+    unsigned long *cipher;
+    int encrypt;               /* 0 ==> decrypt, else encrypt */
+    register des_key_schedule schedule; /* r11 */
+{
+
+    /* better pass 8 bytes, length not checked here */
+
+    register unsigned long R1, L1; /* R1 = r10, L1 = r9 */
+    register unsigned long R2, L2; /* R2 = r8, L2 = r7 */
+    long i;
+    /* one more registers left on VAX, see below P_temp_p */
+#ifdef BITS16
+    sbox_in_16_a S_in_16_a;
+    sbox_in_16_b S_in_16_b;
+    sbox_in_16_c S_in_16_c;
+    unsigned int *S_in_a_16_p = (unsigned int *) &S_in_16_a;
+    unsigned int *S_in_b_16_p = (unsigned int *) &S_in_16_b;
+    unsigned int *S_in_c_16_p = (unsigned int *) &S_in_16_c;
+#endif
+#ifndef BITS32
+#ifndef BITS16
+    dunno how to do this machine type, you lose;
+#endif
+#endif
+    unsigned long P_temp;
+    register unsigned char *P_temp_p = (unsigned char *) & P_temp;
+#ifdef BITS16
+    sbox_out S_out;
+    unsigned long *S_out_p = (unsigned long *) &S_out;
+#endif
+    unsigned long R_save, L_save;
+#ifdef DEBUG
+    unsigned long dbg_tmp[2];
+#endif
+
+    /*
+     * Use L1,R1 and L2,R2 as two sets of "64-bit" registers always
+     * work from L1,R1 input to L2,R2 output; initialize the cleartext
+     * into registers.
+     */
+#ifdef MUSTALIGN
+#ifdef DEBUG
+    /*
+     * If the alignment is wrong, the programmer really screwed up --
+     * we aren't even getting the right data type.  His problem.  Keep
+     * this code for debugging.
+     */
+    /* Make sure schedule is ok */
+    if ((long) schedule & 3) {
+       fprintf(stderr,"des.c schedule arg pointer not aligned\n");
+       abort();
+    }
+#endif
+    if ((long) clear & 3) {
+       bcopy((char *)clear++,(char *)&L_save,sizeof(L_save));
+       bcopy((char *)clear,(char *)&R_save,sizeof(R_save));
+       L1 = L_save;
+       R1 = R_save;
+    }
+    else
+#endif
+    {
+       if (clear) L1 = *clear++;
+       else L1 = NULL;
+       if (clear) R1 = *clear;
+       else R1 = NULL;
+    }
+
+#ifdef DEBUG
+    if (des_debug & 2) {
+       printf("All values printed from low byte (bit 0)");
+       printf(" --> high byte (bit 63)\n");
+       i = 0;
+       dbg_tmp[0] = L1;
+       dbg_tmp[1] = R1;
+       printf("iter = %2d  before IP\n\t\tL1 R1 = ",i);
+       des_cblock_print_file (dbg_tmp, stdout);
+    }
+
+    DBG_PRINT("before IP");
+#endif
+
+/*   IP_start:*/
+
+    /* all the Initial Permutation code is in the include file */
+#include "ip.c"
+    /* reset input to L1,R1 */
+    L1 = L2;
+    R1 = R2;
+
+    /* iterate through the inner loop */
+    for (i = 0; i <= (AUTH_DES_ITER-1); i++) {
+
+#ifdef DEBUG
+       if (des_debug & 2) {
+           dbg_tmp[0] = L1;
+           dbg_tmp[1] = R1;
+           printf("iter = %2d  start loop\n\t\tL1 R1 = ",i);
+           des_cblock_print_file (dbg_tmp, stdout);
+           DBG_PRINT("start loop");
+       }
+
+#endif
+
+       R_save = R1;
+       L_save = L1;
+
+/*   E_start:*/
+       /* apply the E permutation from R1 to L2, R2 */
+#ifndef VAXASM
+#ifdef SLOW_E
+#include "e.c"
+#else /* Bill's fast E */
+       L2 = (R1 << 1);
+       if (R1 & (1<<31))
+           L2 |= 1<<0;
+       L2 &= 077;
+       L2 |= (R1 <<3) & 07700;
+       L2 |= (R1 <<5) & 0770000;
+       L2 |= (R1 <<7) & 077000000;
+       L2 |= (R1 <<9) & 07700000000;
+       L2 |= (R1 <<11) & 030000000000;
+
+       /* now from right to right */
+
+       R2 = ((R1 >> 17) & 0176000);
+       if (R1 & (1<<0)) R2 |= 1<<15;
+
+       R2 |= ((R1 >> 21) & 017);
+       R2 |= ((R1 >> 19) & 01760);
+#endif /* SLOW_E */
+#else /* VAXASM */
+       /* E operations */
+       /* right to left */
+       asm("   rotl    $1,r10,r7");
+       L2 &= 077;
+       L2 |= (R1 <<3) & 07700;
+       L2 |= (R1 <<5) & 0770000;
+       L2 |= (R1 <<7) & 077000000;
+       L2 |= (R1 <<9) & 07700000000;
+       L2 |= (R1 <<11) & 030000000000;
+
+       asm("   rotl    $-17,r10,r8");
+       R2 &= 0176000;
+       asm("   rotl    $-21,r10,r0");
+       asm("   bicl2   $-16,r0");
+       asm("  bisl2    r0,r8");
+       asm("   rotl    $-19,r10,r0");
+       asm("   bicl2   $-1009,r0");
+       asm("  bisl2    r0,r8");
+
+#endif
+
+       /* reset input to L1,R1 */
+       L1 = L2;
+       R1 = R2;
+
+#ifdef DEBUG
+       if (des_debug & 2) {
+           dbg_tmp[0] = L1;
+           dbg_tmp[1] = R1;
+           DBG_PRINT("after e");
+           printf("iter = %2d  after e\n\t\tL1 R1 = ",i);
+           des_cblock_print_file (dbg_tmp, stdout);
+       }
+#endif
+
+/*   XOR_start:*/
+       /*
+        * XOR with the key schedule, "schedule"
+        *
+        * If this is an encryption operation, use schedule[i],
+        * otherwise use schedule [AUTH_DES_ITER-i-1]
+        *
+        * First XOR left half.
+        */
+       if (encrypt) {
+           L1 ^= *(((unsigned long *) &schedule[i] )+0);
+           /* now right half */
+           R1 ^= *(((unsigned long *) &schedule[i] )+1);
+       }
+       else {
+           L1 ^= *(((unsigned long *) &schedule[AUTH_DES_ITER-i-1] )+0);
+           /* now right half */
+           R1 ^= *(((unsigned long *) &schedule[AUTH_DES_ITER-i-1] )+1);
+       }
+
+       /* dont have to reset input to L1, R1 */
+
+#ifdef DEBUG
+       if (des_debug & 2) {
+           dbg_tmp[0] = L1;
+           dbg_tmp[1] = R1;
+           DBG_PRINT("after xor");
+           printf("iter = %2d  after xor\n\t\tL1 R1 =",i);
+           des_cblock_print_file (dbg_tmp, stdout);
+       }
+#endif
+
+/*   S_start:*/
+       /* apply the S selection from L1, R1 to R2 */
+
+#ifdef notdef
+#include "s.c"
+#endif
+
+       /* S operations , cant use registers for bit field stuff */
+       /* from S_in to S_out */
+
+#ifdef BITS16
+       *S_in_a_16_p = L1&0xffff;
+       *S_in_b_16_p = (L1>>16)&0xffff;
+       *S_in_c_16_p = R1&0xffff;
+       (*(unsigned long *) &S_out) =
+           (unsigned) S_adj[0][S_in_16_a.b0];
+       S_out.b1 = (unsigned) S_adj[1][S_in_16_a.b1];
+       /* b2 spans two words */
+       S_out.b2 = (unsigned)
+           S_adj[2][(unsigned) S_in_16_a.b2
+                    + (((unsigned) S_in_16_b.b2) << 4)];
+       S_out.b3 = (unsigned) S_adj[3][S_in_16_b.b3];
+       S_out.b4 = (unsigned) S_adj[4][S_in_16_b.b4];
+       /* b5 spans both parts */
+       S_out.b5 = (unsigned)
+           S_adj[5][(unsigned) S_in_16_b.b5
+                    + (((unsigned) S_in_16_c.b5) << 2)];
+       S_out.b6 = (unsigned) S_adj[6][S_in_16_c.b6];
+       S_out.b7 = (unsigned) S_adj[7][S_in_16_c.b7];
+       R1 = *S_out_p;
+#else
+       /* is a 32 bit sys */
+#ifndef VAXASM
+       R2 =  (unsigned) S_adj[0][L1 & 077];
+       L2 = (unsigned) S_adj[1][(L1 >> 6) & 077];
+       R2 |= (L2 <<4 );
+       L2 = (unsigned) S_adj[2][(L1 >> 12) & 077];
+       R2 |= (L2 <<8);
+       L2 = (unsigned) S_adj[3][(L1 >> 18) & 077];
+       R2 |= (L2 <<12);
+       L2 = (unsigned) S_adj[4][(L1 >> 24) & 077];
+       R2 |= (L2 <<16);
+       /* b5 spans both parts */
+       L2 = (unsigned)
+           S_adj[5][(unsigned) ((L1 >>30) & 03) + ((R1 & 017) << 2)];
+       R2 |= (L2 << 20);
+       L2 = (unsigned) S_adj[6][(R1 >> 4) & 077];
+       R2 |= (L2 <<24);
+       L2 = (unsigned) S_adj[7][(R1 >> 10) & 077];
+       R1 = R2 | (L2 <<28);
+       /* reset input to L1, R1 */
+#else /* vaxasm */
+       /*
+        * this is the c code produced above, with
+        * extzv replaced by rotl
+        */
+       asm("bicl3      $-64,r9,r0");
+       asm("movzbl     _S_adj[r0],r8");
+       asm("rotl       $-6,r9,r0");
+       asm("bicl2      $-64,r0");
+       asm("movzbl     _S_adj+64[r0],r7");
+       asm("ashl       $4,r7,r0");
+       asm("bisl2      r0,r8");
+       asm("rotl       $-12,r9,r0");
+       asm("bicl2      $-64,r0");
+       asm("movzbl     _S_adj+128[r0],r7");
+       asm("ashl       $8,r7,r0");
+       asm("bisl2      r0,r8");
+       asm("rotl       $-18,r9,r0");
+       asm("bicl2      $-64,r0");
+       asm("movzbl     _S_adj+192[r0],r7");
+       asm("ashl       $12,r7,r0");
+       asm("bisl2      r0,r8");
+       asm("rotl       $-24,r9,r0");
+       asm("bicl2      $-64,r0");
+       asm("movzbl     _S_adj+256[r0],r7");
+       asm("ashl       $16,r7,r0");
+       asm("bisl2      r0,r8");
+       asm("rotl       $-30,r9,r0");
+       asm("bicl2      $-4,r0");
+       asm("bicl3      $-16,r10,r1");
+       asm("ashl       $2,r1,r1");
+       asm("addl2      r1,r0");
+       asm("movzbl     _S_adj+320[r0],r7");
+       asm("ashl       $20,r7,r0");
+       asm("bisl2      r0,r8");
+       asm("rotl       $-4,r10,r0");
+       asm("bicl2      $-64,r0");
+       asm("movzbl     _S_adj+384[r0],r7");
+       asm("ashl       $24,r7,r0");
+       asm("bisl2      r0,r8");
+       asm("rotl       $-10,r10,r0");
+       asm("bicl2      $-64,r0");
+       asm("movzbl     _S_adj+448[r0],r7");
+       asm("ashl       $28,r7,r0");
+       asm("bisl2      r8,r0");
+       asm("movl       r0,r10");
+
+#endif /* vaxasm */
+#endif
+
+#ifdef DEBUG
+       if (des_debug & 2) {
+           dbg_tmp[0] = L1;
+           dbg_tmp[1] = R1;
+           DBG_PRINT("after s");
+           printf("iter = %2d  after s\n\t\tL1 R1 = ",i);
+           des_cblock_print_file (dbg_tmp, stdout);
+       }
+#endif
+
+/*   P_start:*/
+       /* and then the p permutation from R1 into R2 */
+#include "p.c"
+       /* reset the input to L1, R1 */
+       R1 = R2;
+
+#ifdef DEBUG
+       if (des_debug & 2) {
+           dbg_tmp[0] = L1;
+           dbg_tmp[1] = R1;
+           DBG_PRINT("after p");
+           printf("iter = %2d  after p\n\t\tL1 R1 = ",i);
+           des_cblock_print_file (dbg_tmp, stdout);
+       }
+#endif
+
+       /* R1 is the output value from the f() */
+       /* move R[iter] to L[iter+1] */
+/*   XOR_2_start:*/
+       L1 = R_save;
+       /* xor with left */
+       R1 = L_save ^ R1;
+       /* reset the input */
+    }
+
+    /* flip left and right before final permutation */
+    L2 = R1;                   /* flip */
+    R2 = L1;
+    /* reset the input */
+    L1 = L2;
+    R1 = R2;
+
+#ifdef DEBUG
+    if (des_debug & 2) {
+       dbg_tmp[0] = L1;
+       dbg_tmp[1] = R1;
+       DBG_PRINT("before FP");
+       printf("iter = %2d  before FP\n\t\tL1 R1 = ",i);
+       des_cblock_print_file (dbg_tmp, stdout);
+    }
+
+#endif
+
+/*FP_start:*/
+    /* do the final permutation from L1R1 to L2R2 */
+    /* all the fp code is in the include file */
+#include "fp.c"
+
+    /* copy the output to the ciphertext string;
+     * can be same as cleartext
+     */
+
+#ifdef MUSTALIGN
+    if ((long) cipher & 3) {
+       L_save = L2;    /* cant bcopy a reg */
+       R_save = R2;
+       bcopy((char *)&L_save,(char *)cipher++,sizeof(L_save));
+       bcopy((char *)&R_save,(char *)cipher,sizeof(R_save));
+    }
+    else
+#endif
+    {
+       *cipher++ = L2;
+       *cipher = R2;
+    }
+
+#ifdef DEBUG
+    if (des_debug & 2) {
+       L1 = L2;
+       R1 = R2;
+       dbg_tmp[0] = L1;
+       dbg_tmp[1] = R1;
+       DBG_PRINT("done");
+       printf("iter = %2d  done\n\t\tL1 R1 = ",i);
+       des_cblock_print_file (dbg_tmp, stdout);
+    }
+#endif
+
+    /* that's it, no errors can be returned */
+    return 0;
+}
+
diff --git a/src/lib/crypto/des/des_int.h b/src/lib/crypto/des/des_int.h
new file mode 100644 (file)
index 0000000..feea0d0
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$ 
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Private include file for the Data Encryption Standard library.
+ */
+
+/* only do the whole thing once         */
+#ifndef DES_INTERNAL_DEFS
+#define DES_INTERNAL_DEFS
+
+#include <krb5/config.h>
+#include <krb5/osconf.h>
+
+/*
+ * number of iterations of the inner
+ * loop of the DES algorithm.  The
+ * standard is 16, but in case that is
+ * too slow, we might do less.  Of
+ * course, less also means less
+ * security.
+ */
+#define         AUTH_DES_ITER   16
+
+#ifdef  BITS32
+/* these are for 32 bit machines */
+
+typedef struct {
+    unsigned b0:6;
+    unsigned b1:6;
+    unsigned b2:6;
+    unsigned b3:6;
+    unsigned b4:6;
+    unsigned b5:2;
+}       sbox_in_a;
+
+typedef struct {
+    unsigned b5:4;
+    unsigned b6:6;
+    unsigned b7:6;
+}       sbox_in_b;
+
+typedef struct {
+    unsigned b0:4;
+    unsigned b1:4;
+    unsigned b2:4;
+    unsigned b3:4;
+    unsigned b4:4;
+    unsigned b5:4;
+    unsigned b6:4;
+    unsigned b7:4;
+}       sbox_out;
+
+#else  /*BITS32*/
+/* for sixteen bit machines */
+
+typedef struct {
+    unsigned b0:6;
+    unsigned b1:6;
+    unsigned b2:4;
+}       sbox_in_16_a;
+
+typedef struct {
+    unsigned b2:2;
+    unsigned b3:6;
+    unsigned b4:6;
+    unsigned b5:2;
+}       sbox_in_16_b;
+
+typedef struct {
+    unsigned b5:4;
+    unsigned b6:6;
+    unsigned b7:6;
+}       sbox_in_16_c;
+
+typedef struct {
+    unsigned b0:4;
+    unsigned b1:4;
+    unsigned b2:4;
+    unsigned b3:4;
+    unsigned b4:4;
+    unsigned b5:4;
+    unsigned b6:4;
+    unsigned b7:4;
+}       sbox_out;
+#endif /*BITS32*/
+
+
+#endif /*DES_INTERNAL_DEFS*/
diff --git a/src/lib/crypto/des/enc_dec.c b/src/lib/crypto/des/enc_dec.c
new file mode 100644 (file)
index 0000000..b7fa772
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * 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.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_enc_dec_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+
+#include <krb5/des.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+
+extern int des_debug;
+extern int des_debug_print();
+#endif
+
+
+/*
+       encrypts "size" bytes at "in", storing result in "out".
+       "eblock" points to an encrypt block which has been initialized
+       by process_key().
+
+       "out" must be preallocated by the caller to contain sufficient
+       storage to hold the output; the macro krb5_encrypt_size() can
+       be used to compute this size.
+       
+       returns: errors
+*/
+krb5_error_code encrypt_func(DECLARG(krb5_pointer, in),
+                                   DECLARG(krb5_pointer, out),
+                                   DECLARG(size_t, size),
+                                   DECLARG(krb5_encrypt_block *, key),
+                                   DECLARG(krb5_pointer, ivec))
+OLDDECLARG(krb5_pointer, in)
+OLDDECLARG(krb5_pointer, out)
+OLDDECLARG(size_t, size)
+OLDDECLARG(krb5_encrypt_block *, key)
+OLDDECLARG(krb5_pointer, ivec)
+{
+    krb5_error_code des_cbc_encrypt();
+    krb5_octet *iv;
+    
+    if ( ivec == 0 )
+       iv = key->key->contents;
+    else
+       iv = (krb5_octet *)ivec;
+
+    /* XXX should check that key sched is valid here? */
+    return (des_cbc_encrypt((krb5_octet *)in, 
+                           (krb5_octet *)out,
+                           size, 
+                           (struct des_ks_struct *)key->priv, 
+                           iv,
+                           DES_ENCRYPT));
+}    
+
+/*
+
+       decrypts "size" bytes at "in", storing result in "out".
+       "eblock" points to an encrypt block which has been initialized
+       by process_key().
+
+       "out" must be preallocated by the caller to contain sufficient
+       storage to hold the output; this is guaranteed to be no more than
+       the input size.
+
+       returns: errors
+
+ */
+krb5_error_code decrypt_func(DECLARG(krb5_pointer, in),
+                                   DECLARG(krb5_pointer, out),
+                                   DECLARG(size_t, size),
+                                   DECLARG(krb5_encrypt_block *, key),
+                                   DECLARG(krb5_pointer, ivec))
+OLDDECLARG(krb5_pointer, in)
+OLDDECLARG(krb5_pointer, out)
+OLDDECLARG(size_t, size)
+OLDDECLARG(krb5_encrypt_block *, key)
+OLDDECLARG(krb5_pointer, ivec)
+{
+    krb5_error_code des_cbc_encrypt();
+    krb5_octet *iv;
+
+    if ( ivec == 0 )
+       iv = key->key->contents;
+    else
+       iv = (krb5_octet *)ivec;
+
+    /* XXX should check that key sched is valid here? */
+    return (des_cbc_encrypt ((krb5_octet *)in, 
+                            (krb5_octet *)out, 
+                            size, 
+                            (struct des_ks_struct *)key->priv, 
+                            iv,
+                            DES_DECRYPT));
+}    
+/*
+ * 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.
+ */
+
+krb5_error_code
+des_cbc_encrypt(in,out,length,key,iv,encrypt)
+    krb5_octet   *in;          /* >= length bytes of input text */
+    krb5_octet  *out;          /* >= length bytes of output text */
+    register long length;      /* in bytes */
+    int encrypt;               /* 0 ==> decrypt, else encrypt */
+    des_key_schedule key;              /* precomputed key schedule */
+    krb5_octet *iv;            /* 8 bytes of ivec */
+{
+    int des_ecb_encrypt();
+
+    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/src/lib/crypto/des/fin_rndkey.c b/src/lib/crypto/des/fin_rndkey.c
new file mode 100644 (file)
index 0000000..1c21884
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_fnr_key_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/ext-proto.h>
+
+/*
+        free any resources held by "seed" and assigned by init_random_key()
+ */
+
+krb5_error_code finish_random_key (DECLARG(krb5_pointer *, seed))
+OLDDECLARG(krb5_pointer *, seed)
+{
+    bzero( (char *)*seed, sizeof(des_random_key_seed) );
+    free((char *)*seed);
+    *seed = 0;
+    return 0;          /* XXX init_random_key */
+}
diff --git a/src/lib/crypto/des/finish_key.c b/src/lib/crypto/des/finish_key.c
new file mode 100644 (file)
index 0000000..7a5ec81
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_fin_key_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+
+#include <krb5/des.h>
+
+/*
+       does any necessary clean-up on the eblock (such as releasing
+       resources held by eblock->priv).
+
+       returns: errors
+ */
+
+krb5_error_code finish_key (DECLARG(krb5_encrypt_block *,eblock))
+OLDDECLARG(krb5_encrypt_block *,eblock)
+{
+    bzero((char *)eblock->priv, sizeof(des_key_schedule));
+    free(eblock->priv);
+    eblock->priv = 0;
+    /* free/clear other stuff here? */
+    return 0;
+}
diff --git a/src/lib/crypto/des/init_rkey.c b/src/lib/crypto/des/init_rkey.c
new file mode 100644 (file)
index 0000000..c311cbd
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_inr_key_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/ext-proto.h>
+#include <krb5/krb5_err.h>
+
+extern void des_init_random_number_generator();
+
+/*
+        initialize the random key generator using the encryption key,
+        "seedblock", and allocating private sequence information, filling
+        in "seed" with the address of such information.
+        "seed" is later passed to the random_key() function to provide
+        sequence information.
+ */
+
+krb5_error_code init_random_key (DECLARG(krb5_keyblock *,seedblock),
+                                       DECLARG(krb5_pointer *,seed))
+OLDDECLARG(krb5_keyblock *,seedblock)
+OLDDECLARG(krb5_pointer *,seed)
+{
+    des_random_key_seed * p_seed;
+    if (seedblock->keytype != KEYTYPE_DES)
+       return KRB5_BAD_KEYTYPE;          /* XXX error code bad keytype */
+    if ( !(p_seed = (des_random_key_seed *) 
+          malloc(sizeof(des_random_key_seed))) ) 
+       return ENOMEM;
+    bzero( (char *)p_seed, sizeof(des_random_key_seed) );
+    des_init_random_number_generator(seedblock->contents, p_seed);
+    *seed = (krb5_pointer) p_seed;
+    return 0;
+}
diff --git a/src/lib/crypto/des/key_parity.c b/src/lib/crypto/des/key_parity.c
new file mode 100644 (file)
index 0000000..a6db13b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * These routines check and fix parity of encryption keys for the DES
+ * algorithm.
+ *
+ * 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.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char key_parity_c[] =
+"$Header$";
+#endif /* !lint & !SABER */
+
+#include <mit-copyright.h>
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include "des_internal.h"
+
+#include "odd.h"          /* Load compile-time generated odd_parity table */
+
+/*
+ * des_fixup_key_parity: Forces odd parity per byte; parity is bits
+ *                       8,16,...64 in des order, implies 0, 8, 16, ...
+ *                       vax order.
+ */
+void
+des_fixup_key_parity(key)
+     register des_cblock key;
+{
+    int i;
+
+    for (i=0; i<sizeof(des_cblock); i++)
+      key[i] = odd_parity[key[i]];
+
+    return;
+}
+
+/*
+ * des_check_key_parity: returns true iff key has the correct des parity.
+ *                       See des_fix_key_parity for the definition of
+ *                       correct des parity.
+ */
+int
+des_check_key_parity(key)
+     register des_cblock key;
+{
+    int i;
+
+    for (i=0; i<sizeof(des_cblock); i++)
+      if (key[i] != odd_parity[key[i]])
+       return(0);
+
+    return(1);
+}
diff --git a/src/lib/crypto/des/key_sched.c b/src/lib/crypto/des/key_sched.c
new file mode 100644 (file)
index 0000000..bfe51dd
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine computes the DES key schedule given a key.  The
+ * permutations and shifts have been done at compile time, resulting
+ * in a direct one-step mapping from the input key to the key
+ * schedule.
+ *
+ * Also checks parity and weak keys.
+ *
+ * Watch out for the subscripts -- most effectively start at 1 instead
+ * of at zero.  Maybe some bugs in that area.
+ *
+ * DON'T change the data types for arrays and such, or it will either
+ * break or run slower.  This was optimized for Uvax2.
+ *
+ * In case the user wants to cache the computed key schedule, it is
+ * passed as an arg.  Also implies that caller has explicit control
+ * over zeroing both the key schedule and the key.
+ *
+ * All registers labeled imply Vax using the Ultrix or 4.2bsd compiler.
+ *
+ * Originally written 6/85 by Steve Miller, MIT Project Athena.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char key_sched_c[] =
+"$Header$";
+#endif /* !lint & !SABER */
+
+#include <mit-copyright.h>
+#include "des_internal.h"
+#include <stdio.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include "key_perm.h"
+
+extern int des_debug;
+extern rev_swap_bit_pos_0();
+extern int des_check_key_parity();
+extern int des_is_weak_key();
+
+typedef char key[64];
+/* the following are really void but cc86 doesnt allow it */
+void make_key_sched();
+
+
+int
+des_key_sched(k,schedule)
+    register des_cblock k;     /* r11 */
+    des_key_schedule schedule;
+{
+    /* better pass 8 bytes, length not checked here */
+
+    register i, j, n;          /* i = r10, j = r9, n = r8 */
+    register unsigned int temp;        /*  r7 */
+    register char *p_char;     /* r6 */
+    static key k_char;
+    i = 8;
+    n = 0;
+    p_char = k_char;
+
+#if defined(lint) || defined(SABER)
+    n = n;                             /* fool it in case of VAXASM */
+#endif
+#ifdef DEBUG
+    if (des_debug)
+       fprintf(stderr,"\n\ninput key, left to right = ");
+#endif
+
+    if (!des_check_key_parity(k))      /* bad parity --> return -1 */
+       return(-1);
+
+    do {
+       /* get next input key byte */
+#ifdef DEBUG
+       if (des_debug)
+           fprintf(stderr,"%02x ",*k & 0xff);
+#endif
+       temp = (unsigned int) ((unsigned char) *k++);
+       j = 8;
+
+       do {
+#ifndef VAXASM
+           *p_char++ = (int) temp & 01;
+           temp = temp >> 1;
+#else
+           asm("bicb3  $-2,r7,(r8)+[r6]");
+           asm("rotl   $-1,r7,r7");
+#endif
+       } while (--j > 0);
+    } while (--i > 0);
+
+#ifdef DEBUG
+    if (des_debug) {
+       p_char = k_char;
+       fprintf(stderr,"\nKey bits, from zero to 63");
+       for (i = 0; i <= 7; i++) {
+           fprintf(stderr,"\n\t");
+           for (j = 0; j <=7; j++)
+               fprintf(stderr,"%d ",*p_char++);
+       }
+    }
+#else
+#ifdef lint
+    p_char = p_char;
+#endif
+#endif
+
+    /* check against weak keys */
+    k -= sizeof(des_cblock);
+
+    if (des_is_weak_key(k))
+       return(-2);
+
+    make_key_sched(k_char,schedule);
+
+    /* if key was good, return 0 */
+    return 0;
+}
+
+static void
+make_key_sched(Key,Schedule)
+    register key Key;          /* r11 */
+    des_key_schedule Schedule;
+{
+    /*
+     * The key has been converted to an array to make this run faster;
+     * on a microvax 2, this routine takes about 3.5ms.  The code and
+     * size of the arrays has been played with to get it as fast as
+     * possible.
+     *
+     * Don't change the order of the declarations below without
+     * checking the assembler code to make sure that things are still
+     * where it expects them.
+     */
+
+    /* r10, unroll by AUTH_DES_ITER */
+    register int iter = AUTH_DES_ITER ;
+    register unsigned long *k;  /* r9 */
+    register int *kp;           /* r8 */
+    register unsigned long temp; /* r7 */
+
+    kp = (int *) key_perm;
+    k  = (unsigned long *) Schedule;
+
+    do {
+       /*
+        * create the Key schedule
+        *
+        * put into lsb first order (lsb is bit 0)
+        */
+
+       /*
+        * On the uvax2, this C code below is as fast as straight
+        * assembler, so just use C code below.
+        */
+       temp = 0;
+#ifdef LSBFIRST
+#define BIT(x) x
+#else
+#ifdef notdef
+#define BIT(x) rev_swap_bit_pos_0(x)
+#else
+#define BIT(x) x
+#endif
+#endif
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(0));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(1));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(2));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(3));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(4));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(5));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(6));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(7));
+
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(8));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(9));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(10));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(11));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(12));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(13));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(14));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(15));
+
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(16));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(17));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(18));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(19));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(20));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(21));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(22));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(23));
+
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(24));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(25));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(26));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(27));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(28));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(29));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(30));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(31));
+
+       *k++ = temp;
+       temp = 0;
+
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(0));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(1));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(2));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(3));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(4));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(5));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(6));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(7));
+
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(8));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(9));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(10));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(11));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(12));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(13));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(14));
+       if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(15));
+
+       *k++ = temp;
+
+    } while (--iter > 0);
+
+#ifdef DEBUG
+    if (des_debug) {
+       char *n;
+       int q;
+       fprintf(stderr,"\nKey Schedule, left to right");
+       for (i = 0; i < AUTH_DES_ITER; i++) {
+           n = (char *) &Schedule[i];
+           fprintf(stderr,"\n");
+           for (q = 0; q <= 7; q++)
+               fprintf(stderr,"%02x ",*n++ & 0xff);
+       }
+       fprintf(stderr,"\n");
+    }
+#endif
+}
diff --git a/src/lib/crypto/des/make_e.c b/src/lib/crypto/des/make_e.c
new file mode 100644 (file)
index 0000000..5db85ee
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ *
+ * This routine generates source code that implements the "E"
+ * operations of the DES.
+ */
+
+#include <stdio.h>
+#include "des_internal.h"
+#include "tables.h"
+
+void gen(stream)
+    FILE *stream;
+{
+    register i;
+
+    /* clear the output */
+    fprintf(stream, "    L2 = 0; R2 = 0;\n");
+
+    /* only take bits from R1, put into either L2 or R2 */
+    /* first setup E */
+    fprintf(stream, "/* E operations */\n/* right to left */\n");
+    /* first list mapping from left to left */
+
+    for (i = 0; i <= 31; i++)
+       if (E[i] < 32)
+           fprintf(stream,
+                   "    if (R1 & (1<<%2d)) L2 |= 1<<%2d;\n", E[i], i);
+
+    fprintf(stream, "\n/* now from right to right */\n");
+    /*  list mapping from left to right */
+    for (i = 32; i <= 47; i++)
+       if (E[i] <32)
+           fprintf(stream, "    if (R1 & (1<<%2d)) R2 |= 1<<%2d;\n",
+                   E[i], i-32);
+}
diff --git a/src/lib/crypto/des/make_fp.c b/src/lib/crypto/des/make_fp.c
new file mode 100644 (file)
index 0000000..7e19bd0
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please see the file <mit-copyright.h>.
+ *
+ * This file contains a generation routine for source code
+ * implementing the final permutation of the DES.
+ */
+
+#include <krb5/copyright.h>
+#include <stdio.h>
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include "des_internal.h"
+#include "tables.h"
+
+extern unsigned int swap_bit_pos_0_to_ansi PROTOTYPE((unsigned int));
+extern long swap_long_bytes();
+extern unsigned long swap_long_bytes_bit_number();
+extern void test_set PROTOTYPE((FILE *, char const *, int,
+                               char const *, int));
+
+void gen (stream)
+    FILE * stream;
+{
+    register    i;
+
+    /* clear the output */
+    fprintf(stream,"    L2 = 0; R2 = 0;\n");
+
+    /*
+     *  NOTE: As part of the final permutation, we also have to adjust
+     *  for host bit order via "swap_bit_pos_0()".  Since L2,R2 are
+     *  the output from this, we adjust the bit positions written into
+     *  L2,R2.
+     */
+
+#define SWAP(i,j) \
+    swap_long_bytes_bit_number(swap_bit_pos_0_to_ansi((unsigned)i)-j)
+
+    /* first setup FP */
+    fprintf(stream,
+            "/* FP operations */\n/* first left to left */\n");
+
+    /* first list mapping from left to left */
+    for (i = 0; i <= 31; i++)
+        if (FP[i] < 32)
+            test_set(stream, "L1", FP[i], "L2", SWAP(i,0));
+
+    /* now mapping from right to left */
+    fprintf(stream,"\n\n/* now from right to left */\n");
+    for (i = 0; i <= 31; i++)
+        if (FP[i] >= 32)
+            test_set(stream, "R1", FP[i]-32, "L2", SWAP(i,0));
+
+    fprintf(stream,"\n/* now from left to right */\n");
+
+    /*  list mapping from left to right */
+    for (i = 32; i <= 63; i++)
+        if (FP[i] <32)
+            test_set(stream, "L1", FP[i], "R2", SWAP(i,32));
+
+    /* now mapping from right to right */
+    fprintf(stream,"\n/* last from right to right */\n");
+    for (i = 32; i <= 63; i++)
+        if (FP[i] >= 32)
+            test_set(stream, "R1", FP[i]-32, "R2", SWAP(i,32));
+}
diff --git a/src/lib/crypto/des/make_ip.c b/src/lib/crypto/des/make_ip.c
new file mode 100644 (file)
index 0000000..54e927c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine generates source code implementing the initial
+ * permutation of the DES.
+ */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include "des_internal.h"
+#include "tables.h"
+
+extern long swap_bit_pos_0();
+extern long rev_swap_bit_pos_0();
+extern void test_set();
+extern unsigned long swap_long_bytes_bit_number();
+unsigned long swap_bit_pos_0_to_ansi();
+
+#define SWAP(x) swap_long_bytes_bit_number(swap_bit_pos_0_to_ansi(x))
+
+void gen(stream)
+    FILE *stream;
+{
+    register i;
+
+    /* clear the output */
+    fprintf(stream,"    L2 = 0; R2 = 0;\n");
+
+    /* first setup IP */
+    fprintf(stream,"/* IP operations */\n/* first left to left */\n");
+
+    /* first list mapping from left to left */
+    for (i = 0; i <= 31; i++)
+        if (IP[i] < 32)
+            test_set(stream, "L1", SWAP(IP[i]), "L2", i);
+
+    /* now mapping from right to left */
+    fprintf(stream,"\n/* now from right to left */\n");
+    for (i = 0; i <= 31; i++)
+        if (IP[i] >= 32)
+            test_set(stream, "R1", SWAP(IP[i]-32), "L2", i);
+
+    fprintf(stream,"\n/* now from left to right */\n");
+    /*  list mapping from left to right */
+    for (i = 32; i <= 63; i++)
+        if (IP[i] <32)
+            test_set(stream, "L1", SWAP(IP[i]), "R2", i-32);
+
+    /* now mapping from right to right */
+    fprintf(stream,"\n/* last from right to right */\n");
+    for (i = 32; i <= 63; i++)
+        if (IP[i] >= 32)
+            test_set(stream, "R1", SWAP(IP[i]-32), "R2", i-32);
+    exit(0);
+}
diff --git a/src/lib/crypto/des/make_kp.c b/src/lib/crypto/des/make_kp.c
new file mode 100644 (file)
index 0000000..18c3342
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * $Source$
+ * $Author$
+ * $Locker$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This routine calculates an effective Key schedule set of
+ * permutations for des.  Beginning with the pre-defined key schedule
+ * algorithm, it reduces it to a set of 16 permutations upon the
+ * initial key.  Only needs to execute once to produce a header file.
+ * Note that we subtract one from the values ouput to fix up for C
+ * subscripts starting at 0.
+ */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <errno.h>
+#include "des_internal.h"
+
+#ifndef lint
+static char rcsid[]=
+    "$Header$";
+#endif /* lint */
+
+char *progname;
+extern char *errmsg();
+extern int errno;
+extern long swap_bit_pos_1();
+extern long swap_bit_pos_0();
+int sflag;
+int vflag;
+int dflag;
+int pid;
+int child_status;
+
+int key_position[64+1];
+int C[28+1];
+int D[28+1];
+int C_temp, D_temp;
+
+/*
+ *  CONVENTIONS for numbering the bits
+ *  bit 0 ==> lsb
+ *  L starts at bit 0
+ *  R starts at bit 64
+ *
+ *  BEWARE-- some stuff starts at 0, some at 1;  perhaps some bugs still?
+ */
+
+/*
+ * Sequence of shifts used for the key schedule.
+ */
+int  shift[16+1] = { 0,
+    1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
+};
+
+int pc_1[64+1] = { 0,
+
+    57,49,41,33,25,17, 9,
+     1,58,50,42,34,26,18,
+    10, 2,59,51,43,35,27,
+    19,11, 3,60,52,44,36,
+
+    63,55,47,39,31,23,15,
+     7,62,54,46,38,30,22,
+    14, 6,61,53,45,37,29,
+    21,13, 5,28,20,12, 4,
+};
+
+
+/*
+ * Permuted-choice 2, to pick out the bits from
+ * the CD array that generate the key schedule.
+ */
+int  pc_2[48+1] = { 0,
+
+    14,17,11,24, 1, 5,
+     3,28,15, 6,21,10,
+    23,19,12, 4,26, 8,
+    16, 7,27,20,13, 2,
+
+    41,52,31,37,47,55,
+    30,40,51,45,33,48,
+    44,49,39,56,34,53,
+    46,42,50,36,29,32,
+};
+
+int ks_perm[16+1][48+1];
+
+int des_debug;
+
+void gen(stream)
+    FILE *stream;
+{
+    /*  Local Declarations */
+    register i, j, iter;
+
+    /*
+     * initialize the key_position array s.t. key_position[i] = i;
+     * that is, each element is equal to its starting position.
+     *
+     * Also adjust for the bit order within bytes.
+     */
+
+    for (i=0; i<65; i++)
+        key_position[i]= swap_bit_pos_1(i);
+
+    fprintf(stream,"static int const key_perm[16][48] = {\n");
+
+    /*
+     * apply pc_1 to initial key_position to create C[0] and D[0]
+     * Start at pc_1[1], not pc_1[0]
+     */
+    for (i=1; i<=28; i++) {
+        C[i] = key_position[pc_1[i]];
+        D[i] = key_position[pc_1[i+28]];
+    }
+
+    /*
+     * major loop over the 16 iterations
+     * start at iter = 1, not zero.
+     */
+    for (iter = 1; iter <= 16; iter++) {
+        if (des_debug) {
+            /*  for debugging */
+            printf(
+                    "/* DEBUG-- start iteration = %d  shifts = %d",
+                    iter, shift[iter]);
+            printf("\nC array");
+            for (i = 1; i <=4 ; i++) {
+                printf("\n");
+                for (j = 1; j<=7; j++)
+                    printf("%d, ",C[(i-1)*7+j]);
+            }
+            printf("\n\nD array");
+            for (i = 1; i <=4 ; i++) {
+                printf("\n");
+                for (j = 1; j<=7; j++)
+                    printf("%d, ",D[(i-1)*7+j]);
+            }
+            printf("\n */");
+            fflush(stdout);
+        }
+
+        /* apply the appropriate left shifts */
+        for (i = 1; i <= shift[iter]; i++) {
+            C_temp = C[1];
+            D_temp = D[1];
+            for (j =1; j<=27; j++) {
+                C[j] = C[j+1];
+                D[j] = D[j+1];
+            }
+            C[j] = C_temp;
+            D[j] = D_temp;
+        }
+
+
+        if (des_debug) {
+            /* for debugging */
+            printf("/* DEBUG:\n");
+            printf(" * after shifts, iteration = %d  shifts = %d",
+                    iter, shift[iter]);
+            printf("\nC array");
+            for (i = 1; i <=4 ; i++) {
+                printf("\n");
+                for (j = 1; j<=7; j++)
+                    printf("%d, ",C[(i-1)*7+j]);
+            }
+            printf("\n\nD array");
+            for (i = 1; i <=4 ; i++) {
+                printf("\n");
+                for (j = 1; j<=7; j++)
+                    printf("%d, ",D[(i-1)*7+j]);
+            }
+            printf("\n */");
+            fflush(stdout);
+        }
+
+        /*
+         * apply pc_2
+         * Start at pc_2[1], not pc_2[0]
+         *
+         * Start stuffing ks_perm[1][1], not ks_perm[0][0]
+         *
+         * Adjust ks_perm for bit order if needed.
+         */
+        for (i = 1; i <= 48; i++) {
+            if (pc_2[i] <= 28)
+                ks_perm[iter][(i)] = C[pc_2[i]];
+            else
+                ks_perm[iter][(i)] = D[pc_2[i]-28];
+        }
+
+        /* now output the resulting key permutation */
+        fprintf(stream, "    /* ks permutation iteration = %2d */",
+                iter);
+        for (i = 1; i <= 6; i++) {
+            fprintf(stream, "\n    ");
+            for (j = 1; j <= 8; j++) {
+                /*
+                 * IMPORTANT -- subtract one from value to adjust to a
+                 * zero-based subscript for key
+                 */
+                fprintf(stream, "%d", ks_perm[iter][(i-1)*8+j]-1);
+                /* omit last comma */
+                if ((j != 8) || (i != 6) || (iter != 16)) {
+                    fprintf(stream,", ");
+                }
+            }
+        }
+    }
+    fprintf(stream,"\n};\n");
+}
diff --git a/src/lib/crypto/des/make_odd.c b/src/lib/crypto/des/make_odd.c
new file mode 100644 (file)
index 0000000..d441595
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see
+ * the file <mit-copyright.h>.
+ *
+ * This routine generates an odd-parity table for use in key generation.
+ */
+
+#include <krb5/copyright.h>
+#include <stdio.h>
+
+void gen(stream)
+    FILE *stream;
+{
+    /*
+     * map a byte into its equivalent with odd parity, where odd
+     * parity is in the least significant bit
+     */
+    register i, j, k, odd;
+
+    fprintf(stream,
+            "static unsigned char const odd_parity[256] = {\n");
+
+    for (i = 0; i < 256; i++) {
+        odd = 0;
+        /* shift out the lsb parity bit */
+        k = i >> 1;
+        /* then count the other bits */
+        for (j = 0; j < 7; j++) {
+            odd ^= (k&1);
+            k = k >> 1;
+        }
+        k = i&~1;
+        if (!odd)
+            k |= 1;
+        fprintf(stream, "%3d", k);
+        if (i < 255)
+            fprintf(stream, ", ");
+        if (i%8 == 0)
+            fprintf(stream, "\n");
+    }
+    fprintf(stream, "};\n");
+}
diff --git a/src/lib/crypto/des/make_p.c b/src/lib/crypto/des/make_p.c
new file mode 100644 (file)
index 0000000..becac62
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1985, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please
+ * see the file <mit-copyright.h>.
+ *
+ * This routine generates the P permutation code for the DES.
+ */
+
+#include <krb5/copyright.h>
+#include <stdio.h>
+#include "des_internal.h"
+#include "tables.h"
+
+void gen(stream)
+    FILE *stream;
+{
+    /* P permutes 32 bit input R1 into 32 bit output R2 */     
+
+    /* clear the output */
+    fprintf(stream,"    L2 = 0;\n");
+#ifndef        BIG
+    fprintf(stream,"    R2 = 0;\n");
+    fprintf(stream,
+           "/* P operations */\n/* from right to right */\n");
+    /* first list mapping from left to left */
+    for (i = 0; i <=31; i++)
+       if (P[i] < 32)
+           fprintf(stream,
+                   "    if (R1 & (1<<%d)) R2 |= 1<<%d;\n",P[i],i);
+#else /* BIG */
+    /* flip p into p_temp */
+    fprintf(stream,"    P_temp = R1;\n");
+    fprintf(stream,"    P_temp_p = (unsigned char *) &P_temp;\n");
+#ifdef LSBFIRST
+    fprintf(stream,"    R2 = P_prime[0][*P_temp_p++];\n");
+    fprintf(stream,"    R2 |= P_prime[1][*P_temp_p++];\n");
+    fprintf(stream,"    R2 |= P_prime[2][*P_temp_p++];\n");
+    fprintf(stream,"    R2 |= P_prime[3][*P_temp_p];\n");
+#else /* MSBFIRST */
+    fprintf(stream,"    R2 = P_prime[3][*P_temp_p++];\n");
+    fprintf(stream,"    R2 |= P_prime[2][*P_temp_p++];\n");
+    fprintf(stream,"    R2 |= P_prime[1][*P_temp_p++];\n");
+    fprintf(stream,"    R2 |= P_prime[0][*P_temp_p];\n");
+#endif /* MSBFIRST */
+#endif /* BIG */
+}
diff --git a/src/lib/crypto/des/make_pt.c b/src/lib/crypto/des/make_pt.c
new file mode 100644 (file)
index 0000000..2d8787b
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1985, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please
+ * see the file <mit-copyright.h>.
+ *
+ */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include "des_internal.h"
+#include "tables.h"
+
+extern unsigned long swap_byte_bits();
+extern unsigned long rev_swap_bit_pos_0();
+static unsigned char P_temp[32];
+static unsigned long P_prime[4][256];
+
+void gen(stream)
+    FILE *stream;
+{
+    register i,j,k,m;
+    /* P permutes 32 bit input R1 into 32 bit output R2 */
+
+#ifdef BIG
+    /* flip p into p_temp */
+    for (i = 0; i<32; i++)
+       P_temp[P[rev_swap_bit_pos_0(i)]] = rev_swap_bit_pos_0(i);
+
+    /*
+     * now for each byte of input, figure out all possible combinations
+     */
+    for (i = 0; i <4 ; i ++) { /* each input byte */
+       for (j = 0; j<256; j++) { /* each possible byte value */
+           /* flip bit order */
+           k = j;
+           /* swap_byte_bits(j); */
+           for (m = 0; m < 8; m++) { /* each bit */
+               if (k & (1 << m)) {
+                   /* set output values */
+                   P_prime[i][j] |= 1 << P_temp[(i*8)+m];
+               }
+           }
+       }
+    }
+
+    fprintf(stream,
+           "\n\tstatic unsigned long const P_prime[4][256] = {\n\t");
+    for (i = 0; i < 4; i++) {
+       fprintf(stream,"\n");
+       for (j = 0; j < 64; j++) {
+           fprintf(stream,"\n");
+           for (k = 0; k < 4; k++) {
+               fprintf(stream,"0x%08X",P_prime[i][j*4+k]);
+               if ((i == 3) && (j == 63) && (k == 3))
+                   fprintf(stream,"\n};");
+               else
+                   fprintf(stream,", ");
+           }
+       }
+    }
+
+#endif
+    fprintf(stream,"\n");
+}
diff --git a/src/lib/crypto/des/make_s.c b/src/lib/crypto/des/make_s.c
new file mode 100644 (file)
index 0000000..1e17817
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1985, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please
+ * see the file <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include "des_internal.h"
+#include "s_table.h"
+
+void gen(stream)
+    FILE *stream;
+{
+    /* clear the output */
+    fprintf(stream,"\n\tL2 = 0; R2 = 0;");
+
+#ifdef notdef
+    /* P permutes 32 bit input R1 into 32 bit output R2 */
+
+    fprintf(stream,"\n/* P operations */\n/* first left to left */\n");
+    /* first list mapping from left to left */
+    for (i = 0; i <=31; i++)
+       if (S[i] < 32)
+           fprintf(stream,
+                   "\n\tif (R1 & (1<<%d)) R2 |= 1<<%d;",S[i],i);
+#endif
+    fprintf(stream,"\n");
+}
diff --git a/src/lib/crypto/des/make_st.c b/src/lib/crypto/des/make_st.c
new file mode 100644 (file)
index 0000000..78601e0
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1985, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please
+ * see the file <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include "des_internal.h"
+#include "tables.h"
+
+extern unsigned long swap_bit_pos_0();
+extern unsigned long swap_six_bits_to_ansi();
+extern unsigned long swap_four_bits_to_ansi();
+char temp[8][64];
+int des_debug;
+
+void gen(stream)
+    FILE *stream;
+{
+    register unsigned long i,j,k,l,m,n;
+
+    /* rearrange the S table entries, and adjust for host bit order */
+
+    fprintf(stream, "static unsigned char const S_adj[8][64] = {");
+    fprintf(stream, "    /* adjusted */\n");
+
+    for (i = 0; i<=7 ; i++) {
+        for (j = 0; j <= 63; j++) {
+            /*
+             * figure out which one to put in the new S[i][j]
+             *
+             * start by assuming the value of the input bits is "j" in
+             * host order, then figure out what it means in standard
+             * form.
+             */
+            k = swap_six_bits_to_ansi(j);
+            /* figure out the index for k */
+            l = (((k >> 5) & 01) << 5)
+                + ((k & 01) <<4) + ((k >> 1) & 0xf);
+            m = S[i][l];
+            /* restore in host order */
+            n = swap_four_bits_to_ansi(m);
+            if (des_debug)
+                fprintf(stderr,
+                "i = %d, j = %d, k = %d, l = %d, m = %d, n = %d\n",
+                        i,j,k,l,m,n);
+            temp[i][j] = n;
+        }
+    }
+
+    for (i = 0; i<=7; i++) {
+        fprintf(stream,"\n");
+        k =0;
+        for (j = 0; j<= 3; j++) {
+            fprintf(stream,"\n");
+            for (m = 0; m <= 15; m++) {
+                fprintf(stream,"%2d",temp[i][k]);
+                if ((k++ != 63) || (i !=7)) {
+                    fprintf(stream,", ");
+                }
+            }
+        }
+    }
+
+    fprintf(stream,"\n};\n");
+}
diff --git a/src/lib/crypto/des/misc.c b/src/lib/crypto/des/misc.c
new file mode 100644 (file)
index 0000000..a7add4c
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information,
+ * please seethe file <mit-copyright.h>.
+ *
+ * This file contains most of the routines needed by the various
+ * make_foo programs, to account for bit- and byte-ordering on
+ * different machine types.  It also contains other routines useful in
+ * generating the intermediate source files.
+ */
+
+#include <krb5/copyright.h>
+#include <stdio.h>
+#include <sys/errno.h>
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+
+#include <krb5/des.h>
+#include "des_internal.h"
+
+/*
+ * The DES algorithm is defined in terms of MSBFIRST, so sometimes,
+ * e.g.  VAXes, we need to fix it up.  ANSI order means the DES
+ * MSBFIRST order.
+ */
+
+#if 0 /* These don't seem to get used anywhere.... */
+void swap_bits(array)
+    char *array;
+{
+#ifdef MSBFIRST
+    /* just return */
+    return;
+#else /* LSBFIRST */
+    register old,new,i,j;
+
+    /* for an eight byte block-- */
+    /* flips the bit order within each byte from 0 lsb to 0 msb */
+    for (i = 0; i<=7; i++) {
+        old = *array;
+        new = 0;
+        for (j = 0; j<=7; j++) {
+            new |= old & 01;    /* copy a bit */
+            if (j < 7) {
+                /* rotate in opposite directions */
+                old = old >> 1;
+                new = new << 1;
+            }
+        }
+        *array++ = new;
+    }
+#endif /* MSBFIRST */
+}
+
+unsigned long long_swap_bits(x)
+    unsigned long x;
+{
+#ifdef MSBFIRST
+    return x;
+#else
+    char *array = (char *) &x;
+    register old,new,i,j;
+
+    /* flips the bit order within each byte from 0 lsb to 0 msb */
+    for (i = 0; i <= (sizeof(long)-1); i++) {
+        old = *array;
+        new = 0;
+        for (j = 0; j<=7; j++) {
+            if (old & 01)
+                new = new | 01;
+            if (j < 7) {
+                old = old >> 1;
+                new = new << 1;
+            }
+        }
+        *array++ = new;
+    }
+    return x;
+#endif /* LSBFIRST */
+}
+#endif /* 0 */
+
+unsigned long swap_six_bits_to_ansi(old)
+    unsigned long old;
+{
+    register unsigned long new, j;
+
+    /* flips the bit order within each byte from 0 lsb to 0 msb */
+    new = 0;
+    for (j = 0; j<=5; j++) {
+        new |= old & 01;        /* copy a bit */
+        if (j < 5) {
+            /* rotate in opposite directions */
+            old = old >> 1;
+            new = new << 1;
+        }
+    }
+    return new;
+}
+
+unsigned long swap_four_bits_to_ansi(old)
+    unsigned long old;
+{
+    register unsigned long new,j;
+
+    /* flips the bit order within each byte from 0 lsb to 0 msb */
+    new = 0;
+    for (j = 0; j<=3; j++) {
+        new |= (old & 01);      /* copy a bit */
+        if (j < 3) {
+            old = old >> 1;
+            new = new << 1;
+        }
+    }
+    return new;
+}
+
+unsigned long swap_bit_pos_1(x)
+    unsigned long x;
+{
+    /*
+     * This corrects for the bit ordering of the algorithm, e.g.
+     * bit 0 ==> msb, bit 7 lsb.
+     *
+     * given the number of a bit position, >=1, flips the bit order
+     * each byte. e.g. bit 3 --> bit 6, bit 13 --> bit 12
+     */
+    register y,z;
+
+    /* always do it, only used by des_make_key_perm.c so far */
+    y = (x-1)/8;
+    z = (x-1)%8;
+
+    x = (8-z) + (y*8);
+
+    return x;
+}
+
+unsigned long swap_bit_pos_0(x)
+    unsigned long x;
+{
+    /*  zero based version */
+
+    /*
+     * This corrects for the bit ordering of the algorithm, e.g.
+     * bit 0 ==> msb, bit 7 lsb.
+     */
+
+#ifdef MSBFIRST
+    return x;
+#else /* LSBFIRST */
+    register y,z;
+
+    /*
+     * given the number of a bit position, >=0, flips the bit order
+     * each byte. e.g. bit 3 --> bit 6, bit 13 --> bit 12
+     */
+    y = x/8;
+    z = x%8;
+
+    x = (7-z) + (y*8);
+
+    return x;
+#endif /* LSBFIRST */
+}
+
+unsigned long swap_bit_pos_0_to_ansi(x)
+    unsigned long x;
+{
+    /* zero based version */
+
+    /*
+     * This corrects for the bit ordering of the algorithm, e.g.
+     * bit 0 ==> msb, bit 7 lsb.
+     */
+
+    register y,z;
+    /*
+     * given the number of a bit position, >=0, flips the bit order each
+     * byte. e.g. bit 3 --> bit 6, bit 13 --> bit 12
+     */
+    y = x/8;
+    z = x%8;
+
+    x = (7-z) + (y*8);
+
+    return x;
+}
+
+unsigned long rev_swap_bit_pos_0(x)
+    unsigned long x;
+{
+    /* zero based version */
+
+    /*
+     * This corrects for the bit ordering of the algorithm, e.g.
+     *  bit 0 ==> msb, bit 7 lsb.
+     *
+     * Role of LSB and MSB flipped from the swap_bit_pos_0()
+     */
+
+#ifdef LSBFIRST
+    return x;
+#else /* MSBFIRST */
+
+    register y,z;
+
+    /*
+     * given the number of a bit position, >=0, flips the bit order each
+     * byte. e.g. bit 3 --> bit 6, bit 13 --> bit 12
+     */
+    y = x/8;
+    z = x%8;
+
+    x = (7-z) + (y*8);
+
+    return x;
+#endif /* MSBFIRST */
+}
+
+unsigned long swap_byte_bits(x)
+    unsigned long x;
+{
+#ifdef MSBFIRST
+    return x;
+#else /* LSBFIRST */
+
+    char *array = (char *) &x;
+    register unsigned long old,new,j;
+
+    /* flips the bit order within each byte from 0 lsb to 0 msb */
+    old = *array;
+    new = 0;
+    for (j = 0; j<=7; j++) {
+        new |= (old & 01);      /* copy a bit */
+        if (j < 7) {
+            old = old >> 1;
+            new = new << 1;
+        }
+    }
+    return new;
+#endif /* LSBFIRST */
+}
+
+unsigned long
+swap_long_bytes_bit_number(x)
+    unsigned long x;
+{
+    /*
+     * given a bit number (0-31) from a vax, swap the byte part of the
+     * bit number to change the byte ordering to mSBFIRST type
+     */
+#ifdef LSBFIRST
+    return x;
+#else /* MSBFIRST */
+    unsigned long y,z;
+
+    y = x/8;                    /* initial byte component */
+    z = x%8;                    /* bit within byte */
+
+    x = (3-y)*8 +z;
+    return x;
+#endif /* MSBFIRST */
+}
+
+void test_set(stream, src, testbit, dest, setbit)
+    FILE *stream;
+    const char *src;
+    int testbit;
+    const char *dest;
+    int setbit;
+{
+#ifdef DES_SHIFT_SHIFT
+    if (testbit == setbit)
+        fprintf(stream, "    %s |=  %s & (1<<%2d);\n",
+                dest, src, testbit);
+    else
+        fprintf(stream, "    %s |= (%s & (1<<%2d)) %s %2d;\n",
+                dest, src, testbit,
+                (testbit < setbit) ? "<<" : ">>",
+                abs(testbit - setbit));
+#else
+    fprintf(stream,
+            "    if (%s & (1<<%2d))  %s |= 1<<%2d;\n",
+            src, testbit, dest, setbit);
+#endif
+}
+
+extern void gen PROTOTYPE((FILE *));
+int des_debug;
+char const *whoami;
+
+void
+main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    char *filename;
+    char *arg;
+    FILE *stream = 0;
+
+    whoami = argv[0];
+    filename = (char *)NULL;
+
+    while (argc--, *++argv) {
+        arg = *argv;
+        if (*arg == '-') {
+            if (!strcmp(arg, "-d") && !strcmp(arg, "-debug"))
+                des_debug++;
+            else {
+                fprintf(stderr, "%s: unknown control argument %s\n",
+                        whoami, arg);
+                goto usage;
+            }
+        }
+        else if (filename) {
+            fprintf(stderr,
+                    "%s: multiple file names provided: %s, %s\n",
+                    whoami, filename, arg);
+            goto usage;
+        }
+        else
+            filename = arg;
+    }
+
+    if (!filename) {
+        fprintf(stderr, "%s: no file name provided\n", whoami);
+        goto usage;
+    }
+
+    stream = fopen(filename, "w");
+    if (!stream) {
+        perror(filename);
+    usage:
+        fprintf(stderr, "usage: %s [-debug] filename\n", whoami);
+        exit(1);
+    }
+
+    fputs(
+      "/* This file is automatically generated.  Do not edit it. */\n",
+          stream);
+
+    /* This routine will generate the contents of the file. */
+    gen(stream);
+    if (fclose(stream) == EOF) {
+        perror(filename);
+        exit(1);
+    }
+    exit(0);
+}
diff --git a/src/lib/crypto/des/new_rn_key.c b/src/lib/crypto/des/new_rn_key.c
new file mode 100644 (file)
index 0000000..437e88c
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * New pseudo-random key generator, using DES encryption to make the
+ * pseudo-random cycle as hard to break as DES.
+ *
+ * Written by Mark Lillibridge, MIT Project Athena
+ *
+ * Under U.S. law, this software may not be exported outside the US
+ * without license from the U.S. Commerce department.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char new_rnd_key_c[] =
+"$Header$";
+#endif /* !lint & !SABER */
+
+#include <mit-copyright.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include "des_internal.h"
+
+extern void des_fixup_key_parity();
+extern int des_is_weak_key();
+extern int des_ecb_encrypt();
+extern int des_key_sched();
+void des_set_random_generator_seed(), des_set_sequence_number();
+void des_generate_random_block();
+
+/*
+ * des_new_random_key: create a random des key
+ *
+ * Requires: des_set_random_number_generater_seed must be at called least
+ *           once before this routine is called.
+ *
+ * Notes: the returned key has correct parity and is guarenteed not
+ *        to be a weak des key.  Des_generate_random_block is used to
+ *        provide the random bits.
+ */
+int
+des_new_random_key(key, p_seed)
+    des_cblock key;
+    des_random_key_seed        *p_seed;
+{
+    do {
+       des_generate_random_block(key, p_seed);
+       des_fixup_key_parity(key);
+    } while (des_is_weak_key(key));
+
+    return(0);
+}
+
+/*
+ * des_init_random_number_generator:
+ *
+ *    This routine takes a secret key possibly shared by a number
+ * of servers and uses it to generate a random number stream that is
+ * not shared by any of the other servers.  It does this by using the current
+ * process id, host id, and the current time to the nearest second.  The
+ * resulting stream seed is not useful information for cracking the secret
+ * key.   Moreover, this routine keeps no copy of the secret key.
+ * This routine is used for example, by the kerberos server(s) with the
+ * key in question being the kerberos master key.
+ *
+ * Note: this routine calls des_set_random_generator_seed.
+ */
+#ifndef BSDUNIX
+  you lose...   (aka, you get to implement an analog of this for your
+                system...)
+#else
+
+#include <sys/time.h>
+#include <krb5/ext-proto.h>
+extern long gethostid();
+
+void des_init_random_number_generator(key,p_seed)
+    des_cblock key;
+    des_random_key_seed        *p_seed;
+{
+    struct { /* This must be 64 bits exactly */
+       long process_id;
+       long host_id;
+    } seed;
+    struct timeval time; /* this must also be 64 bits exactly */
+    des_cblock new_key;
+
+    /*
+     * use a host id and process id in generating the seed to ensure
+     * that different servers have different streams:
+     */
+    seed.host_id = gethostid();
+    seed.process_id = (long) getpid();
+
+    /*
+     * Generate a tempory value that depends on the key, host_id, and
+     * process_id such that it gives no useful information about the key:
+     */
+    des_set_random_generator_seed(key, p_seed);
+    des_set_sequence_number((unsigned char *)&seed, p_seed);
+    des_new_random_key(new_key, p_seed);
+
+    /*
+     * use it to select a random stream:
+     */      
+    des_set_random_generator_seed(new_key, p_seed);
+
+    /*
+     * use a time stamp to ensure that a server started later does not reuse
+     * an old stream:
+     */
+    gettimeofday(&time, (struct timezone *)0);
+    des_set_sequence_number((unsigned char *)&time, p_seed);
+
+    /*
+     * use the time stamp finally to select the final seed using the
+     * current random number stream:
+     */
+    des_new_random_key(new_key, p_seed);
+    des_set_random_generator_seed(new_key, p_seed);
+}
+
+#endif /* ifdef BSDUNIX */
+
+/*
+ * This module implements a random number generator faculty such that the next
+ * number in any random number stream is very hard to predict without knowing
+ * the seed for that stream even given the preceeding random numbers.
+ */
+
+/*
+ * des_set_random_generator_seed: this routine is used to select a random
+ *                                number stream.  The stream that results is
+ *                                totally determined by the passed in key.
+ *                                (I.e., calling this routine again with the
+ *                                same key allows repeating a sequence of
+ *                                random numbers)
+ *
+ * Requires: key is a valid des key.  I.e., has correct parity and is not a
+ *           weak des key.
+ */
+void
+des_set_random_generator_seed(key, p_seed)
+    des_cblock key;
+    des_random_key_seed        *p_seed;
+{
+    register int i;
+
+    /* select the new stream: (note errors are not possible here...) */
+    des_key_sched(key, p_seed->random_sequence_key);
+
+    /* "seek" to the start of the stream: */
+    for (i=0; i<8; i++)
+      p_seed->sequence_number[i] = 0;
+}
+
+/*
+ * des_set_sequence_number: this routine is used to set the sequence number
+ *                          of the current random number stream.  This routine
+ *                          may be used to "seek" within the current random
+ *                          number stream.
+ *
+ * Note that des_set_random_generator_seed resets the sequence number to 0.
+ */
+void
+des_set_sequence_number(new_sequence_number, p_seed)
+    des_cblock new_sequence_number;
+    des_random_key_seed        *p_seed;
+{
+    bcopy((char *)new_sequence_number, (char *)p_seed->sequence_number,
+         sizeof(p_seed->sequence_number));
+}
+
+/*
+ * des_generate_random_block: routine to return the next random number
+ *                            from the current random number stream.
+ *                            The returned number is 64 bits long.
+ *
+ * Requires: des_set_random_generator_seed must have been called at least once
+ *           before this routine is called.
+ */
+void des_generate_random_block(block, p_seed)
+    des_cblock block;
+    des_random_key_seed        *p_seed;
+{
+    int i;
+
+    /*
+     * Encrypt the sequence number to get the new random block:
+     */
+    des_ecb_encrypt((unsigned long *)p_seed->sequence_number, 
+                   (unsigned long *)block, 
+                   p_seed->random_sequence_key, 1);
+
+    /*
+     * Increment the sequence number as an 8 byte unsigned number with wrap:
+     * (using LSB here)
+     */
+    for (i=0; i<8; i++) {
+       p_seed->sequence_number[i] = (p_seed->sequence_number[i] + 1) & 0xff;
+       if (p_seed->sequence_number[i])
+         break;
+    }
+}
diff --git a/src/lib/crypto/des/process_ky.c b/src/lib/crypto/des/process_ky.c
new file mode 100644 (file)
index 0000000..be62beb
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_prc_key_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/ext-proto.h>
+#include <krb5/krb5_err.h>
+
+extern int des_key_sched();
+/*
+        does any necessary key preprocessing (such as computing key
+                schedules for DES).
+        eblock->crypto_entry must be set by the caller; the other elements
+        of eblock are to be assigned by this function.
+        [in particular, eblock->key must be set by this function if the key
+        is needed in raw form by the encryption routine]
+
+        The caller may not move or reallocate "keyblock" before calling
+        finish_key on "eblock"
+
+        returns: errors
+ */
+
+krb5_error_code process_key (DECLARG(krb5_encrypt_block *, eblock),
+                                   DECLARG(krb5_keyblock *,keyblock))
+OLDDECLARG(krb5_encrypt_block *, eblock)
+OLDDECLARG(krb5_keyblock *,keyblock)
+{
+    struct des_ks_struct       *schedule;      /* pointer to key schedules */
+    
+    if (keyblock->length != sizeof (des_cblock))
+       return KRB5_BAD_KEYSIZE;        /* XXX error code-bad key size */
+
+    if ( !(schedule = (struct des_ks_struct *) malloc(sizeof(des_key_schedule))) )
+        return ENOMEM;
+#define cleanup() { free( (char *) schedule); }
+
+    switch (des_key_sched (keyblock->contents, schedule)) {
+    case -1:
+       cleanup();
+       return KRB5DES_BAD_KEYPAR;      /* XXX error code-bad key parity */
+
+    case -2:
+       cleanup();
+       return KRB5DES_WEAK_KEY;        /* XXX error code-weak key */
+
+    default:
+       eblock->key = keyblock;
+       eblock->priv = (krb5_pointer) schedule;
+       return 0;
+    }
+}
diff --git a/src/lib/crypto/des/random_key.c b/src/lib/crypto/des/random_key.c
new file mode 100644 (file)
index 0000000..5fd4075
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_ran_key_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/ext-proto.h>
+
+extern int des_new_random_key();
+
+/*
+        generate a random encryption key, allocating storage for it and
+        filling in the keyblock address in *keyblock
+ */
+
+krb5_error_code random_key (DECLARG(krb5_pointer, seed),
+                                  DECLARG(krb5_keyblock **, keyblock))
+OLDDECLARG(krb5_pointer, seed)
+OLDDECLARG(krb5_keyblock **, keyblock)
+{
+    krb5_keyblock *randkey;
+
+    if (!(randkey = (krb5_keyblock *)malloc(sizeof(*randkey))))
+       return ENOMEM;
+    if (!(randkey->contents = (krb5_octet *)malloc(sizeof(des_cblock)))) {
+       free((char *)randkey);
+       return ENOMEM;
+    }
+    randkey->length = sizeof(des_cblock);
+    randkey->keytype = KEYTYPE_DES;
+    des_new_random_key(randkey->contents, (des_random_key_seed *) seed);
+    *keyblock = randkey;
+    return 0;
+}
diff --git a/src/lib/crypto/des/string2key.c b/src/lib/crypto/des/string2key.c
new file mode 100644 (file)
index 0000000..729c5d4
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/mit-copyright.h>.
+ *
+ * Wrapper for the V4 libdes for use with kerberos V5.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char des_st2_key_c[] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include <sys/errno.h>
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/krb5_err.h>
+#include <krb5/ext-proto.h>
+
+#include "des_internal.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+extern int des_debug;
+extern int des_debug_print();
+#endif
+
+extern void des_fixup_key_parity();
+extern int des_key_sched();
+extern void des_cbc_cksum();
+/*
+       converts the string pointed to by "data" into an encryption key
+       of type "keytype".  *keyblock is filled in with the key info;
+       in particular, keyblock->contents is to be set to allocated storage.
+       It is the responsibility of the caller to release this storage
+       when the generated key no longer needed.
+
+       The routine may use "princ" to seed or alter the conversion
+       algorithm.
+
+       If the particular function called does not know how to make a
+       key of type "keytype", an error may be returned.
+
+       returns: errors
+ */
+
+krb5_error_code string_to_key (DECLARG(krb5_keytype, keytype),
+                                     DECLARG(krb5_keyblock *,keyblock),
+                                     DECLARG(krb5_data *,data),
+                                     DECLARG(krb5_principal, princ))
+OLDDECLARG(krb5_keytype, keytype)
+OLDDECLARG(krb5_keyblock *,keyblock)
+OLDDECLARG(krb5_data *,data)
+OLDDECLARG(krb5_principal, princ)
+{
+    char copystr[512];
+
+    register char *str = copystr;
+    register krb5_octet *key;
+
+    register unsigned temp,i;
+    register int j;
+    register long length;
+    static unsigned char *k_p;
+    static int forward;
+    register char *p_char;
+    static char k_char[64];
+    static des_key_schedule key_sked;
+
+#define min(A, B) ((A) < (B) ? (A): (B))
+
+#if defined(lint) || defined(SABER)
+    princ = princ;
+#endif
+
+    if ( keytype != KEYTYPE_DES )
+       return (KRB5_PROG_KEYTYPE_NOSUPP);
+
+    if ( !(keyblock->contents = (krb5_octet *)malloc(sizeof(des_cblock))) )
+       return(ENOMEM);
+
+#define cleanup() {memset(keyblock->contents, sizeof(des_cblock), 0);\
+                      (void) free((char *) keyblock->contents);}
+
+    keyblock->keytype = KEYTYPE_DES;
+    keyblock->length = sizeof(des_cblock);
+    key = keyblock->contents;
+    bzero(copystr, sizeof(copystr));
+    (void) strncpy(copystr, data->data, min(data->length,511));
+
+    /* convert copystr to des key */
+    forward = 1;
+    p_char = k_char;
+    length = strlen(str);
+
+    /* init key array for bits */
+    bzero(k_char,sizeof(k_char));
+
+#ifdef DEBUG
+    if (des_debug)
+       fprintf(stdout,
+               "\n\ninput str length = %d  string = %s\nstring = 0x ",
+               length,str);
+#endif
+
+    /* get next 8 bytes, strip parity, xor */
+    for (i = 1; i <= length; i++) {
+       /* get next input key byte */
+       temp = (unsigned int) *str++;
+#ifdef DEBUG
+       if (des_debug)
+           fprintf(stdout,"%02x ",temp & 0xff);
+#endif
+       /* loop through bits within byte, ignore parity */
+       for (j = 0; j <= 6; j++) {
+           if (forward)
+               *p_char++ ^= (int) temp & 01;
+           else
+               *--p_char ^= (int) temp & 01;
+           temp = temp >> 1;
+       } while (--j > 0);
+
+       /* check and flip direction */
+       if ((i%8) == 0)
+           forward = !forward;
+    }
+
+    /* now stuff into the key des_cblock, and force odd parity */
+    p_char = k_char;
+    k_p = (unsigned char *) key;
+
+    for (i = 0; i <= 7; i++) {
+       temp = 0;
+       for (j = 0; j <= 6; j++)
+           temp |= *p_char++ << (1+j);
+       *k_p++ = (unsigned char) temp;
+    }
+
+    /* fix key parity */
+    des_fixup_key_parity(key);
+
+    /* Now one-way encrypt it with the folded key */
+    (void) des_key_sched(key, key_sked);
+    (void) des_cbc_cksum((krb5_octet *)copystr, key, length, key_sked, key);
+    /* erase key_sked */
+    bzero((char *)key_sked, sizeof(key_sked));
+
+    /* now fix up key parity again */
+    des_fixup_key_parity(key);
+
+#ifdef DEBUG
+    if (des_debug)
+       fprintf(stdout,
+               "\nResulting string_to_key = 0x%x 0x%x\n",
+               *((unsigned long *) key),
+               *((unsigned long *) key+1));
+#endif
+    
+    return 0;
+}
diff --git a/src/lib/crypto/des/tables.h b/src/lib/crypto/des/tables.h
new file mode 100644 (file)
index 0000000..1367338
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * part of the Athena Kerberos encryption system
+ *
+ * spm 8/85
+ */
+
+/*
+ * Initial permutation, adjust to zero based subscript
+ */
+static char    IP[] = {
+       58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1,  2-1, 
+       60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1,  4-1, 
+       62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1,  6-1, 
+       64-1, 56-1, 48-1, 40-1, 32-1, 24-1, 16-1,  8-1, 
+       57-1, 49-1, 41-1, 33-1, 25-1, 17-1,  9-1,  1-1, 
+       59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1,  3-1, 
+       61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1,  5-1, 
+       63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,  7-1, 
+};
+
+/*
+ * Final permutation,  FP = IP^(-1) adjust to zero based subscript
+ */
+static char    FP[] = {
+       40-1,  8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1, 
+       39-1,  7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1, 
+       38-1,  6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1, 
+       37-1,  5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1, 
+       36-1,  4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1, 
+       35-1,  3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1, 
+       34-1,  2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1, 
+       33-1,  1-1, 41-1,  9-1, 49-1, 17-1, 57-1, 25-1, 
+};
+
+/* the E selection function, adjusted to zero based subscripts */
+static char    E[] = {
+       32-1,   1-1,    2-1,    3-1,    4-1,    5-1,
+        4-1,   5-1,    6-1,    7-1,    8-1,    9-1,
+        8-1,   9-1,    10-1,   11-1,   12-1,   13-1,
+       12-1,   13-1,   14-1,   15-1,   16-1,   17-1,
+       16-1,   17-1,   18-1,   19-1,   20-1,   21-1,
+       20-1,   21-1,   22-1,   23-1,   24-1,   25-1,
+       24-1,   25-1,   26-1,   27-1,   28-1,   29-1,
+       28-1,   29-1,   30-1,   31-1,   32-1,   1-1,
+};
+
+/* the P permutation, adjusted to zero based subscripts */
+static char    P[] = {
+       16-1,    7-1,   20-1,   21-1,   
+       29-1,   12-1,   28-1,   17-1,   
+        1-1,   15-1,   23-1,   26-1,   
+        5-1,   18-1,   31-1,   10-1,   
+        2-1,    8-1,   24-1,   14-1,   
+       32-1,   27-1,    3-1,    9-1,   
+       19-1,   13-1,   30-1,    6-1,   
+       22-1,   11-1,    4-1,   25-1,   
+};
+
+/* S tables, original form */
+static char    S[8][64] = {
+       14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
+        0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
+        4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
+       15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
+
+       15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
+        3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
+        0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
+       13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
+
+       10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
+       13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
+       13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
+        1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
+
+        7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
+       13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
+       10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
+        3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
+
+        2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
+       14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
+        4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
+       11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
+
+       12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
+       10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
+        9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
+        4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
+
+        4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
+       13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
+        1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
+        6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
+
+       13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
+        1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
+        7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
+        2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
+};
diff --git a/src/lib/crypto/des/verify.c b/src/lib/crypto/des/verify.c
new file mode 100644 (file)
index 0000000..54ac58e
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Program to test the correctness of the DES library
+ * implementation.
+ *
+ * exit returns         0 ==> success
+ *             -1 ==> error
+ */
+
+#ifndef        lint
+static char rcsid_verify_c[] =
+"$Id$";
+#endif /*lint*/
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/krb5_err.h>
+
+extern void com_err();
+extern int errno;
+extern krb5_cryptosystem_entry mit_des_cryptosystem_entry;
+extern des_cbc_cksum();
+extern des_ecb_encrypt();
+extern exit();
+char *progname;
+int nflag = 2;
+int vflag;
+int mflag;
+int zflag;
+int pid;
+int des_debug;
+
+krb5_encrypt_block eblock;
+krb5_keyblock keyblock;
+
+unsigned char cipher_text[64];
+unsigned char clear_text[64] = "Now is the time for all " ;
+unsigned char clear_text2[64] = "7654321 Now is the time for ";
+unsigned char clear_text3[64] = {2,0,0,0, 1,0,0,0};
+unsigned char output[64];
+unsigned char zero_text[8] = {0x0,0,0,0,0,0,0,0};
+unsigned char msb_text[8] = {0x0,0,0,0, 0,0,0,0x40}; /* to ANSI MSB */
+unsigned char *input;
+
+/* 0x0123456789abcdef */
+unsigned char default_key[8] = {
+    0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
+};
+unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f };
+unsigned char key3[8] = { 0x80,1,1,1,1,1,1,1 };
+des_cblock s_key;
+unsigned char default_ivec[8] = {
+    0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef
+};
+unsigned char *ivec;
+unsigned char zero_key[8] = {1,1,1,1,1,1,1,1}; /* just parity bits */
+int i,j;
+krb5_error_code retval;
+
+/*
+ * Can also add :
+ * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?)
+ */
+
+void
+main(argc,argv)
+    int argc;
+    char *argv[];
+{
+    /* Local Declarations */
+    long in_length;
+    void do_encrypt();
+    void do_decrypt();
+
+    progname=argv[0];          /* salt away invoking program */
+
+    /* Assume a long is four bytes */
+    if (sizeof(long) != 4) {
+       printf("\nERROR,  size of long is %d",sizeof(long));
+       exit(-1);
+    }
+
+    while (--argc > 0 && (*++argv)[0] == '-')
+       for (i=1; argv[0][i] != '\0'; i++) {
+           switch (argv[0][i]) {
+
+               /* debug flag */
+           case 'd':
+               des_debug=3;
+               continue;
+
+           case 'z':
+               zflag = 1;
+               continue;
+
+           case 'm':
+               mflag = 1;
+               continue;
+
+           default:
+               printf("%s: illegal flag \"%c\" ",
+                      progname,argv[0][i]);
+               exit(1);
+           }
+       };
+
+    if (argc) {
+       fprintf(stderr, "Usage: %s [-dmz]\n", progname);
+       exit(1);
+    }
+
+    /* do some initialisation */
+    initialize_krb5_error_table(); 
+
+    eblock.crypto_entry = &mit_des_cryptosystem_entry;
+    keyblock.keytype = KEYTYPE_DES;
+    keyblock.length = sizeof (des_cblock);
+
+    /* use known input and key */
+
+    /* ECB zero text zero key */
+    if (zflag) {
+       input = zero_text;
+       keyblock.contents = (krb5_octet *)zero_key;
+       if (retval = (*eblock.crypto_entry->process_key)(&eblock,&keyblock)) {
+           com_err("des verify", retval, "can't process zero key");
+           exit(-1);
+       }
+       printf("plaintext = key = 0, cipher = 0x8ca64de9c1b123a7\n");
+       do_encrypt(input,cipher_text);
+       printf("\tcipher  = (low to high bytes)\n\t\t");
+       for (j = 0; j<=7; j++)
+           printf("%02x ",cipher_text[j]);
+       printf("\n");
+       do_decrypt(output,cipher_text);
+       if (retval = (*eblock.crypto_entry->finish_key)(&eblock)) {
+           com_err("des verify", retval, "can't finish zero key");
+           exit(-1);
+       }
+       exit(0);
+    }
+
+    if (mflag) {
+       input = msb_text;
+       keyblock.contents = (krb5_octet *)key3;
+       if (retval = (*eblock.crypto_entry->process_key)(&eblock,&keyblock)) {
+           com_err("des verify", retval, "can't process key3");
+           exit(-1);
+       }
+       printf("plaintext = 0x00 00 00 00 00 00 00 40, ");
+       printf("key = 0, cipher = 0x??\n");
+       do_encrypt(input,cipher_text);
+       printf("\tcipher  = (low to high bytes)\n\t\t");
+       for (j = 0; j<=7; j++) {
+           printf("%02x ",cipher_text[j]);
+       }
+       printf("\n");
+       do_decrypt(output,cipher_text);
+       if (retval = (*eblock.crypto_entry->finish_key)(&eblock)) {
+           com_err("des verify", retval, "can't finish key3");
+           exit(-1);
+       }
+       exit(0);
+    }
+
+    /* ECB mode Davies and Price */
+    {
+       input = zero_text;
+       keyblock.contents = (krb5_octet *)key2;
+       if (retval = (*eblock.crypto_entry->process_key)(&eblock,&keyblock)) {
+           com_err("des verify", retval, "can't process key2");
+           exit(-1);
+       }
+       printf("Examples per FIPS publication 81, keys ivs and cipher\n");
+       printf("in hex.  These are the correct answers, see below for\n");
+       printf("the actual answers.\n\n");
+       printf("Examples per Davies and Price.\n\n");
+       printf("EXAMPLE ECB\tkey = 08192a3b4c5d6e7f\n");
+       printf("\tclear = 0\n");
+       printf("\tcipher = 25 dd ac 3e 96 17 64 67\n");
+       printf("ACTUAL ECB\n");
+       printf("\tclear \"%s\"\n", input);
+       do_encrypt(input,cipher_text);
+       printf("\tcipher  = (low to high bytes)\n\t\t");
+       for (j = 0; j<=7; j++)
+           printf("%02x ",cipher_text[j]);
+       printf("\n\n");
+       do_decrypt(output,cipher_text);
+       if (retval = (*eblock.crypto_entry->finish_key)(&eblock)) {
+           com_err("des verify", retval, "can't finish key2");
+           exit(-1);
+       }
+    }
+
+    /* ECB mode */
+    {
+       keyblock.contents = (krb5_octet *)default_key;
+       if (retval = (*eblock.crypto_entry->process_key)(&eblock,&keyblock)) {
+           com_err("des verify", retval, "can't process key2");
+           exit(-1);
+       }
+       input = clear_text;
+       ivec = default_ivec;
+       printf("EXAMPLE ECB\tkey = 0123456789abcdef\n");
+       printf("\tclear = \"Now is the time for all \"\n");
+       printf("\tcipher = 3f a4 0e 8a 98 4d 48 15 ...\n");
+       printf("ACTUAL ECB\n\tclear \"%s\"",input);
+       do_encrypt(input,cipher_text);
+       printf("\n\tcipher      = (low to high bytes)\n\t\t");
+       for (j = 0; j<=7; j++) {
+           printf("%02x ",cipher_text[j]);
+       }
+       printf("\n\n");
+       do_decrypt(output,cipher_text);
+    }
+
+    /* CBC mode */
+    printf("EXAMPLE CBC\tkey = 0123456789abcdef");
+    printf("\tiv = 1234567890abcdef\n");
+    printf("\tclear = \"Now is the time for all \"\n");
+    printf("\tcipher =\te5 c7 cd de 87 2b f2 7c\n");
+    printf("\t\t\t43 e9 34 00 8c 38 9c 0f\n");
+    printf("\t\t\t68 37 88 49 9a 7c 05 f6\n");
+
+    printf("ACTUAL CBC\n\tclear \"%s\"\n",input);
+    in_length = strlen(input);
+    if (retval =
+        (*eblock.crypto_entry->encrypt_func)((krb5_pointer) input,
+                                             (krb5_pointer) cipher_text,
+                                             (size_t) in_length, 
+                                            &eblock, (krb5_pointer) ivec)) {
+       com_err("des verify", retval, "can't encrypt");
+       exit(-1);
+    }
+    printf("\tciphertext = (low to high bytes)\n");
+    for (i = 0; i <= 7; i++) {
+       printf("\t\t");
+       for (j = 0; j <= 7; j++) {
+           printf("%02x ",cipher_text[i*8+j]);
+       }
+       printf("\n");
+    }
+    if (retval =
+        (*eblock.crypto_entry->decrypt_func)((krb5_pointer) cipher_text,
+                                             (krb5_pointer) clear_text,
+                                            (size_t) in_length, 
+                                            &eblock, (krb5_pointer) ivec)) {
+       com_err("des verify", retval, "can't decrypt");
+       exit(-1);
+    }
+    printf("\tdecrypted clear_text = \"%s\"\n",clear_text);
+
+    printf("EXAMPLE CBC checksum");
+    printf("\tkey =  0123456789abcdef\tiv =  1234567890abcdef\n");
+    printf("\tclear =\t\t\"7654321 Now is the time for \"\n");
+    printf("\tchecksum\t58 d2 e7 7e 86 06 27 33, ");
+    printf("or some part thereof\n");
+    input = clear_text2;
+    des_cbc_cksum(input,cipher_text,(long) strlen(input),eblock.priv,ivec,1);
+    printf("ACTUAL CBC checksum\n");
+    printf("\t\tencrypted cksum = (low to high bytes)\n\t\t");
+    for (j = 0; j<=7; j++)
+       printf("%02x ",cipher_text[j]);
+    printf("\n\n");
+    if (retval = (*eblock.crypto_entry->finish_key)(&eblock)) {
+       com_err("des verify", retval, "can't finish key2");
+       exit(-1);
+    }
+    exit(0);
+}
+
+void
+flip(array)
+    char *array;
+{
+    register old,new,i,j;
+    /* flips the bit order within each byte from 0 lsb to 0 msb */
+    for (i = 0; i<=7; i++) {
+       old = *array;
+       new = 0;
+       for (j = 0; j<=7; j++) {
+           if (old & 01)
+               new = new | 01;
+           if (j < 7) {
+               old = old >> 1;
+               new = new << 1;
+           }
+       }
+       *array = new;
+       array++;
+    }
+}
+
+void
+do_encrypt(in,out)
+    char *in;
+    char *out;
+{
+    for (i =1; i<=nflag; i++) {
+       des_ecb_encrypt(in,out,(struct des_ks_struct *)eblock.priv,1);
+       if (des_debug) {
+           printf("\nclear %s\n",in);
+           for (j = 0; j<=7; j++)
+               printf("%02 X ",in[j] & 0xff);
+           printf("\tcipher ");
+           for (j = 0; j<=7; j++)
+               printf("%02X ",out[j] & 0xff);
+       }
+    }
+}
+
+void
+do_decrypt(in,out)
+    char *out;
+    char *in;
+    /* try to invert it */
+{
+    for (i =1; i<=nflag; i++) {
+       des_ecb_encrypt(out,in,(struct des_ks_struct *)eblock.priv,0);
+       if (des_debug) {
+           printf("clear %s\n",in);
+           for (j = 0; j<=7; j++)
+               printf("%02X ",in[j] & 0xff);
+           printf("\tcipher ");
+           for (j = 0; j<=7; j++)
+               printf("%02X ",out[j] & 0xff);
+       }
+    }
+}
diff --git a/src/lib/crypto/des/weak_key.c b/src/lib/crypto/des/weak_key.c
new file mode 100644 (file)
index 0000000..ffb9c64
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1989 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * 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.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char weak_key_c[] =
+"$Header$";
+#endif /* !lint & !SABER */
+
+#include <krb5/krb5.h>
+#include <krb5/des.h>
+#include <krb5/ext-proto.h>
+#include "des_internal.h"
+
+/*
+ * The following are the weak DES keys:
+ */
+static des_cblock weak[16] = {
+    /* weak keys */
+    {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+    {0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe},
+    {0x1f,0x1f,0x1f,0x1f,0x0e,0x0e,0x0e,0x0e},
+    {0xe0,0xe0,0xe0,0xe0,0xf1,0xf1,0xf1,0xf1},
+
+    /* semi-weak */
+    {0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe},
+    {0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01},
+
+    {0x1f,0xe0,0x1f,0xe0,0x0e,0xf1,0x0e,0xf1},
+    {0xe0,0x1f,0xe0,0x1f,0xf1,0x0e,0xf1,0x0e},
+
+    {0x01,0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1},
+    {0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1,0x01},
+
+    {0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e,0xfe},
+    {0xfe,0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e},
+
+    {0x01,0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e},
+    {0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e,0x01},
+
+    {0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1,0xfe},
+    {0xfe,0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1}
+};
+
+/*
+ * des_is_weak_key: returns true iff key is a [semi-]weak des key.
+ *
+ * Requires: key has correct odd parity.
+ */
+int
+des_is_weak_key(key)
+     des_cblock key;
+{
+    int i;
+    des_cblock *weak_p = weak;
+
+    for (i = 0; i < (sizeof(weak)/sizeof(des_cblock)); i++) {
+       if (!bcmp((char *)weak_p++,(char *)key,sizeof(des_cblock)))
+           return 1;
+    }
+
+    return 0;
+}