1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1988 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 #pragma weak _des_crypt = des_crypt
  33 #pragma weak _des_encrypt = des_encrypt
  34 #pragma weak _des_setkey = des_setkey
  35 
  36 #include <sys/types.h>
  37 #include <crypt.h>
  38 #include "des_soft.h"
  39 
  40 #include <stdlib.h>
  41 #include <thread.h>
  42 #include <pthread.h>
  43 #include <sys/types.h>
  44 
  45 /*
  46  * This program implements the
  47  * Proposed Federal Information Processing
  48  *  Data Encryption Standard.
  49  * See Federal Register, March 17, 1975 (40FR12134)
  50  */
  51 
  52 /*
  53  * Initial permutation,
  54  */
  55 static char IP[] = {
  56         58, 50, 42, 34, 26, 18, 10, 2,
  57         60, 52, 44, 36, 28, 20, 12, 4,
  58         62, 54, 46, 38, 30, 22, 14, 6,
  59         64, 56, 48, 40, 32, 24, 16, 8,
  60         57, 49, 41, 33, 25, 17, 9, 1,
  61         59, 51, 43, 35, 27, 19, 11, 3,
  62         61, 53, 45, 37, 29, 21, 13, 5,
  63         63, 55, 47, 39, 31, 23, 15, 7,
  64 };
  65 
  66 /*
  67  * Final permutation, FP = IP^(-1)
  68  */
  69 static char FP[] = {
  70         40, 8, 48, 16, 56, 24, 64, 32,
  71         39, 7, 47, 15, 55, 23, 63, 31,
  72         38, 6, 46, 14, 54, 22, 62, 30,
  73         37, 5, 45, 13, 53, 21, 61, 29,
  74         36, 4, 44, 12, 52, 20, 60, 28,
  75         35, 3, 43, 11, 51, 19, 59, 27,
  76         34, 2, 42, 10, 50, 18, 58, 26,
  77         33, 1, 41, 9, 49, 17, 57, 25,
  78 };
  79 
  80 /*
  81  * Permuted-choice 1 from the key bits
  82  * to yield C and D.
  83  * Note that bits 8, 16... are left out:
  84  * They are intended for a parity check.
  85  */
  86 static char PC1_C[] = {
  87         57, 49, 41, 33, 25, 17, 9,
  88         1, 58, 50, 42, 34, 26, 18,
  89         10, 2, 59, 51, 43, 35, 27,
  90         19, 11, 3, 60, 52, 44, 36,
  91 };
  92 
  93 static char PC1_D[] = {
  94         63, 55, 47, 39, 31, 23, 15,
  95         7, 62, 54, 46, 38, 30, 22,
  96         14, 6, 61, 53, 45, 37, 29,
  97         21, 13, 5, 28, 20, 12, 4,
  98 };
  99 
 100 /*
 101  * Sequence of shifts used for the key schedule.
 102  */
 103 static char shifts[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, };
 104 
 105 /*
 106  * Permuted-choice 2, to pick out the bits from
 107  * the CD array that generate the key schedule.
 108  */
 109 static char PC2_C[] = {
 110         14, 17, 11, 24, 1, 5,
 111         3, 28, 15, 6, 21, 10,
 112         23, 19, 12, 4, 26, 8,
 113         16, 7, 27, 20, 13, 2,
 114 };
 115 
 116 static char PC2_D[] = {
 117         41, 52, 31, 37, 47, 55,
 118         30, 40, 51, 45, 33, 48,
 119         44, 49, 39, 56, 34, 53,
 120         46, 42, 50, 36, 29, 32,
 121 };
 122 
 123 /*
 124  * The C and D arrays used to calculate the key schedule.
 125  */
 126 
 127 static char C[28];
 128 static char D[28];
 129 /*
 130  * The key schedule.
 131  * Generated from the key.
 132  */
 133 static char KS[16][48];
 134 
 135 /*
 136  * The E bit-selection table.
 137  */
 138 static char E[48];
 139 static char e2[] = {
 140         32, 1, 2, 3, 4, 5,
 141         4, 5, 6, 7, 8, 9,
 142         8, 9, 10, 11, 12, 13,
 143         12, 13, 14, 15, 16, 17,
 144         16, 17, 18, 19, 20, 21,
 145         20, 21, 22, 23, 24, 25,
 146         24, 25, 26, 27, 28, 29,
 147         28, 29, 30, 31, 32, 1,
 148 };
 149 
 150 /*
 151  * Set up the key schedule from the key.
 152  */
 153 
 154 static mutex_t lock = DEFAULTMUTEX;
 155 
 156 static void
 157 des_setkey_nolock(const char *key)
 158 {
 159         int i, j, k;
 160         char t;
 161 
 162         /*
 163          * First, generate C and D by permuting
 164          * the key.  The low order bit of each
 165          * 8-bit char is not used, so C and D are only 28
 166          * bits apiece.
 167          */
 168         for (i = 0; i < 28; i++) {
 169                 C[i] = key[PC1_C[i]-1];
 170                 D[i] = key[PC1_D[i]-1];
 171         }
 172         /*
 173          * To generate Ki, rotate C and D according
 174          * to schedule and pick up a permutation
 175          * using PC2.
 176          */
 177         for (i = 0; i < 16; i++) {
 178                 /*
 179                  * rotate.
 180                  */
 181                 for (k = 0; k < shifts[i]; k++) {
 182                         t = C[0];
 183                         for (j = 0; j < 28-1; j++)
 184                                 C[j] = C[j+1];
 185                         C[27] = (char)t;
 186                         t = D[0];
 187                         for (j = 0; j < 28-1; j++)
 188                                 D[j] = D[j+1];
 189                         D[27] = (char)t;
 190                 }
 191                 /*
 192                  * get Ki. Note C and D are concatenated.
 193                  */
 194                 for (j = 0; j < 24; j++) {
 195                         KS[i][j] = C[PC2_C[j]-1];
 196                         KS[i][j+24] = D[PC2_D[j]-28-1];
 197                 }
 198         }
 199 
 200         for (i = 0; i < 48; i++)
 201                 E[i] = e2[i];
 202 }
 203 
 204 void
 205 des_setkey(const char *key)
 206 {
 207         (void) mutex_lock(&lock);
 208         des_setkey_nolock(key);
 209         (void) mutex_unlock(&lock);
 210 }
 211 
 212 /*
 213  * The 8 selection functions.
 214  * For some reason, they give a 0-origin
 215  * index, unlike everything else.
 216  */
 217 static char S[8][64] = {
 218         14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
 219         0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
 220         4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
 221         15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
 222 
 223         15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
 224         3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
 225         0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
 226         13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
 227 
 228         10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
 229         13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
 230         13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
 231         1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
 232 
 233         7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
 234         13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
 235         10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
 236         3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
 237 
 238         2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
 239         14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
 240         4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
 241         11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
 242 
 243         12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
 244         10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
 245         9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
 246         4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
 247 
 248         4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
 249         13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
 250         1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
 251         6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
 252 
 253         13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
 254         1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
 255         7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
 256         2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
 257 };
 258 
 259 /*
 260  * P is a permutation on the selected combination
 261  * of the current L and key.
 262  */
 263 static char P[] = {
 264         16, 7, 20, 21,
 265         29, 12, 28, 17,
 266         1, 15, 23, 26,
 267         5, 18, 31, 10,
 268         2, 8, 24, 14,
 269         32, 27, 3, 9,
 270         19, 13, 30, 6,
 271         22, 11, 4, 25,
 272 };
 273 
 274 /*
 275  * The current block, divided into 2 halves.
 276  */
 277 static char L[64];
 278 static char tempL[32];
 279 static char f[32];
 280 
 281 /*
 282  * The combination of the key and the input, before selection.
 283  */
 284 static char preS[48];
 285 
 286 /*
 287  * The payoff: encrypt a block.
 288  */
 289 
 290 static void
 291 des_encrypt_nolock(char *block, int edflag)
 292 {
 293         if (edflag)
 294                 (void) _des_decrypt1(block, L, IP, &L[32],
 295                     preS, E, KS, S, f, tempL, P, FP);
 296         else
 297                 (void) des_encrypt1(block, L, IP, &L[32],
 298                     preS, E, KS, S, f, tempL, P, FP);
 299 }
 300 
 301 void
 302 des_encrypt(char *block, int edflag)
 303 {
 304         (void) mutex_lock(&lock);
 305         des_encrypt_nolock(block, edflag);
 306         (void) mutex_unlock(&lock);
 307 }
 308 
 309 
 310 
 311 #define IOBUF_SIZE      16
 312 
 313 static char *
 314 _get_iobuf(thread_key_t *keyp, unsigned size)
 315 {
 316         char *iobuf;
 317 
 318         if (thr_keycreate_once(keyp, free) != 0)
 319                 return (NULL);
 320         iobuf = pthread_getspecific(*keyp);
 321         if (iobuf == NULL) {
 322                 if (thr_setspecific(*keyp, (iobuf = malloc(size))) != 0) {
 323                         if (iobuf)
 324                                 (void) free(iobuf);
 325                         iobuf = NULL;
 326                 }
 327         }
 328         return (iobuf);
 329 }
 330 
 331 char *
 332 des_crypt(const char *pw, const char *salt)
 333 {
 334         int     i, j;
 335         char    c, temp;
 336         char block[66];
 337         static thread_key_t key = THR_ONCE_KEY;
 338         char *iobuf = _get_iobuf(&key, IOBUF_SIZE);
 339 
 340         (void) mutex_lock(&lock);
 341         for (i = 0; i < 66; i++)
 342                 block[i] = 0;
 343         for (i = 0; (c = *pw) && (i < 64); pw++) {
 344                 for (j = 0; j < 7; j++, i++)
 345                         block[i] = (c>>(6-j)) & 01;
 346                 i++;
 347         }
 348 
 349         des_setkey_nolock(block);
 350 
 351         for (i = 0; i < 66; i++)
 352                 block[i] = 0;
 353 
 354         for (i = 0; i < 2; i++) {
 355                 c = *salt++;
 356                 iobuf[i] = (char)c;
 357                 if (c > 'Z')
 358                         c -= 6;
 359                 if (c > '9')
 360                         c -= 7;
 361                 c -= '.';
 362                 for (j = 0; j < 6; j++) {
 363                         if ((c>>j) & 01) {
 364                                 temp = E[6*i+j];
 365                                 E[6*i+j] = E[6*i+j+24];
 366                                 E[6*i+j+24] = (char)temp;
 367                         }
 368                 }
 369         }
 370 
 371         for (i = 0; i < 25; i++)
 372                 (void) des_encrypt_nolock(block, 0);
 373 
 374         for (i = 0; i < 11; i++) {
 375                 c = 0;
 376                 for (j = 0; j < 6; j++) {
 377                         c <<= 1;
 378                         c |= block[6*i+j];
 379                 }
 380                 c += '.';
 381                 if (c > '9')
 382                         c += 7;
 383                 if (c > 'Z')
 384                         c += 6;
 385                 iobuf[i+2] = (char)c;
 386         }
 387         iobuf[i+2] = 0;
 388         if (iobuf[1] == 0)
 389                 iobuf[1] = iobuf[0];
 390         (void) mutex_unlock(&lock);
 391         return (iobuf);
 392 }