1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** DES Encryption Standard (DES) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #include "nx_api.h"
23 #include "nx_des.h"
24
25
26 /* Define macros for the DES transform function. */
27
28
29 /* Define the eight S-box data structures used in the permutation. Keep them static, since there is no
30 reason to have these symbols referenced outside this file. */
31
32 static ULONG sb1[64] =
33 {
34
35 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
36 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
37 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
38 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
39 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
40 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
41 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
42 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
43 };
44
45 static ULONG sb2[64] =
46 {
47
48 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
49 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
50 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
51 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
52 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
53 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
54 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
55 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
56 };
57
58 static ULONG sb3[64] =
59 {
60
61 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
62 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
63 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
64 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
65 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
66 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
67 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
68 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
69 };
70
71 static ULONG sb4[64] =
72 {
73
74 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
75 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
76 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
77 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
78 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
79 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
80 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
81 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
82 };
83
84 static ULONG sb5[64] =
85 {
86
87 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
88 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
89 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
90 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
91 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
92 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
93 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
94 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
95 };
96
97 static ULONG sb6[64] =
98 {
99
100 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
101 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
102 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
103 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
104 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
105 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
106 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
107 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
108 };
109
110 static ULONG sb7[64] =
111 {
112
113 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
114 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
115 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
116 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
117 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
118 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
119 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
120 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
121 };
122
123 static ULONG sb8[64] =
124 {
125
126 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
127 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
128 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
129 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
130 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
131 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
132 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
133 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
134 };
135
136
137 /* Define the left half bit swap table. */
138
139 static ULONG left_half_bit_swap[16] =
140 {
141
142 0x00000000UL, 0x00000001UL, 0x00000100UL, 0x00000101UL,
143 0x00010000UL, 0x00010001UL, 0x00010100UL, 0x00010101UL,
144 0x01000000UL, 0x01000001UL, 0x01000100UL, 0x01000101UL,
145 0x01010000UL, 0x01010001UL, 0x01010100UL, 0x01010101UL
146 };
147
148 /* Define the right half bit swap table. */
149
150 static ULONG right_half_bit_swap[16] =
151 {
152 0x00000000UL, 0x01000000UL, 0x00010000UL, 0x01010000UL,
153 0x00000100UL, 0x01000100UL, 0x00010100UL, 0x01010100UL,
154 0x00000001UL, 0x01000001UL, 0x00010001UL, 0x01010001UL,
155 0x00000101UL, 0x01000101UL, 0x00010101UL, 0x01010101UL
156 };
157
158
159 /**************************************************************************/
160 /* */
161 /* FUNCTION RELEASE */
162 /* */
163 /* _nx_des_key_set PORTABLE C */
164 /* 6.1 */
165 /* AUTHOR */
166 /* */
167 /* Yuxin Zhou, Microsoft Corporation */
168 /* */
169 /* DESCRIPTION */
170 /* */
171 /* This function sets up the 32 encryption keys as well as the 32 */
172 /* decryption keys for the DES algorithm. It must be called before */
173 /* either _nx_des_encrypt or _nx_des_decrypt can be called. */
174 /* destination. */
175 /* */
176 /* INPUT */
177 /* */
178 /* context DES context pointer */
179 /* key 8-byte (64-bit) key */
180 /* */
181 /* OUTPUT */
182 /* */
183 /* status Completion status */
184 /* */
185 /* CALLS */
186 /* */
187 /* None */
188 /* */
189 /* CALLED BY */
190 /* */
191 /* NetX Applications */
192 /* */
193 /* RELEASE HISTORY */
194 /* */
195 /* DATE NAME DESCRIPTION */
196 /* */
197 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
198 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
199 /* resulting in version 6.1 */
200 /* */
201 /**************************************************************************/
_nx_des_key_set(NX_DES * context,UCHAR key[8])202 UINT _nx_des_key_set(NX_DES *context, UCHAR key[8])
203 {
204
205 ULONG left, right, temp;
206 ULONG *encrypt_keys_ptr;
207 ULONG *decrypt_keys_ptr;
208 UINT round;
209
210
211 /* Determine if the context is non-null. */
212 if (context == NX_NULL)
213 return(NX_PTR_ERROR);
214
215 /* First, convert the 8-byte raw key into two ULONG halves, in an endian neutral fashion. */
216 left = (((ULONG) key[0]) << 24) | (((ULONG) key[1]) << 16) | (((ULONG) key[2]) << 8) | ((ULONG) key[3]);
217 right = (((ULONG) key[4]) << 24) | (((ULONG) key[5]) << 16) | (((ULONG) key[6]) << 8) | ((ULONG) key[7]);
218
219 /* Perform permutation on the key halves. */
220 temp = ((right >> 4) ^ left) & 0x0F0F0F0FUL;
221 left = left ^ temp;
222 right = right ^ (temp << 4);
223 temp = (right ^ left) & 0x10101010;
224 left = left ^ temp;
225 right = right ^ temp;
226
227 left = (left_half_bit_swap[(left) & 0xf] << 3) | (left_half_bit_swap[(left >> 8) & 0xf] << 2) |
228 (left_half_bit_swap[(left >> 16) & 0xf] << 1) | (left_half_bit_swap[(left >> 24) & 0xf]) |
229 (left_half_bit_swap[(left >> 5) & 0xf] << 7) | (left_half_bit_swap[(left >> 13) & 0xf] << 6) |
230 (left_half_bit_swap[(left >> 21) & 0xf] << 5) | (left_half_bit_swap[(left >> 29) & 0xf] << 4);
231 left = left & 0x0fffffff;
232
233 right = (right_half_bit_swap[(right >> 1) & 0xf] << 3) | (right_half_bit_swap[(right >> 9) & 0xf] << 2) |
234 (right_half_bit_swap[(right >> 17) & 0xf] << 1) | (right_half_bit_swap[(right >> 25) & 0xf]) |
235 (right_half_bit_swap[(right >> 4) & 0xf] << 7) | (right_half_bit_swap[(right >> 12) & 0xf] << 6) |
236 (right_half_bit_swap[(right >> 20) & 0xf] << 5) | (right_half_bit_swap[(right >> 28) & 0xf] << 4);
237 right = right & 0x0fffffff;
238
239 /* Setup encryption keys pointer. */
240 encrypt_keys_ptr = context -> nx_des_encryption_keys;
241
242 /* Calculate the encryption keys. */
243 for (round = 0; round < 16; round++)
244 {
245
246 /* Modify the left and right portions of the keys. */
247 if ((round < 2) || (round == 8) || (round == 15))
248 {
249
250 left = ((left << 1) | (left >> 27)) & 0x0FFFFFFFUL;
251 right = ((right << 1) | (right >> 27)) & 0x0FFFFFFFUL;
252 }
253 else
254 {
255
256 left = ((left << 2) | (left >> 26)) & 0x0FFFFFFFUL;
257 right = ((right << 2) | (right >> 26)) & 0x0FFFFFFFUL;
258 }
259
260 /* Setup the key. */
261 *encrypt_keys_ptr++ = ((left << 4) & 0x24000000UL) | ((left << 28) & 0x10000000UL) |
262 ((left << 14) & 0x08000000UL) | ((left << 18) & 0x02080000UL) |
263 ((left << 6) & 0x01000000UL) | ((left << 9) & 0x00200000UL) |
264 ((left >> 1) & 0x00100000UL) | ((left << 10) & 0x00040000UL) |
265 ((left << 2) & 0x00020000UL) | ((left >> 10) & 0x00010000UL) |
266 ((right >> 13) & 0x00002000UL) | ((right >> 4) & 0x00001000UL) |
267 ((right << 6) & 0x00000800UL) | ((right >> 1) & 0x00000400UL) |
268 ((right >> 14) & 0x00000200UL) | (right & 0x00000100UL) |
269 ((right >> 5) & 0x00000020UL) | ((right >> 10) & 0x00000010UL) |
270 ((right >> 3) & 0x00000008UL) | ((right >> 18) & 0x00000004UL) |
271 ((right >> 26) & 0x00000002UL) | ((right >> 24) & 0x00000001UL);
272
273 /* Setup the next key. */
274 *encrypt_keys_ptr++ = ((left << 15) & 0x20000000UL) | ((left << 17) & 0x10000000UL) |
275 ((left << 10) & 0x08000000UL) | ((left << 22) & 0x04000000UL) |
276 ((left >> 2) & 0x02000000UL) | ((left << 1) & 0x01000000UL) |
277 ((left << 16) & 0x00200000UL) | ((left << 11) & 0x00100000UL) |
278 ((left << 3) & 0x00080000UL) | ((left >> 6) & 0x00040000UL) |
279 ((left << 15) & 0x00020000UL) | ((left >> 4) & 0x00010000UL) |
280 ((right >> 2) & 0x00002000UL) | ((right << 8) & 0x00001000UL) |
281 ((right >> 14) & 0x00000808UL) | ((right >> 9) & 0x00000400UL) |
282 ((right) & 0x00000200UL) | ((right << 7) & 0x00000100UL) |
283 ((right >> 7) & 0x00000020UL) | ((right >> 3) & 0x00000011UL) |
284 ((right << 2) & 0x00000004UL) | ((right >> 21) & 0x00000002UL);
285 }
286
287 /* Reposition the encryption key pointer. */
288 encrypt_keys_ptr = encrypt_keys_ptr - 2;
289
290 /* Setup decryption pointer. */
291 decrypt_keys_ptr = context -> nx_des_decryption_keys;
292
293 /* Now setup decryption keys. */
294 for (round = 0; round < 16; round++)
295 {
296
297 /* Copy the reverse of the encryption keys. */
298 *decrypt_keys_ptr++ = *encrypt_keys_ptr;
299 *decrypt_keys_ptr++ = *(encrypt_keys_ptr + 1);
300
301 /* Adjust the encryption keys pointer. */
302 encrypt_keys_ptr = encrypt_keys_ptr - 2;
303 }
304
305 /* Return successful completion. */
306 return(NX_SUCCESS);
307 }
308
309
310 /**************************************************************************/
311 /* */
312 /* FUNCTION RELEASE */
313 /* */
314 /* _nx_des_encrypt PORTABLE C */
315 /* 6.1 */
316 /* AUTHOR */
317 /* */
318 /* Yuxin Zhou, Microsoft Corporation */
319 /* */
320 /* DESCRIPTION */
321 /* */
322 /* This function uses the DES algorithm to encrypt 8-bytes (64-bits). */
323 /* The result is 8 encrypted bytes. Note that the caller must make */
324 /* sure the source and destination are 8-bytes in size! */
325 /* */
326 /* INPUT */
327 /* */
328 /* context DES context pointer */
329 /* source 8-byte source */
330 /* destination 8-byte destination */
331 /* */
332 /* OUTPUT */
333 /* */
334 /* status Completion status */
335 /* */
336 /* CALLS */
337 /* */
338 /* _nx_des_process_block Encrypt 8-bytes of source */
339 /* */
340 /* CALLED BY */
341 /* */
342 /* NetX Applications */
343 /* */
344 /* RELEASE HISTORY */
345 /* */
346 /* DATE NAME DESCRIPTION */
347 /* */
348 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
349 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
350 /* resulting in version 6.1 */
351 /* */
352 /**************************************************************************/
_nx_des_encrypt(NX_DES * context,UCHAR source[8],UCHAR destination[8])353 UINT _nx_des_encrypt(NX_DES *context, UCHAR source[8], UCHAR destination[8])
354 {
355
356 /* Determine if the context is non-null. */
357 if (context == NX_NULL)
358 return(NX_PTR_ERROR);
359
360 /* Encrypt the block by supplying the encryption key set. */
361 _nx_des_process_block(source, destination, context -> nx_des_encryption_keys);
362
363 /* Return successful completion. */
364 return(NX_SUCCESS);
365 }
366
367
368 /**************************************************************************/
369 /* */
370 /* FUNCTION RELEASE */
371 /* */
372 /* _nx_des_decrypt PORTABLE C */
373 /* 6.1 */
374 /* AUTHOR */
375 /* */
376 /* Yuxin Zhou, Microsoft Corporation */
377 /* */
378 /* DESCRIPTION */
379 /* */
380 /* This function uses the DES algorithm to decrypt 8-bytes (64-bits). */
381 /* The result is 8 original source bytes. Note that the caller must */
382 /* make sure the source and destination are 8-bytes in size! */
383 /* */
384 /* INPUT */
385 /* */
386 /* context DES context pointer */
387 /* source 8-byte source */
388 /* destination 8-byte destination */
389 /* */
390 /* OUTPUT */
391 /* */
392 /* status Completion status */
393 /* */
394 /* CALLS */
395 /* */
396 /* _nx_des_process_block Decrypt 8-bytes of source */
397 /* */
398 /* CALLED BY */
399 /* */
400 /* NetX Applications */
401 /* */
402 /* RELEASE HISTORY */
403 /* */
404 /* DATE NAME DESCRIPTION */
405 /* */
406 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
407 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
408 /* resulting in version 6.1 */
409 /* */
410 /**************************************************************************/
_nx_des_decrypt(NX_DES * context,UCHAR source[8],UCHAR destination[8])411 UINT _nx_des_decrypt(NX_DES *context, UCHAR source[8], UCHAR destination[8])
412 {
413
414 /* Determine if the context is non-null. */
415 if (context == NX_NULL)
416 return(NX_PTR_ERROR);
417
418 /* Decrypt the block by supplying the decryption key set. */
419 _nx_des_process_block(source, destination, context -> nx_des_decryption_keys);
420
421 /* Return successful completion. */
422 return(NX_SUCCESS);
423 }
424
425
426 /**************************************************************************/
427 /* */
428 /* FUNCTION RELEASE */
429 /* */
430 /* _nx_des_process_block PORTABLE C */
431 /* 6.1 */
432 /* AUTHOR */
433 /* */
434 /* Yuxin Zhou, Microsoft Corporation */
435 /* */
436 /* DESCRIPTION */
437 /* */
438 /* This function uses the DES algorithm to decrypt 8-bytes (64-bits). */
439 /* The result is 8 original source bytes. Note that the caller must */
440 /* make sure the source and destination are 8-bytes in size! */
441 /* */
442 /* INPUT */
443 /* */
444 /* source 8-byte source */
445 /* destination 8-byte destination */
446 /* keys Pointer to either the encrypt */
447 /* or decrypt keys */
448 /* */
449 /* OUTPUT */
450 /* */
451 /* status Completion status */
452 /* */
453 /* CALLS */
454 /* */
455 /* None */
456 /* */
457 /* CALLED BY */
458 /* */
459 /* NetX Applications */
460 /* */
461 /* RELEASE HISTORY */
462 /* */
463 /* DATE NAME DESCRIPTION */
464 /* */
465 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
466 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
467 /* resulting in version 6.1 */
468 /* */
469 /**************************************************************************/
_nx_des_process_block(UCHAR source[8],UCHAR destination[8],ULONG keys[32])470 VOID _nx_des_process_block(UCHAR source[8], UCHAR destination[8], ULONG keys[32])
471 {
472
473 ULONG left, right, temp;
474 ULONG *key_ptr;
475 UINT round;
476
477
478 /* First, convert the 8-byte source into two ULONG halves, in an endian neutral fashion. */
479 left = (((ULONG) source[0]) << 24) | (((ULONG) source[1]) << 16) | (((ULONG) source[2]) << 8) | ((ULONG) source[3]);
480 right = (((ULONG) source[4]) << 24) | (((ULONG) source[5]) << 16) | (((ULONG) source[6]) << 8) | ((ULONG) source[7]);
481
482 /* Compute the initial permutation. */
483 temp = ((left >> 4) ^ right) & 0x0F0F0F0FUL;
484 right = right ^ temp;
485 left = left ^ (temp << 4);
486 temp = ((left >> 16) ^ right) & 0x0000FFFFUL;
487 right = right ^ temp;
488 left = left ^ (temp << 16);
489 temp = ((right >> 2) ^ left) & 0x33333333UL;
490 left = left ^ temp;
491 right = right ^ (temp << 2);
492 temp = ((right >> 8) ^ left) & 0x00FF00FFUL;
493 left = left ^ temp;
494 right = right ^ (temp << 8);
495 right = ((right << 1) | (right >> 31)) & 0xFFFFFFFFUL;
496 temp = (left ^ right) & 0xAAAAAAAAUL;
497 right = right ^ temp;
498 left = left ^ temp;
499 left = ((left << 1) | (left >> 31)) & 0xFFFFFFFFUL;
500
501 /* Setup pointer to input keys. */
502 key_ptr = keys;
503
504 /* Now process the 16 rounds of the DES computation. There are two rounds per
505 loop. */
506 for (round = 0; round < 8; round++)
507 {
508
509 /* Calculate the left half. */
510 temp = *key_ptr++ ^ right;
511 left = left ^ sb8[temp & 0x3F] ^ sb6[(temp >> 8) & 0x3F] ^ sb4[(temp >> 16) & 0x3F] ^ sb2[(temp >> 24) & 0x3F];
512
513 temp = *key_ptr++ ^ ((right << 28) | (right >> 4));
514 left = left ^ sb7[temp & 0x3F] ^ sb5[(temp >> 8) & 0x3F] ^ sb3[(temp >> 16) & 0x3F] ^ sb1[(temp >> 24) & 0x3F];
515
516 /* Calculate the right half. */
517 temp = *key_ptr++ ^ left;
518 right = right ^ sb8[temp & 0x3F] ^ sb6[(temp >> 8) & 0x3F] ^ sb4[(temp >> 16) & 0x3F] ^ sb2[(temp >> 24) & 0x3F];
519
520 temp = *key_ptr++ ^ ((left << 28) | (left >> 4));
521 right = right ^ sb7[temp & 0x3F] ^ sb5[(temp >> 8) & 0x3F] ^ sb3[(temp >> 16) & 0x3F] ^ sb1[(temp >> 24) & 0x3F];
522 }
523
524 /* Now compute the final permutation. */
525 right = ((right << 31) | (right >> 1)) & 0xFFFFFFFFUL;
526 temp = (right ^ left) & 0xAAAAAAAAUL;
527 right = right ^ temp;
528 left = left ^ temp;
529 left = ((left << 31) | (left >> 1)) & 0xFFFFFFFFUL;
530 temp = ((left >> 8) ^ right) & 0x00FF00FFUL;
531 right = right ^ temp;
532 left = left ^ (temp << 8);
533 temp = ((left >> 2) ^ right) & 0x33333333UL;
534 right = right ^ temp;
535 left = left ^ (temp << 2);
536 temp = ((right >> 16) ^ left) & 0x0000FFFFUL;
537 left = left ^ temp;
538 right = right ^ (temp << 16);
539 temp = ((right >> 4) ^ left) & 0x0F0F0F0FUL;
540 left = left ^ temp;
541 right = right ^ (temp << 4);
542
543 /* Finally, build the output. */
544 destination[0] = (UCHAR) (right >> 24);
545 destination[1] = (UCHAR) (right >> 16);
546 destination[2] = (UCHAR) (right >> 8);
547 destination[3] = (UCHAR) (right);
548 destination[4] = (UCHAR) (left >> 24);
549 destination[5] = (UCHAR) (left >> 16);
550 destination[6] = (UCHAR) (left >> 8);
551 destination[7] = (UCHAR) (left);
552 }
553
554