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