op25/op25/gr-op25/lib/deskey.c

125 lines
3.2 KiB
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
*/
#include <string.h>
#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(DES_KS k,unsigned char *key,int decrypt)
/* Key schedule array */
/* 64 bits (will use only 56) */
/* 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;
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;
}
}
}
/* Generate key schedule for triple DES in E-D-E (or D-E-D) mode.
*
* The key argument is taken to be 24 bytes. The first 8 bytes are K1
* for the first stage, the second 8 bytes are K2 for the middle stage
* and the third 8 bytes are K3 for the last stage
*/
void
des3key(DES3_KS k,unsigned char *key,int decrypt)
/* 192 bits (will use only 168) */
/* 0 = encrypt, 1 = decrypt */
{
if(!decrypt){
deskey(&k[0],&key[0],0);
deskey(&k[16],&key[8],1);
deskey(&k[32],&key[16],0);
} else {
deskey(&k[32],&key[0],1);
deskey(&k[16],&key[8],0);
deskey(&k[0],&key[16],1);
}
}