|
|
1.1 ! root 1: /* ! 2: * $Source: /mit/kerberos/src/lib/des/RCS/key_sched.c,v $ ! 3: * $Author: wesommer $ ! 4: * ! 5: * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute ! 6: * of Technology. ! 7: * ! 8: * For copying and distribution information, please see the file ! 9: * <mit-copyright.h>. ! 10: * ! 11: * This routine computes the DES key schedule given a key. The ! 12: * permutations and shifts have been done at compile time, resulting ! 13: * in a direct one-step mapping from the input key to the key ! 14: * schedule. ! 15: * ! 16: * Also checks parity and weak keys. ! 17: * ! 18: * Watch out for the subscripts -- most effectively start at 1 instead ! 19: * of at zero. Maybe some bugs in that area. ! 20: * ! 21: * DON'T change the data types for arrays and such, or it will either ! 22: * break or run slower. This was optimized for Uvax2. ! 23: * ! 24: * In case the user wants to cache the computed key schedule, it is ! 25: * passed as an arg. Also implies that caller has explicit control ! 26: * over zeroing both the key schedule and the key. ! 27: * ! 28: * All registers labeled imply Vax using the Ultrix or 4.2bsd compiler. ! 29: * ! 30: * Originally written 6/85 by Steve Miller, MIT Project Athena. ! 31: */ ! 32: ! 33: #ifndef lint ! 34: static char rcsid_key_sched_c[] = ! 35: "$Header: key_sched.c,v 4.7 89/01/23 15:42:17 wesommer Exp $"; ! 36: #endif lint ! 37: ! 38: #include <mit-copyright.h> ! 39: #include "des_internal.h" ! 40: #include <stdio.h> ! 41: ! 42: #include "des.h" ! 43: #include "key_perm.h" ! 44: ! 45: extern int des_debug; ! 46: extern rev_swap_bit_pos_0(); ! 47: ! 48: typedef char key[64]; ! 49: /* the following are really void but cc86 doesnt allow it */ ! 50: int make_key_sched(); ! 51: ! 52: ! 53: int ! 54: des_key_sched(k,schedule) ! 55: register des_cblock k; /* r11 */ ! 56: des_key_schedule schedule; ! 57: { ! 58: /* better pass 8 bytes, length not checked here */ ! 59: ! 60: register i, j, n; /* i = r10, j = r9, n = r8 */ ! 61: register unsigned int temp; /* r7 */ ! 62: register char *p_char; /* r6 */ ! 63: static key k_char; ! 64: i = 8; ! 65: n = 0; ! 66: p_char = k_char; ! 67: ! 68: #ifdef lint ! 69: n = n; /* fool it in case of VAXASM */ ! 70: #endif ! 71: #ifdef DEBUG ! 72: if (des_debug) ! 73: fprintf(stderr,"\n\ninput key, left to right = "); ! 74: #endif ! 75: ! 76: if (!des_check_key_parity(k)) /* bad parity --> return -1 */ ! 77: return(-1); ! 78: ! 79: do { ! 80: /* get next input key byte */ ! 81: #ifdef DEBUG ! 82: if (des_debug) ! 83: fprintf(stderr,"%02x ",*k & 0xff); ! 84: #endif ! 85: temp = (unsigned int) ((unsigned char) *k++); ! 86: j = 8; ! 87: ! 88: do { ! 89: #ifndef VAXASM ! 90: *p_char++ = (int) temp & 01; ! 91: temp = temp >> 1; ! 92: #else ! 93: asm("bicb3 $-2,r7,(r8)+[r6]"); ! 94: asm("rotl $-1,r7,r7"); ! 95: #endif ! 96: } while (--j > 0); ! 97: } while (--i > 0); ! 98: ! 99: #ifdef DEBUG ! 100: if (des_debug) { ! 101: p_char = k_char; ! 102: fprintf(stderr,"\nKey bits, from zero to 63"); ! 103: for (i = 0; i <= 7; i++) { ! 104: fprintf(stderr,"\n\t"); ! 105: for (j = 0; j <=7; j++) ! 106: fprintf(stderr,"%d ",*p_char++); ! 107: } ! 108: } ! 109: #else ! 110: #ifdef lint ! 111: p_char = p_char; ! 112: #endif ! 113: #endif ! 114: ! 115: /* check against weak keys */ ! 116: k -= sizeof(des_cblock); ! 117: ! 118: if (des_is_weak_key(k)) ! 119: return(-2); ! 120: ! 121: make_key_sched(k_char,schedule); ! 122: ! 123: /* if key was good, return 0 */ ! 124: return 0; ! 125: } ! 126: ! 127: static int ! 128: make_key_sched(Key,Schedule) ! 129: register key Key; /* r11 */ ! 130: des_key_schedule Schedule; ! 131: { ! 132: /* ! 133: * The key has been converted to an array to make this run faster; ! 134: * on a microvax 2, this routine takes about 3.5ms. The code and ! 135: * size of the arrays has been played with to get it as fast as ! 136: * possible. ! 137: * ! 138: * Don't change the order of the declarations below without ! 139: * checking the assembler code to make sure that things are still ! 140: * where it expects them. ! 141: */ ! 142: ! 143: /* r10, unroll by AUTH_DES_ITER */ ! 144: register int iter = AUTH_DES_ITER ; ! 145: register unsigned long *k; /* r9 */ ! 146: register int *kp; /* r8 */ ! 147: register unsigned long temp; /* r7 */ ! 148: ! 149: kp = (int *) key_perm; ! 150: k = (unsigned long *) Schedule; ! 151: ! 152: do { ! 153: /* ! 154: * create the Key schedule ! 155: * ! 156: * put into lsb first order (lsb is bit 0) ! 157: */ ! 158: ! 159: /* ! 160: * On the uvax2, this C code below is as fast as straight ! 161: * assembler, so just use C code below. ! 162: */ ! 163: temp = 0; ! 164: #ifdef LSBFIRST ! 165: #define BIT(x) x ! 166: #else ! 167: #ifdef notdef ! 168: #define BIT(x) rev_swap_bit_pos_0(x) ! 169: #else ! 170: #define BIT(x) x ! 171: #endif ! 172: #endif ! 173: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(0)); ! 174: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(1)); ! 175: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(2)); ! 176: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(3)); ! 177: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(4)); ! 178: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(5)); ! 179: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(6)); ! 180: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(7)); ! 181: ! 182: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(8)); ! 183: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(9)); ! 184: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(10)); ! 185: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(11)); ! 186: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(12)); ! 187: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(13)); ! 188: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(14)); ! 189: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(15)); ! 190: ! 191: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(16)); ! 192: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(17)); ! 193: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(18)); ! 194: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(19)); ! 195: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(20)); ! 196: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(21)); ! 197: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(22)); ! 198: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(23)); ! 199: ! 200: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(24)); ! 201: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(25)); ! 202: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(26)); ! 203: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(27)); ! 204: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(28)); ! 205: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(29)); ! 206: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(30)); ! 207: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(31)); ! 208: ! 209: *k++ = temp; ! 210: temp = 0; ! 211: ! 212: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(0)); ! 213: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(1)); ! 214: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(2)); ! 215: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(3)); ! 216: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(4)); ! 217: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(5)); ! 218: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(6)); ! 219: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(7)); ! 220: ! 221: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(8)); ! 222: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(9)); ! 223: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(10)); ! 224: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(11)); ! 225: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(12)); ! 226: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(13)); ! 227: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(14)); ! 228: if ((unsigned) Key[(int) *kp++]) temp |= (1<< BIT(15)); ! 229: ! 230: *k++ = temp; ! 231: ! 232: } while (--iter > 0); ! 233: ! 234: #ifdef DEBUG ! 235: if (des_debug) { ! 236: char *n; ! 237: int q; ! 238: fprintf(stderr,"\nKey Schedule, left to right"); ! 239: for (i = 0; i < AUTH_DES_ITER; i++) { ! 240: n = (char *) &Schedule[i]; ! 241: fprintf(stderr,"\n"); ! 242: for (q = 0; q <= 7; q++) ! 243: fprintf(stderr,"%02x ",*n++ & 0xff); ! 244: } ! 245: fprintf(stderr,"\n"); ! 246: } ! 247: #endif ! 248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.