1 /*
2  * UFC-crypt: ultra fast crypt(3) implementation
3  *
4  * Copyright (C) 1991-2022 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  * see <https://www.gnu.org/licenses/>.
19  *
20  * @(#)crypt.c	2.25 12/20/96
21  *
22  * Semiportable C version
23  *
24  */
25 
26 #include "crypt-private.h"
27 
28 #ifdef _UFC_32_
29 
30 /*
31  * 32 bit version
32  */
33 
34 #define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
35 
36 void
_ufc_doit_r(ufc_long itr,struct crypt_data * __restrict __data,ufc_long * res)37 _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
38 	     ufc_long *res)
39 {
40   int i;
41   long32 s, *k;
42   long32 *sb01 = (long32*)__data->sb0;
43   long32 *sb23 = (long32*)__data->sb2;
44   long32 l1, l2, r1, r2;
45 
46   l1 = (long32)res[0]; l2 = (long32)res[1];
47   r1 = (long32)res[2]; r2 = (long32)res[3];
48 
49   while(itr--) {
50     k = (long32*)__data->keysched;
51     for(i=8; i--; ) {
52       s = *k++ ^ r1;
53       l1 ^= SBA(sb01, s & 0xffff); l2 ^= SBA(sb01, (s & 0xffff)+4);
54       l1 ^= SBA(sb01, s >>= 16  ); l2 ^= SBA(sb01, (s         )+4);
55       s = *k++ ^ r2;
56       l1 ^= SBA(sb23, s & 0xffff); l2 ^= SBA(sb23, (s & 0xffff)+4);
57       l1 ^= SBA(sb23, s >>= 16  ); l2 ^= SBA(sb23, (s         )+4);
58 
59       s = *k++ ^ l1;
60       r1 ^= SBA(sb01, s & 0xffff); r2 ^= SBA(sb01, (s & 0xffff)+4);
61       r1 ^= SBA(sb01, s >>= 16  ); r2 ^= SBA(sb01, (s         )+4);
62       s = *k++ ^ l2;
63       r1 ^= SBA(sb23, s & 0xffff); r2 ^= SBA(sb23, (s & 0xffff)+4);
64       r1 ^= SBA(sb23, s >>= 16  ); r2 ^= SBA(sb23, (s         )+4);
65     }
66     s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
67   }
68   res[0] = l1; res[1] = l2; res[2] = r1; res[3] = r2;
69 }
70 
71 #endif
72 
73 #ifdef _UFC_64_
74 
75 /*
76  * 64 bit version
77  */
78 
79 #define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
80 
81 void
_ufc_doit_r(ufc_long itr,struct crypt_data * __restrict __data,ufc_long * res)82 _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
83 	     ufc_long *res)
84 {
85   int i;
86   long64 l, r, s, *k;
87   long64 *sb01 = (long64*)__data->sb0;
88   long64 *sb23 = (long64*)__data->sb2;
89 
90   l = (((long64)res[0]) << 32) | ((long64)res[1]);
91   r = (((long64)res[2]) << 32) | ((long64)res[3]);
92 
93   while(itr--) {
94     k = (long64*)__data->keysched;
95     for(i=8; i--; ) {
96       s = *k++ ^ r;
97       l ^= SBA(sb23, (s       ) & 0xffff);
98       l ^= SBA(sb23, (s >>= 16) & 0xffff);
99       l ^= SBA(sb01, (s >>= 16) & 0xffff);
100       l ^= SBA(sb01, (s >>= 16)         );
101 
102       s = *k++ ^ l;
103       r ^= SBA(sb23, (s       ) & 0xffff);
104       r ^= SBA(sb23, (s >>= 16) & 0xffff);
105       r ^= SBA(sb01, (s >>= 16) & 0xffff);
106       r ^= SBA(sb01, (s >>= 16)         );
107     }
108     s=l; l=r; r=s;
109   }
110 
111   res[0] = l >> 32; res[1] = l & 0xffffffff;
112   res[2] = r >> 32; res[3] = r & 0xffffffff;
113 }
114 
115 #endif
116