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