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 5cb620785Sraf * Common Development and Distribution License (the "License"). 6cb620785Sraf * 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 27cb620785Sraf /* Copyright (c) 1988 AT&T */ 28cb620785Sraf /* All Rights Reserved */ 29cb620785Sraf 30*7257d1b4Sraf #pragma weak _des_crypt = des_crypt 31*7257d1b4Sraf #pragma weak _des_encrypt = des_encrypt 32*7257d1b4Sraf #pragma weak _des_setkey = des_setkey 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <sys/types.h> 357c478bd9Sstevel@tonic-gate #include <crypt.h> 367c478bd9Sstevel@tonic-gate #include "des_soft.h" 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include <stdlib.h> 397c478bd9Sstevel@tonic-gate #include <thread.h> 40cb620785Sraf #include <pthread.h> 417c478bd9Sstevel@tonic-gate #include <sys/types.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* 447c478bd9Sstevel@tonic-gate * This program implements the 457c478bd9Sstevel@tonic-gate * Proposed Federal Information Processing 467c478bd9Sstevel@tonic-gate * Data Encryption Standard. 477c478bd9Sstevel@tonic-gate * See Federal Register, March 17, 1975 (40FR12134) 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * Initial permutation, 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate static char IP[] = { 547c478bd9Sstevel@tonic-gate 58, 50, 42, 34, 26, 18, 10, 2, 557c478bd9Sstevel@tonic-gate 60, 52, 44, 36, 28, 20, 12, 4, 567c478bd9Sstevel@tonic-gate 62, 54, 46, 38, 30, 22, 14, 6, 577c478bd9Sstevel@tonic-gate 64, 56, 48, 40, 32, 24, 16, 8, 587c478bd9Sstevel@tonic-gate 57, 49, 41, 33, 25, 17, 9, 1, 597c478bd9Sstevel@tonic-gate 59, 51, 43, 35, 27, 19, 11, 3, 607c478bd9Sstevel@tonic-gate 61, 53, 45, 37, 29, 21, 13, 5, 617c478bd9Sstevel@tonic-gate 63, 55, 47, 39, 31, 23, 15, 7, 627c478bd9Sstevel@tonic-gate }; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * Final permutation, FP = IP^(-1) 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate static char FP[] = { 687c478bd9Sstevel@tonic-gate 40, 8, 48, 16, 56, 24, 64, 32, 697c478bd9Sstevel@tonic-gate 39, 7, 47, 15, 55, 23, 63, 31, 707c478bd9Sstevel@tonic-gate 38, 6, 46, 14, 54, 22, 62, 30, 717c478bd9Sstevel@tonic-gate 37, 5, 45, 13, 53, 21, 61, 29, 727c478bd9Sstevel@tonic-gate 36, 4, 44, 12, 52, 20, 60, 28, 737c478bd9Sstevel@tonic-gate 35, 3, 43, 11, 51, 19, 59, 27, 747c478bd9Sstevel@tonic-gate 34, 2, 42, 10, 50, 18, 58, 26, 757c478bd9Sstevel@tonic-gate 33, 1, 41, 9, 49, 17, 57, 25, 767c478bd9Sstevel@tonic-gate }; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* 797c478bd9Sstevel@tonic-gate * Permuted-choice 1 from the key bits 807c478bd9Sstevel@tonic-gate * to yield C and D. 817c478bd9Sstevel@tonic-gate * Note that bits 8, 16... are left out: 827c478bd9Sstevel@tonic-gate * They are intended for a parity check. 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate static char PC1_C[] = { 857c478bd9Sstevel@tonic-gate 57, 49, 41, 33, 25, 17, 9, 867c478bd9Sstevel@tonic-gate 1, 58, 50, 42, 34, 26, 18, 877c478bd9Sstevel@tonic-gate 10, 2, 59, 51, 43, 35, 27, 887c478bd9Sstevel@tonic-gate 19, 11, 3, 60, 52, 44, 36, 897c478bd9Sstevel@tonic-gate }; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate static char PC1_D[] = { 927c478bd9Sstevel@tonic-gate 63, 55, 47, 39, 31, 23, 15, 937c478bd9Sstevel@tonic-gate 7, 62, 54, 46, 38, 30, 22, 947c478bd9Sstevel@tonic-gate 14, 6, 61, 53, 45, 37, 29, 957c478bd9Sstevel@tonic-gate 21, 13, 5, 28, 20, 12, 4, 967c478bd9Sstevel@tonic-gate }; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * Sequence of shifts used for the key schedule. 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate static char shifts[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, }; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * Permuted-choice 2, to pick out the bits from 1057c478bd9Sstevel@tonic-gate * the CD array that generate the key schedule. 1067c478bd9Sstevel@tonic-gate */ 1077c478bd9Sstevel@tonic-gate static char PC2_C[] = { 1087c478bd9Sstevel@tonic-gate 14, 17, 11, 24, 1, 5, 1097c478bd9Sstevel@tonic-gate 3, 28, 15, 6, 21, 10, 1107c478bd9Sstevel@tonic-gate 23, 19, 12, 4, 26, 8, 1117c478bd9Sstevel@tonic-gate 16, 7, 27, 20, 13, 2, 1127c478bd9Sstevel@tonic-gate }; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate static char PC2_D[] = { 1157c478bd9Sstevel@tonic-gate 41, 52, 31, 37, 47, 55, 1167c478bd9Sstevel@tonic-gate 30, 40, 51, 45, 33, 48, 1177c478bd9Sstevel@tonic-gate 44, 49, 39, 56, 34, 53, 1187c478bd9Sstevel@tonic-gate 46, 42, 50, 36, 29, 32, 1197c478bd9Sstevel@tonic-gate }; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate /* 1227c478bd9Sstevel@tonic-gate * The C and D arrays used to calculate the key schedule. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate static char C[28]; 1267c478bd9Sstevel@tonic-gate static char D[28]; 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * The key schedule. 1297c478bd9Sstevel@tonic-gate * Generated from the key. 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate static char KS[16][48]; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate /* 1347c478bd9Sstevel@tonic-gate * The E bit-selection table. 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate static char E[48]; 1377c478bd9Sstevel@tonic-gate static char e2[] = { 1387c478bd9Sstevel@tonic-gate 32, 1, 2, 3, 4, 5, 1397c478bd9Sstevel@tonic-gate 4, 5, 6, 7, 8, 9, 1407c478bd9Sstevel@tonic-gate 8, 9, 10, 11, 12, 13, 1417c478bd9Sstevel@tonic-gate 12, 13, 14, 15, 16, 17, 1427c478bd9Sstevel@tonic-gate 16, 17, 18, 19, 20, 21, 1437c478bd9Sstevel@tonic-gate 20, 21, 22, 23, 24, 25, 1447c478bd9Sstevel@tonic-gate 24, 25, 26, 27, 28, 29, 1457c478bd9Sstevel@tonic-gate 28, 29, 30, 31, 32, 1, 1467c478bd9Sstevel@tonic-gate }; 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /* 1497c478bd9Sstevel@tonic-gate * Set up the key schedule from the key. 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate static mutex_t lock = DEFAULTMUTEX; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate static void 1557c478bd9Sstevel@tonic-gate des_setkey_nolock(const char *key) 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate int i, j, k; 1587c478bd9Sstevel@tonic-gate char t; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate /* 1617c478bd9Sstevel@tonic-gate * First, generate C and D by permuting 1627c478bd9Sstevel@tonic-gate * the key. The low order bit of each 1637c478bd9Sstevel@tonic-gate * 8-bit char is not used, so C and D are only 28 1647c478bd9Sstevel@tonic-gate * bits apiece. 1657c478bd9Sstevel@tonic-gate */ 1667c478bd9Sstevel@tonic-gate for (i = 0; i < 28; i++) { 1677c478bd9Sstevel@tonic-gate C[i] = key[PC1_C[i]-1]; 1687c478bd9Sstevel@tonic-gate D[i] = key[PC1_D[i]-1]; 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * To generate Ki, rotate C and D according 1727c478bd9Sstevel@tonic-gate * to schedule and pick up a permutation 1737c478bd9Sstevel@tonic-gate * using PC2. 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * rotate. 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate for (k = 0; k < shifts[i]; k++) { 1807c478bd9Sstevel@tonic-gate t = C[0]; 1817c478bd9Sstevel@tonic-gate for (j = 0; j < 28-1; j++) 1827c478bd9Sstevel@tonic-gate C[j] = C[j+1]; 1837c478bd9Sstevel@tonic-gate C[27] = (char)t; 1847c478bd9Sstevel@tonic-gate t = D[0]; 1857c478bd9Sstevel@tonic-gate for (j = 0; j < 28-1; j++) 1867c478bd9Sstevel@tonic-gate D[j] = D[j+1]; 1877c478bd9Sstevel@tonic-gate D[27] = (char)t; 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate /* 1907c478bd9Sstevel@tonic-gate * get Ki. Note C and D are concatenated. 1917c478bd9Sstevel@tonic-gate */ 1927c478bd9Sstevel@tonic-gate for (j = 0; j < 24; j++) { 1937c478bd9Sstevel@tonic-gate KS[i][j] = C[PC2_C[j]-1]; 1947c478bd9Sstevel@tonic-gate KS[i][j+24] = D[PC2_D[j]-28-1]; 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate for (i = 0; i < 48; i++) 1997c478bd9Sstevel@tonic-gate E[i] = e2[i]; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate void 2037c478bd9Sstevel@tonic-gate des_setkey(const char *key) 2047c478bd9Sstevel@tonic-gate { 2057c478bd9Sstevel@tonic-gate (void) mutex_lock(&lock); 2067c478bd9Sstevel@tonic-gate des_setkey_nolock(key); 2077c478bd9Sstevel@tonic-gate (void) mutex_unlock(&lock); 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* 2117c478bd9Sstevel@tonic-gate * The 8 selection functions. 2127c478bd9Sstevel@tonic-gate * For some reason, they give a 0-origin 2137c478bd9Sstevel@tonic-gate * index, unlike everything else. 2147c478bd9Sstevel@tonic-gate */ 2157c478bd9Sstevel@tonic-gate static char S[8][64] = { 2167c478bd9Sstevel@tonic-gate 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 2177c478bd9Sstevel@tonic-gate 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 2187c478bd9Sstevel@tonic-gate 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 2197c478bd9Sstevel@tonic-gate 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 2227c478bd9Sstevel@tonic-gate 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 2237c478bd9Sstevel@tonic-gate 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 2247c478bd9Sstevel@tonic-gate 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 2277c478bd9Sstevel@tonic-gate 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 2287c478bd9Sstevel@tonic-gate 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 2297c478bd9Sstevel@tonic-gate 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 2327c478bd9Sstevel@tonic-gate 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 2337c478bd9Sstevel@tonic-gate 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 2347c478bd9Sstevel@tonic-gate 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 2377c478bd9Sstevel@tonic-gate 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 2387c478bd9Sstevel@tonic-gate 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 2397c478bd9Sstevel@tonic-gate 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 2427c478bd9Sstevel@tonic-gate 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 2437c478bd9Sstevel@tonic-gate 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 2447c478bd9Sstevel@tonic-gate 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 2477c478bd9Sstevel@tonic-gate 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 2487c478bd9Sstevel@tonic-gate 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 2497c478bd9Sstevel@tonic-gate 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 2527c478bd9Sstevel@tonic-gate 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 2537c478bd9Sstevel@tonic-gate 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2547c478bd9Sstevel@tonic-gate 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, 2557c478bd9Sstevel@tonic-gate }; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* 2587c478bd9Sstevel@tonic-gate * P is a permutation on the selected combination 2597c478bd9Sstevel@tonic-gate * of the current L and key. 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate static char P[] = { 2627c478bd9Sstevel@tonic-gate 16, 7, 20, 21, 2637c478bd9Sstevel@tonic-gate 29, 12, 28, 17, 2647c478bd9Sstevel@tonic-gate 1, 15, 23, 26, 2657c478bd9Sstevel@tonic-gate 5, 18, 31, 10, 2667c478bd9Sstevel@tonic-gate 2, 8, 24, 14, 2677c478bd9Sstevel@tonic-gate 32, 27, 3, 9, 2687c478bd9Sstevel@tonic-gate 19, 13, 30, 6, 2697c478bd9Sstevel@tonic-gate 22, 11, 4, 25, 2707c478bd9Sstevel@tonic-gate }; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate /* 2737c478bd9Sstevel@tonic-gate * The current block, divided into 2 halves. 2747c478bd9Sstevel@tonic-gate */ 2757c478bd9Sstevel@tonic-gate static char L[64]; 2767c478bd9Sstevel@tonic-gate static char tempL[32]; 2777c478bd9Sstevel@tonic-gate static char f[32]; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /* 2807c478bd9Sstevel@tonic-gate * The combination of the key and the input, before selection. 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate static char preS[48]; 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* 2857c478bd9Sstevel@tonic-gate * The payoff: encrypt a block. 2867c478bd9Sstevel@tonic-gate */ 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate static void 2897c478bd9Sstevel@tonic-gate des_encrypt_nolock(char *block, int edflag) 2907c478bd9Sstevel@tonic-gate { 2917c478bd9Sstevel@tonic-gate if (edflag) 292*7257d1b4Sraf (void) _des_decrypt1(block, L, IP, &L[32], 2937c478bd9Sstevel@tonic-gate preS, E, KS, S, f, tempL, P, FP); 2947c478bd9Sstevel@tonic-gate else 2957c478bd9Sstevel@tonic-gate (void) des_encrypt1(block, L, IP, &L[32], 2967c478bd9Sstevel@tonic-gate preS, E, KS, S, f, tempL, P, FP); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate void 3007c478bd9Sstevel@tonic-gate des_encrypt(char *block, int edflag) 3017c478bd9Sstevel@tonic-gate { 3027c478bd9Sstevel@tonic-gate (void) mutex_lock(&lock); 3037c478bd9Sstevel@tonic-gate des_encrypt_nolock(block, edflag); 3047c478bd9Sstevel@tonic-gate (void) mutex_unlock(&lock); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate #define IOBUF_SIZE 16 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate static char * 312cb620785Sraf _get_iobuf(thread_key_t *keyp, unsigned size) 3137c478bd9Sstevel@tonic-gate { 314cb620785Sraf char *iobuf; 3157c478bd9Sstevel@tonic-gate 316cb620785Sraf if (thr_keycreate_once(keyp, free) != 0) 3177c478bd9Sstevel@tonic-gate return (NULL); 318cb620785Sraf iobuf = pthread_getspecific(*keyp); 319cb620785Sraf if (iobuf == NULL) { 320cb620785Sraf if (thr_setspecific(*keyp, (iobuf = malloc(size))) != 0) { 3217c478bd9Sstevel@tonic-gate if (iobuf) 3227c478bd9Sstevel@tonic-gate (void) free(iobuf); 323cb620785Sraf iobuf = NULL; 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate return (iobuf); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate char * 3307c478bd9Sstevel@tonic-gate des_crypt(const char *pw, const char *salt) 3317c478bd9Sstevel@tonic-gate { 3327c478bd9Sstevel@tonic-gate int i, j; 3337c478bd9Sstevel@tonic-gate char c, temp; 334cb620785Sraf char block[66]; 335cb620785Sraf static thread_key_t key = THR_ONCE_KEY; 336cb620785Sraf char *iobuf = _get_iobuf(&key, IOBUF_SIZE); 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate (void) mutex_lock(&lock); 3397c478bd9Sstevel@tonic-gate for (i = 0; i < 66; i++) 3407c478bd9Sstevel@tonic-gate block[i] = 0; 3417c478bd9Sstevel@tonic-gate for (i = 0; (c = *pw) && (i < 64); pw++) { 3427c478bd9Sstevel@tonic-gate for (j = 0; j < 7; j++, i++) 3437c478bd9Sstevel@tonic-gate block[i] = (c>>(6-j)) & 01; 3447c478bd9Sstevel@tonic-gate i++; 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate des_setkey_nolock(block); 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate for (i = 0; i < 66; i++) 3507c478bd9Sstevel@tonic-gate block[i] = 0; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 3537c478bd9Sstevel@tonic-gate c = *salt++; 3547c478bd9Sstevel@tonic-gate iobuf[i] = (char)c; 3557c478bd9Sstevel@tonic-gate if (c > 'Z') 3567c478bd9Sstevel@tonic-gate c -= 6; 3577c478bd9Sstevel@tonic-gate if (c > '9') 3587c478bd9Sstevel@tonic-gate c -= 7; 3597c478bd9Sstevel@tonic-gate c -= '.'; 3607c478bd9Sstevel@tonic-gate for (j = 0; j < 6; j++) { 3617c478bd9Sstevel@tonic-gate if ((c>>j) & 01) { 3627c478bd9Sstevel@tonic-gate temp = E[6*i+j]; 3637c478bd9Sstevel@tonic-gate E[6*i+j] = E[6*i+j+24]; 3647c478bd9Sstevel@tonic-gate E[6*i+j+24] = (char)temp; 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate for (i = 0; i < 25; i++) 3707c478bd9Sstevel@tonic-gate (void) des_encrypt_nolock(block, 0); 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate for (i = 0; i < 11; i++) { 3737c478bd9Sstevel@tonic-gate c = 0; 3747c478bd9Sstevel@tonic-gate for (j = 0; j < 6; j++) { 3757c478bd9Sstevel@tonic-gate c <<= 1; 3767c478bd9Sstevel@tonic-gate c |= block[6*i+j]; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate c += '.'; 3797c478bd9Sstevel@tonic-gate if (c > '9') 3807c478bd9Sstevel@tonic-gate c += 7; 3817c478bd9Sstevel@tonic-gate if (c > 'Z') 3827c478bd9Sstevel@tonic-gate c += 6; 3837c478bd9Sstevel@tonic-gate iobuf[i+2] = (char)c; 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate iobuf[i+2] = 0; 3867c478bd9Sstevel@tonic-gate if (iobuf[1] == 0) 3877c478bd9Sstevel@tonic-gate iobuf[1] = iobuf[0]; 3887c478bd9Sstevel@tonic-gate (void) mutex_unlock(&lock); 3897c478bd9Sstevel@tonic-gate return (iobuf); 3907c478bd9Sstevel@tonic-gate } 391