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/md.h"
17 #include "cc_general_defs.h"
18 #include "mbedtls/cmac.h"
19 /* pal */
20 #include "test_pal_mem.h"
21
22 /* local */
23 #include "run_integration_pal_log.h"
24 #include "run_integration_test.h"
25 #include "run_integration_helper.h"
26
27 /************************************************************
28 *
29 * static function prototypes
30 *
31 ************************************************************/
32 static RunItError_t runIt_hmac(void);
33 static RunItError_t runIt_cmac(void);
34 static RunItError_t runIt_cmacProfiling(size_t data_len);
35
36 /************************************************************
37 *
38 * static functions
39 *
40 ************************************************************/
runIt_hmac(void)41 static RunItError_t runIt_hmac(void)
42 {
43 RunItError_t rc = RUNIT_ERROR__OK;
44
45 static uint8_t hmacTest_Key[] = { 0x15, 0xb2, 0x9a, 0xd8, 0xae, 0x2a, 0xad, 0x73, 0xa7, 0x26, 0x43, 0x50, 0x70, 0xe8, 0xe9, 0xda, 0x9b, 0x47, 0x69, 0xc3, 0xe3, 0xa4, 0xee, 0x99, 0x6e, 0x20, 0x6a, 0x9b, 0x4f, 0x0c, 0x35, 0xca, 0x4f, 0xa2, 0xf7, 0x43, 0xed, 0xf2, 0xc7, 0xcb, 0xa3, 0x1e, 0x94, 0xac, 0x6b, 0xca, 0xc4, 0xc0, 0x82, 0xcf, 0x1c, 0xcb, 0x6c, 0x2f, 0xe0, 0x0d, 0x38, 0x4e, 0x3b, 0x18, 0x05, 0x5f, 0xe0, 0xe0 };
46 static const uint16_t hmacTest_KeySize = sizeof(hmacTest_Key);
47 static uint8_t hmacTest_InputData[] = { 0x99, 0xfd, 0x18, 0xa3, 0x5d, 0x50, 0x81, 0x84, 0xa6, 0xf3, 0x61, 0xc6, 0x7c, 0xd9, 0xb1, 0x0b, 0x4c, 0xd1, 0xd8, 0xb2, 0x46, 0x57, 0x2a, 0x4d, 0x03, 0xb0, 0xae, 0x55, 0x6b, 0x36, 0x24, 0x1d, 0xd6, 0xf0, 0x46, 0x05, 0x71, 0x65, 0x4f, 0xf0, 0xe4, 0xb2, 0xba, 0xf8, 0x31, 0xdb, 0x4c, 0x60, 0xdf, 0x5f, 0x54, 0xc9, 0x59, 0x0f, 0x32, 0xa9, 0x91, 0x1f, 0x16, 0xfa, 0xe8, 0x7e, 0x0a, 0x2f, 0x52 };
48 static const uint32_t hmacTest_InputDataSize = sizeof(hmacTest_InputData);
49 static CCHashResultBuf_t hmacTest_ExpOutData = { 0xE0903CC8, 0x24C89469, 0x71B12528, 0x6DEFD88C, 0xF662C7FC, 0x971C4DD1, 0x5755CB85, 0x8E72FD6F };
50 static const uint32_t hmacTest_ExpOutDataSize = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES * sizeof(uint8_t);
51
52 uint8_t *pDataInBuff = NULL;
53 uint8_t *pKey = NULL;
54
55 RunItPtr dataInBuffPtr;
56 RunItPtr keyPtr;
57
58 const mbedtls_md_info_t *md_info = NULL;
59 mbedtls_md_context_t ctx;
60 unsigned char hmacOutBuff[64] = { 0 };
61
62 const char* TEST_NAME = "HMAC";
63 RUNIT_SUB_TEST_START(TEST_NAME);
64
65 ALLOC_AND_COPY(dataInBuffPtr, pDataInBuff, hmacTest_InputData, hmacTest_InputDataSize);
66 ALLOC_AND_COPY(keyPtr, pKey, hmacTest_Key, hmacTest_KeySize);
67
68 /***************************************************************************************
69 *
70 * Integrated operation
71 *
72 ***************************************************************************************/
73 RUNIT_API_ASSIGNMENT(md_info, mbedtls_md_info_from_string(HashAlgMode2mbedtlsString[CC_HASH_SHA256_mode]));
74 RUNIT_ASSERT(md_info != NULL);
75
76 RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac( md_info,
77 pKey,
78 hmacTest_KeySize,
79 pDataInBuff,
80 hmacTest_InputDataSize,
81 hmacOutBuff ), CC_OK);
82
83 RUNIT_ASSERT(memcmp(hmacOutBuff, hmacTest_ExpOutData, hmacTest_ExpOutDataSize) == 0);
84
85
86 /***************************************************************************************
87 *
88 * Non integrated operation
89 *
90 ***************************************************************************************/
91 memset(hmacOutBuff, 0, 64);
92
93 RUNIT_API(mbedtls_md_init(&ctx));
94
95 RUNIT_ASSERT_WITH_RESULT(mbedtls_md_setup(&ctx, md_info, 1), CC_OK); // 1 = HMAC
96
97 RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac_starts(&ctx, pKey, hmacTest_KeySize), CC_OK);
98
99 RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac_update(&ctx, pDataInBuff, hmacTest_InputDataSize), CC_OK);
100
101 RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac_finish(&ctx, hmacOutBuff), CC_OK);
102
103 RUNIT_ASSERT(memcmp(hmacOutBuff, hmacTest_ExpOutData, hmacTest_ExpOutDataSize) == 0);
104 /***************************************************************************************/
105
106 bail:
107
108 FREE_IF_NOT_NULL(dataInBuffPtr);
109 FREE_IF_NOT_NULL(keyPtr);
110
111 mbedtls_md_free(&ctx);
112
113 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA256] KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] ",
114 (uint32_t)hmacTest_KeySize * 8, (uint32_t)hmacTest_InputDataSize);
115 return rc;
116 }
117
118 /**
119 * This test is meant to measure the execution times of the API.
120 * This test doesn't compare the results with expected result.
121 * I uses the return value to verify everything went well.
122 *
123 * @param block1_len
124 * @return
125 */
runIt_cmacProfiling(size_t data_len)126 static RunItError_t runIt_cmacProfiling(size_t data_len)
127 {
128 RunItError_t rc = RUNIT_ERROR__OK;
129
130 mbedtls_cipher_type_t cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
131 const char *key_string = "2b7e151628aed2a6abf7158809cf4f3c";
132 int keybits = 128;
133
134 unsigned char *key = NULL;
135 unsigned char *data = NULL;
136 const mbedtls_cipher_info_t *cipher_info = NULL;
137 mbedtls_cipher_context_t *ctx = NULL;
138 unsigned char *output = NULL;
139 char testParam[PARAM_LEN] = { 0 };
140
141 RunItPtr ketPtr;
142 RunItPtr dataPtr;
143 RunItPtr ctxPtr;
144 RunItPtr outputPtr;
145
146 const char* TEST_NAME = "CMAC-Profile";
147 RUNIT_SUB_TEST_START(TEST_NAME);
148
149 ALLOC(ketPtr, key, keybits / 8);
150 ALLOC(dataPtr, data, data_len);
151 ALLOC_STRUCT(mbedtls_cipher_context_t, ctxPtr, ctx);
152 ALLOC(outputPtr, output, MBEDTLS_CIPHER_BLKSIZE_MAX);
153
154 snprintf(testParam, PARAM_LEN - 1, "%"PRIu32"B", (uint32_t)data_len);
155
156 /* Convert the test parameters to binary data */
157 runIt_unhexify( key, key_string );
158
159 /* this is temporary patch */
160 RUNIT_API(mbedtls_cipher_init( ctx ));
161
162 /* Set up */
163 RUNIT_API_ASSIGNMENT(cipher_info, mbedtls_cipher_info_from_type(cipher_type));
164 RUNIT_ASSERT(cipher_info != NULL);
165
166 RUNIT_ASSERT_API(mbedtls_cipher_setup(ctx, cipher_info) == 0);
167
168 RUNIT_ASSERT_API(mbedtls_cipher_cmac_starts(ctx, (const unsigned char* )key, keybits) == 0);
169
170 RUNIT_ASSERT_API(mbedtls_cipher_cmac_reset(ctx) == 0);
171
172 /* Multiple partial and complete blocks. A negative length means skip the
173 * update operation */
174 RUNIT_ASSERT_W_PARAM(testParam, mbedtls_cipher_cmac_update(ctx, (unsigned char* )data, data_len) == 0);
175
176 RUNIT_ASSERT_API(mbedtls_cipher_cmac_finish(ctx, output) == 0);
177
178 bail:
179
180 RUNIT_API(mbedtls_cipher_free( ctx ));
181
182 FREE_IF_NOT_NULL(ketPtr);
183 FREE_IF_NOT_NULL(dataPtr);
184 FREE_IF_NOT_NULL(ctxPtr);
185 FREE_IF_NOT_NULL(outputPtr);
186
187 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "TYPE[AES_128_ECB] KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] ",
188 (uint32_t)keybits, (uint32_t)data_len);
189 return rc;
190 }
191
runIt_cmac(void)192 static RunItError_t runIt_cmac(void)
193 {
194 RunItError_t rc = RUNIT_ERROR__OK;
195
196 mbedtls_cipher_type_t cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
197 const char *key_string = "2b7e151628aed2a6abf7158809cf4f3c";
198 int keybits = 128;
199 int block_size = 16;
200 const char *block1_string = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710";
201 int block1_len = 64;
202 const char *expected_result_string = "51f0bebf7e3b9d92fc49741779363cfe";
203
204 unsigned char *key = NULL;
205 unsigned char *block1 = NULL;
206 unsigned char *expected_result = NULL;
207 const mbedtls_cipher_info_t *cipher_info = NULL;
208 mbedtls_cipher_context_t *ctx = NULL;
209 unsigned char *output = NULL;
210
211 RunItPtr ketPtr;
212 RunItPtr block1Ptr;
213 RunItPtr expectedResultPtr;
214 RunItPtr ctxPtr;
215 RunItPtr outputPtr;
216
217 const char* TEST_NAME = "CMAC";
218 RUNIT_SUB_TEST_START(TEST_NAME);
219
220 ALLOC(ketPtr, key, keybits / 8);
221 ALLOC(block1Ptr, block1, block1_len);
222 ALLOC(expectedResultPtr, expected_result, block_size);
223 ALLOC_STRUCT(mbedtls_cipher_context_t, ctxPtr, ctx);
224 ALLOC(outputPtr, output, MBEDTLS_CIPHER_BLKSIZE_MAX);
225
226 /* Convert the test parameters to binary data */
227 runIt_unhexify( key, key_string );
228 runIt_unhexify( block1, block1_string );
229 runIt_unhexify( expected_result, expected_result_string );
230
231 RUNIT_API(mbedtls_cipher_init( ctx ));
232
233 /* Set up */
234 RUNIT_API_ASSIGNMENT(cipher_info, mbedtls_cipher_info_from_type(cipher_type));
235 RUNIT_ASSERT(cipher_info != NULL);
236
237 /*
238 * Non Integrated
239 */
240 RUNIT_ASSERT_API(mbedtls_cipher_setup(ctx, cipher_info) == 0);
241
242 RUNIT_ASSERT_API(mbedtls_cipher_cmac_starts(ctx, (const unsigned char* )key, keybits) == 0);
243
244 /* this is temporary patch */
245 RUNIT_ASSERT_API(mbedtls_cipher_cmac_reset(ctx) == 0);
246
247 /* Multiple partial and complete blocks. A negative length means skip the
248 * update operation */
249 RUNIT_ASSERT_API(mbedtls_cipher_cmac_update(ctx, (unsigned char* )block1, block1_len) == 0);
250
251 RUNIT_ASSERT_API(mbedtls_cipher_cmac_finish(ctx, output) == 0);
252
253 RUNIT_PRINT_BUF(output, MBEDTLS_CIPHER_BLKSIZE_MAX, "output");
254 RUNIT_PRINT_BUF(expected_result, MBEDTLS_CIPHER_BLKSIZE_MAX, "expected_result");
255
256 RUNIT_ASSERT(memcmp(output, expected_result, block_size) == 0);
257
258 /*
259 * Integrated
260 */
261 memset(output, 0, MBEDTLS_CIPHER_BLKSIZE_MAX);
262
263 RUNIT_ASSERT_API(mbedtls_cipher_cmac(cipher_info,
264 key, keybits,
265 block1, block1_len,
266 output) == 0);
267
268 RUNIT_ASSERT(memcmp(output, expected_result, block_size) == 0);
269
270 bail:
271
272 RUNIT_API(mbedtls_cipher_free( ctx ));
273
274 FREE_IF_NOT_NULL(ketPtr);
275 FREE_IF_NOT_NULL(block1Ptr);
276 FREE_IF_NOT_NULL(expectedResultPtr);
277 FREE_IF_NOT_NULL(ctxPtr);
278 FREE_IF_NOT_NULL(outputPtr);
279
280 RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "TYPE[AES_128_ECB] KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] ",
281 (uint32_t)keybits, (uint32_t)block1_len);
282 return rc;
283 }
284
285 /************************************************************
286 *
287 * public functions
288 *
289 ************************************************************/
runIt_macTest(void)290 RunItError_t runIt_macTest(void)
291 {
292 RunItError_t rc = RUNIT_ERROR__OK;
293
294 const char* TEST_NAME = "HMAC";
295 RUNIT_TEST_START(TEST_NAME);
296
297 RUNIT_ASSERT(runIt_hmac() == RUNIT_ERROR__OK);
298 RUNIT_ASSERT(runIt_cmac() == RUNIT_ERROR__OK);
299 RUNIT_ASSERT(runIt_cmacProfiling(16) == RUNIT_ERROR__OK);
300 RUNIT_ASSERT(runIt_cmacProfiling(128) == RUNIT_ERROR__OK);
301 RUNIT_ASSERT(runIt_cmacProfiling(1024) == RUNIT_ERROR__OK);
302 RUNIT_ASSERT(runIt_cmacProfiling(8192) == RUNIT_ERROR__OK);
303 RUNIT_ASSERT(runIt_cmacProfiling(65535) == RUNIT_ERROR__OK);
304
305 bail:
306
307 RUNIT_TEST_RESULT(TEST_NAME);
308 return rc;
309 }
310