1*48d3e433Sjsing /* $OpenBSD: des_fcrypt.c,v 1.4 2024/08/31 16:22:18 jsing Exp $ */ 2cc54cb09Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3cc54cb09Sjsing * All rights reserved. 4cc54cb09Sjsing * 5cc54cb09Sjsing * This package is an SSL implementation written 6cc54cb09Sjsing * by Eric Young (eay@cryptsoft.com). 7cc54cb09Sjsing * The implementation was written so as to conform with Netscapes SSL. 8cc54cb09Sjsing * 9cc54cb09Sjsing * This library is free for commercial and non-commercial use as long as 10cc54cb09Sjsing * the following conditions are aheared to. The following conditions 11cc54cb09Sjsing * apply to all code found in this distribution, be it the RC4, RSA, 12cc54cb09Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13cc54cb09Sjsing * included with this distribution is covered by the same copyright terms 14cc54cb09Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15cc54cb09Sjsing * 16cc54cb09Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in 17cc54cb09Sjsing * the code are not to be removed. 18cc54cb09Sjsing * If this package is used in a product, Eric Young should be given attribution 19cc54cb09Sjsing * as the author of the parts of the library used. 20cc54cb09Sjsing * This can be in the form of a textual message at program startup or 21cc54cb09Sjsing * in documentation (online or textual) provided with the package. 22cc54cb09Sjsing * 23cc54cb09Sjsing * Redistribution and use in source and binary forms, with or without 24cc54cb09Sjsing * modification, are permitted provided that the following conditions 25cc54cb09Sjsing * are met: 26cc54cb09Sjsing * 1. Redistributions of source code must retain the copyright 27cc54cb09Sjsing * notice, this list of conditions and the following disclaimer. 28cc54cb09Sjsing * 2. Redistributions in binary form must reproduce the above copyright 29cc54cb09Sjsing * notice, this list of conditions and the following disclaimer in the 30cc54cb09Sjsing * documentation and/or other materials provided with the distribution. 31cc54cb09Sjsing * 3. All advertising materials mentioning features or use of this software 32cc54cb09Sjsing * must display the following acknowledgement: 33cc54cb09Sjsing * "This product includes cryptographic software written by 34cc54cb09Sjsing * Eric Young (eay@cryptsoft.com)" 35cc54cb09Sjsing * The word 'cryptographic' can be left out if the rouines from the library 36cc54cb09Sjsing * being used are not cryptographic related :-). 37cc54cb09Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from 38cc54cb09Sjsing * the apps directory (application code) you must include an acknowledgement: 39cc54cb09Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40cc54cb09Sjsing * 41cc54cb09Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42cc54cb09Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43cc54cb09Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44cc54cb09Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45cc54cb09Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46cc54cb09Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47cc54cb09Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48cc54cb09Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49cc54cb09Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50cc54cb09Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51cc54cb09Sjsing * SUCH DAMAGE. 52cc54cb09Sjsing * 53cc54cb09Sjsing * The licence and distribution terms for any publically available version or 54cc54cb09Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 55cc54cb09Sjsing * copied and put under another distribution licence 56cc54cb09Sjsing * [including the GNU Public Licence.] 57cc54cb09Sjsing */ 58cc54cb09Sjsing 59cc54cb09Sjsing #include <stdio.h> 60cc54cb09Sjsing 61cc54cb09Sjsing /* This version of crypt has been developed from my MIT compatible 62cc54cb09Sjsing * DES library. 63cc54cb09Sjsing * Eric Young (eay@cryptsoft.com) 64cc54cb09Sjsing */ 65cc54cb09Sjsing 66cc54cb09Sjsing /* Modification by Jens Kupferschmidt (Cu) 67cc54cb09Sjsing * I have included directive PARA for shared memory computers. 68cc54cb09Sjsing * I have included a directive LONGCRYPT to using this routine to cipher 69cc54cb09Sjsing * passwords with more than 8 bytes like HP-UX 10.x it used. The MAXPLEN 70cc54cb09Sjsing * definition is the maximum of length of password and can changed. I have 71cc54cb09Sjsing * defined 24. 72cc54cb09Sjsing */ 73cc54cb09Sjsing 74cc54cb09Sjsing #define DES_FCRYPT 75cc54cb09Sjsing #include "des_local.h" 76cc54cb09Sjsing #undef DES_FCRYPT 77cc54cb09Sjsing 78cc54cb09Sjsing #undef PERM_OP 79cc54cb09Sjsing #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)), \ 80cc54cb09Sjsing (b)^=(t), \ 81cc54cb09Sjsing (a)^=((t)<<(n))) 82cc54cb09Sjsing 83cc54cb09Sjsing #undef HPERM_OP 84cc54cb09Sjsing #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)), \ 85cc54cb09Sjsing (a)=(a)^(t)^(t>>(16-(n)))) \ 86cc54cb09Sjsing 87*48d3e433Sjsing static void 88cc54cb09Sjsing fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0, 89cc54cb09Sjsing DES_LONG Eswap1) 90cc54cb09Sjsing { 91cc54cb09Sjsing DES_LONG l, r, t, u; 92cc54cb09Sjsing DES_LONG *s; 93cc54cb09Sjsing int j; 94cc54cb09Sjsing DES_LONG E0, E1; 95cc54cb09Sjsing 96cc54cb09Sjsing l = 0; 97cc54cb09Sjsing r = 0; 98cc54cb09Sjsing 99cc54cb09Sjsing s = (DES_LONG *)ks; 100cc54cb09Sjsing E0 = Eswap0; 101cc54cb09Sjsing E1 = Eswap1; 102cc54cb09Sjsing 103cc54cb09Sjsing for (j = 0; j < 25; j++) { 104cc54cb09Sjsing #ifndef DES_UNROLL 105cc54cb09Sjsing int i; 106cc54cb09Sjsing 107cc54cb09Sjsing for (i = 0; i < 32; i += 4) { 108cc54cb09Sjsing D_ENCRYPT(l, r, i + 0); /* 1 */ 109cc54cb09Sjsing D_ENCRYPT(r, l, i + 2); /* 2 */ 110cc54cb09Sjsing } 111cc54cb09Sjsing #else 112cc54cb09Sjsing D_ENCRYPT(l, r, 0); /* 1 */ 113cc54cb09Sjsing D_ENCRYPT(r, l, 2); /* 2 */ 114cc54cb09Sjsing D_ENCRYPT(l, r, 4); /* 3 */ 115cc54cb09Sjsing D_ENCRYPT(r, l, 6); /* 4 */ 116cc54cb09Sjsing D_ENCRYPT(l, r, 8); /* 5 */ 117cc54cb09Sjsing D_ENCRYPT(r, l, 10); /* 6 */ 118cc54cb09Sjsing D_ENCRYPT(l, r, 12); /* 7 */ 119cc54cb09Sjsing D_ENCRYPT(r, l, 14); /* 8 */ 120cc54cb09Sjsing D_ENCRYPT(l, r, 16); /* 9 */ 121cc54cb09Sjsing D_ENCRYPT(r, l, 18); /* 10 */ 122cc54cb09Sjsing D_ENCRYPT(l, r, 20); /* 11 */ 123cc54cb09Sjsing D_ENCRYPT(r, l, 22); /* 12 */ 124cc54cb09Sjsing D_ENCRYPT(l, r, 24); /* 13 */ 125cc54cb09Sjsing D_ENCRYPT(r, l, 26); /* 14 */ 126cc54cb09Sjsing D_ENCRYPT(l, r, 28); /* 15 */ 127cc54cb09Sjsing D_ENCRYPT(r, l, 30); /* 16 */ 128cc54cb09Sjsing #endif 129cc54cb09Sjsing 130cc54cb09Sjsing t = l; 131cc54cb09Sjsing l = r; 132cc54cb09Sjsing r = t; 133cc54cb09Sjsing } 134cc54cb09Sjsing l = ROTATE(l, 3) & 0xffffffffL; 135cc54cb09Sjsing r = ROTATE(r, 3) & 0xffffffffL; 136cc54cb09Sjsing 137cc54cb09Sjsing PERM_OP(l, r, t, 1, 0x55555555L); 138cc54cb09Sjsing PERM_OP(r, l, t, 8, 0x00ff00ffL); 139cc54cb09Sjsing PERM_OP(l, r, t, 2, 0x33333333L); 140cc54cb09Sjsing PERM_OP(r, l, t, 16, 0x0000ffffL); 141cc54cb09Sjsing PERM_OP(l, r, t, 4, 0x0f0f0f0fL); 142cc54cb09Sjsing 143cc54cb09Sjsing out[0] = r; 144cc54cb09Sjsing out[1] = l; 145cc54cb09Sjsing } 146cc54cb09Sjsing 147cc54cb09Sjsing /* Added more values to handle illegal salt values the way normal 148cc54cb09Sjsing * crypt() implementations do. The patch was sent by 149cc54cb09Sjsing * Bjorn Gronvall <bg@sics.se> 150cc54cb09Sjsing */ 151cc54cb09Sjsing static unsigned const char con_salt[128] = { 152cc54cb09Sjsing 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 153cc54cb09Sjsing 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 154cc54cb09Sjsing 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 155cc54cb09Sjsing 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 156cc54cb09Sjsing 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 157cc54cb09Sjsing 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 158cc54cb09Sjsing 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 159cc54cb09Sjsing 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 160cc54cb09Sjsing 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 161cc54cb09Sjsing 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 162cc54cb09Sjsing 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 163cc54cb09Sjsing 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, 164cc54cb09Sjsing 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 165cc54cb09Sjsing 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 166cc54cb09Sjsing 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 167cc54cb09Sjsing 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 168cc54cb09Sjsing }; 169cc54cb09Sjsing 170cc54cb09Sjsing static unsigned const char cov_2char[64] = { 171cc54cb09Sjsing 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 172cc54cb09Sjsing 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 173cc54cb09Sjsing 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 174cc54cb09Sjsing 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 175cc54cb09Sjsing 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 176cc54cb09Sjsing 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 177cc54cb09Sjsing 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 178cc54cb09Sjsing 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A 179cc54cb09Sjsing }; 180cc54cb09Sjsing 181cc54cb09Sjsing char * 182cc54cb09Sjsing DES_crypt(const char *buf, const char *salt) 183cc54cb09Sjsing { 184cc54cb09Sjsing static char buff[14]; 185cc54cb09Sjsing 186cc54cb09Sjsing return (DES_fcrypt(buf, salt, buff)); 187cc54cb09Sjsing } 188cc54cb09Sjsing LCRYPTO_ALIAS(DES_crypt); 189cc54cb09Sjsing 190cc54cb09Sjsing char * 191cc54cb09Sjsing DES_fcrypt(const char *buf, const char *salt, char *ret) 192cc54cb09Sjsing { 193cc54cb09Sjsing unsigned int i, j, x, y; 194cc54cb09Sjsing DES_LONG Eswap0, Eswap1; 195cc54cb09Sjsing DES_LONG out[2], ll; 196cc54cb09Sjsing DES_cblock key; 197cc54cb09Sjsing DES_key_schedule ks; 198cc54cb09Sjsing unsigned char bb[9]; 199cc54cb09Sjsing unsigned char *b = bb; 200cc54cb09Sjsing unsigned char c, u; 201cc54cb09Sjsing 202cc54cb09Sjsing /* eay 25/08/92 203cc54cb09Sjsing * If you call crypt("pwd","*") as often happens when you 204cc54cb09Sjsing * have * as the pwd field in /etc/passwd, the function 205cc54cb09Sjsing * returns *\0xxxxxxxxx 206cc54cb09Sjsing * The \0 makes the string look like * so the pwd "*" would 207cc54cb09Sjsing * crypt to "*". This was found when replacing the crypt in 208cc54cb09Sjsing * our shared libraries. People found that the disabled 209cc54cb09Sjsing * accounts effectively had no passwd :-(. */ 210cc54cb09Sjsing x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]); 211cc54cb09Sjsing Eswap0 = con_salt[x] << 2; 212cc54cb09Sjsing x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]); 213cc54cb09Sjsing Eswap1 = con_salt[x] << 6; 214cc54cb09Sjsing /* EAY 215cc54cb09Sjsing r=strlen(buf); 216cc54cb09Sjsing r=(r+7)/8; 217cc54cb09Sjsing */ 218cc54cb09Sjsing for (i = 0; i < 8; i++) { 219cc54cb09Sjsing c = *(buf++); 220cc54cb09Sjsing if (!c) 221cc54cb09Sjsing break; 222cc54cb09Sjsing key[i] = (c << 1); 223cc54cb09Sjsing } 224cc54cb09Sjsing for (; i < 8; i++) 225cc54cb09Sjsing key[i] = 0; 226cc54cb09Sjsing 227cc54cb09Sjsing DES_set_key_unchecked(&key, &ks); 228cc54cb09Sjsing fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1); 229cc54cb09Sjsing 230cc54cb09Sjsing ll = out[0]; 231cc54cb09Sjsing l2c(ll, b); 232cc54cb09Sjsing ll = out[1]; 233cc54cb09Sjsing l2c(ll, b); 234cc54cb09Sjsing y = 0; 235cc54cb09Sjsing u = 0x80; 236cc54cb09Sjsing bb[8] = 0; 237cc54cb09Sjsing for (i = 2; i < 13; i++) { 238cc54cb09Sjsing c = 0; 239cc54cb09Sjsing for (j = 0; j < 6; j++) { 240cc54cb09Sjsing c <<= 1; 241cc54cb09Sjsing if (bb[y] & u) 242cc54cb09Sjsing c |= 1; 243cc54cb09Sjsing u >>= 1; 244cc54cb09Sjsing if (!u) { 245cc54cb09Sjsing y++; 246cc54cb09Sjsing u = 0x80; 247cc54cb09Sjsing } 248cc54cb09Sjsing } 249cc54cb09Sjsing ret[i] = cov_2char[c]; 250cc54cb09Sjsing } 251cc54cb09Sjsing ret[13] = '\0'; 252cc54cb09Sjsing return (ret); 253cc54cb09Sjsing } 254cc54cb09Sjsing LCRYPTO_ALIAS(DES_fcrypt); 255