Back to index

glibc  2.9
Defines | Functions | Variables
des_impl.c File Reference
#include <string.h>
#include <stdint.h>
#include "des.h"

Go to the source code of this file.

Defines

#define c2l(c, l)
#define l2c(l, c)
#define PERM_OP(a, b, t, n, m)
#define HPERM_OP(a, t, n, m)
#define D_ENCRYPT(L, R, S)
#define ITERATIONS   16

Functions

static void des_set_key (unsigned char *, static void des_encrypt(unsigned long unsigned long *)
static void internal_function des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
int _des_crypt (char *buf, unsigned len, struct desparams *desp)

Variables

static const uint32_t des_SPtrans [8][64]
static const uint32_t des_skb [8][64]
static const char shifts2 [16]

Define Documentation

#define c2l (   c,
  l 
)
Value:
(l =((unsigned long)(*((c)++)))    , \
                      l|=((unsigned long)(*((c)++)))<< 8, \
                      l|=((unsigned long)(*((c)++)))<<16, \
                      l|=((unsigned long)(*((c)++)))<<24)

Definition at line 299 of file des_impl.c.

#define D_ENCRYPT (   L,
  R,
  S 
)
Value:
u=(R^s[S  ]); \
       t=R^s[S+1]; \
       t=((t>>4)+(t<<28)); \
       L^=    des_SPtrans[1][(t    )&0x3f]| \
              des_SPtrans[3][(t>> 8)&0x3f]| \
              des_SPtrans[5][(t>>16)&0x3f]| \
              des_SPtrans[7][(t>>24)&0x3f]| \
              des_SPtrans[0][(u    )&0x3f]| \
              des_SPtrans[2][(u>> 8)&0x3f]| \
              des_SPtrans[4][(u>>16)&0x3f]| \
              des_SPtrans[6][(u>>24)&0x3f];

Definition at line 356 of file des_impl.c.

#define HPERM_OP (   a,
  t,
  n,
  m 
)
Value:
((t)=((((a)<<(16-(n)))^(a))&(m)),\
       (a)=(a)^(t)^(t>>(16-(n))))

Definition at line 352 of file des_impl.c.

#define ITERATIONS   16

Definition at line 369 of file des_impl.c.

#define l2c (   l,
  c 
)
Value:
(*((c)++)=(unsigned char)(((l)    )&0xff), \
                      *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                      *((c)++)=(unsigned char)(((l)>>16)&0xff), \
                      *((c)++)=(unsigned char)(((l)>>24)&0xff))

Definition at line 304 of file des_impl.c.

#define PERM_OP (   a,
  b,
  t,
  n,
  m 
)
Value:
((t)=((((a)>>(n))^(b))&(m)),\
       (b)^=(t),\
       (a)^=((t)<<(n)))

Definition at line 348 of file des_impl.c.


Function Documentation

int _des_crypt ( char *  buf,
unsigned  len,
struct desparams desp 
)

Definition at line 520 of file des_impl.c.

{
  unsigned long schedule[32];
  register unsigned long tin0, tin1;
  register unsigned long tout0, tout1, xor0, xor1;
  register unsigned char *in, *out;
  unsigned long tbuf[2];
  unsigned char *iv, *oiv;
  int cbc_mode;

  cbc_mode = (desp->des_mode == CBC) ? 1 : 0;

  in = (unsigned char *) buf;
  out = (unsigned char *) buf;
  oiv = iv = (unsigned char *) desp->des_ivec;

  des_set_key (desp->des_key, schedule);

  tin0 = tin1 = 0;          /* For GCC */
  if (desp->des_dir == ENCRYPT)
    {
      c2l (iv, tout0);
      c2l (iv, tout1);
      for (; len > 0; len -= 8)
       {
         c2l (in, tin0);
         c2l (in, tin1);
         if (cbc_mode)
           {
             tin0 ^= tout0;
             tin1 ^= tout1;
           }
         tbuf[0] = tin0;
         tbuf[1] = tin1;
         des_encrypt (tbuf, schedule, 1);
         tout0 = tbuf[0];
         tout1 = tbuf[1];
         l2c (tout0, out);
         l2c (tout1, out);
       }
      l2c (tout0, oiv);
      l2c (tout1, oiv);
    }
  else
    {
      c2l (iv, xor0);
      c2l (iv, xor1);
      for (; len > 0; len -= 8)
       {
         c2l (in, tin0);
         c2l (in, tin1);
         tbuf[0] = tin0;
         tbuf[1] = tin1;
         des_encrypt (tbuf, schedule, 0);
         if (cbc_mode)
           {
             tout0 = tbuf[0] ^ xor0;
             tout1 = tbuf[1] ^ xor1;
             xor0 = tin0;
             xor1 = tin1;
           }
         else
           {
             tout0 = tbuf[0];
             tout1 = tbuf[1];
           }
         l2c (tout0, out);
         l2c (tout1, out);
       }
      l2c (tin0, oiv);
      l2c (tin1, oiv);
    }
  tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
  tbuf[0] = tbuf[1] = 0;
  __bzero (schedule, sizeof (schedule));

  return (1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void internal_function des_encrypt ( unsigned long *  buf,
unsigned long *  schedule,
int  encrypt 
) [static]

Definition at line 444 of file des_impl.c.

{
  register unsigned long l, r, t, u;
  register int i;
  register unsigned long *s;

  l = buf[0];
  r = buf[1];

  /* do IP */
  PERM_OP (r, l, t, 4, 0x0f0f0f0f);
  PERM_OP (l, r, t, 16, 0x0000ffff);
  PERM_OP (r, l, t, 2, 0x33333333);
  PERM_OP (l, r, t, 8, 0x00ff00ff);
  PERM_OP (r, l, t, 1, 0x55555555);
  /* r and l are reversed - remember that :-) - fix
   * it in the next step */

  /* Things have been modified so that the initial rotate is
   * done outside the loop.  This required the
   * des_SPtrans values in sp.h to be rotated 1 bit to the right.
   * One perl script later and things have a 5% speed up on a sparc2.
   * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
   * for pointing this out. */
  t = (r << 1) | (r >> 31);
  r = (l << 1) | (l >> 31);
  l = t;

  /* clear the top bits on machines with 8byte longs */
  l &= 0xffffffff;
  r &= 0xffffffff;

  s = (unsigned long *) schedule;
  /* I don't know if it is worth the effort of loop unrolling the
   * inner loop */
  if (encrypt)
    {
      for (i = 0; i < 32; i += 4)
       {
         D_ENCRYPT (l, r, i + 0);  /*  1 */
         D_ENCRYPT (r, l, i + 2);  /*  2 */
       }
    }
  else
    {
      for (i = 30; i > 0; i -= 4)
       {
         D_ENCRYPT (l, r, i - 0);  /* 16 */
         D_ENCRYPT (r, l, i - 2);  /* 15 */
       }
    }
  l = (l >> 1) | (l << 31);
  r = (r >> 1) | (r << 31);
  /* clear the top bits on machines with 8byte longs */
  l &= 0xffffffff;
  r &= 0xffffffff;

  /* swap l and r
   * we will not do the swap so just remember they are
   * reversed for the rest of the subroutine
   * luckily FP fixes this problem :-) */

  PERM_OP (r, l, t, 1, 0x55555555);
  PERM_OP (l, r, t, 8, 0x00ff00ff);
  PERM_OP (r, l, t, 2, 0x33333333);
  PERM_OP (l, r, t, 16, 0x0000ffff);
  PERM_OP (r, l, t, 4, 0x0f0f0f0f);

  buf[0] = l;
  buf[1] = r;

  l = r = t = u = 0;
}

Here is the caller graph for this function:

static void des_set_key ( unsigned char *  ,
static void des_encrypt (unsigned long  unsigned long * 
) [static]

Definition at line 374 of file des_impl.c.

{
  register unsigned long c, d, t, s;
  register unsigned char *in;
  register unsigned long *k;
  register int i;

  k = (unsigned long *) schedule;
  in = key;

  c2l (in, c);
  c2l (in, d);

  /* I now do it in 47 simple operations :-)
   * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
   * for the inspiration. :-) */
  PERM_OP (d, c, t, 4, 0x0f0f0f0f);
  HPERM_OP (c, t, -2, 0xcccc0000);
  HPERM_OP (d, t, -2, 0xcccc0000);
  PERM_OP (d, c, t, 1, 0x55555555);
  PERM_OP (c, d, t, 8, 0x00ff00ff);
  PERM_OP (d, c, t, 1, 0x55555555);
  d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
       ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
  c &= 0x0fffffff;

  for (i = 0; i < ITERATIONS; i++)
    {
      if (shifts2[i])
       {
         c = ((c >> 2) | (c << 26));
         d = ((d >> 2) | (d << 26));
       }
      else
       {
         c = ((c >> 1) | (c << 27));
         d = ((d >> 1) | (d << 27));
       }
      c &= 0x0fffffff;
      d &= 0x0fffffff;
      /* could be a few less shifts but I am to lazy at this
       * point in time to investigate */
      s = des_skb[0][(c) & 0x3f] |
       des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
       des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
       des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
      t = des_skb[4][(d) & 0x3f] |
       des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
       des_skb[6][(d >> 15) & 0x3f] |
       des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];

      /* table contained 0213 4657 */
      *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
      s = ((s >> 16) | (t & 0xffff0000));

      s = (s << 4) | (s >> 28);
      *(k++) = s & 0xffffffff;
    }
}

Here is the caller graph for this function:


Variable Documentation

const uint32_t des_skb[8][64] [static]

Definition at line 159 of file des_impl.c.

const uint32_t des_SPtrans[8][64] [static]

Definition at line 13 of file des_impl.c.

const char shifts2[16] [static]
Initial value:
{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0}

Definition at line 371 of file des_impl.c.