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/ccm.h"
17 #include "mbedtls_cc_ccm_star.h"
18 #include "mbedtls_ccm_common.h"
19 #include "mbedtls/cipher.h"
20 #include "mbedtls/timing.h"
21 #include "mbedtls/ctr_drbg.h"
22 
23 /* local */
24 #include "run_integration_pal_log.h"
25 #include "run_integration_test.h"
26 #include "run_integration_helper.h"
27 
28 #define AESCCM_DEFAULT_NONCE_SIZE 16
29 /************************************************************
30  *
31  * static function prototypes
32  *
33  ************************************************************/
34 static RunItError_t runIt_ccm(void);
35 
36 /************************************************************
37  *
38  * static functions
39  *
40  ************************************************************/
runIt_ccmStarEncOnly(void)41 static RunItError_t runIt_ccmStarEncOnly(void)
42 {
43     RunItError_t rc = RUNIT_ERROR__OK;
44 
45     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CCM.pdf */
46     static const uint8_t KEY[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
47     const uint8_t AD[20] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 };
48     const uint8_t MSG[24] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
49     const uint8_t RES[] = {0x5a, 0x21, 0xaf, 0x13, 0x2a, 0xf4, 0x02, 0x43, 0x31, 0xba, 0x7c, 0x4d, 0x7c, 0x3d, 0xcc, 0x0e, 0x19, 0x3e, 0x4d, 0x46, 0xa5, 0xc9, 0xa6, 0x82, };
50 
51     static const size_t TAG_LEN = 0;
52 
53     uint32_t FrameCounter = 5;
54     unsigned char nonceBuff[MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES];
55     uint8_t srcAddr[16] = { 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e };
56 
57     uint8_t buf[32];
58     mbedtls_ccm_context *pCtx = NULL;
59     RunItPtr ctxPtr;
60 
61     const char* TEST_NAME = "CCM STAR - ENC ONLY";
62     RUNIT_SUB_TEST_START(TEST_NAME);
63 
64     ALLOC_STRUCT(mbedtls_ccm_context, ctxPtr, pCtx);
65 
66     /* generate random buffer */
67     RUNIT_ASSERT_API(mbedtls_ccm_star_nonce_generate((uint8_t*)srcAddr, FrameCounter, TAG_LEN, nonceBuff) == 0);
68 
69     /* Initialize ccm engine */
70     RUNIT_API(mbedtls_ccm_init(pCtx));
71 
72     /* set key into context */
73     RUNIT_ASSERT_API(mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, KEY, 8 * sizeof(KEY)) == 0);
74 
75     /* perform cryptographic operation */
76     RUNIT_ASSERT_API(mbedtls_ccm_star_encrypt_and_tag(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), MSG, buf, buf + sizeof(MSG), TAG_LEN) == 0);
77 
78     RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "signed");
79 
80     /* compare result */
81     RUNIT_ASSERT(memcmp(buf, RES, sizeof(MSG) + TAG_LEN) == 0);
82 
83     /* perform cryptographic operation */
84     RUNIT_ASSERT_API(mbedtls_ccm_star_auth_decrypt(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), RES, buf, RES + sizeof(MSG), TAG_LEN) == 0);
85 
86     RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "verified");
87 
88     /* compare result */
89     RUNIT_ASSERT(memcmp(buf, MSG, sizeof(MSG)) == 0);
90 
91 bail:
92     RUNIT_API(mbedtls_ccm_free(pCtx));
93 
94     FREE_IF_NOT_NULL(ctxPtr);
95 
96     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] AAD[%"PRIu32"B] MSG[%"PRIu32"B] TAG[%"PRIu32"B]",
97                                    (uint32_t)8 * sizeof(KEY), (uint32_t)sizeof(AD), (uint32_t)sizeof(MSG), (uint32_t)TAG_LEN);
98     return rc;
99 }
100 
runIt_ccmStar(void)101 static RunItError_t runIt_ccmStar(void)
102 {
103     RunItError_t rc = RUNIT_ERROR__OK;
104 
105     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CCM.pdf */
106     static const uint8_t KEY[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
107     const uint8_t AD[20] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 };
108     const uint8_t MSG[24] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
109     const uint8_t RES[] = {0x07, 0x11, 0x7e, 0x35, 0x39, 0xb2, 0xed, 0x4c, 0x84, 0x91, 0x66, 0x07, 0x0b, 0x33, 0xe6, 0x39, 0x0c, 0xf8, 0xda, 0xcc, 0x37, 0x44, 0x00, 0x9d, 0xb1, 0xac, 0x43, 0x81, 0x81, 0x8e, 0x17, 0x6d, 0x54, 0x63, 0x78, 0x4b, 0xd7, 0xd0, 0xc5, 0x46, };
110 
111     static const size_t TAG_LEN = 16;
112 
113     uint32_t FrameCounter = 5;
114     unsigned char nonceBuff[MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES];
115     uint8_t srcAddr[16] = { 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e };
116 
117     uint8_t buf[40];
118     mbedtls_ccm_context *pCtx = NULL;
119     RunItPtr ctxPtr;
120 
121     const char* TEST_NAME = "CCM STAR";
122     RUNIT_SUB_TEST_START(TEST_NAME);
123 
124     ALLOC_STRUCT(mbedtls_ccm_context, ctxPtr, pCtx);
125 
126     /* generate random buffer */
127     RUNIT_ASSERT_API(mbedtls_ccm_star_nonce_generate((uint8_t*)srcAddr, FrameCounter, TAG_LEN, nonceBuff) == 0);
128 
129     /* Initialize ccm engine */
130     RUNIT_API(mbedtls_ccm_init(pCtx));
131 
132     /* set key into context */
133     RUNIT_ASSERT_API(mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, KEY, 8 * sizeof(KEY)) == 0);
134 
135     /* perform cryptographic operation */
136     RUNIT_ASSERT_API(mbedtls_ccm_star_encrypt_and_tag(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), MSG, buf, buf + sizeof(MSG), TAG_LEN) == 0);
137 
138     RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "signed");
139 
140     /* compare result */
141     RUNIT_ASSERT(memcmp(buf, RES, sizeof(MSG) + TAG_LEN) == 0);
142 
143     /* perform cryptographic operation */
144     RUNIT_ASSERT_API(mbedtls_ccm_star_auth_decrypt(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), RES, buf, RES + sizeof(MSG), TAG_LEN) == 0);
145 
146     RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "verified");
147 
148     /* compare result */
149     RUNIT_ASSERT(memcmp(buf, MSG, sizeof(MSG)) == 0);
150 
151 bail:
152     RUNIT_API(mbedtls_ccm_free(pCtx));
153 
154     FREE_IF_NOT_NULL(ctxPtr);
155 
156     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] AAD[%"PRIu32"B] MSG[%"PRIu32"B] TAG[%"PRIu32"B]",
157                                    (uint32_t)8 * sizeof(KEY), (uint32_t)sizeof(AD), (uint32_t)sizeof(MSG), (uint32_t)TAG_LEN);
158     return rc;
159 }
160 
runIt_ccm(void)161 static RunItError_t runIt_ccm(void)
162 {
163     RunItError_t rc = RUNIT_ERROR__OK;
164 #if defined(MBEDTLS_CCM_C)
165     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CCM.pdf */
166     static const uint8_t KEY[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
167     static const uint8_t IV[12] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b };
168     const uint8_t AD[20] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 };
169     const uint8_t MSG[24] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
170     const uint8_t RES[32] = { 0xE3, 0xB2, 0x01, 0xA9, 0xF5, 0xB7, 0x1A, 0x7A, 0x9B, 0x1C, 0xEA, 0xEC, 0xCD, 0x97, 0xE7, 0x0B, 0x61, 0x76, 0xAA, 0xD9, 0xA4, 0x42, 0x8A, 0xA5, 0x48, 0x43, 0x92, 0xFB, 0xC1, 0xB0, 0x99, 0x51 };
171     static const size_t TAG_LEN = 8;
172 
173     uint8_t buf[32];
174     RunItPtr ctxPtr;
175     mbedtls_ccm_context *pCtx = NULL;
176 
177     const char* TEST_NAME = "CCM";
178     RUNIT_SUB_TEST_START(TEST_NAME);
179 
180     ALLOC_STRUCT(mbedtls_ccm_context, ctxPtr, pCtx);
181 
182     /* Initialize ccm engine */
183     RUNIT_API(mbedtls_ccm_init(pCtx));
184 
185     /* set key into context */
186     RUNIT_ASSERT_API(mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, KEY, 8 * sizeof(KEY)) == 0);
187 
188     /* perform cryptographic operation */
189     RUNIT_ASSERT_API(mbedtls_ccm_encrypt_and_tag(pCtx, sizeof(MSG), IV, sizeof(IV), AD, sizeof(AD), MSG, buf, buf + sizeof(MSG), TAG_LEN) == 0);
190 
191     RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "signed");
192 
193     /* compare result */
194     RUNIT_ASSERT(memcmp(buf, RES, sizeof(MSG) + TAG_LEN) == 0);
195 
196     /* perform cryptographic operation */
197     RUNIT_ASSERT_API(mbedtls_ccm_auth_decrypt(pCtx, sizeof(MSG), IV, sizeof(IV), AD, sizeof(AD), RES, buf, RES + sizeof(MSG), TAG_LEN) == 0);
198 
199     RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "verified");
200 
201     /* compare result */
202     RUNIT_ASSERT(memcmp(buf, MSG, sizeof(MSG)) == 0);
203 
204 bail:
205     RUNIT_API(mbedtls_ccm_free(pCtx));
206 
207     FREE_IF_NOT_NULL(ctxPtr);
208 
209     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] AAD[%"PRIu32"B] MSG[%"PRIu32"B]",
210                                    (uint32_t)8 * sizeof(KEY), (uint32_t)sizeof(AD), (uint32_t)sizeof(MSG));
211 #endif /* MBEDTLS_CCM_C */
212     return rc;
213 }
214 
215 /************************************************************
216  *
217  * public functions
218  *
219  ************************************************************/
runIt_ccmTest(void)220 RunItError_t runIt_ccmTest(void)
221 {
222     RunItError_t rc = RUNIT_ERROR__OK;
223 
224     const char* TEST_NAME = "CCM";
225     RUNIT_TEST_START(TEST_NAME);
226 
227     RUNIT_ASSERT(runIt_ccm() == RUNIT_ERROR__OK);
228 #ifdef MBEDTLS_CCM_ALT
229     RUNIT_ASSERT(runIt_ccmStar() == RUNIT_ERROR__OK);
230     RUNIT_ASSERT(runIt_ccmStarEncOnly() == RUNIT_ERROR__OK);
231 #else
232     (void)runIt_ccmStar;
233     (void)runIt_ccmStarEncOnly;
234 #endif
235 
236 bail:
237 
238     RUNIT_TEST_RESULT(TEST_NAME);
239     return rc;
240 }
241