/* * deskey.c * 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. * * Version: $Id: deskey.c,v 1.1 2003/02/07 18:46:51 chessing Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright 2000 The FreeRADIUS server project * FIXME add copyrights */ #include #include "des.h" /* 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" */ void deskey(k,key,decrypt) unsigned long k[16][2]; /* Key schedule array */ 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 */ int i,j,l; int m; 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 */ pc1m[j]=(key[l>>3] & /* find which key byte l is in */ bytebit[m]) /* and which bit of that byte */ ? 1 : 0; /* 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 */ pcr[j] = pc1m[(l=j+totrot[decrypt? 15-i : i])<(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]); if(Asmversion){ /* The assembler versions pre-shift each subkey 2 bits * so the Spbox indexes are already computed */ k[i][0] <<= 2; k[i][1] <<= 2; } } }