1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 31*7c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 32*7c478bd9Sstevel@tonic-gate */ 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate * Warning! Things are arranged very carefully in this file to 36*7c478bd9Sstevel@tonic-gate * allow read-only data to be moved to the text segment. The 37*7c478bd9Sstevel@tonic-gate * various DES tables must appear before any function definitions 38*7c478bd9Sstevel@tonic-gate * (this is arranged by including them immediately below) and partab 39*7c478bd9Sstevel@tonic-gate * must also appear before and function definitions 40*7c478bd9Sstevel@tonic-gate * This arrangement allows all data up through the first text to 41*7c478bd9Sstevel@tonic-gate * be moved to text. 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * Fast (?) software implementation of DES 46*7c478bd9Sstevel@tonic-gate * Has been seen going at 2000 bytes/sec on a Sun-2 47*7c478bd9Sstevel@tonic-gate * Works on a VAX too. 48*7c478bd9Sstevel@tonic-gate * Won't work without 8 bit chars and 32 bit longs 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 52*7c478bd9Sstevel@tonic-gate #include <des/des.h> 53*7c478bd9Sstevel@tonic-gate #include <des/softdes.h> 54*7c478bd9Sstevel@tonic-gate #include <des/desdata.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate static void des_setkey(u_char userkey[8], struct deskeydata *kd, 58*7c478bd9Sstevel@tonic-gate unsigned int dir); 59*7c478bd9Sstevel@tonic-gate static void des_encrypt(u_char *data, struct deskeydata *kd); 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate #define btst(k, b) (k[b >> 3] & (0x80 >> (b & 07))) 62*7c478bd9Sstevel@tonic-gate #define BIT28 (1<<28) 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* 65*7c478bd9Sstevel@tonic-gate * Software encrypt or decrypt a block of data (multiple of 8 bytes) 66*7c478bd9Sstevel@tonic-gate * Do the CBC ourselves if needed. 67*7c478bd9Sstevel@tonic-gate */ 68*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 69*7c478bd9Sstevel@tonic-gate int 70*7c478bd9Sstevel@tonic-gate _des_crypt(char *buf, size_t len, struct desparams *desp) 71*7c478bd9Sstevel@tonic-gate { 72*7c478bd9Sstevel@tonic-gate short i; 73*7c478bd9Sstevel@tonic-gate uint_t mode; 74*7c478bd9Sstevel@tonic-gate uint_t dir; 75*7c478bd9Sstevel@tonic-gate char nextiv[8]; 76*7c478bd9Sstevel@tonic-gate struct deskeydata softkey; 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate mode = desp->des_mode; 79*7c478bd9Sstevel@tonic-gate dir = desp->des_dir; 80*7c478bd9Sstevel@tonic-gate des_setkey(desp->des_key, &softkey, dir); 81*7c478bd9Sstevel@tonic-gate while (len != 0) { 82*7c478bd9Sstevel@tonic-gate switch (mode) { 83*7c478bd9Sstevel@tonic-gate case CBC: 84*7c478bd9Sstevel@tonic-gate switch (dir) { 85*7c478bd9Sstevel@tonic-gate case ENCRYPT: 86*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) 87*7c478bd9Sstevel@tonic-gate buf[i] ^= desp->des_ivec[i]; 88*7c478bd9Sstevel@tonic-gate des_encrypt((u_char *)buf, &softkey); 89*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) 90*7c478bd9Sstevel@tonic-gate desp->des_ivec[i] = buf[i]; 91*7c478bd9Sstevel@tonic-gate break; 92*7c478bd9Sstevel@tonic-gate case DECRYPT: 93*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) 94*7c478bd9Sstevel@tonic-gate nextiv[i] = buf[i]; 95*7c478bd9Sstevel@tonic-gate des_encrypt((u_char *)buf, &softkey); 96*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) { 97*7c478bd9Sstevel@tonic-gate buf[i] ^= desp->des_ivec[i]; 98*7c478bd9Sstevel@tonic-gate desp->des_ivec[i] = nextiv[i]; 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate break; 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate break; 103*7c478bd9Sstevel@tonic-gate case ECB: 104*7c478bd9Sstevel@tonic-gate des_encrypt((u_char *)buf, &softkey); 105*7c478bd9Sstevel@tonic-gate break; 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate buf += 8; 108*7c478bd9Sstevel@tonic-gate len -= 8; 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate return (1); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * Set the key and direction for an encryption operation 116*7c478bd9Sstevel@tonic-gate * We build the 16 key entries here 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 119*7c478bd9Sstevel@tonic-gate static void 120*7c478bd9Sstevel@tonic-gate des_setkey(u_char userkey[8], struct deskeydata *kd, unsigned int dir) 121*7c478bd9Sstevel@tonic-gate { 122*7c478bd9Sstevel@tonic-gate int32_t C, D; 123*7c478bd9Sstevel@tonic-gate short i; 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * First, generate C and D by permuting 127*7c478bd9Sstevel@tonic-gate * the key. The low order bit of each 128*7c478bd9Sstevel@tonic-gate * 8-bit char is not used, so C and D are only 28 129*7c478bd9Sstevel@tonic-gate * bits apiece. 130*7c478bd9Sstevel@tonic-gate */ 131*7c478bd9Sstevel@tonic-gate { 132*7c478bd9Sstevel@tonic-gate short bit; 133*7c478bd9Sstevel@tonic-gate short *pcc = (short *)PC1_C, *pcd = (short *)PC1_D; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate C = D = 0; 136*7c478bd9Sstevel@tonic-gate for (i = 0; i < 28; i++) { 137*7c478bd9Sstevel@tonic-gate C <<= 1; 138*7c478bd9Sstevel@tonic-gate D <<= 1; 139*7c478bd9Sstevel@tonic-gate bit = *pcc++; 140*7c478bd9Sstevel@tonic-gate if (btst(userkey, bit)) 141*7c478bd9Sstevel@tonic-gate C |= 1; 142*7c478bd9Sstevel@tonic-gate bit = *pcd++; 143*7c478bd9Sstevel@tonic-gate if (btst(userkey, bit)) 144*7c478bd9Sstevel@tonic-gate D |= 1; 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate /* 148*7c478bd9Sstevel@tonic-gate * To generate Ki, rotate C and D according 149*7c478bd9Sstevel@tonic-gate * to schedule and pick up a permutation 150*7c478bd9Sstevel@tonic-gate * using PC2. 151*7c478bd9Sstevel@tonic-gate */ 152*7c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 153*7c478bd9Sstevel@tonic-gate chunk_t *c; 154*7c478bd9Sstevel@tonic-gate short j, k, bit; 155*7c478bd9Sstevel@tonic-gate int bbit; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * Do the "left shift" (rotate) 159*7c478bd9Sstevel@tonic-gate * We know we always rotate by either 1 or 2 bits 160*7c478bd9Sstevel@tonic-gate * the shifts table tells us if its 2 161*7c478bd9Sstevel@tonic-gate */ 162*7c478bd9Sstevel@tonic-gate C <<= 1; 163*7c478bd9Sstevel@tonic-gate if (C & BIT28) 164*7c478bd9Sstevel@tonic-gate C |= 1; 165*7c478bd9Sstevel@tonic-gate D <<= 1; 166*7c478bd9Sstevel@tonic-gate if (D & BIT28) 167*7c478bd9Sstevel@tonic-gate D |= 1; 168*7c478bd9Sstevel@tonic-gate if (shifts[i]) { 169*7c478bd9Sstevel@tonic-gate C <<= 1; 170*7c478bd9Sstevel@tonic-gate if (C & BIT28) 171*7c478bd9Sstevel@tonic-gate C |= 1; 172*7c478bd9Sstevel@tonic-gate D <<= 1; 173*7c478bd9Sstevel@tonic-gate if (D & BIT28) 174*7c478bd9Sstevel@tonic-gate D |= 1; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * get Ki. Note C and D are concatenated. 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate bit = 0; 180*7c478bd9Sstevel@tonic-gate switch (dir) { 181*7c478bd9Sstevel@tonic-gate case ENCRYPT: 182*7c478bd9Sstevel@tonic-gate c = &kd->keyval[i]; 183*7c478bd9Sstevel@tonic-gate break; 184*7c478bd9Sstevel@tonic-gate case DECRYPT: 185*7c478bd9Sstevel@tonic-gate c = &kd->keyval[15 - i]; 186*7c478bd9Sstevel@tonic-gate break; 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate c->long0 = 0; 189*7c478bd9Sstevel@tonic-gate c->long1 = 0; 190*7c478bd9Sstevel@tonic-gate bbit = (1 << 5) << 24; 191*7c478bd9Sstevel@tonic-gate for (j = 0; j < 4; j++) { 192*7c478bd9Sstevel@tonic-gate for (k = 0; k < 6; k++) { 193*7c478bd9Sstevel@tonic-gate if (C & (BIT28 >> PC2_C[bit])) 194*7c478bd9Sstevel@tonic-gate c->long0 |= bbit >> k; 195*7c478bd9Sstevel@tonic-gate if (D & (BIT28 >> PC2_D[bit])) 196*7c478bd9Sstevel@tonic-gate c->long1 |= bbit >> k; 197*7c478bd9Sstevel@tonic-gate bit++; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate bbit >>= 8; 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * Do an encryption operation 208*7c478bd9Sstevel@tonic-gate * Much pain is taken (with preprocessor) to avoid loops so the compiler 209*7c478bd9Sstevel@tonic-gate * can do address arithmetic instead of doing it at runtime. 210*7c478bd9Sstevel@tonic-gate * Note that the byte-to-chunk conversion is necessary to guarantee 211*7c478bd9Sstevel@tonic-gate * processor byte-order independence. 212*7c478bd9Sstevel@tonic-gate */ 213*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 214*7c478bd9Sstevel@tonic-gate static void 215*7c478bd9Sstevel@tonic-gate des_encrypt(u_char *data, struct deskeydata *kd) 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate chunk_t work1, work2; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate /* 220*7c478bd9Sstevel@tonic-gate * Initial permutation 221*7c478bd9Sstevel@tonic-gate * and byte to chunk conversion 222*7c478bd9Sstevel@tonic-gate */ 223*7c478bd9Sstevel@tonic-gate { 224*7c478bd9Sstevel@tonic-gate const uint32_t *lp; 225*7c478bd9Sstevel@tonic-gate uint32_t l0, l1, w; 226*7c478bd9Sstevel@tonic-gate short i, pbit; 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate work1.byte0 = data[0]; 229*7c478bd9Sstevel@tonic-gate work1.byte1 = data[1]; 230*7c478bd9Sstevel@tonic-gate work1.byte2 = data[2]; 231*7c478bd9Sstevel@tonic-gate work1.byte3 = data[3]; 232*7c478bd9Sstevel@tonic-gate work1.byte4 = data[4]; 233*7c478bd9Sstevel@tonic-gate work1.byte5 = data[5]; 234*7c478bd9Sstevel@tonic-gate work1.byte6 = data[6]; 235*7c478bd9Sstevel@tonic-gate work1.byte7 = data[7]; 236*7c478bd9Sstevel@tonic-gate l0 = l1 = 0; 237*7c478bd9Sstevel@tonic-gate w = work1.long0; 238*7c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 0; i < 32; i++) { 239*7c478bd9Sstevel@tonic-gate if (w & *lp++) { 240*7c478bd9Sstevel@tonic-gate pbit = IPtab[i]; 241*7c478bd9Sstevel@tonic-gate if (pbit < 32) 242*7c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 243*7c478bd9Sstevel@tonic-gate else 244*7c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate w = work1.long1; 248*7c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 32; i < 64; i++) { 249*7c478bd9Sstevel@tonic-gate if (w & *lp++) { 250*7c478bd9Sstevel@tonic-gate pbit = IPtab[i]; 251*7c478bd9Sstevel@tonic-gate if (pbit < 32) 252*7c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 253*7c478bd9Sstevel@tonic-gate else 254*7c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate work2.long0 = l0; 258*7c478bd9Sstevel@tonic-gate work2.long1 = l1; 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate /* 262*7c478bd9Sstevel@tonic-gate * Expand 8 bits of 32 bit R to 48 bit R 263*7c478bd9Sstevel@tonic-gate */ 264*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 265*7c478bd9Sstevel@tonic-gate #define do_R_to_ER(op, b) { \ 266*7c478bd9Sstevel@tonic-gate struct R_to_ER *p = \ 267*7c478bd9Sstevel@tonic-gate (struct R_to_ER *)&R_to_ER_tab[b][R.byte##b]; \ 268*7c478bd9Sstevel@tonic-gate e0 op p->l0; \ 269*7c478bd9Sstevel@tonic-gate e1 op p->l1; \ 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate #else 272*7c478bd9Sstevel@tonic-gate #define do_R_to_ER(op, b) { \ 273*7c478bd9Sstevel@tonic-gate /*CSTYLED*/ \ 274*7c478bd9Sstevel@tonic-gate struct R_to_ER *p = &R_to_ER_tab[b][R.byte/**/b]; \ 275*7c478bd9Sstevel@tonic-gate e0 op p->l0; \ 276*7c478bd9Sstevel@tonic-gate e1 op p->l1; \ 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate #endif 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* 281*7c478bd9Sstevel@tonic-gate * Inner part of the algorithm: 282*7c478bd9Sstevel@tonic-gate * Expand R from 32 to 48 bits; xor key value; 283*7c478bd9Sstevel@tonic-gate * apply S boxes; permute 32 bits of output 284*7c478bd9Sstevel@tonic-gate */ 285*7c478bd9Sstevel@tonic-gate #define do_F(iter, inR, outR) { \ 286*7c478bd9Sstevel@tonic-gate chunk_t R, ER; \ 287*7c478bd9Sstevel@tonic-gate u_int e0, e1; \ 288*7c478bd9Sstevel@tonic-gate R.long0 = inR; \ 289*7c478bd9Sstevel@tonic-gate /*CSTYLED*/ \ 290*7c478bd9Sstevel@tonic-gate do_R_to_ER(=,0); \ 291*7c478bd9Sstevel@tonic-gate /*CSTYLED*/ \ 292*7c478bd9Sstevel@tonic-gate do_R_to_ER(|=,1); \ 293*7c478bd9Sstevel@tonic-gate /*CSTYLED*/ \ 294*7c478bd9Sstevel@tonic-gate do_R_to_ER(|=,2); \ 295*7c478bd9Sstevel@tonic-gate /*CSTYLED*/ \ 296*7c478bd9Sstevel@tonic-gate do_R_to_ER(|=,3); \ 297*7c478bd9Sstevel@tonic-gate ER.long0 = e0 ^ kd->keyval[iter].long0; \ 298*7c478bd9Sstevel@tonic-gate ER.long1 = e1 ^ kd->keyval[iter].long1; \ 299*7c478bd9Sstevel@tonic-gate R.long0 = \ 300*7c478bd9Sstevel@tonic-gate S_tab[0][ER.byte0] + \ 301*7c478bd9Sstevel@tonic-gate S_tab[1][ER.byte1] + \ 302*7c478bd9Sstevel@tonic-gate S_tab[2][ER.byte2] + \ 303*7c478bd9Sstevel@tonic-gate S_tab[3][ER.byte3] + \ 304*7c478bd9Sstevel@tonic-gate S_tab[4][ER.byte4] + \ 305*7c478bd9Sstevel@tonic-gate S_tab[5][ER.byte5] + \ 306*7c478bd9Sstevel@tonic-gate S_tab[6][ER.byte6] + \ 307*7c478bd9Sstevel@tonic-gate S_tab[7][ER.byte7]; \ 308*7c478bd9Sstevel@tonic-gate outR = \ 309*7c478bd9Sstevel@tonic-gate P_tab[0][R.byte0] + \ 310*7c478bd9Sstevel@tonic-gate P_tab[1][R.byte1] + \ 311*7c478bd9Sstevel@tonic-gate P_tab[2][R.byte2] + \ 312*7c478bd9Sstevel@tonic-gate P_tab[3][R.byte3]; \ 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* 316*7c478bd9Sstevel@tonic-gate * Do a cipher step 317*7c478bd9Sstevel@tonic-gate * Apply inner part; do xor and exchange of 32 bit parts 318*7c478bd9Sstevel@tonic-gate */ 319*7c478bd9Sstevel@tonic-gate #define cipher(iter, inR, inL, outR, outL) { \ 320*7c478bd9Sstevel@tonic-gate do_F(iter, inR, outR); \ 321*7c478bd9Sstevel@tonic-gate outR ^= inL; \ 322*7c478bd9Sstevel@tonic-gate outL = inR; \ 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* 326*7c478bd9Sstevel@tonic-gate * Apply the 16 ciphering steps 327*7c478bd9Sstevel@tonic-gate */ 328*7c478bd9Sstevel@tonic-gate { 329*7c478bd9Sstevel@tonic-gate u_int r0, l0, r1, l1; 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate l0 = work2.long0; 332*7c478bd9Sstevel@tonic-gate r0 = work2.long1; 333*7c478bd9Sstevel@tonic-gate cipher(0, r0, l0, r1, l1); 334*7c478bd9Sstevel@tonic-gate cipher(1, r1, l1, r0, l0); 335*7c478bd9Sstevel@tonic-gate cipher(2, r0, l0, r1, l1); 336*7c478bd9Sstevel@tonic-gate cipher(3, r1, l1, r0, l0); 337*7c478bd9Sstevel@tonic-gate cipher(4, r0, l0, r1, l1); 338*7c478bd9Sstevel@tonic-gate cipher(5, r1, l1, r0, l0); 339*7c478bd9Sstevel@tonic-gate cipher(6, r0, l0, r1, l1); 340*7c478bd9Sstevel@tonic-gate cipher(7, r1, l1, r0, l0); 341*7c478bd9Sstevel@tonic-gate cipher(8, r0, l0, r1, l1); 342*7c478bd9Sstevel@tonic-gate cipher(9, r1, l1, r0, l0); 343*7c478bd9Sstevel@tonic-gate cipher(10, r0, l0, r1, l1); 344*7c478bd9Sstevel@tonic-gate cipher(11, r1, l1, r0, l0); 345*7c478bd9Sstevel@tonic-gate cipher(12, r0, l0, r1, l1); 346*7c478bd9Sstevel@tonic-gate cipher(13, r1, l1, r0, l0); 347*7c478bd9Sstevel@tonic-gate cipher(14, r0, l0, r1, l1); 348*7c478bd9Sstevel@tonic-gate cipher(15, r1, l1, r0, l0); 349*7c478bd9Sstevel@tonic-gate work1.long0 = r0; 350*7c478bd9Sstevel@tonic-gate work1.long1 = l0; 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate /* 354*7c478bd9Sstevel@tonic-gate * Final permutation 355*7c478bd9Sstevel@tonic-gate * and chunk to byte conversion 356*7c478bd9Sstevel@tonic-gate */ 357*7c478bd9Sstevel@tonic-gate { 358*7c478bd9Sstevel@tonic-gate const uint32_t *lp; 359*7c478bd9Sstevel@tonic-gate uint32_t l0, l1, w; 360*7c478bd9Sstevel@tonic-gate short i, pbit; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate l0 = l1 = 0; 363*7c478bd9Sstevel@tonic-gate w = work1.long0; 364*7c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 0; i < 32; i++) { 365*7c478bd9Sstevel@tonic-gate if (w & *lp++) { 366*7c478bd9Sstevel@tonic-gate pbit = FPtab[i]; 367*7c478bd9Sstevel@tonic-gate if (pbit < 32) 368*7c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 369*7c478bd9Sstevel@tonic-gate else 370*7c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate w = work1.long1; 374*7c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 32; i < 64; i++) { 375*7c478bd9Sstevel@tonic-gate if (w & *lp++) { 376*7c478bd9Sstevel@tonic-gate pbit = FPtab[i]; 377*7c478bd9Sstevel@tonic-gate if (pbit < 32) 378*7c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 379*7c478bd9Sstevel@tonic-gate else 380*7c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate work2.long0 = l0; 384*7c478bd9Sstevel@tonic-gate work2.long1 = l1; 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate data[0] = work2.byte0; 387*7c478bd9Sstevel@tonic-gate data[1] = work2.byte1; 388*7c478bd9Sstevel@tonic-gate data[2] = work2.byte2; 389*7c478bd9Sstevel@tonic-gate data[3] = work2.byte3; 390*7c478bd9Sstevel@tonic-gate data[4] = work2.byte4; 391*7c478bd9Sstevel@tonic-gate data[5] = work2.byte5; 392*7c478bd9Sstevel@tonic-gate data[6] = work2.byte6; 393*7c478bd9Sstevel@tonic-gate data[7] = work2.byte7; 394*7c478bd9Sstevel@tonic-gate } 395