1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <limits.h>
14 
15 /* mbedtls lib */
16 #include "mbedtls/aes.h"
17 #include "mbedtls/timing.h"
18 #include "mbedtls/gcm.h"
19 
20 /* CC */
21 #include "mbedtls_cc_aes_key_wrap.h"
22 
23 
24 /* pal */
25 #include "test_pal_mem.h"
26 
27 /* local */
28 #include "run_integration_pal_log.h"
29 #include "run_integration_test.h"
30 #include "run_integration_helper.h"
31 
32 #if defined(MBEDTLS_AES_C)
33 
34 #define AES_IV_SIZE     16
35 #define AES_BLOCK_SIZE  16
36 
37 /************************************************************
38  *
39  * static functions prototypes
40  *
41  ************************************************************/
42 static RunItError_t runIt_aesOfbTest(void);
43 static RunItError_t runIt_aesCtrTestProfiling(size_t data_len);
44 static RunItError_t runIt_aesCtrTest(void);
45 static RunItError_t runIt_aesCbcTest(void);
46 static RunItError_t runIt_aesEcbTest(void);
47 
48 /************************************************************
49  *
50  * static functions
51  *
52  ************************************************************/
53 
runIt_aesOfbTest(void)54 static RunItError_t runIt_aesOfbTest(void)
55 {
56     RunItError_t rc = RUNIT_ERROR__OK;
57 #if defined(MBEDTLS_CIPHER_MODE_OFB) && defined(MBEDTLS_AES_ALT)
58     const uint32_t KEY_SIZE = 256;
59 
60     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_OFB.pdf */
61     static const uint8_t IV[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
62     static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
63     static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
64     static const uint8_t CYPHER[] = { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60 };
65 
66     uint8_t key[KEY_SIZE / 8];
67     uint8_t iv[AES_IV_SIZE];
68     uint8_t buf[AES_BLOCK_SIZE];
69     mbedtls_aes_context ctx;
70 
71     const char* TEST_NAME = "AES-OFB-256";
72     RUNIT_SUB_TEST_START(TEST_NAME);
73 
74     /* Initialize aes engine */
75     RUNIT_API(mbedtls_aes_init(&ctx));
76 
77     memcpy(key, KEY, sizeof(key));
78 
79     /*
80      * encrypt
81      */
82     memcpy(buf, PLAIN, sizeof(buf));
83     memcpy(iv, IV, sizeof(iv));
84 
85     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
86 
87     /* set key into context */
88     RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
89 
90     /* perform cryptographic operation */
91     RUNIT_ASSERT_API(mbedtls_aes_crypt_ofb(&ctx, sizeof(buf), 0, iv, buf, buf) == 0);
92 
93     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
94 
95     /* compare result */
96     RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
97 
98     /*
99      * decrypt
100      */
101     memcpy(buf, CYPHER, sizeof(buf));
102     memcpy(iv, IV, sizeof(iv));
103 
104     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_dec");
105 
106     /* set key into context */
107     RUNIT_ASSERT_API(mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE) == 0);
108 
109     /* perform cryptographic operation */
110     RUNIT_ASSERT_API(mbedtls_aes_crypt_ofb(&ctx, sizeof(buf), 0, iv, buf, buf) == 0);
111 
112     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
113 
114     /* compare result */
115     RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
116 
117 bail:
118     RUNIT_API(mbedtls_aes_free(&ctx));
119 
120     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] IV[%uB] PLAIN[%uB]", sizeof(key) * 8, sizeof(iv), sizeof(buf));
121 #endif /* MBEDTLS_CIPHER_MODE_OFB && MBEDTLS_AES_ALT */
122     return rc;
123 
124 }
125 
runIt_aesCtrTestProfiling(size_t data_len)126 static RunItError_t runIt_aesCtrTestProfiling(size_t data_len)
127 {
128     RunItError_t rc = RUNIT_ERROR__OK;
129 #if defined(MBEDTLS_CIPHER_MODE_CTR)
130     const uint32_t KEY_SIZE = 128;
131 
132     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf */
133     static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81 };
134     static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
135     static const uint8_t NONCE[] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
136 
137     size_t offset;
138     uint8_t key[KEY_SIZE / 8];
139     uint8_t *buf = NULL;
140     unsigned char nonce_counter[16];
141     unsigned char stream_block[16];
142     mbedtls_aes_context ctx;
143     char testParam[PARAM_LEN] = { 0 };
144 
145     RunItPtr bufPtr;
146 
147     const char* TEST_NAME = "AES-CTR-128";
148     RUNIT_SUB_TEST_START(TEST_NAME);
149 
150     snprintf(testParam, PARAM_LEN - 1, "%uB", data_len);
151 
152     ALLOC32(bufPtr, buf, data_len);
153 
154     /* Initialize aes engine */
155     RUNIT_API(mbedtls_aes_init(&ctx));
156 
157     memcpy(key, KEY, sizeof(key));
158 
159     /*
160      * encrypt
161      */
162     memcpy(buf, PLAIN, sizeof(PLAIN));
163     memcpy(nonce_counter, NONCE, sizeof(nonce_counter));
164     offset = 0;
165 
166     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
167 
168     /* set key into context */
169     RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
170 
171     /* perform cryptographic operation */
172     RUNIT_ASSERT_W_PARAM(testParam, mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, nonce_counter, stream_block, buf, buf) == 0);
173 
174 bail:
175     RUNIT_API(mbedtls_aes_free(&ctx));
176 
177     FREE_IF_NOT_NULL(bufPtr);
178 
179     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", (unsigned int)KEY_SIZE, (unsigned int)data_len);
180 #endif /* MBEDTLS_CIPHER_MODE_CTR */
181     return rc;
182 }
183 
runIt_aesCtrTest(void)184 static RunItError_t runIt_aesCtrTest(void)
185 {
186     RunItError_t rc = RUNIT_ERROR__OK;
187 #if defined(MBEDTLS_CIPHER_MODE_CTR)
188     const uint32_t KEY_SIZE = 256;
189 
190     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf */
191     static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
192     static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
193     static const uint8_t CYPHER[] = { 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28 };
194     static const uint8_t NONCE[] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
195 
196     size_t offset;
197     uint8_t key[KEY_SIZE / 8];
198     uint8_t buf[AES_BLOCK_SIZE];
199     unsigned char nonce_counter[16];
200     unsigned char stream_block[16];
201     mbedtls_aes_context ctx;
202 
203     const char* TEST_NAME = "AES-CTR-256";
204     RUNIT_SUB_TEST_START(TEST_NAME);
205 
206     /* Initialize aes engine */
207     RUNIT_API(mbedtls_aes_init(&ctx));
208 
209     memcpy(key, KEY, sizeof(key));
210 
211     /*
212      * encrypt
213      */
214     memcpy(buf, PLAIN, sizeof(buf));
215     memcpy(nonce_counter, NONCE, sizeof(nonce_counter));
216     offset = 0;
217 
218     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
219 
220     /* set key into context */
221     RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
222 
223     /* perform cryptographic operation */
224     RUNIT_ASSERT_API(mbedtls_aes_crypt_ctr(&ctx, sizeof(buf), &offset, nonce_counter, stream_block, buf, buf) == 0);
225 
226     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
227 
228     /* compare result */
229     RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
230 
231     /*
232      * decrypt
233      */
234     memcpy(buf, CYPHER, sizeof(buf));
235     memcpy(nonce_counter, NONCE, sizeof(nonce_counter));
236     offset = 0;
237 
238     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_dec");
239 
240     /* set key into context, also in aes ctr decrypt, nonce should be encrypted */
241     /* aes ctr is fully symmetric so we use the encrypt operation to decrypt */
242     /* by using mbedtls_aes_setkey_enc we select an encryption operation */
243 
244     RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
245 
246     /* perform cryptographic operation */
247     RUNIT_ASSERT_API(mbedtls_aes_crypt_ctr(&ctx, sizeof(buf), &offset, nonce_counter, stream_block, buf, buf) == 0);
248 
249     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
250 
251     /* compare result */
252     RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
253 
254 bail:
255     RUNIT_API(mbedtls_aes_free(&ctx));
256 
257     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", (unsigned int)KEY_SIZE, sizeof(buf));
258 #endif /* MBEDTLS_CIPHER_MODE_CTR */
259     return rc;
260 }
261 
runIt_aesCbcTest(void)262 static RunItError_t runIt_aesCbcTest(void)
263 {
264     RunItError_t rc = RUNIT_ERROR__OK;
265 #if defined(MBEDTLS_CIPHER_MODE_CBC)
266 
267     const uint32_t KEY_SIZE = 256;
268 
269     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CBC.pdf */
270     static const uint8_t IV[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
271     static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
272     static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
273     static const uint8_t CYPHER[] = { 0xF5, 0x8C, 0x4C, 0x04, 0xD6, 0xE5, 0xF1, 0xBA, 0x77, 0x9E, 0xAB, 0xFB, 0x5F, 0x7B, 0xFB, 0xD6 };
274 
275     uint8_t key[KEY_SIZE / 8];
276     uint8_t buf[AES_BLOCK_SIZE];
277     uint8_t iv[AES_IV_SIZE];
278     mbedtls_aes_context ctx;
279 
280     const char* TEST_NAME = "AES-CBC-256";
281     RUNIT_SUB_TEST_START(TEST_NAME);
282 
283     /* Initialize aes engine */
284     RUNIT_API(mbedtls_aes_init(&ctx));
285 
286     memcpy(key, KEY, sizeof(key));
287 
288     /*
289      * encrypt
290      */
291     memcpy(iv, IV, sizeof(iv));
292     memcpy(buf, PLAIN, sizeof(buf));
293 
294     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
295     RUNIT_PRINT_BUF(iv, AES_IV_SIZE, "iv_enc");
296 
297     /* set key into context */
298     RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
299 
300     /* perform cryptographic operation */
301     RUNIT_ASSERT_API(mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(buf), iv, buf, buf) == 0);
302 
303     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
304 
305     /* compare result */
306     RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
307 
308     /*
309      * decrypt
310      */
311     memcpy(iv, IV, sizeof(iv));
312     memcpy(buf, CYPHER, sizeof(buf));
313 
314     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_dec");
315     RUNIT_PRINT_BUF(iv, AES_IV_SIZE, "iv_dec");
316 
317     /* set key into context */
318     RUNIT_ASSERT_API(mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE) == 0);
319 
320     /* perform cryptographic operation */
321     RUNIT_ASSERT_API(mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(buf), iv, buf, buf) == 0);
322 
323     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
324 
325     /* compare result */
326     RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
327 
328 bail:
329     RUNIT_API(mbedtls_aes_free(&ctx));
330 
331     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", sizeof(key) * 8, sizeof(buf));
332 #endif /* MBEDTLS_CIPHER_MODE_CBC */
333     return rc;
334 }
335 
runIt_aesEcbTest(void)336 static RunItError_t runIt_aesEcbTest(void)
337 {
338     RunItError_t rc = RUNIT_ERROR__OK;
339     const uint32_t KEY_SIZE = 256;
340 
341     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CBC.pdf */
342     static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
343     static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
344     static const uint8_t CYPHER[] = { 0xF3, 0xEE, 0xD1, 0xBD, 0xB5, 0xD2, 0xA0, 0x3C, 0x06, 0x4B, 0x5A, 0x7E, 0x3D, 0xB1, 0x81, 0xF8 };
345 
346     uint8_t key[KEY_SIZE / 8];
347     uint8_t buf[AES_BLOCK_SIZE];
348     mbedtls_aes_context ctx;
349 
350     const char* TEST_NAME = "AES-ECB-256";
351     RUNIT_SUB_TEST_START(TEST_NAME);
352 
353     /* Initialize aes engine */
354     RUNIT_API(mbedtls_aes_init(&ctx));
355 
356     memcpy(key, KEY, sizeof(key));
357 
358     /*
359      * encrypt
360      */
361     memcpy(buf, PLAIN, sizeof(buf));
362 
363     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init");
364 
365     /* set key into context */
366     RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
367 
368     /* perform cryptographic operation */
369     RUNIT_ASSERT_API(mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, buf, buf) == 0);
370 
371     /* compare result */
372     RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
373 
374     /*
375      * decrypt
376      */
377     memcpy(buf, CYPHER, sizeof(buf));
378 
379     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
380 
381     /* set key into context */
382     RUNIT_ASSERT_API(mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE) == 0);
383 
384     /* perform cryptographic operation */
385     RUNIT_ASSERT_API(mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, buf, buf) == 0);
386 
387     RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
388 
389     /* compare result */
390     RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
391 
392 bail:
393     RUNIT_API(mbedtls_aes_free(&ctx));
394 
395     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", sizeof(key) * 8, sizeof(buf));
396     return rc;
397 
398 }
399 
400 
401 
402 
403 /************************************************************
404  *
405  * public functions
406  *
407  ************************************************************/
runIt_aesTest(void)408 RunItError_t runIt_aesTest(void)
409 {
410     RunItError_t rc = RUNIT_ERROR__OK;
411 
412     const char* TEST_NAME = "AES";
413     RUNIT_TEST_START(TEST_NAME);
414 
415 
416     RUNIT_ASSERT(runIt_aesEcbTest() == RUNIT_ERROR__OK);
417     RUNIT_ASSERT(runIt_aesCbcTest() == RUNIT_ERROR__OK);
418     RUNIT_ASSERT(runIt_aesCtrTest() == RUNIT_ERROR__OK);
419 
420     RUNIT_ASSERT(runIt_aesOfbTest() == RUNIT_ERROR__OK);
421     RUNIT_ASSERT(runIt_aesCtrTestProfiling(16) == RUNIT_ERROR__OK);
422     RUNIT_ASSERT(runIt_aesCtrTestProfiling(128) == RUNIT_ERROR__OK);
423     RUNIT_ASSERT(runIt_aesCtrTestProfiling(1024) == RUNIT_ERROR__OK);
424     RUNIT_ASSERT(runIt_aesCtrTestProfiling(8192) == RUNIT_ERROR__OK);
425     RUNIT_ASSERT(runIt_aesCtrTestProfiling(65535) == RUNIT_ERROR__OK);
426 
427 bail:
428     RUNIT_TEST_RESULT(TEST_NAME);
429     return rc;
430 }
431 
432 #endif /* MBEDTLS_AES_C */
433