Blame crypt/crypt_util.c

Packit 6c4009
/*
Packit 6c4009
 * UFC-crypt: ultra fast crypt(3) implementation
Packit 6c4009
 *
Packit 6c4009
 * Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit 6c4009
 *
Packit 6c4009
 * This library is free software; you can redistribute it and/or
Packit 6c4009
 * modify it under the terms of the GNU Lesser General Public
Packit 6c4009
 * License as published by the Free Software Foundation; either
Packit 6c4009
 * version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
 *
Packit 6c4009
 * This library is distributed in the hope that it will be useful,
Packit 6c4009
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
 * Lesser General Public License for more details.
Packit 6c4009
 *
Packit 6c4009
 * You should have received a copy of the GNU Lesser General Public
Packit 6c4009
 * License along with this library; see the file COPYING.LIB.  If not,
Packit 6c4009
 * see <http://www.gnu.org/licenses/>.
Packit 6c4009
 *
Packit 6c4009
 * @(#)crypt_util.c	2.56 12/20/96
Packit 6c4009
 *
Packit 6c4009
 * Support routines
Packit 6c4009
 *
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
#ifdef DEBUG
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#endif
Packit 6c4009
#include <atomic.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
Packit 6c4009
#ifndef STATIC
Packit 6c4009
#define STATIC static
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include "crypt-private.h"
Packit 6c4009
#include <shlib-compat.h>
Packit 6c4009
Packit 6c4009
/* Prototypes for local functions.  */
Packit 6c4009
#ifndef __GNU_LIBRARY__
Packit 6c4009
void _ufc_clearmem (char *start, int cnt);
Packit 6c4009
void _ufc_copymem (char *from, char *to, int cnt);
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
STATIC void shuffle_sb (long32 *k, ufc_long saltbits);
Packit 6c4009
#else
Packit 6c4009
STATIC void shuffle_sb (long64 *k, ufc_long saltbits);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Permutation done once on the 56 bit
Packit 6c4009
 *  key derived from the original 8 byte ASCII key.
Packit 6c4009
 */
Packit 6c4009
static const int pc1[56] = {
Packit 6c4009
  57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
Packit 6c4009
  10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
Packit 6c4009
  63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
Packit 6c4009
  14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * How much to rotate each 28 bit half of the pc1 permutated
Packit 6c4009
 *  56 bit key before using pc2 to give the i' key
Packit 6c4009
 */
Packit 6c4009
static const int rots[16] = {
Packit 6c4009
  1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Permutation giving the key
Packit 6c4009
 * of the i' DES round
Packit 6c4009
 */
Packit 6c4009
static const int pc2[48] = {
Packit 6c4009
  14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
Packit 6c4009
  23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
Packit 6c4009
  41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
Packit 6c4009
  44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * The E expansion table which selects
Packit 6c4009
 * bits from the 32 bit intermediate result.
Packit 6c4009
 */
Packit 6c4009
static const int esel[48] = {
Packit 6c4009
  32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
Packit 6c4009
   8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
Packit 6c4009
  16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
Packit 6c4009
  24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Permutation done on the
Packit 6c4009
 * result of sbox lookups
Packit 6c4009
 */
Packit 6c4009
static const int perm32[32] = {
Packit 6c4009
  16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
Packit 6c4009
  2,   8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * The sboxes
Packit 6c4009
 */
Packit 6c4009
static const int sbox[8][4][16]= {
Packit 6c4009
	{ { 14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7 },
Packit 6c4009
	  {  0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8 },
Packit 6c4009
	  {  4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0 },
Packit 6c4009
	  { 15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ { 15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10 },
Packit 6c4009
	  {  3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5 },
Packit 6c4009
	  {  0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15 },
Packit 6c4009
	  { 13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ { 10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8 },
Packit 6c4009
	  { 13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1 },
Packit 6c4009
	  { 13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7 },
Packit 6c4009
	  {  1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ {  7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15 },
Packit 6c4009
	  { 13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9 },
Packit 6c4009
	  { 10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4 },
Packit 6c4009
	  {  3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ {  2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9 },
Packit 6c4009
	  { 14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6 },
Packit 6c4009
	  {  4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14 },
Packit 6c4009
	  { 11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ { 12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11 },
Packit 6c4009
	  { 10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8 },
Packit 6c4009
	  {  9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6 },
Packit 6c4009
	  {  4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ {  4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1 },
Packit 6c4009
	  { 13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6 },
Packit 6c4009
	  {  1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2 },
Packit 6c4009
	  {  6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12 }
Packit 6c4009
	},
Packit 6c4009
Packit 6c4009
	{ { 13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7 },
Packit 6c4009
	  {  1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2 },
Packit 6c4009
	  {  7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8 },
Packit 6c4009
	  {  2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11 }
Packit 6c4009
	}
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
Packit 6c4009
/*
Packit 6c4009
 * This is the initial
Packit 6c4009
 * permutation matrix
Packit 6c4009
 */
Packit 6c4009
static const int initial_perm[64] = {
Packit 6c4009
  58, 50, 42, 34, 26, 18, 10,  2, 60, 52, 44, 36, 28, 20, 12, 4,
Packit 6c4009
  62, 54, 46, 38, 30, 22, 14,  6, 64, 56, 48, 40, 32, 24, 16, 8,
Packit 6c4009
  57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11, 3,
Packit 6c4009
  61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15, 7
Packit 6c4009
};
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * This is the final
Packit 6c4009
 * permutation matrix
Packit 6c4009
 */
Packit 6c4009
static const int final_perm[64] = {
Packit 6c4009
  40,  8, 48, 16, 56, 24, 64, 32, 39,  7, 47, 15, 55, 23, 63, 31,
Packit 6c4009
  38,  6, 46, 14, 54, 22, 62, 30, 37,  5, 45, 13, 53, 21, 61, 29,
Packit 6c4009
  36,  4, 44, 12, 52, 20, 60, 28, 35,  3, 43, 11, 51, 19, 59, 27,
Packit 6c4009
  34,  2, 42, 10, 50, 18, 58, 26, 33,  1, 41,  9, 49, 17, 57, 25
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
Packit 6c4009
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
Packit 6c4009
Packit 6c4009
static const ufc_long BITMASK[24] = {
Packit 6c4009
  0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000,
Packit 6c4009
  0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000,
Packit 6c4009
  0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200,
Packit 6c4009
  0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
static const unsigned char bytemask[8]  = {
Packit 6c4009
  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
static const ufc_long longmask[32] = {
Packit 6c4009
  0x80000000, 0x40000000, 0x20000000, 0x10000000,
Packit 6c4009
  0x08000000, 0x04000000, 0x02000000, 0x01000000,
Packit 6c4009
  0x00800000, 0x00400000, 0x00200000, 0x00100000,
Packit 6c4009
  0x00080000, 0x00040000, 0x00020000, 0x00010000,
Packit 6c4009
  0x00008000, 0x00004000, 0x00002000, 0x00001000,
Packit 6c4009
  0x00000800, 0x00000400, 0x00000200, 0x00000100,
Packit 6c4009
  0x00000080, 0x00000040, 0x00000020, 0x00000010,
Packit 6c4009
  0x00000008, 0x00000004, 0x00000002, 0x00000001
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * do_pc1: permform pc1 permutation in the key schedule generation.
Packit 6c4009
 *
Packit 6c4009
 * The first   index is the byte number in the 8 byte ASCII key
Packit 6c4009
 *  -  second    -      -    the two 28 bits halfs of the result
Packit 6c4009
 *  -  third     -   selects the 7 bits actually used of each byte
Packit 6c4009
 *
Packit 6c4009
 * The result is kept with 28 bit per 32 bit with the 4 most significant
Packit 6c4009
 * bits zero.
Packit 6c4009
 */
Packit 6c4009
static ufc_long do_pc1[8][2][128];
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * do_pc2: permform pc2 permutation in the key schedule generation.
Packit 6c4009
 *
Packit 6c4009
 * The first   index is the septet number in the two 28 bit intermediate values
Packit 6c4009
 *  -  second    -    -  -  septet values
Packit 6c4009
 *
Packit 6c4009
 * Knowledge of the structure of the pc2 permutation is used.
Packit 6c4009
 *
Packit 6c4009
 * The result is kept with 28 bit per 32 bit with the 4 most significant
Packit 6c4009
 * bits zero.
Packit 6c4009
 */
Packit 6c4009
static ufc_long do_pc2[8][128];
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * eperm32tab: do 32 bit permutation and E selection
Packit 6c4009
 *
Packit 6c4009
 * The first index is the byte number in the 32 bit value to be permuted
Packit 6c4009
 *  -  second  -   is the value of this byte
Packit 6c4009
 *  -  third   -   selects the two 32 bit values
Packit 6c4009
 *
Packit 6c4009
 * The table is used and generated internally in init_des to speed it up
Packit 6c4009
 */
Packit 6c4009
static ufc_long eperm32tab[4][256][2];
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * efp: undo an extra e selection and do final
Packit 6c4009
 *      permutation giving the DES result.
Packit 6c4009
 *
Packit 6c4009
 *      Invoked 6 bit a time on two 48 bit values
Packit 6c4009
 *      giving two 32 bit longs.
Packit 6c4009
 */
Packit 6c4009
static ufc_long efp[16][64][2];
Packit 6c4009
Packit 6c4009
/* Table with characters for base64 transformation.  */
Packit 6c4009
static const char b64t[64] =
Packit 6c4009
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * For use by the old, non-reentrant routines
Packit 6c4009
 * (crypt/encrypt/setkey)
Packit 6c4009
 */
Packit 6c4009
struct crypt_data _ufc_foobar;
Packit 6c4009
Packit 6c4009
#ifdef __GNU_LIBRARY__
Packit 6c4009
#include <libc-lock.h>
Packit 6c4009
Packit 6c4009
__libc_lock_define_initialized (static, _ufc_tables_lock)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef DEBUG
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_ufc_prbits (ufc_long *a, int n)
Packit 6c4009
{
Packit 6c4009
  ufc_long i, j, t, tmp;
Packit 6c4009
  n /= 8;
Packit 6c4009
  for(i = 0; i < n; i++) {
Packit 6c4009
    tmp=0;
Packit 6c4009
    for(j = 0; j < 8; j++) {
Packit 6c4009
      t=8*i+j;
Packit 6c4009
      tmp|=(a[t/24] & BITMASK[t % 24])?bytemask[j]:0;
Packit 6c4009
    }
Packit 6c4009
    (void)printf("%02lx ", tmp);
Packit 6c4009
  }
Packit 6c4009
  printf(" ");
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void __attribute__ ((unused))
Packit 6c4009
_ufc_set_bits (ufc_long v, ufc_long *b)
Packit 6c4009
{
Packit 6c4009
  ufc_long i;
Packit 6c4009
  *b = 0;
Packit 6c4009
  for(i = 0; i < 24; i++) {
Packit 6c4009
    if(v & longmask[8 + i])
Packit 6c4009
      *b |= BITMASK[i];
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifndef __GNU_LIBRARY__
Packit 6c4009
/*
Packit 6c4009
 * Silly rewrites of 'bzero'/'memset'. I do so
Packit 6c4009
 * because some machines don't have
Packit 6c4009
 * bzero and some don't have memset.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_ufc_clearmem (char *start, int cnt)
Packit 6c4009
{
Packit 6c4009
  while(cnt--)
Packit 6c4009
    *start++ = '\0';
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_ufc_copymem (char *from, char *to, int cnt)
Packit 6c4009
{
Packit 6c4009
  while(cnt--)
Packit 6c4009
    *to++ = *from++;
Packit 6c4009
}
Packit 6c4009
#else
Packit 6c4009
#define _ufc_clearmem(start, cnt)   memset(start, 0, cnt)
Packit 6c4009
#define _ufc_copymem(from, to, cnt) memcpy(to, from, cnt)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* lookup a 6 bit value in sbox */
Packit 6c4009
Packit 6c4009
#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Initialize unit - may be invoked directly
Packit 6c4009
 * by fcrypt users.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
__init_des_r (struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  int comes_from_bit;
Packit 6c4009
  int bit, sg;
Packit 6c4009
  ufc_long j;
Packit 6c4009
  ufc_long mask1, mask2;
Packit 6c4009
  int e_inverse[64];
Packit 6c4009
  static volatile int small_tables_initialized = 0;
Packit 6c4009
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
  long32 *sb[4];
Packit 6c4009
  sb[0] = (long32*)__data->sb0; sb[1] = (long32*)__data->sb1;
Packit 6c4009
  sb[2] = (long32*)__data->sb2; sb[3] = (long32*)__data->sb3;
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
  long64 *sb[4];
Packit 6c4009
  sb[0] = (long64*)__data->sb0; sb[1] = (long64*)__data->sb1;
Packit 6c4009
  sb[2] = (long64*)__data->sb2; sb[3] = (long64*)__data->sb3;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  if(small_tables_initialized == 0) {
Packit 6c4009
#ifdef __GNU_LIBRARY__
Packit 6c4009
    __libc_lock_lock (_ufc_tables_lock);
Packit 6c4009
    if(small_tables_initialized)
Packit 6c4009
      goto small_tables_done;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    /*
Packit 6c4009
     * Create the do_pc1 table used
Packit 6c4009
     * to affect pc1 permutation
Packit 6c4009
     * when generating keys
Packit 6c4009
     */
Packit 6c4009
    _ufc_clearmem((char*)do_pc1, (int)sizeof(do_pc1));
Packit 6c4009
    for(bit = 0; bit < 56; bit++) {
Packit 6c4009
      comes_from_bit  = pc1[bit] - 1;
Packit 6c4009
      mask1 = bytemask[comes_from_bit % 8 + 1];
Packit 6c4009
      mask2 = longmask[bit % 28 + 4];
Packit 6c4009
      for(j = 0; j < 128; j++) {
Packit 6c4009
	if(j & mask1)
Packit 6c4009
	  do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
    /*
Packit 6c4009
     * Create the do_pc2 table used
Packit 6c4009
     * to affect pc2 permutation when
Packit 6c4009
     * generating keys
Packit 6c4009
     */
Packit 6c4009
    _ufc_clearmem((char*)do_pc2, (int)sizeof(do_pc2));
Packit 6c4009
    for(bit = 0; bit < 48; bit++) {
Packit 6c4009
      comes_from_bit  = pc2[bit] - 1;
Packit 6c4009
      mask1 = bytemask[comes_from_bit % 7 + 1];
Packit 6c4009
      mask2 = BITMASK[bit % 24];
Packit 6c4009
      for(j = 0; j < 128; j++) {
Packit 6c4009
	if(j & mask1)
Packit 6c4009
	  do_pc2[comes_from_bit / 7][j] |= mask2;
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
    /*
Packit 6c4009
     * Now generate the table used to do combined
Packit 6c4009
     * 32 bit permutation and e expansion
Packit 6c4009
     *
Packit 6c4009
     * We use it because we have to permute 16384 32 bit
Packit 6c4009
     * longs into 48 bit in order to initialize sb.
Packit 6c4009
     *
Packit 6c4009
     * Looping 48 rounds per permutation becomes
Packit 6c4009
     * just too slow...
Packit 6c4009
     *
Packit 6c4009
     */
Packit 6c4009
Packit 6c4009
    _ufc_clearmem((char*)eperm32tab, (int)sizeof(eperm32tab));
Packit 6c4009
    for(bit = 0; bit < 48; bit++) {
Packit 6c4009
      ufc_long mask1,comes_from;
Packit 6c4009
      comes_from = perm32[esel[bit]-1]-1;
Packit 6c4009
      mask1      = bytemask[comes_from % 8];
Packit 6c4009
      for(j = 256; j--;) {
Packit 6c4009
	if(j & mask1)
Packit 6c4009
	  eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK[bit % 24];
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
    /*
Packit 6c4009
     * Create an inverse matrix for esel telling
Packit 6c4009
     * where to plug out bits if undoing it
Packit 6c4009
     */
Packit 6c4009
    for(bit=48; bit--;) {
Packit 6c4009
      e_inverse[esel[bit] - 1     ] = bit;
Packit 6c4009
      e_inverse[esel[bit] - 1 + 32] = bit + 48;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
    /*
Packit 6c4009
     * create efp: the matrix used to
Packit 6c4009
     * undo the E expansion and effect final permutation
Packit 6c4009
     */
Packit 6c4009
    _ufc_clearmem((char*)efp, (int)sizeof efp);
Packit 6c4009
    for(bit = 0; bit < 64; bit++) {
Packit 6c4009
      int o_bit, o_long;
Packit 6c4009
      ufc_long word_value, mask1, mask2;
Packit 6c4009
      int comes_from_f_bit, comes_from_e_bit;
Packit 6c4009
      int comes_from_word, bit_within_word;
Packit 6c4009
Packit 6c4009
      /* See where bit i belongs in the two 32 bit long's */
Packit 6c4009
      o_long = bit / 32; /* 0..1  */
Packit 6c4009
      o_bit  = bit % 32; /* 0..31 */
Packit 6c4009
Packit 6c4009
      /*
Packit 6c4009
       * And find a bit in the e permutated value setting this bit.
Packit 6c4009
       *
Packit 6c4009
       * Note: the e selection may have selected the same bit several
Packit 6c4009
       * times. By the initialization of e_inverse, we only look
Packit 6c4009
       * for one specific instance.
Packit 6c4009
       */
Packit 6c4009
      comes_from_f_bit = final_perm[bit] - 1;         /* 0..63 */
Packit 6c4009
      comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */
Packit 6c4009
      comes_from_word  = comes_from_e_bit / 6;        /* 0..15 */
Packit 6c4009
      bit_within_word  = comes_from_e_bit % 6;        /* 0..5  */
Packit 6c4009
Packit 6c4009
      mask1 = longmask[bit_within_word + 26];
Packit 6c4009
      mask2 = longmask[o_bit];
Packit 6c4009
Packit 6c4009
      for(word_value = 64; word_value--;) {
Packit 6c4009
	if(word_value & mask1)
Packit 6c4009
	  efp[comes_from_word][word_value][o_long] |= mask2;
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
    atomic_write_barrier ();
Packit 6c4009
    small_tables_initialized = 1;
Packit 6c4009
#ifdef __GNU_LIBRARY__
Packit 6c4009
small_tables_done:
Packit 6c4009
    __libc_lock_unlock(_ufc_tables_lock);
Packit 6c4009
#endif
Packit 6c4009
  } else
Packit 6c4009
    atomic_read_barrier ();
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Create the sb tables:
Packit 6c4009
   *
Packit 6c4009
   * For each 12 bit segment of an 48 bit intermediate
Packit 6c4009
   * result, the sb table precomputes the two 4 bit
Packit 6c4009
   * values of the sbox lookups done with the two 6
Packit 6c4009
   * bit halves, shifts them to their proper place,
Packit 6c4009
   * sends them through perm32 and finally E expands
Packit 6c4009
   * them so that they are ready for the next
Packit 6c4009
   * DES round.
Packit 6c4009
   *
Packit 6c4009
   */
Packit 6c4009
Packit 6c4009
  if (__data->sb0 + sizeof (__data->sb0) == __data->sb1
Packit 6c4009
      && __data->sb1 + sizeof (__data->sb1) == __data->sb2
Packit 6c4009
      && __data->sb2 + sizeof (__data->sb2) == __data->sb3)
Packit 6c4009
    _ufc_clearmem(__data->sb0,
Packit 6c4009
		  (int)sizeof(__data->sb0)
Packit 6c4009
		  + (int)sizeof(__data->sb1)
Packit 6c4009
		  + (int)sizeof(__data->sb2)
Packit 6c4009
		  + (int)sizeof(__data->sb3));
Packit 6c4009
  else {
Packit 6c4009
    _ufc_clearmem(__data->sb0, (int)sizeof(__data->sb0));
Packit 6c4009
    _ufc_clearmem(__data->sb1, (int)sizeof(__data->sb1));
Packit 6c4009
    _ufc_clearmem(__data->sb2, (int)sizeof(__data->sb2));
Packit 6c4009
    _ufc_clearmem(__data->sb3, (int)sizeof(__data->sb3));
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  for(sg = 0; sg < 4; sg++) {
Packit 6c4009
    int j1, j2;
Packit 6c4009
    int s1, s2;
Packit 6c4009
Packit 6c4009
    for(j1 = 0; j1 < 64; j1++) {
Packit 6c4009
      s1 = s_lookup(2 * sg, j1);
Packit 6c4009
      for(j2 = 0; j2 < 64; j2++) {
Packit 6c4009
	ufc_long to_permute, inx;
Packit 6c4009
Packit 6c4009
	s2         = s_lookup(2 * sg + 1, j2);
Packit 6c4009
	to_permute = (((ufc_long)s1 << 4)  |
Packit 6c4009
		      (ufc_long)s2) << (24 - 8 * (ufc_long)sg);
Packit 6c4009
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
	inx = ((j1 << 6)  | j2) << 1;
Packit 6c4009
	sb[sg][inx  ]  = eperm32tab[0][(to_permute >> 24) & 0xff][0];
Packit 6c4009
	sb[sg][inx+1]  = eperm32tab[0][(to_permute >> 24) & 0xff][1];
Packit 6c4009
	sb[sg][inx  ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
Packit 6c4009
	sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
Packit 6c4009
	sb[sg][inx  ] |= eperm32tab[2][(to_permute >>  8) & 0xff][0];
Packit 6c4009
	sb[sg][inx+1] |= eperm32tab[2][(to_permute >>  8) & 0xff][1];
Packit 6c4009
	sb[sg][inx  ] |= eperm32tab[3][(to_permute)       & 0xff][0];
Packit 6c4009
	sb[sg][inx+1] |= eperm32tab[3][(to_permute)       & 0xff][1];
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
	inx = ((j1 << 6)  | j2);
Packit 6c4009
	sb[sg][inx]  =
Packit 6c4009
	  ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
Packit 6c4009
	   (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
Packit 6c4009
	sb[sg][inx] |=
Packit 6c4009
	  ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
Packit 6c4009
	   (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
Packit 6c4009
	sb[sg][inx] |=
Packit 6c4009
	  ((long64)eperm32tab[2][(to_permute >>  8) & 0xff][0] << 32) |
Packit 6c4009
	   (long64)eperm32tab[2][(to_permute >>  8) & 0xff][1];
Packit 6c4009
	sb[sg][inx] |=
Packit 6c4009
	  ((long64)eperm32tab[3][(to_permute)       & 0xff][0] << 32) |
Packit 6c4009
	   (long64)eperm32tab[3][(to_permute)       & 0xff][1];
Packit 6c4009
#endif
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  __data->current_saltbits = 0;
Packit 6c4009
  __data->current_salt[0] = 0;
Packit 6c4009
  __data->current_salt[1] = 0;
Packit 6c4009
  __data->initialized++;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
__init_des (void)
Packit 6c4009
{
Packit 6c4009
  __init_des_r(&_ufc_foobar);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Process the elements of the sb table permuting the
Packit 6c4009
 * bits swapped in the expansion by the current salt.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
STATIC void
Packit 6c4009
shuffle_sb (long32 *k, ufc_long saltbits)
Packit 6c4009
{
Packit 6c4009
  ufc_long j;
Packit 6c4009
  long32 x;
Packit 6c4009
  for(j=4096; j--;) {
Packit 6c4009
    x = (k[0] ^ k[1]) & (long32)saltbits;
Packit 6c4009
    *k++ ^= x;
Packit 6c4009
    *k++ ^= x;
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
STATIC void
Packit 6c4009
shuffle_sb (long64 *k, ufc_long saltbits)
Packit 6c4009
{
Packit 6c4009
  ufc_long j;
Packit 6c4009
  long64 x;
Packit 6c4009
  for(j=4096; j--;) {
Packit 6c4009
    x = ((*k >> 32) ^ *k) & (long64)saltbits;
Packit 6c4009
    *k++ ^= (x << 32) | x;
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Return false iff C is in the specified alphabet for crypt salt.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
static bool
Packit 6c4009
bad_for_salt (char c)
Packit 6c4009
{
Packit 6c4009
  switch (c)
Packit 6c4009
    {
Packit 6c4009
    case '0' ... '9':
Packit 6c4009
    case 'A' ... 'Z':
Packit 6c4009
    case 'a' ... 'z':
Packit 6c4009
    case '.': case '/':
Packit 6c4009
      return false;
Packit 6c4009
Packit 6c4009
    default:
Packit 6c4009
      return true;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Setup the unit for a new salt
Packit 6c4009
 * Hopefully we'll not see a new salt in each crypt call.
Packit 6c4009
 * Return false if an unexpected character was found in s[0] or s[1].
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
bool
Packit 6c4009
_ufc_setup_salt_r (const char *s, struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  ufc_long i, j, saltbits;
Packit 6c4009
  char s0, s1;
Packit 6c4009
Packit 6c4009
  if(__data->initialized == 0)
Packit 6c4009
    __init_des_r(__data);
Packit 6c4009
Packit 6c4009
  s0 = s[0];
Packit 6c4009
  if(bad_for_salt (s0))
Packit 6c4009
    return false;
Packit 6c4009
Packit 6c4009
  s1 = s[1];
Packit 6c4009
  if(bad_for_salt (s1))
Packit 6c4009
    return false;
Packit 6c4009
Packit 6c4009
  if(s0 == __data->current_salt[0] && s1 == __data->current_salt[1])
Packit 6c4009
    return true;
Packit 6c4009
Packit 6c4009
  __data->current_salt[0] = s0;
Packit 6c4009
  __data->current_salt[1] = s1;
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * This is the only crypt change to DES:
Packit 6c4009
   * entries are swapped in the expansion table
Packit 6c4009
   * according to the bits set in the salt.
Packit 6c4009
   */
Packit 6c4009
  saltbits = 0;
Packit 6c4009
  for(i = 0; i < 2; i++) {
Packit 6c4009
    long c=ascii_to_bin(s[i]);
Packit 6c4009
    for(j = 0; j < 6; j++) {
Packit 6c4009
      if((c >> j) & 0x1)
Packit 6c4009
	saltbits |= BITMASK[6 * i + j];
Packit 6c4009
    }
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Permute the sb table values
Packit 6c4009
   * to reflect the changed e
Packit 6c4009
   * selection table
Packit 6c4009
   */
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
#define LONGG long32*
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
#define LONGG long64*
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  shuffle_sb((LONGG)__data->sb0, __data->current_saltbits ^ saltbits);
Packit 6c4009
  shuffle_sb((LONGG)__data->sb1, __data->current_saltbits ^ saltbits);
Packit 6c4009
  shuffle_sb((LONGG)__data->sb2, __data->current_saltbits ^ saltbits);
Packit 6c4009
  shuffle_sb((LONGG)__data->sb3, __data->current_saltbits ^ saltbits);
Packit 6c4009
Packit 6c4009
  __data->current_saltbits = saltbits;
Packit 6c4009
Packit 6c4009
  return true;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_ufc_mk_keytab_r (const char *key, struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  ufc_long v1, v2, *k1;
Packit 6c4009
  int i;
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
  long32 v, *k2;
Packit 6c4009
  k2 = (long32*)__data->keysched;
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
  long64 v, *k2;
Packit 6c4009
  k2 = (long64*)__data->keysched;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  v1 = v2 = 0; k1 = &do_pc1[0][0][0];
Packit 6c4009
  for(i = 8; i--;) {
Packit 6c4009
    v1 |= k1[*key   & 0x7f]; k1 += 128;
Packit 6c4009
    v2 |= k1[*key++ & 0x7f]; k1 += 128;
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  for(i = 0; i < 16; i++) {
Packit 6c4009
    k1 = &do_pc2[0][0];
Packit 6c4009
Packit 6c4009
    v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
Packit 6c4009
    v  = k1[(v1 >> 21) & 0x7f]; k1 += 128;
Packit 6c4009
    v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
Packit 6c4009
    v |= k1[(v1 >>  7) & 0x7f]; k1 += 128;
Packit 6c4009
    v |= k1[(v1      ) & 0x7f]; k1 += 128;
Packit 6c4009
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
    *k2++ = (v | 0x00008000);
Packit 6c4009
    v = 0;
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
    v = (v << 32);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
    v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
Packit 6c4009
    v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
Packit 6c4009
    v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
Packit 6c4009
    v |= k1[(v2 >>  7) & 0x7f]; k1 += 128;
Packit 6c4009
    v |= k1[(v2      ) & 0x7f];
Packit 6c4009
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
    *k2++ = (v | 0x00008000);
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
    *k2++ = v | 0x0000800000008000l;
Packit 6c4009
#endif
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  __data->direction = 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * Undo an extra E selection and do final permutations
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_ufc_dofinalperm_r (ufc_long *res, struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  ufc_long v1, v2, x;
Packit 6c4009
  ufc_long l1,l2,r1,r2;
Packit 6c4009
Packit 6c4009
  l1 = res[0]; l2 = res[1];
Packit 6c4009
  r1 = res[2]; r2 = res[3];
Packit 6c4009
Packit 6c4009
  x = (l1 ^ l2) & __data->current_saltbits; l1 ^= x; l2 ^= x;
Packit 6c4009
  x = (r1 ^ r2) & __data->current_saltbits; r1 ^= x; r2 ^= x;
Packit 6c4009
Packit 6c4009
  v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
Packit 6c4009
Packit 6c4009
  v1 |= efp[15][ r2         & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
Packit 6c4009
  v1 |= efp[14][(r2 >>= 6)  & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
Packit 6c4009
  v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
Packit 6c4009
  v1 |= efp[12][(r2 >>= 6)  & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
Packit 6c4009
Packit 6c4009
  v1 |= efp[11][ r1         & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
Packit 6c4009
  v1 |= efp[10][(r1 >>= 6)  & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 8][(r1 >>= 6)  & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
Packit 6c4009
Packit 6c4009
  v1 |= efp[ 7][ l2         & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 6][(l2 >>= 6)  & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 4][(l2 >>= 6)  & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
Packit 6c4009
Packit 6c4009
  v1 |= efp[ 3][ l1         & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 2][(l1 >>= 6)  & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
Packit 6c4009
  v1 |= efp[ 0][(l1 >>= 6)  & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
Packit 6c4009
Packit 6c4009
  res[0] = v1; res[1] = v2;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * crypt only: convert from 64 bit to 11 bit ASCII
Packit 6c4009
 * prefixing with the salt
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
_ufc_output_conversion_r (ufc_long v1, ufc_long v2, const char *salt,
Packit 6c4009
			  struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  int i, s, shf;
Packit 6c4009
Packit 6c4009
  __data->crypt_3_buf[0] = salt[0];
Packit 6c4009
  __data->crypt_3_buf[1] = salt[1] ? salt[1] : salt[0];
Packit 6c4009
Packit 6c4009
  for(i = 0; i < 5; i++) {
Packit 6c4009
    shf = (26 - 6 * i); /* to cope with MSC compiler bug */
Packit 6c4009
    __data->crypt_3_buf[i + 2] = bin_to_ascii((v1 >> shf) & 0x3f);
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  s  = (v2 & 0xf) << 2;
Packit 6c4009
  v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
Packit 6c4009
Packit 6c4009
  for(i = 5; i < 10; i++) {
Packit 6c4009
    shf = (56 - 6 * i);
Packit 6c4009
    __data->crypt_3_buf[i + 2] = bin_to_ascii((v2 >> shf) & 0x3f);
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  __data->crypt_3_buf[12] = bin_to_ascii(s);
Packit 6c4009
  __data->crypt_3_buf[13] = 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * UNIX encrypt function. Takes a bitvector
Packit 6c4009
 * represented by one byte per bit and
Packit 6c4009
 * encrypt/decrypt according to edflag
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
__encrypt_r (char *__block, int __edflag,
Packit 6c4009
	     struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  ufc_long l1, l2, r1, r2, res[4];
Packit 6c4009
  int i;
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
  long32 *kt;
Packit 6c4009
  kt = (long32*)__data->keysched;
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
  long64 *kt;
Packit 6c4009
  kt = (long64*)__data->keysched;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Undo any salt changes to E expansion
Packit 6c4009
   */
Packit 6c4009
  _ufc_setup_salt_r("..", __data);
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Reverse key table if
Packit 6c4009
   * changing operation (encrypt/decrypt)
Packit 6c4009
   */
Packit 6c4009
  if((__edflag == 0) != (__data->direction == 0)) {
Packit 6c4009
    for(i = 0; i < 8; i++) {
Packit 6c4009
#ifdef _UFC_32_
Packit 6c4009
      long32 x;
Packit 6c4009
      x = kt[2 * (15-i)];
Packit 6c4009
      kt[2 * (15-i)] = kt[2 * i];
Packit 6c4009
      kt[2 * i] = x;
Packit 6c4009
Packit 6c4009
      x = kt[2 * (15-i) + 1];
Packit 6c4009
      kt[2 * (15-i) + 1] = kt[2 * i + 1];
Packit 6c4009
      kt[2 * i + 1] = x;
Packit 6c4009
#endif
Packit 6c4009
#ifdef _UFC_64_
Packit 6c4009
      long64 x;
Packit 6c4009
      x = kt[15-i];
Packit 6c4009
      kt[15-i] = kt[i];
Packit 6c4009
      kt[i] = x;
Packit 6c4009
#endif
Packit 6c4009
      }
Packit 6c4009
    __data->direction = __edflag;
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Do initial permutation + E expansion
Packit 6c4009
   */
Packit 6c4009
  i = 0;
Packit 6c4009
  for(l1 = 0; i < 24; i++) {
Packit 6c4009
    if(__block[initial_perm[esel[i]-1]-1])
Packit 6c4009
      l1 |= BITMASK[i];
Packit 6c4009
  }
Packit 6c4009
  for(l2 = 0; i < 48; i++) {
Packit 6c4009
    if(__block[initial_perm[esel[i]-1]-1])
Packit 6c4009
      l2 |= BITMASK[i-24];
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  i = 0;
Packit 6c4009
  for(r1 = 0; i < 24; i++) {
Packit 6c4009
    if(__block[initial_perm[esel[i]-1+32]-1])
Packit 6c4009
      r1 |= BITMASK[i];
Packit 6c4009
  }
Packit 6c4009
  for(r2 = 0; i < 48; i++) {
Packit 6c4009
    if(__block[initial_perm[esel[i]-1+32]-1])
Packit 6c4009
      r2 |= BITMASK[i-24];
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Do DES inner loops + final conversion
Packit 6c4009
   */
Packit 6c4009
  res[0] = l1; res[1] = l2;
Packit 6c4009
  res[2] = r1; res[3] = r2;
Packit 6c4009
  _ufc_doit_r((ufc_long)1, __data, &res[0]);
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * Do final permutations
Packit 6c4009
   */
Packit 6c4009
  _ufc_dofinalperm_r(res, __data);
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   * And convert to bit array
Packit 6c4009
   */
Packit 6c4009
  l1 = res[0]; r1 = res[1];
Packit 6c4009
  for(i = 0; i < 32; i++) {
Packit 6c4009
    *__block++ = (l1 & longmask[i]) != 0;
Packit 6c4009
  }
Packit 6c4009
  for(i = 0; i < 32; i++) {
Packit 6c4009
    *__block++ = (r1 & longmask[i]) != 0;
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
weak_alias (__encrypt_r, encrypt_r)
Packit 6c4009
compat_symbol (libcrypt, encrypt_r, encrypt_r, GLIBC_2_0);
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
encrypt (char *__block, int __edflag)
Packit 6c4009
{
Packit 6c4009
  __encrypt_r(__block, __edflag, &_ufc_foobar);
Packit 6c4009
}
Packit 6c4009
compat_symbol (libcrypt, encrypt, encrypt, GLIBC_2_0);
Packit 6c4009
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * UNIX setkey function. Take a 64 bit DES
Packit 6c4009
 * key and setup the machinery.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
__setkey_r (const char *__key, struct crypt_data * __restrict __data)
Packit 6c4009
{
Packit 6c4009
  int i,j;
Packit 6c4009
  unsigned char c;
Packit 6c4009
  unsigned char ktab[8];
Packit 6c4009
Packit 6c4009
  _ufc_setup_salt_r("..", __data); /* be sure we're initialized */
Packit 6c4009
Packit 6c4009
  for(i = 0; i < 8; i++) {
Packit 6c4009
    for(j = 0, c = 0; j < 8; j++)
Packit 6c4009
      c = c << 1 | *__key++;
Packit 6c4009
    ktab[i] = c >> 1;
Packit 6c4009
  }
Packit 6c4009
  _ufc_mk_keytab_r((char *) ktab, __data);
Packit 6c4009
}
Packit 6c4009
weak_alias (__setkey_r, setkey_r)
Packit 6c4009
compat_symbol (libcrypt, setkey_r, setkey_r, GLIBC_2_0);
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
setkey (const char *__key)
Packit 6c4009
{
Packit 6c4009
  __setkey_r(__key, &_ufc_foobar);
Packit 6c4009
}
Packit 6c4009
compat_symbol (libcrypt, setkey, setkey, GLIBC_2_0);
Packit 6c4009
#endif /* SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28) */
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
__b64_from_24bit (char **cp, int *buflen,
Packit 6c4009
		  unsigned int b2, unsigned int b1, unsigned int b0,
Packit 6c4009
		  int n)
Packit 6c4009
{
Packit 6c4009
  unsigned int w = (b2 << 16) | (b1 << 8) | b0;
Packit 6c4009
  while (n-- > 0 && (*buflen) > 0)
Packit 6c4009
    {
Packit 6c4009
      *(*cp)++ = b64t[w & 0x3f];
Packit 6c4009
      --(*buflen);
Packit 6c4009
      w >>= 6;
Packit 6c4009
    }
Packit 6c4009
}