Coverage Report

Created: 2024-05-20 06:23

/src/nss/lib/freebl/des.c
Line
Count
Source
1
/*
2
 *  des.c
3
 *
4
 *  core source file for DES-150 library
5
 *  Make key schedule from DES key.
6
 *  Encrypt/Decrypt one 8-byte block.
7
 *
8
 * This Source Code Form is subject to the terms of the Mozilla Public
9
 * License, v. 2.0. If a copy of the MPL was not distributed with this
10
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11
12
#include "des.h"
13
#include "blapii.h"
14
#include <stddef.h> /* for ptrdiff_t */
15
/* #define USE_INDEXING 1 */
16
17
/*
18
 * The tables below are the 8 sbox functions, with the 6-bit input permutation
19
 * and the 32-bit output permutation pre-computed.
20
 * They are shifted circularly to the left 3 bits, which removes 2 shifts
21
 * and an or from each round by reducing the number of sboxes whose
22
 * indices cross word broundaries from 2 to 1.
23
 */
24
25
static const HALF SP[8][64] = {
26
    /* Box S1 */
27
    { 0x04041000, 0x00000000, 0x00040000, 0x04041010,
28
      0x04040010, 0x00041010, 0x00000010, 0x00040000,
29
      0x00001000, 0x04041000, 0x04041010, 0x00001000,
30
      0x04001010, 0x04040010, 0x04000000, 0x00000010,
31
      0x00001010, 0x04001000, 0x04001000, 0x00041000,
32
      0x00041000, 0x04040000, 0x04040000, 0x04001010,
33
      0x00040010, 0x04000010, 0x04000010, 0x00040010,
34
      0x00000000, 0x00001010, 0x00041010, 0x04000000,
35
      0x00040000, 0x04041010, 0x00000010, 0x04040000,
36
      0x04041000, 0x04000000, 0x04000000, 0x00001000,
37
      0x04040010, 0x00040000, 0x00041000, 0x04000010,
38
      0x00001000, 0x00000010, 0x04001010, 0x00041010,
39
      0x04041010, 0x00040010, 0x04040000, 0x04001010,
40
      0x04000010, 0x00001010, 0x00041010, 0x04041000,
41
      0x00001010, 0x04001000, 0x04001000, 0x00000000,
42
      0x00040010, 0x00041000, 0x00000000, 0x04040010 },
43
    /* Box S2 */
44
    { 0x00420082, 0x00020002, 0x00020000, 0x00420080,
45
      0x00400000, 0x00000080, 0x00400082, 0x00020082,
46
      0x00000082, 0x00420082, 0x00420002, 0x00000002,
47
      0x00020002, 0x00400000, 0x00000080, 0x00400082,
48
      0x00420000, 0x00400080, 0x00020082, 0x00000000,
49
      0x00000002, 0x00020000, 0x00420080, 0x00400002,
50
      0x00400080, 0x00000082, 0x00000000, 0x00420000,
51
      0x00020080, 0x00420002, 0x00400002, 0x00020080,
52
      0x00000000, 0x00420080, 0x00400082, 0x00400000,
53
      0x00020082, 0x00400002, 0x00420002, 0x00020000,
54
      0x00400002, 0x00020002, 0x00000080, 0x00420082,
55
      0x00420080, 0x00000080, 0x00020000, 0x00000002,
56
      0x00020080, 0x00420002, 0x00400000, 0x00000082,
57
      0x00400080, 0x00020082, 0x00000082, 0x00400080,
58
      0x00420000, 0x00000000, 0x00020002, 0x00020080,
59
      0x00000002, 0x00400082, 0x00420082, 0x00420000 },
60
    /* Box S3 */
61
    { 0x00000820, 0x20080800, 0x00000000, 0x20080020,
62
      0x20000800, 0x00000000, 0x00080820, 0x20000800,
63
      0x00080020, 0x20000020, 0x20000020, 0x00080000,
64
      0x20080820, 0x00080020, 0x20080000, 0x00000820,
65
      0x20000000, 0x00000020, 0x20080800, 0x00000800,
66
      0x00080800, 0x20080000, 0x20080020, 0x00080820,
67
      0x20000820, 0x00080800, 0x00080000, 0x20000820,
68
      0x00000020, 0x20080820, 0x00000800, 0x20000000,
69
      0x20080800, 0x20000000, 0x00080020, 0x00000820,
70
      0x00080000, 0x20080800, 0x20000800, 0x00000000,
71
      0x00000800, 0x00080020, 0x20080820, 0x20000800,
72
      0x20000020, 0x00000800, 0x00000000, 0x20080020,
73
      0x20000820, 0x00080000, 0x20000000, 0x20080820,
74
      0x00000020, 0x00080820, 0x00080800, 0x20000020,
75
      0x20080000, 0x20000820, 0x00000820, 0x20080000,
76
      0x00080820, 0x00000020, 0x20080020, 0x00080800 },
77
    /* Box S4 */
78
    { 0x02008004, 0x00008204, 0x00008204, 0x00000200,
79
      0x02008200, 0x02000204, 0x02000004, 0x00008004,
80
      0x00000000, 0x02008000, 0x02008000, 0x02008204,
81
      0x00000204, 0x00000000, 0x02000200, 0x02000004,
82
      0x00000004, 0x00008000, 0x02000000, 0x02008004,
83
      0x00000200, 0x02000000, 0x00008004, 0x00008200,
84
      0x02000204, 0x00000004, 0x00008200, 0x02000200,
85
      0x00008000, 0x02008200, 0x02008204, 0x00000204,
86
      0x02000200, 0x02000004, 0x02008000, 0x02008204,
87
      0x00000204, 0x00000000, 0x00000000, 0x02008000,
88
      0x00008200, 0x02000200, 0x02000204, 0x00000004,
89
      0x02008004, 0x00008204, 0x00008204, 0x00000200,
90
      0x02008204, 0x00000204, 0x00000004, 0x00008000,
91
      0x02000004, 0x00008004, 0x02008200, 0x02000204,
92
      0x00008004, 0x00008200, 0x02000000, 0x02008004,
93
      0x00000200, 0x02000000, 0x00008000, 0x02008200 },
94
    /* Box S5 */
95
    { 0x00000400, 0x08200400, 0x08200000, 0x08000401,
96
      0x00200000, 0x00000400, 0x00000001, 0x08200000,
97
      0x00200401, 0x00200000, 0x08000400, 0x00200401,
98
      0x08000401, 0x08200001, 0x00200400, 0x00000001,
99
      0x08000000, 0x00200001, 0x00200001, 0x00000000,
100
      0x00000401, 0x08200401, 0x08200401, 0x08000400,
101
      0x08200001, 0x00000401, 0x00000000, 0x08000001,
102
      0x08200400, 0x08000000, 0x08000001, 0x00200400,
103
      0x00200000, 0x08000401, 0x00000400, 0x08000000,
104
      0x00000001, 0x08200000, 0x08000401, 0x00200401,
105
      0x08000400, 0x00000001, 0x08200001, 0x08200400,
106
      0x00200401, 0x00000400, 0x08000000, 0x08200001,
107
      0x08200401, 0x00200400, 0x08000001, 0x08200401,
108
      0x08200000, 0x00000000, 0x00200001, 0x08000001,
109
      0x00200400, 0x08000400, 0x00000401, 0x00200000,
110
      0x00000000, 0x00200001, 0x08200400, 0x00000401 },
111
    /* Box S6 */
112
    { 0x80000040, 0x81000000, 0x00010000, 0x81010040,
113
      0x81000000, 0x00000040, 0x81010040, 0x01000000,
114
      0x80010000, 0x01010040, 0x01000000, 0x80000040,
115
      0x01000040, 0x80010000, 0x80000000, 0x00010040,
116
      0x00000000, 0x01000040, 0x80010040, 0x00010000,
117
      0x01010000, 0x80010040, 0x00000040, 0x81000040,
118
      0x81000040, 0x00000000, 0x01010040, 0x81010000,
119
      0x00010040, 0x01010000, 0x81010000, 0x80000000,
120
      0x80010000, 0x00000040, 0x81000040, 0x01010000,
121
      0x81010040, 0x01000000, 0x00010040, 0x80000040,
122
      0x01000000, 0x80010000, 0x80000000, 0x00010040,
123
      0x80000040, 0x81010040, 0x01010000, 0x81000000,
124
      0x01010040, 0x81010000, 0x00000000, 0x81000040,
125
      0x00000040, 0x00010000, 0x81000000, 0x01010040,
126
      0x00010000, 0x01000040, 0x80010040, 0x00000000,
127
      0x81010000, 0x80000000, 0x01000040, 0x80010040 },
128
    /* Box S7 */
129
    { 0x00800000, 0x10800008, 0x10002008, 0x00000000,
130
      0x00002000, 0x10002008, 0x00802008, 0x10802000,
131
      0x10802008, 0x00800000, 0x00000000, 0x10000008,
132
      0x00000008, 0x10000000, 0x10800008, 0x00002008,
133
      0x10002000, 0x00802008, 0x00800008, 0x10002000,
134
      0x10000008, 0x10800000, 0x10802000, 0x00800008,
135
      0x10800000, 0x00002000, 0x00002008, 0x10802008,
136
      0x00802000, 0x00000008, 0x10000000, 0x00802000,
137
      0x10000000, 0x00802000, 0x00800000, 0x10002008,
138
      0x10002008, 0x10800008, 0x10800008, 0x00000008,
139
      0x00800008, 0x10000000, 0x10002000, 0x00800000,
140
      0x10802000, 0x00002008, 0x00802008, 0x10802000,
141
      0x00002008, 0x10000008, 0x10802008, 0x10800000,
142
      0x00802000, 0x00000000, 0x00000008, 0x10802008,
143
      0x00000000, 0x00802008, 0x10800000, 0x00002000,
144
      0x10000008, 0x10002000, 0x00002000, 0x00800008 },
145
    /* Box S8 */
146
    { 0x40004100, 0x00004000, 0x00100000, 0x40104100,
147
      0x40000000, 0x40004100, 0x00000100, 0x40000000,
148
      0x00100100, 0x40100000, 0x40104100, 0x00104000,
149
      0x40104000, 0x00104100, 0x00004000, 0x00000100,
150
      0x40100000, 0x40000100, 0x40004000, 0x00004100,
151
      0x00104000, 0x00100100, 0x40100100, 0x40104000,
152
      0x00004100, 0x00000000, 0x00000000, 0x40100100,
153
      0x40000100, 0x40004000, 0x00104100, 0x00100000,
154
      0x00104100, 0x00100000, 0x40104000, 0x00004000,
155
      0x00000100, 0x40100100, 0x00004000, 0x00104100,
156
      0x40004000, 0x00000100, 0x40000100, 0x40100000,
157
      0x40100100, 0x40000000, 0x00100000, 0x40004100,
158
      0x00000000, 0x40104100, 0x00100100, 0x40000100,
159
      0x40100000, 0x40004000, 0x40004100, 0x00000000,
160
      0x40104100, 0x00104000, 0x00104000, 0x00004100,
161
      0x00004100, 0x00100100, 0x40000000, 0x40104000 }
162
};
163
164
static const HALF PC2[8][64] = {
165
    /* table 0 */
166
    { 0x00000000, 0x00001000, 0x04000000, 0x04001000,
167
      0x00100000, 0x00101000, 0x04100000, 0x04101000,
168
      0x00008000, 0x00009000, 0x04008000, 0x04009000,
169
      0x00108000, 0x00109000, 0x04108000, 0x04109000,
170
      0x00000004, 0x00001004, 0x04000004, 0x04001004,
171
      0x00100004, 0x00101004, 0x04100004, 0x04101004,
172
      0x00008004, 0x00009004, 0x04008004, 0x04009004,
173
      0x00108004, 0x00109004, 0x04108004, 0x04109004,
174
      0x08000000, 0x08001000, 0x0c000000, 0x0c001000,
175
      0x08100000, 0x08101000, 0x0c100000, 0x0c101000,
176
      0x08008000, 0x08009000, 0x0c008000, 0x0c009000,
177
      0x08108000, 0x08109000, 0x0c108000, 0x0c109000,
178
      0x08000004, 0x08001004, 0x0c000004, 0x0c001004,
179
      0x08100004, 0x08101004, 0x0c100004, 0x0c101004,
180
      0x08008004, 0x08009004, 0x0c008004, 0x0c009004,
181
      0x08108004, 0x08109004, 0x0c108004, 0x0c109004 },
182
    /* table 1 */
183
    { 0x00000000, 0x00002000, 0x80000000, 0x80002000,
184
      0x00000008, 0x00002008, 0x80000008, 0x80002008,
185
      0x00200000, 0x00202000, 0x80200000, 0x80202000,
186
      0x00200008, 0x00202008, 0x80200008, 0x80202008,
187
      0x20000000, 0x20002000, 0xa0000000, 0xa0002000,
188
      0x20000008, 0x20002008, 0xa0000008, 0xa0002008,
189
      0x20200000, 0x20202000, 0xa0200000, 0xa0202000,
190
      0x20200008, 0x20202008, 0xa0200008, 0xa0202008,
191
      0x00000400, 0x00002400, 0x80000400, 0x80002400,
192
      0x00000408, 0x00002408, 0x80000408, 0x80002408,
193
      0x00200400, 0x00202400, 0x80200400, 0x80202400,
194
      0x00200408, 0x00202408, 0x80200408, 0x80202408,
195
      0x20000400, 0x20002400, 0xa0000400, 0xa0002400,
196
      0x20000408, 0x20002408, 0xa0000408, 0xa0002408,
197
      0x20200400, 0x20202400, 0xa0200400, 0xa0202400,
198
      0x20200408, 0x20202408, 0xa0200408, 0xa0202408 },
199
    /* table 2 */
200
    { 0x00000000, 0x00004000, 0x00000020, 0x00004020,
201
      0x00080000, 0x00084000, 0x00080020, 0x00084020,
202
      0x00000800, 0x00004800, 0x00000820, 0x00004820,
203
      0x00080800, 0x00084800, 0x00080820, 0x00084820,
204
      0x00000010, 0x00004010, 0x00000030, 0x00004030,
205
      0x00080010, 0x00084010, 0x00080030, 0x00084030,
206
      0x00000810, 0x00004810, 0x00000830, 0x00004830,
207
      0x00080810, 0x00084810, 0x00080830, 0x00084830,
208
      0x00400000, 0x00404000, 0x00400020, 0x00404020,
209
      0x00480000, 0x00484000, 0x00480020, 0x00484020,
210
      0x00400800, 0x00404800, 0x00400820, 0x00404820,
211
      0x00480800, 0x00484800, 0x00480820, 0x00484820,
212
      0x00400010, 0x00404010, 0x00400030, 0x00404030,
213
      0x00480010, 0x00484010, 0x00480030, 0x00484030,
214
      0x00400810, 0x00404810, 0x00400830, 0x00404830,
215
      0x00480810, 0x00484810, 0x00480830, 0x00484830 },
216
    /* table 3 */
217
    { 0x00000000, 0x40000000, 0x00000080, 0x40000080,
218
      0x00040000, 0x40040000, 0x00040080, 0x40040080,
219
      0x00000040, 0x40000040, 0x000000c0, 0x400000c0,
220
      0x00040040, 0x40040040, 0x000400c0, 0x400400c0,
221
      0x10000000, 0x50000000, 0x10000080, 0x50000080,
222
      0x10040000, 0x50040000, 0x10040080, 0x50040080,
223
      0x10000040, 0x50000040, 0x100000c0, 0x500000c0,
224
      0x10040040, 0x50040040, 0x100400c0, 0x500400c0,
225
      0x00800000, 0x40800000, 0x00800080, 0x40800080,
226
      0x00840000, 0x40840000, 0x00840080, 0x40840080,
227
      0x00800040, 0x40800040, 0x008000c0, 0x408000c0,
228
      0x00840040, 0x40840040, 0x008400c0, 0x408400c0,
229
      0x10800000, 0x50800000, 0x10800080, 0x50800080,
230
      0x10840000, 0x50840000, 0x10840080, 0x50840080,
231
      0x10800040, 0x50800040, 0x108000c0, 0x508000c0,
232
      0x10840040, 0x50840040, 0x108400c0, 0x508400c0 },
233
    /* table 4 */
234
    { 0x00000000, 0x00000008, 0x08000000, 0x08000008,
235
      0x00040000, 0x00040008, 0x08040000, 0x08040008,
236
      0x00002000, 0x00002008, 0x08002000, 0x08002008,
237
      0x00042000, 0x00042008, 0x08042000, 0x08042008,
238
      0x80000000, 0x80000008, 0x88000000, 0x88000008,
239
      0x80040000, 0x80040008, 0x88040000, 0x88040008,
240
      0x80002000, 0x80002008, 0x88002000, 0x88002008,
241
      0x80042000, 0x80042008, 0x88042000, 0x88042008,
242
      0x00080000, 0x00080008, 0x08080000, 0x08080008,
243
      0x000c0000, 0x000c0008, 0x080c0000, 0x080c0008,
244
      0x00082000, 0x00082008, 0x08082000, 0x08082008,
245
      0x000c2000, 0x000c2008, 0x080c2000, 0x080c2008,
246
      0x80080000, 0x80080008, 0x88080000, 0x88080008,
247
      0x800c0000, 0x800c0008, 0x880c0000, 0x880c0008,
248
      0x80082000, 0x80082008, 0x88082000, 0x88082008,
249
      0x800c2000, 0x800c2008, 0x880c2000, 0x880c2008 },
250
    /* table 5 */
251
    { 0x00000000, 0x00400000, 0x00008000, 0x00408000,
252
      0x40000000, 0x40400000, 0x40008000, 0x40408000,
253
      0x00000020, 0x00400020, 0x00008020, 0x00408020,
254
      0x40000020, 0x40400020, 0x40008020, 0x40408020,
255
      0x00001000, 0x00401000, 0x00009000, 0x00409000,
256
      0x40001000, 0x40401000, 0x40009000, 0x40409000,
257
      0x00001020, 0x00401020, 0x00009020, 0x00409020,
258
      0x40001020, 0x40401020, 0x40009020, 0x40409020,
259
      0x00100000, 0x00500000, 0x00108000, 0x00508000,
260
      0x40100000, 0x40500000, 0x40108000, 0x40508000,
261
      0x00100020, 0x00500020, 0x00108020, 0x00508020,
262
      0x40100020, 0x40500020, 0x40108020, 0x40508020,
263
      0x00101000, 0x00501000, 0x00109000, 0x00509000,
264
      0x40101000, 0x40501000, 0x40109000, 0x40509000,
265
      0x00101020, 0x00501020, 0x00109020, 0x00509020,
266
      0x40101020, 0x40501020, 0x40109020, 0x40509020 },
267
    /* table 6 */
268
    { 0x00000000, 0x00000040, 0x04000000, 0x04000040,
269
      0x00000800, 0x00000840, 0x04000800, 0x04000840,
270
      0x00800000, 0x00800040, 0x04800000, 0x04800040,
271
      0x00800800, 0x00800840, 0x04800800, 0x04800840,
272
      0x10000000, 0x10000040, 0x14000000, 0x14000040,
273
      0x10000800, 0x10000840, 0x14000800, 0x14000840,
274
      0x10800000, 0x10800040, 0x14800000, 0x14800040,
275
      0x10800800, 0x10800840, 0x14800800, 0x14800840,
276
      0x00000080, 0x000000c0, 0x04000080, 0x040000c0,
277
      0x00000880, 0x000008c0, 0x04000880, 0x040008c0,
278
      0x00800080, 0x008000c0, 0x04800080, 0x048000c0,
279
      0x00800880, 0x008008c0, 0x04800880, 0x048008c0,
280
      0x10000080, 0x100000c0, 0x14000080, 0x140000c0,
281
      0x10000880, 0x100008c0, 0x14000880, 0x140008c0,
282
      0x10800080, 0x108000c0, 0x14800080, 0x148000c0,
283
      0x10800880, 0x108008c0, 0x14800880, 0x148008c0 },
284
    /* table 7 */
285
    { 0x00000000, 0x00000010, 0x00000400, 0x00000410,
286
      0x00000004, 0x00000014, 0x00000404, 0x00000414,
287
      0x00004000, 0x00004010, 0x00004400, 0x00004410,
288
      0x00004004, 0x00004014, 0x00004404, 0x00004414,
289
      0x20000000, 0x20000010, 0x20000400, 0x20000410,
290
      0x20000004, 0x20000014, 0x20000404, 0x20000414,
291
      0x20004000, 0x20004010, 0x20004400, 0x20004410,
292
      0x20004004, 0x20004014, 0x20004404, 0x20004414,
293
      0x00200000, 0x00200010, 0x00200400, 0x00200410,
294
      0x00200004, 0x00200014, 0x00200404, 0x00200414,
295
      0x00204000, 0x00204010, 0x00204400, 0x00204410,
296
      0x00204004, 0x00204014, 0x00204404, 0x00204414,
297
      0x20200000, 0x20200010, 0x20200400, 0x20200410,
298
      0x20200004, 0x20200014, 0x20200404, 0x20200414,
299
      0x20204000, 0x20204010, 0x20204400, 0x20204410,
300
      0x20204004, 0x20204014, 0x20204404, 0x20204414 }
301
};
302
303
/*
304
 * The PC-1 Permutation
305
 * If we number the bits of the 8 bytes of key input like this (in octal):
306
 *     00 01 02 03 04 05 06 07
307
 *     10 11 12 13 14 15 16 17
308
 *     20 21 22 23 24 25 26 27
309
 *     30 31 32 33 34 35 36 37
310
 *     40 41 42 43 44 45 46 47
311
 *     50 51 52 53 54 55 56 57
312
 *     60 61 62 63 64 65 66 67
313
 *     70 71 72 73 74 75 76 77
314
 * then after the PC-1 permutation,
315
 * C0 is
316
 *     70 60 50 40 30 20 10 00
317
 *     71 61 51 41 31 21 11 01
318
 *     72 62 52 42 32 22 12 02
319
 *     73 63 53 43
320
 * D0 is
321
 *     76 66 56 46 36 26 16 06
322
 *     75 65 55 45 35 25 15 05
323
 *     74 64 54 44 34 24 14 04
324
 *                 33 23 13 03
325
 * and these parity bits have been discarded:
326
 *     77 67 57 47 37 27 17 07
327
 *
328
 * We achieve this by flipping the input matrix about the diagonal from 70-07,
329
 * getting left =
330
 *     77 67 57 47 37 27 17 07  (these are the parity bits)
331
 *     76 66 56 46 36 26 16 06
332
 *     75 65 55 45 35 25 15 05
333
 *     74 64 54 44 34 24 14 04
334
 * right =
335
 *     73 63 53 43 33 23 13 03
336
 *     72 62 52 42 32 22 12 02
337
 *     71 61 51 41 31 21 11 01
338
 *     70 60 50 40 30 20 10 00
339
 * then byte swap right, ala htonl() on a little endian machine.
340
 * right =
341
 *     70 60 50 40 30 20 10 00
342
 *     71 67 57 47 37 27 11 07
343
 *     72 62 52 42 32 22 12 02
344
 *     73 63 53 43 33 23 13 03
345
 * then
346
 *     c0 = right >> 4;
347
 *     d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
348
*/
349
350
#define FLIP_RIGHT_DIAGONAL(word, temp)        \
351
12
    temp = (word ^ (word >> 18)) & 0x00003333; \
352
12
    word ^= temp | (temp << 18);               \
353
12
    temp = (word ^ (word >> 9)) & 0x00550055;  \
354
12
    word ^= temp | (temp << 9);
355
356
#if defined(__GNUC__) && defined(NSS_X86_OR_X64)
357
#define BYTESWAP(word, temp) \
358
162
    __asm("bswap  %0"        \
359
162
          : "+r"(word));
360
#elif (_MSC_VER >= 1300) && defined(NSS_X86_OR_X64)
361
#include <stdlib.h>
362
#pragma intrinsic(_byteswap_ulong)
363
#define BYTESWAP(word, temp) \
364
    word = _byteswap_ulong(word);
365
#elif defined(__GNUC__) && (defined(__thumb2__) ||         \
366
                            (!defined(__thumb__) &&        \
367
                             (defined(__ARM_ARCH_6__) ||   \
368
                              defined(__ARM_ARCH_6J__) ||  \
369
                              defined(__ARM_ARCH_6K__) ||  \
370
                              defined(__ARM_ARCH_6Z__) ||  \
371
                              defined(__ARM_ARCH_6ZK__) || \
372
                              defined(__ARM_ARCH_6T2__) || \
373
                              defined(__ARM_ARCH_7__) ||   \
374
                              defined(__ARM_ARCH_7A__) ||  \
375
                              defined(__ARM_ARCH_7R__))))
376
#define BYTESWAP(word, temp) \
377
    __asm("rev %0, %0"       \
378
          : "+r"(word));
379
#else
380
#define BYTESWAP(word, temp)            \
381
    word = (word >> 16) | (word << 16); \
382
    temp = 0x00ff00ff;                  \
383
    word = ((word & temp) << 8) | ((word >> 8) & temp);
384
#endif
385
386
#define PC1(left, right, c0, d0, temp)                  \
387
6
    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
388
6
    left ^= temp << 4;                                  \
389
6
    FLIP_RIGHT_DIAGONAL(left, temp);                    \
390
6
    FLIP_RIGHT_DIAGONAL(right, temp);                   \
391
6
    BYTESWAP(right, temp);                              \
392
6
    c0 = right >> 4;                                    \
393
6
    d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
394
395
48
#define LEFT_SHIFT_1(reg) (((reg << 1) | (reg >> 27)) & 0x0FFFFFFF)
396
144
#define LEFT_SHIFT_2(reg) (((reg << 2) | (reg >> 26)) & 0x0FFFFFFF)
397
398
/*
399
 *   setup key schedules from key
400
 */
401
402
void
403
DES_MakeSchedule(HALF *ks, const BYTE *key, DESDirection direction)
404
6
{
405
6
    register HALF left, right;
406
6
    register HALF c0, d0;
407
6
    register HALF temp;
408
6
    int delta;
409
6
    unsigned int ls;
410
411
6
#if defined(HAVE_UNALIGNED_ACCESS)
412
6
    left = HALFPTR(key)[0];
413
6
    right = HALFPTR(key)[1];
414
6
#if defined(IS_LITTLE_ENDIAN)
415
6
    BYTESWAP(left, temp);
416
6
    BYTESWAP(right, temp);
417
6
#endif
418
#else
419
    if (((ptrdiff_t)key & 0x03) == 0) {
420
        left = HALFPTR(key)[0];
421
        right = HALFPTR(key)[1];
422
#if defined(IS_LITTLE_ENDIAN)
423
        BYTESWAP(left, temp);
424
        BYTESWAP(right, temp);
425
#endif
426
    } else {
427
        left = ((HALF)key[0] << 24) | ((HALF)key[1] << 16) |
428
               ((HALF)key[2] << 8) | key[3];
429
        right = ((HALF)key[4] << 24) | ((HALF)key[5] << 16) |
430
                ((HALF)key[6] << 8) | key[7];
431
    }
432
#endif
433
434
6
    PC1(left, right, c0, d0, temp);
435
436
6
    if (direction == DES_ENCRYPT) {
437
4
        delta = 2 * (int)sizeof(HALF);
438
4
    } else {
439
2
        ks += 30;
440
2
        delta = (-2) * (int)sizeof(HALF);
441
2
    }
442
443
102
    for (ls = 0x8103; ls; ls >>= 1) {
444
96
        if (ls & 1) {
445
24
            c0 = LEFT_SHIFT_1(c0);
446
24
            d0 = LEFT_SHIFT_1(d0);
447
72
        } else {
448
72
            c0 = LEFT_SHIFT_2(c0);
449
72
            d0 = LEFT_SHIFT_2(d0);
450
72
        }
451
452
#ifdef USE_INDEXING
453
#define PC2LOOKUP(b, c) PC2[b][c]
454
455
        left = PC2LOOKUP(0, ((c0 >> 22) & 0x3F));
456
        left |= PC2LOOKUP(1, ((c0 >> 13) & 0x3F));
457
        left |= PC2LOOKUP(2, ((c0 >> 4) & 0x38) | (c0 & 0x7));
458
        left |= PC2LOOKUP(3, ((c0 >> 18) & 0xC) | ((c0 >> 11) & 0x3) | (c0 & 0x30));
459
460
        right = PC2LOOKUP(4, ((d0 >> 22) & 0x3F));
461
        right |= PC2LOOKUP(5, ((d0 >> 15) & 0x30) | ((d0 >> 14) & 0xf));
462
        right |= PC2LOOKUP(6, ((d0 >> 7) & 0x3F));
463
        right |= PC2LOOKUP(7, ((d0 >> 1) & 0x3C) | (d0 & 0x3));
464
#else
465
768
#define PC2LOOKUP(b, c) *(HALF *)((BYTE *)&PC2[b][0] + (c))
466
467
96
        left = PC2LOOKUP(0, ((c0 >> 20) & 0xFC));
468
96
        left |= PC2LOOKUP(1, ((c0 >> 11) & 0xFC));
469
96
        left |= PC2LOOKUP(2, ((c0 >> 2) & 0xE0) | ((c0 << 2) & 0x1C));
470
96
        left |= PC2LOOKUP(3, ((c0 >> 16) & 0x30) | ((c0 >> 9) & 0xC) | ((c0 << 2) & 0xC0));
471
472
96
        right = PC2LOOKUP(4, ((d0 >> 20) & 0xFC));
473
96
        right |= PC2LOOKUP(5, ((d0 >> 13) & 0xC0) | ((d0 >> 12) & 0x3C));
474
96
        right |= PC2LOOKUP(6, ((d0 >> 5) & 0xFC));
475
96
        right |= PC2LOOKUP(7, ((d0 << 1) & 0xF0) | ((d0 << 2) & 0x0C));
476
96
#endif
477
        /* left  contains key bits for S1 S3 S2 S4 */
478
        /* right contains key bits for S6 S8 S5 S7 */
479
96
        temp = (left << 16)     /* S2 S4 XX XX */
480
96
               | (right >> 16); /* XX XX S6 S8 */
481
96
        ks[0] = temp;
482
483
96
        temp = (left & 0xffff0000)     /* S1 S3 XX XX */
484
96
               | (right & 0x0000ffff); /* XX XX S5 S7 */
485
96
        ks[1] = temp;
486
487
96
        ks = (HALF *)((BYTE *)ks + delta);
488
96
    }
489
6
}
490
491
/*
492
 * The DES Initial Permutation
493
 * if we number the bits of the 8 bytes of input like this (in octal):
494
 *     00 01 02 03 04 05 06 07
495
 *     10 11 12 13 14 15 16 17
496
 *     20 21 22 23 24 25 26 27
497
 *     30 31 32 33 34 35 36 37
498
 *     40 41 42 43 44 45 46 47
499
 *     50 51 52 53 54 55 56 57
500
 *     60 61 62 63 64 65 66 67
501
 *     70 71 72 73 74 75 76 77
502
 * then after the initial permutation, they will be in this order.
503
 *     71 61 51 41 31 21 11 01
504
 *     73 63 53 43 33 23 13 03
505
 *     75 65 55 45 35 25 15 05
506
 *     77 67 57 47 37 27 17 07
507
 *     70 60 50 40 30 20 10 00
508
 *     72 62 52 42 32 22 12 02
509
 *     74 64 54 44 34 24 14 04
510
 *     76 66 56 46 36 26 16 06
511
 *
512
 * One way to do this is in two steps:
513
 * 1. Flip this matrix about the diagonal from 70-07 as done for PC1.
514
 * 2. Rearrange the bytes (rows in the matrix above) with the following code.
515
 *
516
 * #define swapHiLo(word, temp) \
517
 *   temp  = (word ^ (word >> 24)) & 0x000000ff; \
518
 *   word ^=  temp | (temp << 24);
519
 *
520
 *   right ^= temp = ((left << 8) ^ right) & 0xff00ff00;
521
 *   left  ^= temp >> 8;
522
 *   swapHiLo(left, temp);
523
 *   swapHiLo(right,temp);
524
 *
525
 * However, the two steps can be combined, so that the rows are rearranged
526
 * while the matrix is being flipped, reducing the number of bit exchange
527
 * operations from 8 ot 5.
528
 *
529
 * Initial Permutation */
530
#define IP(left, right, temp)                            \
531
36
    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f;  \
532
36
    left ^= temp << 4;                                   \
533
36
    right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
534
36
    left ^= temp << 16;                                  \
535
36
    right ^= temp = ((left << 2) ^ right) & 0xcccccccc;  \
536
36
    left ^= temp >> 2;                                   \
537
36
    right ^= temp = ((left << 8) ^ right) & 0xff00ff00;  \
538
36
    left ^= temp >> 8;                                   \
539
36
    right ^= temp = ((left >> 1) ^ right) & 0x55555555;  \
540
36
    left ^= temp << 1;
541
542
/* The Final (Inverse Initial) permutation is done by reversing the
543
** steps of the Initital Permutation
544
*/
545
546
#define FP(left, right, temp)                            \
547
36
    right ^= temp = ((left >> 1) ^ right) & 0x55555555;  \
548
36
    left ^= temp << 1;                                   \
549
36
    right ^= temp = ((left << 8) ^ right) & 0xff00ff00;  \
550
36
    left ^= temp >> 8;                                   \
551
36
    right ^= temp = ((left << 2) ^ right) & 0xcccccccc;  \
552
36
    left ^= temp >> 2;                                   \
553
36
    right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
554
36
    left ^= temp << 16;                                  \
555
36
    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f;  \
556
36
    left ^= temp << 4;
557
558
void NO_SANITIZE_ALIGNMENT
559
DES_Do1Block(HALF *ks, const BYTE *inbuf, BYTE *outbuf)
560
36
{
561
36
    register HALF left, right;
562
36
    register HALF temp;
563
564
36
#if defined(HAVE_UNALIGNED_ACCESS)
565
36
    left = HALFPTR(inbuf)[0];
566
36
    right = HALFPTR(inbuf)[1];
567
36
#if defined(IS_LITTLE_ENDIAN)
568
36
    BYTESWAP(left, temp);
569
36
    BYTESWAP(right, temp);
570
36
#endif
571
#else
572
    if (((ptrdiff_t)inbuf & 0x03) == 0) {
573
        left = HALFPTR(inbuf)[0];
574
        right = HALFPTR(inbuf)[1];
575
#if defined(IS_LITTLE_ENDIAN)
576
        BYTESWAP(left, temp);
577
        BYTESWAP(right, temp);
578
#endif
579
    } else {
580
        left = ((HALF)inbuf[0] << 24) | ((HALF)inbuf[1] << 16) |
581
               ((HALF)inbuf[2] << 8) | inbuf[3];
582
        right = ((HALF)inbuf[4] << 24) | ((HALF)inbuf[5] << 16) |
583
                ((HALF)inbuf[6] << 8) | inbuf[7];
584
    }
585
#endif
586
587
36
    IP(left, right, temp);
588
589
    /* shift the values left circularly 3 bits. */
590
36
    left = (left << 3) | (left >> 29);
591
36
    right = (right << 3) | (right >> 29);
592
593
#ifdef USE_INDEXING
594
#define KSLOOKUP(s, b) SP[s][((temp >> (b + 2)) & 0x3f)]
595
#else
596
4.60k
#define KSLOOKUP(s, b) *(HALF *)((BYTE *)&SP[s][0] + ((temp >> b) & 0xFC))
597
36
#endif
598
36
#define ROUND(out, in, r)                            \
599
576
    temp = in ^ ks[2 * r];                           \
600
576
    out ^= KSLOOKUP(1, 24);                          \
601
576
    out ^= KSLOOKUP(3, 16);                          \
602
576
    out ^= KSLOOKUP(5, 8);                           \
603
576
    out ^= KSLOOKUP(7, 0);                           \
604
576
    temp = ((in >> 4) | (in << 28)) ^ ks[2 * r + 1]; \
605
576
    out ^= KSLOOKUP(0, 24);                          \
606
576
    out ^= KSLOOKUP(2, 16);                          \
607
576
    out ^= KSLOOKUP(4, 8);                           \
608
576
    out ^= KSLOOKUP(6, 0);
609
610
    /* Do the 16 Feistel rounds */
611
36
    ROUND(left, right, 0)
612
36
    ROUND(right, left, 1)
613
36
    ROUND(left, right, 2)
614
36
    ROUND(right, left, 3)
615
36
    ROUND(left, right, 4)
616
36
    ROUND(right, left, 5)
617
36
    ROUND(left, right, 6)
618
36
    ROUND(right, left, 7)
619
36
    ROUND(left, right, 8)
620
36
    ROUND(right, left, 9)
621
36
    ROUND(left, right, 10)
622
36
    ROUND(right, left, 11)
623
36
    ROUND(left, right, 12)
624
36
    ROUND(right, left, 13)
625
36
    ROUND(left, right, 14)
626
36
    ROUND(right, left, 15)
627
628
    /* now shift circularly right 3 bits to undo the shifting done
629
    ** above.  switch left and right here.
630
    */
631
36
    temp = (left >> 3) | (left << 29);
632
36
    left = (right >> 3) | (right << 29);
633
36
    right = temp;
634
635
36
    FP(left, right, temp);
636
637
36
#if defined(HAVE_UNALIGNED_ACCESS)
638
36
#if defined(IS_LITTLE_ENDIAN)
639
36
    BYTESWAP(left, temp);
640
36
    BYTESWAP(right, temp);
641
36
#endif
642
36
    HALFPTR(outbuf)
643
36
    [0] = left;
644
36
    HALFPTR(outbuf)
645
36
    [1] = right;
646
#else
647
    if (((ptrdiff_t)outbuf & 0x03) == 0) {
648
#if defined(IS_LITTLE_ENDIAN)
649
        BYTESWAP(left, temp);
650
        BYTESWAP(right, temp);
651
#endif
652
        HALFPTR(outbuf)
653
        [0] = left;
654
        HALFPTR(outbuf)
655
        [1] = right;
656
    } else {
657
        outbuf[0] = (BYTE)(left >> 24);
658
        outbuf[1] = (BYTE)(left >> 16);
659
        outbuf[2] = (BYTE)(left >> 8);
660
        outbuf[3] = (BYTE)(left);
661
662
        outbuf[4] = (BYTE)(right >> 24);
663
        outbuf[5] = (BYTE)(right >> 16);
664
        outbuf[6] = (BYTE)(right >> 8);
665
        outbuf[7] = (BYTE)(right);
666
    }
667
#endif
668
36
}
669
670
/* Ackowledgements:
671
** Two ideas used in this implementation were shown to me by Dennis Ferguson
672
** in 1990.  He credits them to Richard Outerbridge and Dan Hoey.  They were:
673
** 1. The method of computing the Initial and Final permutations.
674
** 2. Circularly rotating the SP tables and the initial values of left and
675
**  right to reduce the number of shifts required during the 16 rounds.
676
*/