Merge branch 'master' of ssh://sourceware.org/git/glibc
[platform/upstream/glibc.git] / crypt / crypt.c
1 /*
2  * UFC-crypt: ultra fast crypt(3) implementation
3  *
4  * Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; see the file COPYING.LIB.  If not,
18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * @(#)crypt.c  2.25 12/20/96
22  *
23  * Semiportable C version
24  *
25  */
26
27 #include "ufc-crypt.h"
28 #include "crypt.h"
29 #include "crypt-private.h"
30
31 #ifdef _UFC_32_
32
33 /*
34  * 32 bit version
35  */
36
37 #define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
38
39 void
40 _ufc_doit_r(itr, __data, res)
41      ufc_long itr, *res;
42      struct crypt_data * __restrict __data;
43 {
44   int i;
45   long32 s, *k;
46   long32 *sb01 = (long32*)__data->sb0;
47   long32 *sb23 = (long32*)__data->sb2;
48   long32 l1, l2, r1, r2;
49
50   l1 = (long32)res[0]; l2 = (long32)res[1];
51   r1 = (long32)res[2]; r2 = (long32)res[3];
52
53   while(itr--) {
54     k = (long32*)__data->keysched;
55     for(i=8; i--; ) {
56       s = *k++ ^ r1;
57       l1 ^= SBA(sb01, s & 0xffff); l2 ^= SBA(sb01, (s & 0xffff)+4);
58       l1 ^= SBA(sb01, s >>= 16  ); l2 ^= SBA(sb01, (s         )+4);
59       s = *k++ ^ r2;
60       l1 ^= SBA(sb23, s & 0xffff); l2 ^= SBA(sb23, (s & 0xffff)+4);
61       l1 ^= SBA(sb23, s >>= 16  ); l2 ^= SBA(sb23, (s         )+4);
62
63       s = *k++ ^ l1;
64       r1 ^= SBA(sb01, s & 0xffff); r2 ^= SBA(sb01, (s & 0xffff)+4);
65       r1 ^= SBA(sb01, s >>= 16  ); r2 ^= SBA(sb01, (s         )+4);
66       s = *k++ ^ l2;
67       r1 ^= SBA(sb23, s & 0xffff); r2 ^= SBA(sb23, (s & 0xffff)+4);
68       r1 ^= SBA(sb23, s >>= 16  ); r2 ^= SBA(sb23, (s         )+4);
69     }
70     s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
71   }
72   res[0] = l1; res[1] = l2; res[2] = r1; res[3] = r2;
73 }
74
75 #endif
76
77 #ifdef _UFC_64_
78
79 /*
80  * 64 bit version
81  */
82
83 #define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
84
85 void
86 _ufc_doit_r(itr, __data, res)
87      ufc_long itr, *res;
88      struct crypt_data * __restrict __data;
89 {
90   int i;
91   long64 l, r, s, *k;
92   register long64 *sb01 = (long64*)__data->sb0;
93   register long64 *sb23 = (long64*)__data->sb2;
94
95   l = (((long64)res[0]) << 32) | ((long64)res[1]);
96   r = (((long64)res[2]) << 32) | ((long64)res[3]);
97
98   while(itr--) {
99     k = (long64*)__data->keysched;
100     for(i=8; i--; ) {
101       s = *k++ ^ r;
102       l ^= SBA(sb23, (s       ) & 0xffff);
103       l ^= SBA(sb23, (s >>= 16) & 0xffff);
104       l ^= SBA(sb01, (s >>= 16) & 0xffff);
105       l ^= SBA(sb01, (s >>= 16)         );
106
107       s = *k++ ^ l;
108       r ^= SBA(sb23, (s       ) & 0xffff);
109       r ^= SBA(sb23, (s >>= 16) & 0xffff);
110       r ^= SBA(sb01, (s >>= 16) & 0xffff);
111       r ^= SBA(sb01, (s >>= 16)         );
112     }
113     s=l; l=r; r=s;
114   }
115
116   res[0] = l >> 32; res[1] = l & 0xffffffff;
117   res[2] = r >> 32; res[3] = r & 0xffffffff;
118 }
119
120 #endif