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 /**   CTR Mode                                                            */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #include "nx_crypto_ctr.h"
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  FUNCTION                                               RELEASE        */
27 /*                                                                        */
28 /*    _nx_crypto_ctr_xor                                  PORTABLE C      */
29 /*                                                           6.1          */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Timothy Stapko, Microsoft Corporation                               */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This function performs XOR operation on the output buffer.          */
37 /*                                                                        */
38 /*  INPUT                                                                 */
39 /*                                                                        */
40 /*    plaintext                             Pointer to input plantext     */
41 /*    key                                   Value to be xor'ed            */
42 /*    ciphertext                            Output buffer of 16 bytes     */
43 /*                                                                        */
44 /*  OUTPUT                                                                */
45 /*                                                                        */
46 /*    None                                                                */
47 /*                                                                        */
48 /*  CALLS                                                                 */
49 /*                                                                        */
50 /*    None                                                                */
51 /*                                                                        */
52 /*  CALLED BY                                                             */
53 /*                                                                        */
54 /*    _nx_crypto_ctr_encrypt                Perform CTR mode encryption   */
55 /*                                                                        */
56 /*  RELEASE HISTORY                                                       */
57 /*                                                                        */
58 /*    DATE              NAME                      DESCRIPTION             */
59 /*                                                                        */
60 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
61 /*  09-30-2020     Timothy Stapko           Modified comment(s), disabled */
62 /*                                            unaligned access by default,*/
63 /*                                            resulting in version 6.1    */
64 /*                                                                        */
65 /**************************************************************************/
_nx_crypto_ctr_xor(UCHAR * plaintext,UCHAR * key,UCHAR * ciphertext)66 NX_CRYPTO_KEEP static VOID _nx_crypto_ctr_xor(UCHAR *plaintext, UCHAR *key, UCHAR *ciphertext)
67 {
68 #ifdef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
69 UINT *p = (UINT *)plaintext;
70 UINT *c = (UINT *)ciphertext;
71 UINT *k = (UINT *)key;
72 
73     c[0] = p[0] ^ k[0];
74     c[1] = p[1] ^ k[1];
75     c[2] = p[2] ^ k[2];
76     c[3] = p[3] ^ k[3];
77 #else
78     ciphertext[0] = plaintext[0] ^ key[0];
79     ciphertext[1] = plaintext[1] ^ key[1];
80     ciphertext[2] = plaintext[2] ^ key[2];
81     ciphertext[3] = plaintext[3] ^ key[3];
82     ciphertext[4] = plaintext[4] ^ key[4];
83     ciphertext[5] = plaintext[5] ^ key[5];
84     ciphertext[6] = plaintext[6] ^ key[6];
85     ciphertext[7] = plaintext[7] ^ key[7];
86     ciphertext[8] = plaintext[8] ^ key[8];
87     ciphertext[9] = plaintext[9] ^ key[9];
88     ciphertext[10] = plaintext[10] ^ key[10];
89     ciphertext[11] = plaintext[11] ^ key[11];
90     ciphertext[12] = plaintext[12] ^ key[12];
91     ciphertext[13] = plaintext[13] ^ key[13];
92     ciphertext[14] = plaintext[14] ^ key[14];
93     ciphertext[15] = plaintext[15] ^ key[15];
94 #endif
95 }
96 
97 /**************************************************************************/
98 /*                                                                        */
99 /*  FUNCTION                                               RELEASE        */
100 /*                                                                        */
101 /*    _nx_crypto_ctr_add_one                              PORTABLE C      */
102 /*                                                           6.1          */
103 /*  AUTHOR                                                                */
104 /*                                                                        */
105 /*    Timothy Stapko, Microsoft Corporation                               */
106 /*                                                                        */
107 /*  DESCRIPTION                                                           */
108 /*                                                                        */
109 /*    This function adds one for the last byte.                           */
110 /*                                                                        */
111 /*  INPUT                                                                 */
112 /*                                                                        */
113 /*    control_block                         Pointer to control block      */
114 /*                                                                        */
115 /*  OUTPUT                                                                */
116 /*                                                                        */
117 /*    None                                                                */
118 /*                                                                        */
119 /*  CALLS                                                                 */
120 /*                                                                        */
121 /*    None                                                                */
122 /*                                                                        */
123 /*  CALLED BY                                                             */
124 /*                                                                        */
125 /*    _nx_crypto_ctr_encrypt                Perform CTR mode encryption   */
126 /*                                                                        */
127 /*  RELEASE HISTORY                                                       */
128 /*                                                                        */
129 /*    DATE              NAME                      DESCRIPTION             */
130 /*                                                                        */
131 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
132 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
133 /*                                            resulting in version 6.1    */
134 /*                                                                        */
135 /**************************************************************************/
_nx_crypto_ctr_add_one(UCHAR * control_block)136 NX_CRYPTO_KEEP static VOID _nx_crypto_ctr_add_one(UCHAR *control_block)
137 {
138 USHORT result;
139 
140     /* Add one for last byte. */
141     result = (USHORT)(control_block[15] + 1);
142     control_block[15] = (UCHAR)(result & 0xFF);
143 
144     /* Handle carry. */
145     result = (USHORT)((result >> 8) + control_block[14]);
146     control_block[14] = (UCHAR)(result & 0xFF);
147     result = (USHORT)((result >> 8) + control_block[13]);
148     control_block[13] = (UCHAR)(result & 0xFF);
149     result = (USHORT)((result >> 8) + control_block[12]);
150     control_block[12] = (UCHAR)(result & 0xFF);
151 }
152 
153 /**************************************************************************/
154 /*                                                                        */
155 /*  FUNCTION                                               RELEASE        */
156 /*                                                                        */
157 /*    _nx_crypto_ctr_encrypt                              PORTABLE C      */
158 /*                                                           6.1          */
159 /*  AUTHOR                                                                */
160 /*                                                                        */
161 /*    Timothy Stapko, Microsoft Corporation                               */
162 /*                                                                        */
163 /*  DESCRIPTION                                                           */
164 /*                                                                        */
165 /*    This function performs CTR mode encryption, only support block of   */
166 /*    16 bytes.                                                           */
167 /*                                                                        */
168 /*  INPUT                                                                 */
169 /*                                                                        */
170 /*    crypto_metadata                       Pointer to crypto metadata    */
171 /*    ctr_metadata                          Pointer to CTR metadata       */
172 /*    crypto_function                       Pointer to crypto function    */
173 /*    key_set_function                      Pointer to key set function   */
174 /*    additional_data                       Pointer to the additional data*/
175 /*    additional_len                        Length of additional data     */
176 /*    input                                 Pointer to clear text input   */
177 /*    output                                Pointer to encrypted output   */
178 /*                                            The size of the output      */
179 /*                                            buffer must be at least     */
180 /*                                            the size of input message.  */
181 /*    length                                Length of the input message.  */
182 /*    iv                                    Nonce length + Nonce          */
183 /*    icv_len                               ICV length                    */
184 /*    block_size                            Block size                    */
185 /*                                                                        */
186 /*  OUTPUT                                                                */
187 /*                                                                        */
188 /*    status                                Completion status             */
189 /*                                                                        */
190 /*  CALLS                                                                 */
191 /*                                                                        */
192 /*    _nx_crypto_ctr_xor                    Perform XOR operation         */
193 /*    _nx_crypto_ctr_add_one                Perform add one operation     */
194 /*                                                                        */
195 /*  CALLED BY                                                             */
196 /*                                                                        */
197 /*    _nx_crypto_method_aes_ctr_operation   Handle AES encrypt or decrypt */
198 /*                                                                        */
199 /*  RELEASE HISTORY                                                       */
200 /*                                                                        */
201 /*    DATE              NAME                      DESCRIPTION             */
202 /*                                                                        */
203 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
204 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
205 /*                                            verified memcpy use cases,  */
206 /*                                            resulting in version 6.1    */
207 /*                                                                        */
208 /**************************************************************************/
_nx_crypto_ctr_encrypt(VOID * crypto_metadata,NX_CRYPTO_CTR * ctr_metadata,UINT (* crypto_function)(VOID *,UCHAR *,UCHAR *,UINT),UCHAR * input,UCHAR * output,UINT length,UINT block_size)209 NX_CRYPTO_KEEP UINT _nx_crypto_ctr_encrypt(VOID *crypto_metadata, NX_CRYPTO_CTR *ctr_metadata,
210                                            UINT (*crypto_function)(VOID *, UCHAR *, UCHAR *, UINT),
211                                            UCHAR *input, UCHAR *output, UINT length, UINT block_size)
212 {
213 UCHAR  *control_block = ctr_metadata -> nx_crypto_ctr_counter_block;
214 UCHAR  aes_output[NX_CRYPTO_CTR_BLOCK_SIZE];
215 UINT   i;
216 
217     /* Check the block size.  */
218     if (block_size != NX_CRYPTO_CTR_BLOCK_SIZE)
219     {
220         return(NX_CRYPTO_PTR_ERROR);
221     }
222 
223     for (i = 0; i < length; i += block_size)
224     {
225         if (length - i < block_size)
226         {
227             break;
228         }
229         crypto_function(crypto_metadata, control_block, aes_output, block_size);
230         _nx_crypto_ctr_xor(&input[i], aes_output, &output[i]);
231         _nx_crypto_ctr_add_one(control_block);
232     }
233 
234     /* If the input is not an even multiple of 16 bytes, we need to truncate and xor the remainder. */
235     if (length - i != 0)
236     {
237         crypto_function(crypto_metadata, control_block, aes_output, block_size);
238         _nx_crypto_ctr_xor(&input[i], aes_output, aes_output);
239         NX_CRYPTO_MEMCPY(&output[i], aes_output, length - i); /* Use case of memcpy is verified. */
240     }
241 
242 #ifdef NX_SECURE_KEY_CLEAR
243     NX_CRYPTO_MEMSET(aes_output, 0, sizeof(aes_output));
244 #endif /* NX_SECURE_KEY_CLEAR  */
245 
246     return(NX_CRYPTO_SUCCESS);
247 }
248 
249 /**************************************************************************/
250 /*                                                                        */
251 /*  FUNCTION                                               RELEASE        */
252 /*                                                                        */
253 /*    _nx_crypto_ctr_encrypt_init                         PORTABLE C      */
254 /*                                                           6.1          */
255 /*  AUTHOR                                                                */
256 /*                                                                        */
257 /*    Timothy Stapko, Microsoft Corporation                               */
258 /*                                                                        */
259 /*  DESCRIPTION                                                           */
260 /*                                                                        */
261 /*    This function performs CTR mode initialization.                     */
262 /*                                                                        */
263 /*  INPUT                                                                 */
264 /*                                                                        */
265 /*    ctr_metadata                          Pointer to CTR metadata       */
266 /*    iv                                    Pointer to Initial Vector     */
267 /*    iv_len                                Length of IV. Must be 8       */
268 /*    nonce                                 Pointer to Nonce              */
269 /*    nonce_len                             Length of Nonce. Must be 4    */
270 /*                                                                        */
271 /*  OUTPUT                                                                */
272 /*                                                                        */
273 /*    status                                Completion status             */
274 /*                                                                        */
275 /*  CALLS                                                                 */
276 /*                                                                        */
277 /*    None                                                                */
278 /*                                                                        */
279 /*  CALLED BY                                                             */
280 /*                                                                        */
281 /*    _nx_crypto_method_aes_ctr_operation   Handle AES encrypt or decrypt */
282 /*                                                                        */
283 /*  RELEASE HISTORY                                                       */
284 /*                                                                        */
285 /*    DATE              NAME                      DESCRIPTION             */
286 /*                                                                        */
287 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
288 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
289 /*                                            verified memcpy use cases,  */
290 /*                                            resulting in version 6.1    */
291 /*                                                                        */
292 /**************************************************************************/
_nx_crypto_ctr_encrypt_init(NX_CRYPTO_CTR * ctr_metadata,UCHAR * iv,UINT iv_len,UCHAR * nonce,UINT nonce_len)293 NX_CRYPTO_KEEP UINT _nx_crypto_ctr_encrypt_init(NX_CRYPTO_CTR *ctr_metadata, UCHAR *iv, UINT iv_len,
294                                                 UCHAR *nonce, UINT nonce_len)
295 {
296 UCHAR  *control_block = ctr_metadata -> nx_crypto_ctr_counter_block;
297 
298     /* Check IV length and Nonce length. */
299     if ((iv_len != 8) || (nonce_len != 4))
300     {
301         return(NX_CRYPTO_PTR_ERROR);
302     }
303 
304     /* Control block consists of the following data:
305      * Bits: |   0-31 (32 bits)  |        32-95 (64 bits)     |  96-127 (32 bits) |
306      *       |    All set to 1   | Initialization Vector (IV) |       Nonce       |
307      */
308     NX_CRYPTO_MEMSET(control_block, 0x0, 16);
309     control_block[15] = 1;
310     NX_CRYPTO_MEMCPY(&control_block[4], iv, 8); /* Use case of memcpy is verified. */
311     NX_CRYPTO_MEMCPY(&control_block[0], nonce, 4); /* Use case of memcpy is verified. */
312 
313     return(NX_CRYPTO_SUCCESS);
314 }
315 
316