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 Crypto Component */
17 /** */
18 /** DES Encryption Standard (DES) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #include "nx_crypto_des.h"
24
25
26 /* Define the eight S-box data structures used in the permutation. Keep them static,
27 since there is no reason to have these symbols referenced outside this file. */
28
29 static const ULONG sb1[64] =
30 {
31
32 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
33 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
34 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
35 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
36 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
37 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
38 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
39 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
40 };
41
42 static const ULONG sb2[64] =
43 {
44
45 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
46 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
47 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
48 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
49 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
50 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
51 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
52 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
53 };
54
55 static const ULONG sb3[64] =
56 {
57
58 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
59 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
60 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
61 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
62 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
63 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
64 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
65 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
66 };
67
68 static const ULONG sb4[64] =
69 {
70
71 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
72 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
73 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
74 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
75 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
76 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
77 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
78 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
79 };
80
81 static const ULONG sb5[64] =
82 {
83
84 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
85 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
86 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
87 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
88 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
89 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
90 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
91 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
92 };
93
94 static const ULONG sb6[64] =
95 {
96
97 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
98 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
99 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
100 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
101 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
102 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
103 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
104 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
105 };
106
107 static const ULONG sb7[64] =
108 {
109
110 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
111 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
112 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
113 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
114 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
115 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
116 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
117 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
118 };
119
120 static const ULONG sb8[64] =
121 {
122
123 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
124 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
125 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
126 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
127 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
128 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
129 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
130 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
131 };
132
133
134 /* Define the left half bit swap table. */
135
136 static const ULONG left_half_bit_swap[16] =
137 {
138
139 0x00000000UL, 0x00000001UL, 0x00000100UL, 0x00000101UL,
140 0x00010000UL, 0x00010001UL, 0x00010100UL, 0x00010101UL,
141 0x01000000UL, 0x01000001UL, 0x01000100UL, 0x01000101UL,
142 0x01010000UL, 0x01010001UL, 0x01010100UL, 0x01010101UL
143 };
144
145 /* Define the right half bit swap table. */
146
147 static const ULONG right_half_bit_swap[16] =
148 {
149 0x00000000UL, 0x01000000UL, 0x00010000UL, 0x01010000UL,
150 0x00000100UL, 0x01000100UL, 0x00010100UL, 0x01010100UL,
151 0x00000001UL, 0x01000001UL, 0x00010001UL, 0x01010001UL,
152 0x00000101UL, 0x01000101UL, 0x00010101UL, 0x01010101UL
153 };
154
155
156 /**************************************************************************/
157 /* */
158 /* FUNCTION RELEASE */
159 /* */
160 /* _nx_crypto_des_key_set PORTABLE C */
161 /* 6.1 */
162 /* AUTHOR */
163 /* */
164 /* Timothy Stapko, Microsoft Corporation */
165 /* */
166 /* DESCRIPTION */
167 /* */
168 /* This function sets up the 32 encryption keys as well as the 32 */
169 /* decryption keys for the DES algorithm. It must be called before */
170 /* either _nx_crypto_des_encrypt or _nx_crypto_des_decrypt can be */
171 /* called. */
172 /* */
173 /* INPUT */
174 /* */
175 /* context DES context pointer */
176 /* key 8-byte (64-bit) key */
177 /* */
178 /* OUTPUT */
179 /* */
180 /* status Completion status */
181 /* */
182 /* CALLS */
183 /* */
184 /* None */
185 /* */
186 /* CALLED BY */
187 /* */
188 /* _nx_crypto_3des_key_set Set the key for 3DES */
189 /* _nx_crypto_method_des_init Init the method for DES */
190 /* */
191 /* RELEASE HISTORY */
192 /* */
193 /* DATE NAME DESCRIPTION */
194 /* */
195 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
196 /* 09-30-2020 Timothy Stapko Modified comment(s), */
197 /* resulting in version 6.1 */
198 /* */
199 /**************************************************************************/
_nx_crypto_des_key_set(NX_CRYPTO_DES * context,UCHAR key[8])200 NX_CRYPTO_KEEP UINT _nx_crypto_des_key_set(NX_CRYPTO_DES *context, UCHAR key[8])
201 {
202
203 ULONG left, right, temp;
204 ULONG *encrypt_keys_ptr;
205 ULONG *decrypt_keys_ptr;
206 UINT round;
207
208
209 /* Determine if the context is non-null. */
210 if (context == NX_CRYPTO_NULL)
211 {
212 return(NX_CRYPTO_PTR_ERROR);
213 }
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 #ifdef NX_SECURE_KEY_CLEAR
306 left = 0; right = 0; temp = 0;
307 #endif /* NX_SECURE_KEY_CLEAR */
308
309 /* Return successful completion. */
310 return(NX_CRYPTO_SUCCESS);
311 }
312
313
314 /**************************************************************************/
315 /* */
316 /* FUNCTION RELEASE */
317 /* */
318 /* _nx_crypto_des_encrypt PORTABLE C */
319 /* 6.1.11 */
320 /* AUTHOR */
321 /* */
322 /* Timothy Stapko, Microsoft Corporation */
323 /* */
324 /* DESCRIPTION */
325 /* */
326 /* This function uses the DES algorithm to encrypt 8-bytes (64-bits). */
327 /* The result is 8 encrypted bytes. Note that the caller must make */
328 /* sure the source and destination are 8-bytes in size! */
329 /* */
330 /* INPUT */
331 /* */
332 /* context DES context pointer */
333 /* source 8-byte source */
334 /* destination 8-byte destination */
335 /* length The length of output buffer */
336 /* */
337 /* OUTPUT */
338 /* */
339 /* status Completion status */
340 /* */
341 /* CALLS */
342 /* */
343 /* _nx_crypto_des_process_block Encrypt 8-bytes of source */
344 /* */
345 /* CALLED BY */
346 /* */
347 /* _nx_crypto_3des_encrypt Perform 3DES mode encryption */
348 /* _nx_crypto_3des_decrypt Perform 3DES mode decryption */
349 /* */
350 /* RELEASE HISTORY */
351 /* */
352 /* DATE NAME DESCRIPTION */
353 /* */
354 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
355 /* 09-30-2020 Timothy Stapko Modified comment(s), */
356 /* updated constants, */
357 /* resulting in version 6.1 */
358 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
359 /* warning supression for */
360 /* obsolete DES/3DES, */
361 /* resulting in version 6.1.11 */
362 /* */
363 /**************************************************************************/
_nx_crypto_des_encrypt(NX_CRYPTO_DES * context,UCHAR source[8],UCHAR destination[8],UINT length)364 NX_CRYPTO_KEEP UINT _nx_crypto_des_encrypt(NX_CRYPTO_DES *context, UCHAR source[8], UCHAR destination[8], UINT length)
365 {
366 NX_CRYPTO_PARAMETER_NOT_USED(length);
367
368 /* Encrypt the block by supplying the encryption key set. */
369 _nx_crypto_des_process_block(source, destination, context -> nx_des_encryption_keys); /* lgtm[cpp/weak-cryptographic-algorithm] */
370
371 /* Return successful completion. */
372 return(NX_CRYPTO_SUCCESS);
373 }
374
375
376 /**************************************************************************/
377 /* */
378 /* FUNCTION RELEASE */
379 /* */
380 /* _nx_crypto_des_decrypt PORTABLE C */
381 /* 6.1.11 */
382 /* AUTHOR */
383 /* */
384 /* Timothy Stapko, Microsoft Corporation */
385 /* */
386 /* DESCRIPTION */
387 /* */
388 /* This function uses the DES algorithm to decrypt 8-bytes (64-bits). */
389 /* The result is 8 original source bytes. Note that the caller must */
390 /* make sure the source and destination are 8-bytes in size! */
391 /* */
392 /* INPUT */
393 /* */
394 /* context DES context pointer */
395 /* source 8-byte source */
396 /* destination 8-byte destination */
397 /* length The length of output buffer */
398 /* */
399 /* OUTPUT */
400 /* */
401 /* status Completion status */
402 /* */
403 /* CALLS */
404 /* */
405 /* _nx_crypto_des_process_block Decrypt 8-bytes of source */
406 /* */
407 /* CALLED BY */
408 /* */
409 /* _nx_crypto_3des_encrypt Perform 3DES mode encryption */
410 /* _nx_crypto_3des_decrypt Perform 3DES mode decryption */
411 /* */
412 /* RELEASE HISTORY */
413 /* */
414 /* DATE NAME DESCRIPTION */
415 /* */
416 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
417 /* 09-30-2020 Timothy Stapko Modified comment(s), */
418 /* updated constants, */
419 /* resulting in version 6.1 */
420 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
421 /* warning supression for */
422 /* obsolete DES/3DES, */
423 /* resulting in version 6.1.11 */
424 /* */
425 /**************************************************************************/
_nx_crypto_des_decrypt(NX_CRYPTO_DES * context,UCHAR source[8],UCHAR destination[8],UINT length)426 NX_CRYPTO_KEEP UINT _nx_crypto_des_decrypt(NX_CRYPTO_DES *context, UCHAR source[8], UCHAR destination[8], UINT length)
427 {
428 NX_CRYPTO_PARAMETER_NOT_USED(length);
429
430 /* Decrypt the block by supplying the decryption key set. */
431 _nx_crypto_des_process_block(source, destination, context -> nx_des_decryption_keys); /* lgtm[cpp/weak-cryptographic-algorithm] */
432
433 /* Return successful completion. */
434 return(NX_CRYPTO_SUCCESS);
435 }
436
437
438 /**************************************************************************/
439 /* */
440 /* FUNCTION RELEASE */
441 /* */
442 /* _nx_crypto_des_process_block PORTABLE C */
443 /* 6.1 */
444 /* AUTHOR */
445 /* */
446 /* Timothy Stapko, Microsoft Corporation */
447 /* */
448 /* DESCRIPTION */
449 /* */
450 /* This function uses the DES algorithm to decrypt 8-bytes (64-bits). */
451 /* The result is 8 original source bytes. Note that the caller must */
452 /* make sure the source and destination are 8-bytes in size! */
453 /* */
454 /* INPUT */
455 /* */
456 /* source 8-byte source */
457 /* destination 8-byte destination */
458 /* keys Pointer to either the encrypt */
459 /* or decrypt keys */
460 /* */
461 /* OUTPUT */
462 /* */
463 /* None */
464 /* */
465 /* CALLS */
466 /* */
467 /* None */
468 /* */
469 /* CALLED BY */
470 /* */
471 /* _nx_crypto_des_encrypt Perform DES mode encryption */
472 /* _nx_crypto_des_decrypt Perform DES mode decryption */
473 /* */
474 /* RELEASE HISTORY */
475 /* */
476 /* DATE NAME DESCRIPTION */
477 /* */
478 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
479 /* 09-30-2020 Timothy Stapko Modified comment(s), */
480 /* resulting in version 6.1 */
481 /* */
482 /**************************************************************************/
_nx_crypto_des_process_block(UCHAR source[8],UCHAR destination[8],ULONG keys[32])483 NX_CRYPTO_KEEP VOID _nx_crypto_des_process_block(UCHAR source[8], UCHAR destination[8], ULONG keys[32])
484 {
485
486 ULONG left, right, temp;
487 ULONG *key_ptr;
488 UINT round;
489
490
491 /* First, convert the 8-byte source into two ULONG halves, in an endian neutral fashion. */
492 left = (((ULONG)source[0]) << 24) | (((ULONG)source[1]) << 16) | (((ULONG)source[2]) << 8) | ((ULONG)source[3]);
493 right = (((ULONG)source[4]) << 24) | (((ULONG)source[5]) << 16) | (((ULONG)source[6]) << 8) | ((ULONG)source[7]);
494
495 /* Compute the initial permutation. */
496 temp = ((left >> 4) ^ right) & 0x0F0F0F0FUL;
497 right = right ^ temp;
498 left = left ^ (temp << 4);
499 temp = ((left >> 16) ^ right) & 0x0000FFFFUL;
500 right = right ^ temp;
501 left = left ^ (temp << 16);
502 temp = ((right >> 2) ^ left) & 0x33333333UL;
503 left = left ^ temp;
504 right = right ^ (temp << 2);
505 temp = ((right >> 8) ^ left) & 0x00FF00FFUL;
506 left = left ^ temp;
507 right = right ^ (temp << 8);
508 right = ((right << 1) | (right >> 31)) & 0xFFFFFFFFUL;
509 temp = (left ^ right) & 0xAAAAAAAAUL;
510 right = right ^ temp;
511 left = left ^ temp;
512 left = ((left << 1) | (left >> 31)) & 0xFFFFFFFFUL;
513
514 /* Setup pointer to input keys. */
515 key_ptr = keys;
516
517 /* Now process the 16 rounds of the DES computation. There are two rounds per
518 loop. */
519 for (round = 0; round < 8; round++)
520 {
521
522 /* Calculate the left half. */
523 temp = *key_ptr++ ^ right;
524 left = left ^ sb8[temp & 0x3F] ^ sb6[(temp >> 8) & 0x3F] ^ sb4[(temp >> 16) & 0x3F] ^ sb2[(temp >> 24) & 0x3F];
525
526 temp = *key_ptr++ ^ ((right << 28) | (right >> 4));
527 left = left ^ sb7[temp & 0x3F] ^ sb5[(temp >> 8) & 0x3F] ^ sb3[(temp >> 16) & 0x3F] ^ sb1[(temp >> 24) & 0x3F];
528
529 /* Calculate the right half. */
530 temp = *key_ptr++ ^ left;
531 right = right ^ sb8[temp & 0x3F] ^ sb6[(temp >> 8) & 0x3F] ^ sb4[(temp >> 16) & 0x3F] ^ sb2[(temp >> 24) & 0x3F];
532
533 temp = *key_ptr++ ^ ((left << 28) | (left >> 4));
534 right = right ^ sb7[temp & 0x3F] ^ sb5[(temp >> 8) & 0x3F] ^ sb3[(temp >> 16) & 0x3F] ^ sb1[(temp >> 24) & 0x3F];
535 }
536
537 /* Now compute the final permutation. */
538 right = ((right << 31) | (right >> 1)) & 0xFFFFFFFFUL;
539 temp = (right ^ left) & 0xAAAAAAAAUL;
540 right = right ^ temp;
541 left = left ^ temp;
542 left = ((left << 31) | (left >> 1)) & 0xFFFFFFFFUL;
543 temp = ((left >> 8) ^ right) & 0x00FF00FFUL;
544 right = right ^ temp;
545 left = left ^ (temp << 8);
546 temp = ((left >> 2) ^ right) & 0x33333333UL;
547 right = right ^ temp;
548 left = left ^ (temp << 2);
549 temp = ((right >> 16) ^ left) & 0x0000FFFFUL;
550 left = left ^ temp;
551 right = right ^ (temp << 16);
552 temp = ((right >> 4) ^ left) & 0x0F0F0F0FUL;
553 left = left ^ temp;
554 right = right ^ (temp << 4);
555
556 /* Finally, build the output. */
557 destination[0] = (UCHAR)(right >> 24);
558 destination[1] = (UCHAR)(right >> 16);
559 destination[2] = (UCHAR)(right >> 8);
560 destination[3] = (UCHAR)(right);
561 destination[4] = (UCHAR)(left >> 24);
562 destination[5] = (UCHAR)(left >> 16);
563 destination[6] = (UCHAR)(left >> 8);
564 destination[7] = (UCHAR)(left);
565
566 #ifdef NX_SECURE_KEY_CLEAR
567 left = 0; right = 0; temp = 0;
568 #endif /* NX_SECURE_KEY_CLEAR */
569 }
570
571
572 /**************************************************************************/
573 /* */
574 /* FUNCTION RELEASE */
575 /* */
576 /* _nx_crypto_method_des_init PORTABLE C */
577 /* 6.3.0 */
578 /* AUTHOR */
579 /* */
580 /* Timothy Stapko, Microsoft Corporation */
581 /* */
582 /* DESCRIPTION */
583 /* */
584 /* This function is the common crypto method init callback for */
585 /* Microsoft supported 3DES cryptographic algorithm. */
586 /* */
587 /* INPUT */
588 /* */
589 /* method Pointer to crypto method */
590 /* key Pointer to key */
591 /* key_size_in_bits Length of key size in bits */
592 /* handler Returned crypto handler */
593 /* crypto_metadata Metadata area */
594 /* crypto_metadata_size Size of the metadata area */
595 /* */
596 /* OUTPUT */
597 /* */
598 /* status Completion status */
599 /* */
600 /* CALLS */
601 /* */
602 /* _nx_crypto_des_key_set Set the key for DES */
603 /* */
604 /* CALLED BY */
605 /* */
606 /* Application Code */
607 /* */
608 /* RELEASE HISTORY */
609 /* */
610 /* DATE NAME DESCRIPTION */
611 /* */
612 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
613 /* 09-30-2020 Timothy Stapko Modified comment(s), */
614 /* resulting in version 6.1 */
615 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
616 /* warning supression for */
617 /* obsolete DES/3DES, */
618 /* resulting in version 6.1.11 */
619 /* 10-31-2023 Yanwu Cai Modified comment(s), */
620 /* resulting in version 6.3.0 */
621 /* */
622 /**************************************************************************/
_nx_crypto_method_des_init(struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,VOID ** handle,VOID * crypto_metadata,ULONG crypto_metadata_size)623 NX_CRYPTO_KEEP UINT _nx_crypto_method_des_init(struct NX_CRYPTO_METHOD_STRUCT *method,
624 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits, VOID **handle,
625 VOID *crypto_metadata,
626 ULONG crypto_metadata_size)
627 {
628 NX_CRYPTO_DES *des_context_ptr;
629
630 NX_CRYPTO_PARAMETER_NOT_USED(handle);
631
632 NX_CRYPTO_STATE_CHECK
633
634 /* Validate input parameters. */
635 if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
636 {
637 return(NX_CRYPTO_PTR_ERROR);
638 }
639
640 if ((key_size_in_bits != NX_CRYPTO_DES_KEY_LEN_IN_BITS) || (crypto_metadata_size < sizeof(NX_CRYPTO_DES))) /* lgtm[cpp/weak-cryptographic-algorithm] */
641 {
642 return(NX_CRYPTO_SIZE_ERROR);
643 }
644
645 /* Verify the metadata address is 4-byte aligned. */
646 if((((ULONG)crypto_metadata) & 0x3) != 0)
647 {
648 return(NX_CRYPTO_PTR_ERROR);
649 }
650
651 des_context_ptr = (NX_CRYPTO_DES *)(crypto_metadata);
652
653 _nx_crypto_des_key_set(des_context_ptr, key); /* lgtm[cpp/weak-cryptographic-algorithm] */
654
655 return(NX_CRYPTO_SUCCESS);
656 }
657
658
659 /**************************************************************************/
660 /* */
661 /* FUNCTION RELEASE */
662 /* */
663 /* _nx_crypto_method_des_cleanup PORTABLE C */
664 /* 6.1 */
665 /* AUTHOR */
666 /* */
667 /* Timothy Stapko, Microsoft Corporation */
668 /* */
669 /* DESCRIPTION */
670 /* */
671 /* This function cleans up the crypto metadata. */
672 /* */
673 /* INPUT */
674 /* */
675 /* crypto_metadata Crypto metadata */
676 /* */
677 /* OUTPUT */
678 /* */
679 /* status Completion status */
680 /* */
681 /* CALLS */
682 /* */
683 /* NX_CRYPTO_MEMSET Set the memory */
684 /* */
685 /* CALLED BY */
686 /* */
687 /* Application Code */
688 /* */
689 /* RELEASE HISTORY */
690 /* */
691 /* DATE NAME DESCRIPTION */
692 /* */
693 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
694 /* 09-30-2020 Timothy Stapko Modified comment(s), */
695 /* resulting in version 6.1 */
696 /* */
697 /**************************************************************************/
_nx_crypto_method_des_cleanup(VOID * crypto_metadata)698 NX_CRYPTO_KEEP UINT _nx_crypto_method_des_cleanup(VOID *crypto_metadata)
699 {
700
701 NX_CRYPTO_STATE_CHECK
702
703 #ifdef NX_SECURE_KEY_CLEAR
704 if (!crypto_metadata)
705 return (NX_CRYPTO_SUCCESS);
706
707 /* Clean up the crypto metadata. */
708 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_DES));
709 #else
710 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
711 #endif/* NX_SECURE_KEY_CLEAR */
712
713 return(NX_CRYPTO_SUCCESS);
714 }
715
716
717 /**************************************************************************/
718 /* */
719 /* FUNCTION RELEASE */
720 /* */
721 /* _nx_crypto_method_des_operation PORTABLE C */
722 /* 6.3.0 */
723 /* AUTHOR */
724 /* */
725 /* Timothy Stapko, Microsoft Corporation */
726 /* */
727 /* DESCRIPTION */
728 /* */
729 /* This function handles des encrpt or decrypt operations. */
730 /* */
731 /* INPUT */
732 /* */
733 /* op Operation Type */
734 /* Encrypt, Decrypt, Authenticate*/
735 /* handler Pointer to crypto context */
736 /* method Pointer to crypto method */
737 /* key Pointer to key */
738 /* key_size_in_bits Length of key size in bits */
739 /* input Input Stream */
740 /* input_length_in_byte Input Stream Length */
741 /* iv_ptr Initialized Vector */
742 /* output Output Stream */
743 /* output_length_in_byte Output Stream Length */
744 /* crypto_metadata Metadata area */
745 /* crypto_metadata_size Size of the metadata area */
746 /* packet_ptr Pointer to packet */
747 /* nx_crypto_hw_process_callback Callback function pointer */
748 /* */
749 /* OUTPUT */
750 /* */
751 /* status Completion status */
752 /* */
753 /* CALLS */
754 /* */
755 /* _nx_crypto_cbc_encrypt Perform CBC mode encryption */
756 /* _nx_crypto_cbc_decrypt Perform CBC mode decryption */
757 /* */
758 /* CALLED BY */
759 /* */
760 /* Application Code */
761 /* */
762 /* RELEASE HISTORY */
763 /* */
764 /* DATE NAME DESCRIPTION */
765 /* */
766 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
767 /* 09-30-2020 Timothy Stapko Modified comment(s), */
768 /* resulting in version 6.1 */
769 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
770 /* warning supression for */
771 /* obsolete DES/3DES, */
772 /* resulting in version 6.1.11 */
773 /* 10-31-2023 Yanwu Cai Modified comment(s), */
774 /* resulting in version 6.3.0 */
775 /* */
776 /**************************************************************************/
_nx_crypto_method_des_operation(UINT op,VOID * handler,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))777 NX_CRYPTO_KEEP UINT _nx_crypto_method_des_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
778 VOID *handler, /* Crypto handler */
779 struct NX_CRYPTO_METHOD_STRUCT *method,
780 UCHAR *key,
781 NX_CRYPTO_KEY_SIZE key_size_in_bits,
782 UCHAR *input,
783 ULONG input_length_in_byte,
784 UCHAR *iv_ptr,
785 UCHAR *output,
786 ULONG output_length_in_byte,
787 VOID *crypto_metadata,
788 ULONG crypto_metadata_size,
789 VOID *packet_ptr,
790 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
791 {
792 UINT status = NX_CRYPTO_NOT_SUCCESSFUL;
793 NX_CRYPTO_DES *context;
794
795 NX_CRYPTO_PARAMETER_NOT_USED(handler);
796 NX_CRYPTO_PARAMETER_NOT_USED(key);
797 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
798 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
799 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
800 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
801
802 NX_CRYPTO_STATE_CHECK
803
804 if (op == NX_CRYPTO_AUTHENTICATE)
805 {
806 /* Incorrect Operation. */
807 return(NX_CRYPTO_NOT_SUCCESSFUL);
808 }
809
810 if ((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
811 {
812 return(NX_CRYPTO_PTR_ERROR);
813 }
814
815 /* Verify the metadata address is 4-byte aligned. */
816 if((((ULONG)crypto_metadata) & 0x3) != 0)
817 {
818 return(NX_CRYPTO_PTR_ERROR);
819 }
820
821 if(crypto_metadata_size < sizeof(NX_CRYPTO_DES))
822 {
823 return(NX_CRYPTO_PTR_ERROR);
824 }
825
826 if (method -> nx_crypto_algorithm != NX_CRYPTO_ENCRYPTION_DES_CBC) /* lgtm[cpp/weak-cryptographic-algorithm] */
827 {
828 /* Incorrect method. */
829 return(NX_CRYPTO_NOT_SUCCESSFUL);
830 }
831
832 context = (NX_CRYPTO_DES *)crypto_metadata;
833
834 switch (op)
835 {
836 case NX_CRYPTO_DECRYPT:
837 {
838 status = _nx_crypto_cbc_decrypt_init(&(context -> nx_crypto_cbc_context),
839 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
840 if (status)
841 {
842 break;
843 }
844
845 status = _nx_crypto_cbc_decrypt(context, &(context -> nx_crypto_cbc_context),
846 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_des_decrypt,
847 input, output, input_length_in_byte,
848 (NX_CRYPTO_DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
849 } break;
850
851 case NX_CRYPTO_ENCRYPT:
852 {
853 status = _nx_crypto_cbc_encrypt_init(&(context -> nx_crypto_cbc_context),
854 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
855 if (status)
856 {
857 break;
858 }
859
860 status = _nx_crypto_cbc_encrypt(context, &(context -> nx_crypto_cbc_context),
861 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_des_encrypt,
862 input, output, input_length_in_byte,
863 (NX_CRYPTO_DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
864 } break;
865
866 case NX_CRYPTO_DECRYPT_INITIALIZE:
867 {
868 status = _nx_crypto_cbc_decrypt_init(&(context -> nx_crypto_cbc_context),
869 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
870 } break;
871
872 case NX_CRYPTO_ENCRYPT_INITIALIZE:
873 {
874 status = _nx_crypto_cbc_encrypt_init(&(context -> nx_crypto_cbc_context),
875 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
876 } break;
877
878 case NX_CRYPTO_DECRYPT_UPDATE:
879 {
880 status = _nx_crypto_cbc_decrypt(context, &(context -> nx_crypto_cbc_context),
881 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_des_decrypt,
882 input, output, input_length_in_byte,
883 (NX_CRYPTO_DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
884 } break;
885
886 case NX_CRYPTO_ENCRYPT_UPDATE:
887 {
888 status = _nx_crypto_cbc_encrypt(context, &(context -> nx_crypto_cbc_context),
889 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_des_encrypt,
890 input, output, input_length_in_byte,
891 (NX_CRYPTO_DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
892 } break;
893
894 case NX_CRYPTO_ENCRYPT_CALCULATE:
895 /* fallthrough */
896 case NX_CRYPTO_DECRYPT_CALCULATE:
897 {
898
899 /* Nothing to do. */
900 status = NX_CRYPTO_SUCCESS;
901 } break;
902
903 default:
904 {
905 status = NX_CRYPTO_INVALID_ALGORITHM;
906 } break;
907 }
908
909 return(status);
910 }
911
912