17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7257d1b4Sraf * Common Development and Distribution License (the "License"). 6*7257d1b4Sraf * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21e8031f0aSraf 227c478bd9Sstevel@tonic-gate /* 23*7257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 327c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* 367c478bd9Sstevel@tonic-gate * Warning! Things are arranged very carefully in this file to 377c478bd9Sstevel@tonic-gate * allow read-only data to be moved to the text segment. The 387c478bd9Sstevel@tonic-gate * various DES tables must appear before any function definitions 397c478bd9Sstevel@tonic-gate * (this is arranged by including them immediately below) and partab 407c478bd9Sstevel@tonic-gate * must also appear before and function definitions 417c478bd9Sstevel@tonic-gate * This arrangement allows all data up through the first text to 427c478bd9Sstevel@tonic-gate * be moved to text. 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #ifndef _KERNEL 467c478bd9Sstevel@tonic-gate #define CRYPT /* cannot configure out of user-level code */ 477c478bd9Sstevel@tonic-gate #endif 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #ifdef CRYPT 507c478bd9Sstevel@tonic-gate #include <sys/types.h> 517c478bd9Sstevel@tonic-gate #include <des/softdes.h> 527c478bd9Sstevel@tonic-gate #include <des/desdata.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #ifdef sun 557c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 567c478bd9Sstevel@tonic-gate #include <sys/des.h> 577c478bd9Sstevel@tonic-gate #else 587c478bd9Sstevel@tonic-gate #include <des/des.h> 597c478bd9Sstevel@tonic-gate #endif 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate #include "des_soft.h" 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* 647c478bd9Sstevel@tonic-gate * Fast (?) software implementation of DES 657c478bd9Sstevel@tonic-gate * Has been seen going at 2000 bytes/sec on a Sun-2 667c478bd9Sstevel@tonic-gate * Works on a VAX too. 677c478bd9Sstevel@tonic-gate * Won't work without 8 bit chars and 32 bit longs 687c478bd9Sstevel@tonic-gate */ 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #define btst(k, b) (k[b >> 3] & (0x80 >> (b & 07))) 717c478bd9Sstevel@tonic-gate #define BIT28 (1<<28) 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate #endif /* def CRYPT */ 757c478bd9Sstevel@tonic-gate 76*7257d1b4Sraf static void des_setkey(uchar_t [8], struct deskeydata *, unsigned); 77*7257d1b4Sraf static void des_encrypt(uchar_t *, struct deskeydata *); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate #ifndef _KERNEL 807c478bd9Sstevel@tonic-gate /* 817c478bd9Sstevel@tonic-gate * Table giving odd parity in the low bit for ASCII characters 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate static char partab[128] = { 847c478bd9Sstevel@tonic-gate 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 857c478bd9Sstevel@tonic-gate 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e, 867c478bd9Sstevel@tonic-gate 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, 877c478bd9Sstevel@tonic-gate 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f, 887c478bd9Sstevel@tonic-gate 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26, 897c478bd9Sstevel@tonic-gate 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f, 907c478bd9Sstevel@tonic-gate 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 917c478bd9Sstevel@tonic-gate 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e, 927c478bd9Sstevel@tonic-gate 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, 937c478bd9Sstevel@tonic-gate 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f, 947c478bd9Sstevel@tonic-gate 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57, 957c478bd9Sstevel@tonic-gate 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e, 967c478bd9Sstevel@tonic-gate 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 977c478bd9Sstevel@tonic-gate 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e, 987c478bd9Sstevel@tonic-gate 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, 997c478bd9Sstevel@tonic-gate 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f, 1007c478bd9Sstevel@tonic-gate }; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * Add odd parity to low bit of 8 byte key 1067c478bd9Sstevel@tonic-gate */ 1077c478bd9Sstevel@tonic-gate void 1087c478bd9Sstevel@tonic-gate des_setparity(char *p) 1097c478bd9Sstevel@tonic-gate { 1107c478bd9Sstevel@tonic-gate int i; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) { 1137c478bd9Sstevel@tonic-gate *p = partab[*p & 0x7f]; 1147c478bd9Sstevel@tonic-gate p++; 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate #endif /* def _KERNEL */ 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate #ifdef CRYPT 1207c478bd9Sstevel@tonic-gate /* 1217c478bd9Sstevel@tonic-gate * Software encrypt or decrypt a block of data (multiple of 8 bytes) 1227c478bd9Sstevel@tonic-gate * Do the CBC ourselves if needed. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate int 1257c478bd9Sstevel@tonic-gate __des_crypt(char *buf, unsigned int len, struct desparams *desp) 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate short i; 1287c478bd9Sstevel@tonic-gate unsigned mode; 1297c478bd9Sstevel@tonic-gate unsigned dir; 1307c478bd9Sstevel@tonic-gate char nextiv[8]; 1317c478bd9Sstevel@tonic-gate struct deskeydata softkey; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate mode = (unsigned)desp->des_mode; 1347c478bd9Sstevel@tonic-gate dir = (unsigned)desp->des_dir; 1357c478bd9Sstevel@tonic-gate des_setkey(desp->des_key, &softkey, dir); 1367c478bd9Sstevel@tonic-gate while (len != 0) { 1377c478bd9Sstevel@tonic-gate switch (mode) { 1387c478bd9Sstevel@tonic-gate case CBC: 1397c478bd9Sstevel@tonic-gate switch (dir) { 1407c478bd9Sstevel@tonic-gate case ENCRYPT: 1417c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) 1427c478bd9Sstevel@tonic-gate buf[i] ^= desp->des_ivec[i]; 143*7257d1b4Sraf des_encrypt((uchar_t *)buf, &softkey); 1447c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) 1457c478bd9Sstevel@tonic-gate desp->des_ivec[i] = buf[i]; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case DECRYPT: 1487c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) 1497c478bd9Sstevel@tonic-gate nextiv[i] = buf[i]; 150*7257d1b4Sraf des_encrypt((uchar_t *)buf, &softkey); 1517c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) { 1527c478bd9Sstevel@tonic-gate buf[i] ^= desp->des_ivec[i]; 1537c478bd9Sstevel@tonic-gate desp->des_ivec[i] = nextiv[i]; 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate break; 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate break; 1587c478bd9Sstevel@tonic-gate case ECB: 159*7257d1b4Sraf des_encrypt((uchar_t *)buf, &softkey); 1607c478bd9Sstevel@tonic-gate break; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate buf += 8; 1637c478bd9Sstevel@tonic-gate len -= 8; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate return (1); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * Set the key and direction for an encryption operation 1717c478bd9Sstevel@tonic-gate * We build the 16 key entries here 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate static void 174*7257d1b4Sraf des_setkey(uchar_t userkey[8], struct deskeydata *kd, unsigned int dir) 1757c478bd9Sstevel@tonic-gate { 1767c478bd9Sstevel@tonic-gate long C, D; 1777c478bd9Sstevel@tonic-gate short i; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate /* 1807c478bd9Sstevel@tonic-gate * First, generate C and D by permuting 1817c478bd9Sstevel@tonic-gate * the key. The low order bit of each 1827c478bd9Sstevel@tonic-gate * 8-bit char is not used, so C and D are only 28 1837c478bd9Sstevel@tonic-gate * bits apiece. 1847c478bd9Sstevel@tonic-gate */ 1857c478bd9Sstevel@tonic-gate { 1867c478bd9Sstevel@tonic-gate short bit; 1877c478bd9Sstevel@tonic-gate const short *pcc = PC1_C, *pcd = PC1_D; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate C = D = 0; 1907c478bd9Sstevel@tonic-gate for (i = 0; i < 28; i++) { 1917c478bd9Sstevel@tonic-gate C <<= 1; 1927c478bd9Sstevel@tonic-gate D <<= 1; 1937c478bd9Sstevel@tonic-gate bit = *pcc++; 1947c478bd9Sstevel@tonic-gate if (btst(userkey, bit)) 1957c478bd9Sstevel@tonic-gate C |= 1; 1967c478bd9Sstevel@tonic-gate bit = *pcd++; 1977c478bd9Sstevel@tonic-gate if (btst(userkey, bit)) 1987c478bd9Sstevel@tonic-gate D |= 1; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate /* 2027c478bd9Sstevel@tonic-gate * To generate Ki, rotate C and D according 2037c478bd9Sstevel@tonic-gate * to schedule and pick up a permutation 2047c478bd9Sstevel@tonic-gate * using PC2. 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 2077c478bd9Sstevel@tonic-gate chunk_t *c; 2087c478bd9Sstevel@tonic-gate short j, k, bit; 2097c478bd9Sstevel@tonic-gate long bbit; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* 2127c478bd9Sstevel@tonic-gate * Do the "left shift" (rotate) 2137c478bd9Sstevel@tonic-gate * We know we always rotate by either 1 or 2 bits 2147c478bd9Sstevel@tonic-gate * the shifts table tells us if its 2 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate C <<= 1; 2177c478bd9Sstevel@tonic-gate if (C & BIT28) 2187c478bd9Sstevel@tonic-gate C |= 1; 2197c478bd9Sstevel@tonic-gate D <<= 1; 2207c478bd9Sstevel@tonic-gate if (D & BIT28) 2217c478bd9Sstevel@tonic-gate D |= 1; 2227c478bd9Sstevel@tonic-gate if (shifts[i]) { 2237c478bd9Sstevel@tonic-gate C <<= 1; 2247c478bd9Sstevel@tonic-gate if (C & BIT28) 2257c478bd9Sstevel@tonic-gate C |= 1; 2267c478bd9Sstevel@tonic-gate D <<= 1; 2277c478bd9Sstevel@tonic-gate if (D & BIT28) 2287c478bd9Sstevel@tonic-gate D |= 1; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate /* 2317c478bd9Sstevel@tonic-gate * get Ki. Note C and D are concatenated. 2327c478bd9Sstevel@tonic-gate */ 2337c478bd9Sstevel@tonic-gate bit = 0; 2347c478bd9Sstevel@tonic-gate switch (dir) { 2357c478bd9Sstevel@tonic-gate case ENCRYPT: 2367c478bd9Sstevel@tonic-gate c = &kd->keyval[i]; break; 2377c478bd9Sstevel@tonic-gate case DECRYPT: 2387c478bd9Sstevel@tonic-gate c = &kd->keyval[15 - i]; break; 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate c->long0 = 0; 2417c478bd9Sstevel@tonic-gate c->long1 = 0; 2427c478bd9Sstevel@tonic-gate bbit = (1 << 5) << 24; 2437c478bd9Sstevel@tonic-gate for (j = 0; j < 4; j++) { 2447c478bd9Sstevel@tonic-gate for (k = 0; k < 6; k++) { 2457c478bd9Sstevel@tonic-gate if (C & (BIT28 >> PC2_C[bit])) 2467c478bd9Sstevel@tonic-gate c->long0 |= bbit >> k; 2477c478bd9Sstevel@tonic-gate if (D & (BIT28 >> PC2_D[bit])) 2487c478bd9Sstevel@tonic-gate c->long1 |= bbit >> k; 2497c478bd9Sstevel@tonic-gate bit++; 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate bbit >>= 8; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * Do an encryption operation 2617c478bd9Sstevel@tonic-gate * Much pain is taken (with preprocessor) to avoid loops so the compiler 2627c478bd9Sstevel@tonic-gate * can do address arithmetic instead of doing it at runtime. 2637c478bd9Sstevel@tonic-gate * Note that the byte-to-chunk conversion is necessary to guarantee 2647c478bd9Sstevel@tonic-gate * processor byte-order independence. 2657c478bd9Sstevel@tonic-gate */ 2667c478bd9Sstevel@tonic-gate static void 267*7257d1b4Sraf des_encrypt(uchar_t *data, struct deskeydata *kd) 2687c478bd9Sstevel@tonic-gate { 2697c478bd9Sstevel@tonic-gate chunk_t work1, work2; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate /* 2727c478bd9Sstevel@tonic-gate * Initial permutation 2737c478bd9Sstevel@tonic-gate * and byte to chunk conversion 2747c478bd9Sstevel@tonic-gate */ 2757c478bd9Sstevel@tonic-gate { 2767c478bd9Sstevel@tonic-gate const uint32_t *lp; 2777c478bd9Sstevel@tonic-gate uint32_t l0, l1, w; 2787c478bd9Sstevel@tonic-gate short i, pbit; 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate work1.byte0 = data[0]; 2817c478bd9Sstevel@tonic-gate work1.byte1 = data[1]; 2827c478bd9Sstevel@tonic-gate work1.byte2 = data[2]; 2837c478bd9Sstevel@tonic-gate work1.byte3 = data[3]; 2847c478bd9Sstevel@tonic-gate work1.byte4 = data[4]; 2857c478bd9Sstevel@tonic-gate work1.byte5 = data[5]; 2867c478bd9Sstevel@tonic-gate work1.byte6 = data[6]; 2877c478bd9Sstevel@tonic-gate work1.byte7 = data[7]; 2887c478bd9Sstevel@tonic-gate l0 = l1 = 0; 2897c478bd9Sstevel@tonic-gate w = work1.long0; 2907c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 0; i < 32; i++) { 2917c478bd9Sstevel@tonic-gate if (w & *lp++) { 2927c478bd9Sstevel@tonic-gate pbit = IPtab[i]; 2937c478bd9Sstevel@tonic-gate if (pbit < 32) 2947c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 2957c478bd9Sstevel@tonic-gate else 2967c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate w = work1.long1; 3007c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 32; i < 64; i++) { 3017c478bd9Sstevel@tonic-gate if (w & *lp++) { 3027c478bd9Sstevel@tonic-gate pbit = IPtab[i]; 3037c478bd9Sstevel@tonic-gate if (pbit < 32) 3047c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 3057c478bd9Sstevel@tonic-gate else 3067c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate work2.long0 = l0; 3107c478bd9Sstevel@tonic-gate work2.long1 = l1; 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * Expand 8 bits of 32 bit R to 48 bit R 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate #define do_R_to_ER(op, b) { \ 3177c478bd9Sstevel@tonic-gate const struct R_to_ER *p = &R_to_ER_tab[b][R.byte##b]; \ 3187c478bd9Sstevel@tonic-gate e0 op p->l0; \ 3197c478bd9Sstevel@tonic-gate e1 op p->l1; \ 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate /* 3237c478bd9Sstevel@tonic-gate * Inner part of the algorithm: 3247c478bd9Sstevel@tonic-gate * Expand R from 32 to 48 bits; xor key value; 3257c478bd9Sstevel@tonic-gate * apply S boxes; permute 32 bits of output 3267c478bd9Sstevel@tonic-gate */ 3277c478bd9Sstevel@tonic-gate #define do_F(iter, inR, outR) { \ 3287c478bd9Sstevel@tonic-gate chunk_t R, ER; \ 3297c478bd9Sstevel@tonic-gate uint32_t e0, e1; \ 3307c478bd9Sstevel@tonic-gate R.long0 = inR; \ 331*7257d1b4Sraf /* CSTYLED */ \ 3327c478bd9Sstevel@tonic-gate do_R_to_ER(=, 0); \ 333*7257d1b4Sraf /* CSTYLED */ \ 3347c478bd9Sstevel@tonic-gate do_R_to_ER(|=, 1); \ 335*7257d1b4Sraf /* CSTYLED */ \ 3367c478bd9Sstevel@tonic-gate do_R_to_ER(|=, 2); \ 337*7257d1b4Sraf /* CSTYLED */ \ 3387c478bd9Sstevel@tonic-gate do_R_to_ER(|=, 3); \ 3397c478bd9Sstevel@tonic-gate ER.long0 = e0 ^ kd->keyval[iter].long0; \ 3407c478bd9Sstevel@tonic-gate ER.long1 = e1 ^ kd->keyval[iter].long1; \ 3417c478bd9Sstevel@tonic-gate R.long0 = \ 3427c478bd9Sstevel@tonic-gate S_tab[0][ER.byte0] + \ 3437c478bd9Sstevel@tonic-gate S_tab[1][ER.byte1] + \ 3447c478bd9Sstevel@tonic-gate S_tab[2][ER.byte2] + \ 3457c478bd9Sstevel@tonic-gate S_tab[3][ER.byte3] + \ 3467c478bd9Sstevel@tonic-gate S_tab[4][ER.byte4] + \ 3477c478bd9Sstevel@tonic-gate S_tab[5][ER.byte5] + \ 3487c478bd9Sstevel@tonic-gate S_tab[6][ER.byte6] + \ 3497c478bd9Sstevel@tonic-gate S_tab[7][ER.byte7]; \ 3507c478bd9Sstevel@tonic-gate outR = \ 3517c478bd9Sstevel@tonic-gate P_tab[0][R.byte0] + \ 3527c478bd9Sstevel@tonic-gate P_tab[1][R.byte1] + \ 3537c478bd9Sstevel@tonic-gate P_tab[2][R.byte2] + \ 3547c478bd9Sstevel@tonic-gate P_tab[3][R.byte3]; \ 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * Do a cipher step 3597c478bd9Sstevel@tonic-gate * Apply inner part; do xor and exchange of 32 bit parts 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate #define cipher(iter, inR, inL, outR, outL) { \ 3627c478bd9Sstevel@tonic-gate do_F(iter, inR, outR); \ 3637c478bd9Sstevel@tonic-gate outR ^= inL; \ 3647c478bd9Sstevel@tonic-gate outL = inR; \ 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* 3687c478bd9Sstevel@tonic-gate * Apply the 16 ciphering steps 3697c478bd9Sstevel@tonic-gate */ 3707c478bd9Sstevel@tonic-gate { 3717c478bd9Sstevel@tonic-gate uint32_t r0, l0, r1, l1; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate l0 = work2.long0; 3747c478bd9Sstevel@tonic-gate r0 = work2.long1; 3757c478bd9Sstevel@tonic-gate cipher(0, r0, l0, r1, l1); 3767c478bd9Sstevel@tonic-gate cipher(1, r1, l1, r0, l0); 3777c478bd9Sstevel@tonic-gate cipher(2, r0, l0, r1, l1); 3787c478bd9Sstevel@tonic-gate cipher(3, r1, l1, r0, l0); 3797c478bd9Sstevel@tonic-gate cipher(4, r0, l0, r1, l1); 3807c478bd9Sstevel@tonic-gate cipher(5, r1, l1, r0, l0); 3817c478bd9Sstevel@tonic-gate cipher(6, r0, l0, r1, l1); 3827c478bd9Sstevel@tonic-gate cipher(7, r1, l1, r0, l0); 3837c478bd9Sstevel@tonic-gate cipher(8, r0, l0, r1, l1); 3847c478bd9Sstevel@tonic-gate cipher(9, r1, l1, r0, l0); 3857c478bd9Sstevel@tonic-gate cipher(10, r0, l0, r1, l1); 3867c478bd9Sstevel@tonic-gate cipher(11, r1, l1, r0, l0); 3877c478bd9Sstevel@tonic-gate cipher(12, r0, l0, r1, l1); 3887c478bd9Sstevel@tonic-gate cipher(13, r1, l1, r0, l0); 3897c478bd9Sstevel@tonic-gate cipher(14, r0, l0, r1, l1); 3907c478bd9Sstevel@tonic-gate cipher(15, r1, l1, r0, l0); 3917c478bd9Sstevel@tonic-gate work1.long0 = r0; 3927c478bd9Sstevel@tonic-gate work1.long1 = l0; 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate /* 3967c478bd9Sstevel@tonic-gate * Final permutation 3977c478bd9Sstevel@tonic-gate * and chunk to byte conversion 3987c478bd9Sstevel@tonic-gate */ 3997c478bd9Sstevel@tonic-gate { 4007c478bd9Sstevel@tonic-gate const uint32_t *lp; 4017c478bd9Sstevel@tonic-gate uint32_t l0, l1, w; 4027c478bd9Sstevel@tonic-gate short i, pbit; 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate l0 = l1 = 0; 4057c478bd9Sstevel@tonic-gate w = work1.long0; 4067c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 0; i < 32; i++) { 4077c478bd9Sstevel@tonic-gate if (w & *lp++) { 4087c478bd9Sstevel@tonic-gate pbit = FPtab[i]; 4097c478bd9Sstevel@tonic-gate if (pbit < 32) 4107c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 4117c478bd9Sstevel@tonic-gate else 4127c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate w = work1.long1; 4167c478bd9Sstevel@tonic-gate for (lp = &longtab[0], i = 32; i < 64; i++) { 4177c478bd9Sstevel@tonic-gate if (w & *lp++) { 4187c478bd9Sstevel@tonic-gate pbit = FPtab[i]; 4197c478bd9Sstevel@tonic-gate if (pbit < 32) 4207c478bd9Sstevel@tonic-gate l0 |= longtab[pbit]; 4217c478bd9Sstevel@tonic-gate else 4227c478bd9Sstevel@tonic-gate l1 |= longtab[pbit-32]; 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate work2.long0 = l0; 4267c478bd9Sstevel@tonic-gate work2.long1 = l1; 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate data[0] = work2.byte0; 4297c478bd9Sstevel@tonic-gate data[1] = work2.byte1; 4307c478bd9Sstevel@tonic-gate data[2] = work2.byte2; 4317c478bd9Sstevel@tonic-gate data[3] = work2.byte3; 4327c478bd9Sstevel@tonic-gate data[4] = work2.byte4; 4337c478bd9Sstevel@tonic-gate data[5] = work2.byte5; 4347c478bd9Sstevel@tonic-gate data[6] = work2.byte6; 4357c478bd9Sstevel@tonic-gate data[7] = work2.byte7; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate #endif /* def CRYPT */ 438