Coverage Report

Created: 2025-07-01 06:25

/src/nss/lib/freebl/des.c
Line
Count
Source (jump to first uncovered line)
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
0
    temp = (word ^ (word >> 18)) & 0x00003333; \
352
0
    word ^= temp | (temp << 18);               \
353
0
    temp = (word ^ (word >> 9)) & 0x00550055;  \
354
0
    word ^= temp | (temp << 9);
355
356
#if defined(__GNUC__) && defined(NSS_X86_OR_X64)
357
#define BYTESWAP(word, temp) \
358
0
    __asm("bswap  %0"        \
359
0
          : "+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
0
    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
388
0
    left ^= temp << 4;                                  \
389
0
    FLIP_RIGHT_DIAGONAL(left, temp);                    \
390
0
    FLIP_RIGHT_DIAGONAL(right, temp);                   \
391
0
    BYTESWAP(right, temp);                              \
392
0
    c0 = right >> 4;                                    \
393
0
    d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
394
395
0
#define LEFT_SHIFT_1(reg) (((reg << 1) | (reg >> 27)) & 0x0FFFFFFF)
396
0
#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
0
{
405
0
    register HALF left, right;
406
0
    register HALF c0, d0;
407
0
    register HALF temp;
408
0
    int delta;
409
0
    unsigned int ls;
410
411
0
#if defined(HAVE_UNALIGNED_ACCESS)
412
0
    left = HALFPTR(key)[0];
413
0
    right = HALFPTR(key)[1];
414
0
#if defined(IS_LITTLE_ENDIAN)
415
0
    BYTESWAP(left, temp);
416
0
    BYTESWAP(right, temp);
417
0
#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
0
    PC1(left, right, c0, d0, temp);
435
436
0
    if (direction == DES_ENCRYPT) {
437
0
        delta = 2 * (int)sizeof(HALF);
438
0
    } else {
439
0
        ks += 30;
440
0
        delta = (-2) * (int)sizeof(HALF);
441
0
    }
442
443
0
    for (ls = 0x8103; ls; ls >>= 1) {
444
0
        if (ls & 1) {
445
0
            c0 = LEFT_SHIFT_1(c0);
446
0
            d0 = LEFT_SHIFT_1(d0);
447
0
        } else {
448
0
            c0 = LEFT_SHIFT_2(c0);
449
0
            d0 = LEFT_SHIFT_2(d0);
450
0
        }
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
0
#define PC2LOOKUP(b, c) *(HALF *)((BYTE *)&PC2[b][0] + (c))
466
467
0
        left = PC2LOOKUP(0, ((c0 >> 20) & 0xFC));
468
0
        left |= PC2LOOKUP(1, ((c0 >> 11) & 0xFC));
469
0
        left |= PC2LOOKUP(2, ((c0 >> 2) & 0xE0) | ((c0 << 2) & 0x1C));
470
0
        left |= PC2LOOKUP(3, ((c0 >> 16) & 0x30) | ((c0 >> 9) & 0xC) | ((c0 << 2) & 0xC0));
471
472
0
        right = PC2LOOKUP(4, ((d0 >> 20) & 0xFC));
473
0
        right |= PC2LOOKUP(5, ((d0 >> 13) & 0xC0) | ((d0 >> 12) & 0x3C));
474
0
        right |= PC2LOOKUP(6, ((d0 >> 5) & 0xFC));
475
0
        right |= PC2LOOKUP(7, ((d0 << 1) & 0xF0) | ((d0 << 2) & 0x0C));
476
0
#endif
477
        /* left  contains key bits for S1 S3 S2 S4 */
478
        /* right contains key bits for S6 S8 S5 S7 */
479
0
        temp = (left << 16)     /* S2 S4 XX XX */
480
0
               | (right >> 16); /* XX XX S6 S8 */
481
0
        ks[0] = temp;
482
483
0
        temp = (left & 0xffff0000)     /* S1 S3 XX XX */
484
0
               | (right & 0x0000ffff); /* XX XX S5 S7 */
485
0
        ks[1] = temp;
486
487
0
        ks = (HALF *)((BYTE *)ks + delta);
488
0
    }
489
0
}
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
0
    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f;  \
532
0
    left ^= temp << 4;                                   \
533
0
    right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
534
0
    left ^= temp << 16;                                  \
535
0
    right ^= temp = ((left << 2) ^ right) & 0xcccccccc;  \
536
0
    left ^= temp >> 2;                                   \
537
0
    right ^= temp = ((left << 8) ^ right) & 0xff00ff00;  \
538
0
    left ^= temp >> 8;                                   \
539
0
    right ^= temp = ((left >> 1) ^ right) & 0x55555555;  \
540
0
    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
0
    right ^= temp = ((left >> 1) ^ right) & 0x55555555;  \
548
0
    left ^= temp << 1;                                   \
549
0
    right ^= temp = ((left << 8) ^ right) & 0xff00ff00;  \
550
0
    left ^= temp >> 8;                                   \
551
0
    right ^= temp = ((left << 2) ^ right) & 0xcccccccc;  \
552
0
    left ^= temp >> 2;                                   \
553
0
    right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
554
0
    left ^= temp << 16;                                  \
555
0
    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f;  \
556
0
    left ^= temp << 4;
557
558
void NO_SANITIZE_ALIGNMENT
559
DES_Do1Block(HALF *ks, const BYTE *inbuf, BYTE *outbuf)
560
0
{
561
0
    register HALF left, right;
562
0
    register HALF temp;
563
564
0
#if defined(HAVE_UNALIGNED_ACCESS)
565
0
    left = HALFPTR(inbuf)[0];
566
0
    right = HALFPTR(inbuf)[1];
567
0
#if defined(IS_LITTLE_ENDIAN)
568
0
    BYTESWAP(left, temp);
569
0
    BYTESWAP(right, temp);
570
0
#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
0
    IP(left, right, temp);
588
589
    /* shift the values left circularly 3 bits. */
590
0
    left = (left << 3) | (left >> 29);
591
0
    right = (right << 3) | (right >> 29);
592
593
#ifdef USE_INDEXING
594
#define KSLOOKUP(s, b) SP[s][((temp >> (b + 2)) & 0x3f)]
595
#else
596
0
#define KSLOOKUP(s, b) *(HALF *)((BYTE *)&SP[s][0] + ((temp >> b) & 0xFC))
597
0
#endif
598
0
#define ROUND(out, in, r)                            \
599
0
    temp = in ^ ks[2 * r];                           \
600
0
    out ^= KSLOOKUP(1, 24);                          \
601
0
    out ^= KSLOOKUP(3, 16);                          \
602
0
    out ^= KSLOOKUP(5, 8);                           \
603
0
    out ^= KSLOOKUP(7, 0);                           \
604
0
    temp = ((in >> 4) | (in << 28)) ^ ks[2 * r + 1]; \
605
0
    out ^= KSLOOKUP(0, 24);                          \
606
0
    out ^= KSLOOKUP(2, 16);                          \
607
0
    out ^= KSLOOKUP(4, 8);                           \
608
0
    out ^= KSLOOKUP(6, 0);
609
610
    /* Do the 16 Feistel rounds */
611
0
    ROUND(left, right, 0)
612
0
    ROUND(right, left, 1)
613
0
    ROUND(left, right, 2)
614
0
    ROUND(right, left, 3)
615
0
    ROUND(left, right, 4)
616
0
    ROUND(right, left, 5)
617
0
    ROUND(left, right, 6)
618
0
    ROUND(right, left, 7)
619
0
    ROUND(left, right, 8)
620
0
    ROUND(right, left, 9)
621
0
    ROUND(left, right, 10)
622
0
    ROUND(right, left, 11)
623
0
    ROUND(left, right, 12)
624
0
    ROUND(right, left, 13)
625
0
    ROUND(left, right, 14)
626
0
    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
0
    temp = (left >> 3) | (left << 29);
632
0
    left = (right >> 3) | (right << 29);
633
0
    right = temp;
634
635
0
    FP(left, right, temp);
636
637
0
#if defined(HAVE_UNALIGNED_ACCESS)
638
0
#if defined(IS_LITTLE_ENDIAN)
639
0
    BYTESWAP(left, temp);
640
0
    BYTESWAP(right, temp);
641
0
#endif
642
0
    HALFPTR(outbuf)
643
0
    [0] = left;
644
0
    HALFPTR(outbuf)
645
0
    [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
0
}
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
*/