| /* | 
 |  * UFC-crypt: ultra fast crypt(3) implementation | 
 |  * | 
 |  * Copyright (C) 1991-2016 Free Software Foundation, Inc. | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  * | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |  * Lesser General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU Lesser General Public | 
 |  * License along with this library; see the file COPYING.LIB.  If not, | 
 |  * see <http://www.gnu.org/licenses/>. | 
 |  * | 
 |  * @(#)crypt.c	2.25 12/20/96 | 
 |  * | 
 |  * Semiportable C version | 
 |  * | 
 |  */ | 
 |  | 
 | #include "crypt-private.h" | 
 |  | 
 | #ifdef _UFC_32_ | 
 |  | 
 | /* | 
 |  * 32 bit version | 
 |  */ | 
 |  | 
 | #define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) | 
 |  | 
 | void | 
 | _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data, | 
 | 	     ufc_long *res) | 
 | { | 
 |   int i; | 
 |   long32 s, *k; | 
 |   long32 *sb01 = (long32*)__data->sb0; | 
 |   long32 *sb23 = (long32*)__data->sb2; | 
 |   long32 l1, l2, r1, r2; | 
 |  | 
 |   l1 = (long32)res[0]; l2 = (long32)res[1]; | 
 |   r1 = (long32)res[2]; r2 = (long32)res[3]; | 
 |  | 
 |   while(itr--) { | 
 |     k = (long32*)__data->keysched; | 
 |     for(i=8; i--; ) { | 
 |       s = *k++ ^ r1; | 
 |       l1 ^= SBA(sb01, s & 0xffff); l2 ^= SBA(sb01, (s & 0xffff)+4); | 
 |       l1 ^= SBA(sb01, s >>= 16  ); l2 ^= SBA(sb01, (s         )+4); | 
 |       s = *k++ ^ r2; | 
 |       l1 ^= SBA(sb23, s & 0xffff); l2 ^= SBA(sb23, (s & 0xffff)+4); | 
 |       l1 ^= SBA(sb23, s >>= 16  ); l2 ^= SBA(sb23, (s         )+4); | 
 |  | 
 |       s = *k++ ^ l1; | 
 |       r1 ^= SBA(sb01, s & 0xffff); r2 ^= SBA(sb01, (s & 0xffff)+4); | 
 |       r1 ^= SBA(sb01, s >>= 16  ); r2 ^= SBA(sb01, (s         )+4); | 
 |       s = *k++ ^ l2; | 
 |       r1 ^= SBA(sb23, s & 0xffff); r2 ^= SBA(sb23, (s & 0xffff)+4); | 
 |       r1 ^= SBA(sb23, s >>= 16  ); r2 ^= SBA(sb23, (s         )+4); | 
 |     } | 
 |     s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; | 
 |   } | 
 |   res[0] = l1; res[1] = l2; res[2] = r1; res[3] = r2; | 
 | } | 
 |  | 
 | #endif | 
 |  | 
 | #ifdef _UFC_64_ | 
 |  | 
 | /* | 
 |  * 64 bit version | 
 |  */ | 
 |  | 
 | #define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) | 
 |  | 
 | void | 
 | _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data, | 
 | 	     ufc_long *res) | 
 | { | 
 |   int i; | 
 |   long64 l, r, s, *k; | 
 |   long64 *sb01 = (long64*)__data->sb0; | 
 |   long64 *sb23 = (long64*)__data->sb2; | 
 |  | 
 |   l = (((long64)res[0]) << 32) | ((long64)res[1]); | 
 |   r = (((long64)res[2]) << 32) | ((long64)res[3]); | 
 |  | 
 |   while(itr--) { | 
 |     k = (long64*)__data->keysched; | 
 |     for(i=8; i--; ) { | 
 |       s = *k++ ^ r; | 
 |       l ^= SBA(sb23, (s       ) & 0xffff); | 
 |       l ^= SBA(sb23, (s >>= 16) & 0xffff); | 
 |       l ^= SBA(sb01, (s >>= 16) & 0xffff); | 
 |       l ^= SBA(sb01, (s >>= 16)         ); | 
 |  | 
 |       s = *k++ ^ l; | 
 |       r ^= SBA(sb23, (s       ) & 0xffff); | 
 |       r ^= SBA(sb23, (s >>= 16) & 0xffff); | 
 |       r ^= SBA(sb01, (s >>= 16) & 0xffff); | 
 |       r ^= SBA(sb01, (s >>= 16)         ); | 
 |     } | 
 |     s=l; l=r; r=s; | 
 |   } | 
 |  | 
 |   res[0] = l >> 32; res[1] = l & 0xffffffff; | 
 |   res[2] = r >> 32; res[3] = r & 0xffffffff; | 
 | } | 
 |  | 
 | #endif |