1f15c2e64Schristos /*
2f15c2e64Schristos  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3f15c2e64Schristos  *
4*66bae5e7Schristos  * Licensed under the Apache License 2.0 (the "License").  You may not use
5f15c2e64Schristos  * this file except in compliance with the License.  You can obtain a copy
6f15c2e64Schristos  * in the file LICENSE in the source distribution or at
7f15c2e64Schristos  * https://www.openssl.org/source/license.html
8f15c2e64Schristos  */
9f15c2e64Schristos 
10f15c2e64Schristos #ifndef OSSL_CRYPTO_DES_LOCAL_H
11f15c2e64Schristos # define OSSL_CRYPTO_DES_LOCAL_H
12f15c2e64Schristos 
13f15c2e64Schristos # include <openssl/e_os2.h>
14f15c2e64Schristos 
15f15c2e64Schristos # include <stdio.h>
16f15c2e64Schristos # include <stdlib.h>
17f15c2e64Schristos # include <string.h>
18f15c2e64Schristos 
19f15c2e64Schristos # include <openssl/des.h>
20f15c2e64Schristos 
21f15c2e64Schristos # ifdef OPENSSL_BUILD_SHLIBCRYPTO
22f15c2e64Schristos #  undef OPENSSL_EXTERN
23f15c2e64Schristos #  define OPENSSL_EXTERN OPENSSL_EXPORT
24f15c2e64Schristos # endif
25f15c2e64Schristos 
26f15c2e64Schristos # define ITERATIONS 16
27f15c2e64Schristos # define HALF_ITERATIONS 8
28f15c2e64Schristos 
29f15c2e64Schristos # define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
30f15c2e64Schristos                          l|=((DES_LONG)(*((c)++)))<< 8L, \
31f15c2e64Schristos                          l|=((DES_LONG)(*((c)++)))<<16L, \
32f15c2e64Schristos                          l|=((DES_LONG)(*((c)++)))<<24L)
33f15c2e64Schristos 
34f15c2e64Schristos /* NOTE - c is not incremented as per c2l */
35f15c2e64Schristos # define c2ln(c,l1,l2,n) { \
36f15c2e64Schristos                         c+=n; \
37f15c2e64Schristos                         l1=l2=0; \
38f15c2e64Schristos                         switch (n) { \
39f15c2e64Schristos                         case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
40f15c2e64Schristos                         /* fall thru */                          \
41f15c2e64Schristos                         case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
42f15c2e64Schristos                         /* fall thru */                          \
43f15c2e64Schristos                         case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
44f15c2e64Schristos                         /* fall thru */                          \
45f15c2e64Schristos                         case 5: l2|=((DES_LONG)(*(--(c))));      \
46f15c2e64Schristos                         /* fall thru */                          \
47f15c2e64Schristos                         case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
48f15c2e64Schristos                         /* fall thru */                          \
49f15c2e64Schristos                         case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
50f15c2e64Schristos                         /* fall thru */                          \
51f15c2e64Schristos                         case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
52f15c2e64Schristos                         /* fall thru */                          \
53f15c2e64Schristos                         case 1: l1|=((DES_LONG)(*(--(c))));      \
54f15c2e64Schristos                                 } \
55f15c2e64Schristos                         }
56f15c2e64Schristos 
57f15c2e64Schristos # define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
58f15c2e64Schristos                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
59f15c2e64Schristos                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
60f15c2e64Schristos                          *((c)++)=(unsigned char)(((l)>>24L)&0xff))
61f15c2e64Schristos 
62f15c2e64Schristos /*
63f15c2e64Schristos  * replacements for htonl and ntohl since I have no idea what to do when
64f15c2e64Schristos  * faced with machines with 8 byte longs.
65f15c2e64Schristos  */
66f15c2e64Schristos 
67f15c2e64Schristos # define n2l(c,l)        (l =((DES_LONG)(*((c)++)))<<24L, \
68f15c2e64Schristos                          l|=((DES_LONG)(*((c)++)))<<16L, \
69f15c2e64Schristos                          l|=((DES_LONG)(*((c)++)))<< 8L, \
70f15c2e64Schristos                          l|=((DES_LONG)(*((c)++))))
71f15c2e64Schristos 
72f15c2e64Schristos # define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
73f15c2e64Schristos                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
74f15c2e64Schristos                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
75f15c2e64Schristos                          *((c)++)=(unsigned char)(((l)     )&0xff))
76f15c2e64Schristos 
77f15c2e64Schristos /* NOTE - c is not incremented as per l2c */
78f15c2e64Schristos # define l2cn(l1,l2,c,n) { \
79f15c2e64Schristos                         c+=n; \
80f15c2e64Schristos                         switch (n) { \
81f15c2e64Schristos                         case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
82f15c2e64Schristos                         /* fall thru */                                     \
83f15c2e64Schristos                         case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
84f15c2e64Schristos                         /* fall thru */                                     \
85f15c2e64Schristos                         case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
86f15c2e64Schristos                         /* fall thru */                                     \
87f15c2e64Schristos                         case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
88f15c2e64Schristos                         /* fall thru */                                     \
89f15c2e64Schristos                         case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
90f15c2e64Schristos                         /* fall thru */                                     \
91f15c2e64Schristos                         case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
92f15c2e64Schristos                         /* fall thru */                                     \
93f15c2e64Schristos                         case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
94f15c2e64Schristos                         /* fall thru */                                     \
95f15c2e64Schristos                         case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
96f15c2e64Schristos                                 } \
97f15c2e64Schristos                         }
98f15c2e64Schristos 
99f15c2e64Schristos # if defined(_MSC_VER)
100f15c2e64Schristos #  define ROTATE(a,n)     (_lrotr(a,n))
101f15c2e64Schristos # elif defined(__ICC)
102f15c2e64Schristos #  define ROTATE(a,n)     (_rotr(a,n))
103f15c2e64Schristos # elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
104f15c2e64Schristos #  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
105f15c2e64Schristos #   define ROTATE(a,n)   ({ register unsigned int ret;   \
106f15c2e64Schristos                                 asm ("rorl %1,%0"       \
107f15c2e64Schristos                                         : "=r"(ret)     \
108f15c2e64Schristos                                         : "I"(n),"0"(a) \
109f15c2e64Schristos                                         : "cc");        \
110f15c2e64Schristos                            ret;                         \
111f15c2e64Schristos                         })
112f15c2e64Schristos #  endif
113f15c2e64Schristos # endif
114f15c2e64Schristos # ifndef ROTATE
115f15c2e64Schristos #  define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
116f15c2e64Schristos # endif
117f15c2e64Schristos 
118f15c2e64Schristos /*
119f15c2e64Schristos  * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add
120f15c2e64Schristos  * it's little bit to the front
121f15c2e64Schristos  */
122f15c2e64Schristos 
123f15c2e64Schristos # ifdef DES_FCRYPT
124f15c2e64Schristos 
125f15c2e64Schristos #  define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
126f15c2e64Schristos         { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
127f15c2e64Schristos 
128f15c2e64Schristos #  define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
129f15c2e64Schristos         t=R^(R>>16L); \
130f15c2e64Schristos         u=t&E0; t&=E1; \
131f15c2e64Schristos         tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
132f15c2e64Schristos         tmp=(t<<16); t^=R^s[S+1]; t^=tmp
133f15c2e64Schristos # else
134f15c2e64Schristos #  define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
135f15c2e64Schristos #  define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
136f15c2e64Schristos         u=R^s[S  ]; \
137f15c2e64Schristos         t=R^s[S+1]
138f15c2e64Schristos # endif
139f15c2e64Schristos 
140f15c2e64Schristos /*
141f15c2e64Schristos  * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason
142f15c2e64Schristos  * to not xor all the sub items together.  This potentially saves a register
143f15c2e64Schristos  * since things can be xored directly into L
144f15c2e64Schristos  */
145f15c2e64Schristos 
146f15c2e64Schristos # define D_ENCRYPT(LL,R,S) { \
147f15c2e64Schristos         LOAD_DATA_tmp(R,S,u,t,E0,E1); \
148f15c2e64Schristos         t=ROTATE(t,4); \
149f15c2e64Schristos         LL^= \
150f15c2e64Schristos             DES_SPtrans[0][(u>> 2L)&0x3f]^ \
151f15c2e64Schristos             DES_SPtrans[2][(u>>10L)&0x3f]^ \
152f15c2e64Schristos             DES_SPtrans[4][(u>>18L)&0x3f]^ \
153f15c2e64Schristos             DES_SPtrans[6][(u>>26L)&0x3f]^ \
154f15c2e64Schristos             DES_SPtrans[1][(t>> 2L)&0x3f]^ \
155f15c2e64Schristos             DES_SPtrans[3][(t>>10L)&0x3f]^ \
156f15c2e64Schristos             DES_SPtrans[5][(t>>18L)&0x3f]^ \
157f15c2e64Schristos             DES_SPtrans[7][(t>>26L)&0x3f]; }
158f15c2e64Schristos 
159f15c2e64Schristos         /*-
160f15c2e64Schristos          * IP and FP
161f15c2e64Schristos          * The problem is more of a geometric problem that random bit fiddling.
162f15c2e64Schristos          0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
163f15c2e64Schristos          8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
164f15c2e64Schristos         16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
165f15c2e64Schristos         24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
166f15c2e64Schristos 
167f15c2e64Schristos         32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
168f15c2e64Schristos         40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
169f15c2e64Schristos         48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
170f15c2e64Schristos         56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
171f15c2e64Schristos 
172f15c2e64Schristos         The output has been subject to swaps of the form
173f15c2e64Schristos         0 1 -> 3 1 but the odd and even bits have been put into
174f15c2e64Schristos         2 3    2 0
175f15c2e64Schristos         different words.  The main trick is to remember that
176f15c2e64Schristos         t=((l>>size)^r)&(mask);
177f15c2e64Schristos         r^=t;
178f15c2e64Schristos         l^=(t<<size);
179f15c2e64Schristos         can be used to swap and move bits between words.
180f15c2e64Schristos 
181f15c2e64Schristos         So l =  0  1  2  3  r = 16 17 18 19
182f15c2e64Schristos                 4  5  6  7      20 21 22 23
183f15c2e64Schristos                 8  9 10 11      24 25 26 27
184f15c2e64Schristos                12 13 14 15      28 29 30 31
185f15c2e64Schristos         becomes (for size == 2 and mask == 0x3333)
186f15c2e64Schristos            t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
187f15c2e64Schristos                  6^20  7^21 -- --        4  5 20 21       6  7 22 23
188f15c2e64Schristos                 10^24 11^25 -- --        8  9 24 25      10 11 24 25
189f15c2e64Schristos                 14^28 15^29 -- --       12 13 28 29      14 15 28 29
190f15c2e64Schristos 
191f15c2e64Schristos         Thanks for hints from Richard Outerbridge - he told me IP&FP
192f15c2e64Schristos         could be done in 15 xor, 10 shifts and 5 ands.
193f15c2e64Schristos         When I finally started to think of the problem in 2D
194f15c2e64Schristos         I first got ~42 operations without xors.  When I remembered
195f15c2e64Schristos         how to use xors :-) I got it to its final state.
196f15c2e64Schristos         */
197f15c2e64Schristos # define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
198f15c2e64Schristos         (b)^=(t),\
199f15c2e64Schristos         (a)^=((t)<<(n)))
200f15c2e64Schristos 
201f15c2e64Schristos # define IP(l,r) \
202f15c2e64Schristos         { \
203f15c2e64Schristos         register DES_LONG tt; \
204f15c2e64Schristos         PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
205f15c2e64Schristos         PERM_OP(l,r,tt,16,0x0000ffffL); \
206f15c2e64Schristos         PERM_OP(r,l,tt, 2,0x33333333L); \
207f15c2e64Schristos         PERM_OP(l,r,tt, 8,0x00ff00ffL); \
208f15c2e64Schristos         PERM_OP(r,l,tt, 1,0x55555555L); \
209f15c2e64Schristos         }
210f15c2e64Schristos 
211f15c2e64Schristos # define FP(l,r) \
212f15c2e64Schristos         { \
213f15c2e64Schristos         register DES_LONG tt; \
214f15c2e64Schristos         PERM_OP(l,r,tt, 1,0x55555555L); \
215f15c2e64Schristos         PERM_OP(r,l,tt, 8,0x00ff00ffL); \
216f15c2e64Schristos         PERM_OP(l,r,tt, 2,0x33333333L); \
217f15c2e64Schristos         PERM_OP(r,l,tt,16,0x0000ffffL); \
218f15c2e64Schristos         PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
219f15c2e64Schristos         }
220f15c2e64Schristos 
221f15c2e64Schristos extern const DES_LONG DES_SPtrans[8][64];
222f15c2e64Schristos 
223f15c2e64Schristos void fcrypt_body(DES_LONG *out, DES_key_schedule *ks,
224f15c2e64Schristos                  DES_LONG Eswap0, DES_LONG Eswap1);
225f15c2e64Schristos 
226f15c2e64Schristos #endif
227