OSDN Git Service

LT.old: Make __errno_location/__h_errno_location thread safe
[uclinux-h8/uClibc.git] / libcrypt / des.c
index 8efd05e..64a977c 100644 (file)
@@ -56,7 +56,6 @@
  *     alignment).
  */
 
-#define __FORCE_GLIBC
 #include <sys/cdefs.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <pwd.h>
 #include <string.h>
 #include <crypt.h>
-#include <stdlib.h>
-#include <malloc.h>
 #include "libcrypt.h"
 
-/* We allocate memory for tables on first use, instead of using
- * static buffers - ~70k of statics is not NOMMU-friendly. */
-
-struct crypt_data {
-       u_int32_t saltbits; /* referenced 5 times */
-       u_int32_t old_salt; /* 3 times */
-       u_int32_t old_rawkey0, old_rawkey1; /* 3 times each */
-       u_char  un_pbox[32]; /* 2 times */
-       u_char  inv_comp_perm[56]; /* 3 times */
-       u_char  inv_key_perm[64]; /* 3 times */
-       char    des_initialised; /* 2 times */
-       char    __des_crypt_out[21]; /* private buffer for __des_crypt() */
-       u_int32_t en_keysl[16], en_keysr[16]; /* 2 times each */
-       u_int32_t de_keysl[16], de_keysr[16]; /* 2 times each */
-       u_int32_t ip_maskl[8][256], ip_maskr[8][256]; /* 9 times each */
-       u_int32_t fp_maskl[8][256], fp_maskr[8][256]; /* 9 times each */
-       u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128]; /* 9 times */
-       u_int32_t comp_maskl[8][128], comp_maskr[8][128]; /* 9 times each */
-};
-static struct crypt_data *__uc_des_data;
-#define D (*__uc_des_data)
-#define saltbits        (D.saltbits       )
-#define old_salt        (D.old_salt       )
-#define old_rawkey0     (D.old_rawkey0    )
-#define old_rawkey1     (D.old_rawkey1    )
-#define un_pbox         (D.un_pbox        )
-#define inv_comp_perm   (D.inv_comp_perm  )
-#define inv_key_perm    (D.inv_key_perm   )
-#define des_initialised (D.des_initialised)
-#define __des_crypt_out (D.__des_crypt_out)
-#define en_keysl        (D.en_keysl       )
-#define en_keysr        (D.en_keysr       )
-#define de_keysl        (D.de_keysl       )
-#define de_keysr        (D.de_keysr       )
-#define ip_maskl        (D.ip_maskl       )
-#define ip_maskr        (D.ip_maskr       )
-#define fp_maskl        (D.fp_maskl       )
-#define fp_maskr        (D.fp_maskr       )
-#define key_perm_maskl  (D.key_perm_maskl )
-#define key_perm_maskr  (D.key_perm_maskr )
-#define comp_maskl      (D.comp_maskl     )
-#define comp_maskr      (D.comp_maskr     )
-
-/* Static stuff that stays resident and doesn't change after 
- * being initialized, and therefore doesn't need to be made 
+/* Re-entrantify me -- all this junk needs to be in
+ * struct crypt_data to make this really reentrant... */
+static u_char  inv_key_perm[64];
+static u_char  inv_comp_perm[56];
+static u_char  un_pbox[32];
+static u_int32_t en_keysl[16], en_keysr[16];
+static u_int32_t de_keysl[16], de_keysr[16];
+static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
+static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
+static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
+static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
+static u_int32_t saltbits;
+static u_int32_t old_salt;
+static u_int32_t old_rawkey0, old_rawkey1;
+
+
+/* Static stuff that stays resident and doesn't change after
+ * being initialized, and therefore doesn't need to be made
  * reentrant. */
-struct const_crypt_data {
-       u_char  init_perm[64], final_perm[64]; /* referenced 2 times each */
-       u_char  m_sbox[4][4096]; /* 5 times */
-       u_int32_t psbox[4][256]; /* 5 times */
-};
-static struct const_crypt_data *__uc_des_C_ptr;
-#define C (*__uc_des_C_ptr)
-#define init_perm  (C.init_perm )
-#define final_perm (C.final_perm)
-#define m_sbox     (C.m_sbox    )
-#define psbox      (C.psbox     )
+static u_char  init_perm[64], final_perm[64];
+static u_char  m_sbox[4][4096];
+static u_int32_t psbox[4][256];
+
+
 
 
 /* A pile of data */
@@ -230,7 +194,7 @@ static const u_int32_t bits32[32] =
 static const u_char    bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
 
 
-static int 
+static int
 ascii_to_bin(char ch)
 {
        if (ch > 'z')
@@ -251,19 +215,16 @@ ascii_to_bin(char ch)
 static void
 des_init(void)
 {
+       static int des_initialised = 0;
+
        int     i, j, b, k, inbit, obit;
        u_int32_t       *p, *il, *ir, *fl, *fr;
        const u_int32_t *bits28, *bits24;
        u_char  u_sbox[8][64];
 
-       if (des_initialised)
+       if (des_initialised==1)
                return;
 
-       if (!__uc_des_C_ptr) {
-               /* No need to zero it out, it is fully initialized below */
-               __uc_des_C_ptr = __uc_malloc(sizeof(C));
-       }
-
        old_rawkey0 = old_rawkey1 = 0L;
        saltbits = 0L;
        old_salt = 0L;
@@ -410,7 +371,7 @@ setup_salt(u_int32_t salt)
 }
 
 
-static int
+static void
 des_setkey(const char *key)
 {
        u_int32_t       k0, k1, rawkey0, rawkey1;
@@ -430,7 +391,7 @@ des_setkey(const char *key)
                 * has bad parity anyway) in order to simplify the starting
                 * conditions.
                 */
-               return(0);
+               return;
        }
        old_rawkey0 = rawkey0;
        old_rawkey1 = rawkey1;
@@ -486,41 +447,32 @@ des_setkey(const char *key)
                                | comp_maskr[6][(t1 >> 7) & 0x7f]
                                | comp_maskr[7][t1 & 0x7f];
        }
-       return(0);
 }
 
 
 static int
 do_des(        u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, int count)
 {
-       /*
-        *      l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
-        */
+       /* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. */
        u_int32_t       l, r, *kl, *kr, *kl1, *kr1;
-       u_int32_t       f = f; /* silence gcc */
-       u_int32_t       r48l, r48r;
+       u_int32_t       f, r48l, r48r;
        int             round;
 
        if (count == 0) {
-               return(1);
-       } else if (count > 0) {
-               /*
-                * Encrypting
-                */
+               return 1;
+       }
+       if (count > 0) {
+               /* Encrypting */
                kl1 = en_keysl;
                kr1 = en_keysr;
        } else {
-               /*
-                * Decrypting
-                */
+               /* Decrypting */
                count = -count;
                kl1 = de_keysl;
                kr1 = de_keysr;
        }
 
-       /*
-        *      Do initial permutation (IP).
-        */
+       /* Do initial permutation (IP). */
        l = ip_maskl[0][l_in >> 24]
          | ip_maskl[1][(l_in >> 16) & 0xff]
          | ip_maskl[2][(l_in >> 8) & 0xff]
@@ -539,22 +491,17 @@ do_des(   u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, int
          | ip_maskr[7][r_in & 0xff];
 
        while (count--) {
-               /*
-                * Do each round.
-                */
+               /* Do each round. */
                kl = kl1;
                kr = kr1;
                round = 16;
-               while (round--) {
-                       /*
-                        * Expand R to 48 bits (simulate the E-box).
-                        */
+               do {
+                       /* Expand R to 48 bits (simulate the E-box). */
                        r48l    = ((r & 0x00000001) << 23)
                                | ((r & 0xf8000000) >> 9)
                                | ((r & 0x1f800000) >> 11)
                                | ((r & 0x01f80000) >> 13)
                                | ((r & 0x001f8000) >> 15);
-
                        r48r    = ((r & 0x0001f800) << 7)
                                | ((r & 0x00001f80) << 5)
                                | ((r & 0x000001f8) << 3)
@@ -575,19 +522,15 @@ do_des(   u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out, int
                          | psbox[1][m_sbox[1][r48l & 0xfff]]
                          | psbox[2][m_sbox[2][r48r >> 12]]
                          | psbox[3][m_sbox[3][r48r & 0xfff]];
-                       /*
-                        * Now that we've permuted things, complete f().
-                        */
+                       /* Now that we've permuted things, complete f(). */
                        f ^= l;
                        l = r;
                        r = f;
-               }
+               } while (--round);
                r = l;
                l = f;
        }
-       /*
-        * Do final permutation (inverse of IP).
-        */
+       /* Do final permutation (inverse of IP). */
        *l_out  = fp_maskl[0][l >> 24]
                | fp_maskl[1][(l >> 16) & 0xff]
                | fp_maskl[2][(l >> 8) & 0xff]
@@ -644,9 +587,6 @@ setkey(const char *key)
        u_int32_t       packed_keys[2];
        u_char  *p;
 
-       if (!__uc_des_data)
-               __uc_des_data = memset(__uc_malloc(sizeof(D)), 0, sizeof(D));
-
        p = (u_char *) packed_keys;
 
        for (i = 0; i < 8; i++) {
@@ -666,9 +606,6 @@ encrypt(char *block, int flag)
        u_char  *p;
        int     i, j;
 
-        /* if user didn't call setkey() before and __uc_des_data
-         * is NULL, it's user's own fault. */
-
        des_init();
 
        setup_salt(0L);
@@ -685,20 +622,11 @@ encrypt(char *block, int flag)
                        block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0;
 }
 
-
 char *__des_crypt(const unsigned char *key, const unsigned char *setting)
 {
        u_int32_t       count, salt, l, r0, r1, keybuf[2];
        u_char          *p, *q;
-
-/* Used to have static char output[21] here, but since we already
- * allocate ~70k for des tables, we can carve out 21 bytes
- * from that memory instead */
-#define output __des_crypt_out
-
-       if (!__uc_des_data) {
-               __uc_des_data = memset(__uc_malloc(sizeof(D)), 0, sizeof(D));
-       }
+       static char     output[21];
 
        des_init();
 
@@ -712,8 +640,7 @@ char *__des_crypt(const unsigned char *key, const unsigned char *setting)
                if (*(q - 1))
                        key++;
        }
-       if (des_setkey((char *)keybuf))
-               return(NULL);
+       des_setkey((char *)keybuf);
 
 #if 0
        if (*setting == _PASSWORD_EFMT1) {
@@ -742,8 +669,7 @@ char *__des_crypt(const unsigned char *key, const unsigned char *setting)
                        while (q - (u_char *)keybuf - 8 && *key)
                                *q++ ^= *key++ << 1;
 
-                       if (des_setkey((char *)keybuf))
-                               return(NULL);
+                       des_setkey((char *)keybuf);
                }
                strncpy(output, setting, 9);
 
@@ -756,7 +682,7 @@ char *__des_crypt(const unsigned char *key, const unsigned char *setting)
                 */
                output[9] = '\0';
                p = (u_char *)output + strlen(output);
-       } else 
+       } else
 #endif
        {
                /*