/* Portable C code to create DES key schedules from user-provided keys * This doesn't have to be fast unless you're cracking keys or UNIX * passwords */ #include /* Key schedule-related tables from FIPS-46 */ /* permuted choice table (key) */ static unsigned char pc1[] = { 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 }; /* number left rotations of pc1 */ static unsigned char totrot[] = { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; /* permuted choice key (table) */ static unsigned char pc2[] = { 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 }; /* End of DES-defined tables */ /* bit 0 is left-most in byte */ static int bytebit[] = { 0200,0100,040,020,010,04,02,01 }; /* Generate key schedule for encryption or decryption * depending on the value of "decrypt" */ static void deskey(k,key/*,decrypt*/) unsigned long k[16][2]; /* Key schedule array */ const unsigned char *key; /* 64 bits (will use only 56) */ /*int decrypt;*/ /* 0 = encrypt, 1 = decrypt */ { unsigned char pc1m[56]; /* place to modify pc1 into */ unsigned char pcr[56]; /* place to rotate pc1 into */ register int i,j,l; int m, n; unsigned char ks[8]; for (j=0; j<56; j++) { /* convert pc1 to bits of key */ l=pc1[j]-1; /* integer bit location */ m = l & 07; /* find bit */ n = key[l >> 3] & bytebit[m]; pc1m[j]=n ? 1 : 0; /* find which key byte l is in */ /* and which bit of that byte */ /* and store 1-bit result */ } for (i=0; i<16; i++) { /* key chunk for each iteration */ memset(ks,0,sizeof(ks)); /* Clear key schedule */ for (j=0; j<56; j++) { /* rotate pc1 the right amount */ l=j+totrot[/*decrypt? 15-i :*/ i]; pcr[j] = pc1m[l<(j<28? 28 : 56) ? l: l-28]; /* rotate left and right halves independently */ } for (j=0; j<48; j++){ /* select bits individually */ /* check bit that goes to ks[j] */ if (pcr[pc2[j]-1]){ /* mask it in if it's there */ l= j % 6; ks[j/6] |= bytebit[l] >> 2; } } /* Now convert to packed odd/even interleaved form */ k[i][0] = ((long)ks[0] << 24) | ((long)ks[2] << 16) | ((long)ks[4] << 8) | ((long)ks[6]); k[i][1] = ((long)ks[1] << 24) | ((long)ks[3] << 16) | ((long)ks[5] << 8) | ((long)ks[7]); } }