tacacs-F4.0.4.28/fdes.c (107 lines of code) (raw):

/* * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved * Copyright (c) 1991 David G. Koontz. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms. Inclusion in a product or release * as part of a package for sale is not agreed to. Storing this * software in a nonvolatile storage device characterized as an * integrated circuit providing read only memory (ROM), either as * source code or machine executeable instructions is similarly not * agreed to. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE * IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE */ #ifndef lint char Copyright[]= "@(#) Copyright (c) 1991 David G. Koontz\n All rights reserved.\n"; #endif /* * fdes.c - faster implementation of DES algorithm. */ #include "config.h" #include "fdes.h" #include "des_ip.h" #include "des_iip.h" #include "des_key.h" #include "des_s_p.h" /* Key Schedule permuted for S Box input: */ static union block_48 K_S[16]; static union block_48 *key_start; static int des_mode; #pragma weak tac_des #pragma weak tac_des_loadkey #pragma weak tac_set_des_mode void tac_set_des_mode(int encode) { if (encode) { key_start = &K_S[0]; des_mode = SHIFT_FOR_ENCRYPT; } else { key_start = &K_S[15]; des_mode = SHIFT_FOR_DECRYPT; } } void tac_des_loadkey(unsigned char *key, int shift) { unsigned i,j; union block_48 data; if (!shift) /* key lookup table always shifts */ for (i = 0; i < 8; i++) data.string[i] = key[i] >> 1; else for (i = 0; i < 8; i++) data.string[i] = key[i]; for ( j = 0; j < 16; j++) /* key load must be re-entrant */ K_S[j].AB[0] = K_S[j].AB[1] = 0; for (i = 0; i < 8; i++) { /* 8 bytes (56 bits) of key */ for(j = 0; j < 16;j++) { /* load K_S[0-16] byte at a time */ K_S[j].AB[0] |= KEY[i][data.string[i]][j][0]; K_S[j].AB[1] |= KEY[i][data.string[i]][j][1]; } } } static void no_ip_des(union LR_block *block) { unsigned int round; int shift; unsigned long temp_f; union block_48 pre_S, *k_s; k_s = key_start; shift = des_mode; for (round = 0; round < 8; round++) { /* f(R,K), 16 double rounds */ /* Expansion Permutation, E XOR K */ temp_f = block->LR[RR]; /* L/R reg. is R31,R0...R30 (D0-D31) format */ pre_S.AB[0] = temp_f & 0x3f3f3f3f ^ k_s->AB[0]; /* S1S3S5S7 */ pre_S.AB[1] = ((temp_f >> 4 | temp_f << 28) & 0x3f3f3f3f) ^ k_s->AB[1]; k_s += shift; /* S2S4S6S8 */ /* S Box and P lookup: temp_f = f(R,K) */ temp_f = S_P[0][pre_S.string[S1]] | S_P[1][pre_S.string[S2]] | S_P[2][pre_S.string[S3]] | S_P[3][pre_S.string[S4]] | S_P[4][pre_S.string[S5]] | S_P[5][pre_S.string[S6]] | S_P[6][pre_S.string[S7]] | S_P[7][pre_S.string[S8]]; /* f(R,K) EXOR L */ temp_f ^= block->LR[LL]; /* temp_f is new R */ block->LR[LL] = temp_f; /* update L register */ /* Repeat round (temp_f carried through) */ pre_S.AB[0] = temp_f & 0x3f3f3f3f ^ k_s->AB[0]; pre_S.AB[1] = ((temp_f >> 4 | temp_f << 28) & 0x3f3f3f3f) ^ k_s->AB[1]; k_s += shift; temp_f = S_P[0][pre_S.string[S1]] | S_P[1][pre_S.string[S2]] | S_P[2][pre_S.string[S3]] | S_P[3][pre_S.string[S4]] | S_P[4][pre_S.string[S5]] | S_P[5][pre_S.string[S6]] | S_P[6][pre_S.string[S7]] | S_P[7][pre_S.string[S8]]; temp_f ^= block->LR[RR]; /* L is old R */ block->LR[RR] = temp_f; /* update R register */ } /* had L/R swap here */ } void tac_des(union LR_block *block) { unsigned long temp; union LR_block data; data.LR[LL] = block->LR[LL]; data.LR[RR] = block->LR[RR]; temp = IP[ 0][data.string[0]] | IP[ 1][data.string[1]] | IP[ 2][data.string[2]] | IP[ 3][data.string[3]] | IP[ 4][data.string[4]] | IP[ 5][data.string[5]] | IP[ 6][data.string[6]] | IP[ 7][data.string[7]]; data.LR[LL] = IP[ 8][data.string[0]] | IP[ 9][data.string[1]] | IP[10][data.string[2]] | IP[11][data.string[3]] | IP[12][data.string[4]] | IP[13][data.string[5]] | IP[14][data.string[6]] | IP[15][data.string[7]]; data.LR[RR] = temp; no_ip_des(&data); temp = IIP[ 0][data.string[0]] | IIP[ 1][data.string[1]] | IIP[ 2][data.string[2]] | IIP[ 3][data.string[3]] | IIP[ 4][data.string[4]] | IIP[ 5][data.string[5]] | IIP[ 6][data.string[6]] | IIP[ 7][data.string[7]]; block->LR[AA] = IIP[ 8][data.string[0]] | IIP[ 9][data.string[1]] | IIP[10][data.string[2]] | IIP[11][data.string[3]] | IIP[12][data.string[4]] | IIP[13][data.string[5]] | IIP[14][data.string[6]] | IIP[15][data.string[7]]; block->LR[BB] = temp; }