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