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