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