--- /dev/null
+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))
--- /dev/null
+/*
+ * $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;
+}
+
--- /dev/null
+/*
+ * $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;
+}
--- /dev/null
+/*
+ * $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)
+ };
--- /dev/null
+/*
+ * $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;
+}
+
--- /dev/null
+/*
+ * $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*/
--- /dev/null
+/*
+ * $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;
+ }
+}
--- /dev/null
+/*
+ * $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 */
+}
--- /dev/null
+/*
+ * $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;
+}
--- /dev/null
+/*
+ * $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;
+}
--- /dev/null
+/*
+ * $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);
+}
--- /dev/null
+/*
+ * $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
+}
--- /dev/null
+/*
+ * $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);
+}
--- /dev/null
+/*
+ * $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));
+}
--- /dev/null
+/*
+ * $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);
+}
--- /dev/null
+/*
+ * $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");
+}
--- /dev/null
+/*
+ * $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");
+}
--- /dev/null
+/*
+ * $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 */
+}
--- /dev/null
+/*
+ * $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");
+}
--- /dev/null
+/*
+ * $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");
+}
--- /dev/null
+/*
+ * $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");
+}
--- /dev/null
+/*
+ * $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);
+}
--- /dev/null
+/*
+ * $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;
+ }
+}
--- /dev/null
+/*
+ * $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;
+ }
+}
--- /dev/null
+/*
+ * $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;
+}
--- /dev/null
+/*
+ * $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;
+}
--- /dev/null
+/*
+ * $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,
+};
--- /dev/null
+/*
+ * $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);
+ }
+ }
+}
--- /dev/null
+/*
+ * $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;
+}