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 #include <limits.h>
13 
14 /* mbedtls lib */
15 #include "mbedtls/hkdf.h"
16 #include "mbedtls/md.h"
17 #include "mbedtls/timing.h"
18 
19 /* CC */
20 #include "cc_aes_defs.h"
21 #include "cc_pal_types.h"
22 #include "mbedtls_cc_util_defs.h"
23 #include "cc_util_error.h"
24 #include "mbedtls_cc_util_key_derivation.h"
25 #include "cc_hash_defs.h"
26 
27 /* pal */
28 #include "test_pal_mem.h"
29 
30 /* local */
31 #include "run_integration_pal_log.h"
32 #include "run_integration_test.h"
33 #include "run_integration_helper.h"
34 #include "run_integration_otp.h"
35 
36 #ifdef RUNIT_PIE_ENABLED
37 /* include sbrom data file to determine whether we are running system flows */
38 #include "bsv_integration_data_def.h"
39 #endif /* RUNIT_PIE_ENABLED */
40 
41 #ifndef RUNIT_KDF_SKIP_COMPARE
42 #define RUNIT_KDF_SKIP_COMPARE 1
43 #endif
44 
45 #ifndef RUNIT_KDF_ROOT_KEY_SKIP_TEST
46 #define RUNIT_KDF_ROOT_KEY_SKIP_TEST 1
47 #endif
48 
49 /************************************************************
50  *
51  * static functions prototypes
52  *
53  ************************************************************/
54 static RunItError_t runIt_hmacKeyDerivTest(void);
55 static RunItError_t runIt_cmacKeyDerivTest(void);
56 static RunItError_t runIt_cmacRootKeyDerivTest(void);
57 static RunItError_t runIt_hkdfKeyDerivTest(void);
58 
59 /************************************************************
60  *
61  * static functions
62  *
63  ************************************************************/
runIt_hmacKeyDerivTest(void)64 static RunItError_t runIt_hmacKeyDerivTest(void)
65 {
66     RunItError_t rc = RUNIT_ERROR__OK;
67 
68     static const uint8_t userKeyDataOut[] = { 0xba, 0x58, 0xa5, 0xc5, 0x88, 0x59, 0x88, 0x37, 0x72, 0xb6, 0x93, 0x68, 0xee, 0x53, 0xf4, 0x7c  };
69     static const uint8_t label[] = { 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xEF, 0x3E, 0x3E, 0xE8, 0xEF };
70     static const uint8_t context[] = { 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D, 0xFB, 0xAF, 0x7F };
71     static const uint8_t userKey[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
72 
73     uint8_t* pLabel = NULL;
74     uint8_t* pContext = NULL;
75     uint8_t* pUserKey = NULL;
76     uint8_t* pDataOut = NULL;
77 
78     RunItPtr labelPtr;
79     RunItPtr contextPtr;
80     RunItPtr userKeyPtr;
81     RunItPtr dataOutPtr;
82 
83     mbedtls_util_keydata keyData = {0};
84     uint32_t dataOutLength = sizeof(userKeyDataOut);
85 
86     const char* TEST_NAME = "HMAC Key Derivation";
87     RUNIT_SUB_TEST_START(TEST_NAME);
88 
89     ALLOC_AND_COPY(labelPtr, pLabel, label, sizeof(label));
90     ALLOC_AND_COPY(contextPtr, pContext, context, sizeof(context));
91     ALLOC_AND_COPY(userKeyPtr, pUserKey, userKey, sizeof(userKey));
92     ALLOC(dataOutPtr, pDataOut, dataOutLength);
93 
94     keyData.pKey = pUserKey;
95     keyData.keySize = sizeof(userKey);
96 
97     RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_hmac(CC_UTIL_USER_KEY,
98                                                               (void*)&keyData,
99                                                               CC_HASH_SHA256_mode,
100                                                               (uint8_t *)pLabel,
101                                                               sizeof(label),
102                                                               (uint8_t *)pContext,
103                                                               sizeof(context),
104                                                               (uint8_t *)pDataOut,
105                                                               dataOutLength),
106                              CC_UTIL_OK);
107 
108     RUNIT_PRINT_BUF(keyData.pKey, keyData.keySize, "keyData.pKey");
109     RUNIT_PRINT_BUF(label, sizeof(label), "label");
110     RUNIT_PRINT_BUF(context, sizeof(context), "context");
111     RUNIT_PRINT_BUF(pDataOut, dataOutLength, "dataOutBuff");
112 
113     RUNIT_ASSERT(memcmp(pDataOut, userKeyDataOut, dataOutLength) == 0);
114 
115 bail:
116 
117     FREE_IF_NOT_NULL(labelPtr);
118     FREE_IF_NOT_NULL(contextPtr);
119     FREE_IF_NOT_NULL(userKeyPtr);
120     FREE_IF_NOT_NULL(dataOutPtr);
121 
122     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA256] KEY[%ub] CONTEXT[%uB] LABEL[%uB]", keyData.keySize * 8, sizeof(context), sizeof(label));
123     return rc;
124 }
125 
runIt_cmacKeyDerivTest(void)126 static RunItError_t runIt_cmacKeyDerivTest(void)
127 {
128     RunItError_t rc = RUNIT_ERROR__OK;
129 
130     static uint8_t context[] = { 0x54,0x45,0x53,0x54 };
131     static uint8_t label[] = { 0x55,0x53,0x45,0x52,0xF2,0x4B,0x45,0x59 };
132     static const uint8_t userKey[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
133     static const uint8_t userKeyDataOut[] = { 0x2B, 0x05, 0xE1, 0xF8, 0xF0, 0x58, 0x78, 0xAC, 0x41, 0xB0, 0xB5, 0x5D, 0xB0, 0x42, 0x9E, 0x5C };
134 
135     uint8_t* pLabel = NULL;
136     uint8_t* pContext = NULL;
137     uint8_t* pUserKey = NULL;
138     uint8_t* pDataOut = NULL;
139 
140     RunItPtr labelPtr;
141     RunItPtr contextPtr;
142     RunItPtr userKeyPtr;
143     RunItPtr dataOutPtr;
144 
145     mbedtls_util_keydata keyData={0};
146     uint32_t dataOutLength = sizeof(userKeyDataOut);
147 
148     const char* TEST_NAME = "CMAC Key Derivation";
149     RUNIT_SUB_TEST_START(TEST_NAME);
150 
151     ALLOC_AND_COPY(labelPtr, pLabel, label, sizeof(label));
152     ALLOC_AND_COPY(contextPtr, pContext, context, sizeof(context));
153     ALLOC_AND_COPY(userKeyPtr, pUserKey, userKey, sizeof(userKey));
154     ALLOC(dataOutPtr, pDataOut, dataOutLength);
155 
156     keyData.pKey = (uint8_t*)pUserKey;
157     keyData.keySize = sizeof(userKey);
158 
159     RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_cmac(CC_UTIL_USER_KEY,
160                                                               (void*)&keyData,
161                                                               (uint8_t *)pLabel,
162                                                               sizeof(label),
163                                                               (uint8_t *)pContext,
164                                                               sizeof(context),
165                                                               (uint8_t *)pDataOut,
166                                                               dataOutLength),
167                              CC_UTIL_OK);
168 
169     RUNIT_PRINT_BUF(pDataOut, dataOutLength, "pDataOut");
170 
171     RUNIT_ASSERT(memcmp(pDataOut, userKeyDataOut, dataOutLength) == 0);
172 
173 bail:
174 
175     FREE_IF_NOT_NULL(labelPtr);
176     FREE_IF_NOT_NULL(contextPtr);
177     FREE_IF_NOT_NULL(userKeyPtr);
178     FREE_IF_NOT_NULL(dataOutPtr);
179 
180     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] CONTEXT[%"PRIu32"B] LABEL[%"PRIu32"B]",
181                                    (uint32_t)keyData.keySize * 8, (uint32_t)sizeof(context), (uint32_t)sizeof(label));
182     return rc;
183 }
184 
runIt_cmacRootKeyDerivTest(void)185 static RunItError_t runIt_cmacRootKeyDerivTest(void)
186 {
187     RunItError_t rc = RUNIT_ERROR__OK;
188 
189 #if !RUNIT_KDF_ROOT_KEY_SKIP_TEST
190     static uint8_t context[] = { 0x54,0x45,0x53,0x54 };
191     static uint8_t label[] = { 0x55,0x53,0x45,0x52,0xF2,0x4B,0x45,0x59 };
192     static const uint8_t userKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
193 
194     static const uint8_t userKeyDataOut[] = { RUNIT_KDF_RESULT };
195 
196     uint8_t* pLabel = NULL;
197     uint8_t* pContext = NULL;
198     uint8_t* pUserKey = NULL;
199     uint8_t* pDataOut = NULL;
200     uint8_t* pDataOutRef = NULL;
201 
202     RunItPtr labelPtr;
203     RunItPtr contextPtr;
204     RunItPtr userKeyPtr;
205     RunItPtr dataOutPtr;
206     RunItPtr dataOutRefPtr;
207 
208     mbedtls_util_keydata keyData;
209     uint32_t dataOutLength = sizeof(userKeyDataOut);
210 
211     const char* TEST_NAME = "CMAC Root Key Derivation";
212     RUNIT_SUB_TEST_START(TEST_NAME);
213 
214     (void)userKeyDataOut;
215 
216     ALLOC_AND_COPY(labelPtr, pLabel, label, sizeof(label));
217     ALLOC_AND_COPY(contextPtr, pContext, context, sizeof(context));
218     ALLOC_AND_COPY(userKeyPtr, pUserKey, userKey, sizeof(userKey));
219     ALLOC(dataOutPtr, pDataOut, dataOutLength);
220     ALLOC(dataOutRefPtr, pDataOutRef, dataOutLength);
221 
222     keyData.pKey = (uint8_t*)pUserKey;
223     keyData.keySize = sizeof(userKey);
224 
225     RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_cmac(CC_UTIL_USER_KEY,
226                                                               (void*)&keyData,
227                                                               (uint8_t *)pLabel,
228                                                               sizeof(label),
229                                                               (uint8_t *)pContext,
230                                                               sizeof(context),
231                                                               (uint8_t *)pDataOutRef,
232                                                               dataOutLength),
233                              CC_UTIL_OK);
234 
235     RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_cmac(CC_UTIL_ROOT_KEY,
236                                                               (void*)&keyData,
237                                                               (uint8_t *)pLabel,
238                                                               sizeof(label),
239                                                               (uint8_t *)pContext,
240                                                               sizeof(context),
241                                                               (uint8_t *)pDataOut,
242                                                               dataOutLength),
243                              CC_UTIL_OK);
244 
245     RUNIT_PRINT_BUF(pDataOutRef, dataOutLength, "pDataOutRef");
246     RUNIT_PRINT_BUF(pDataOut, dataOutLength, "pDataOut");
247 
248 
249 #if RUNIT_KDF_COMPARE_EXPECTED_RESULT
250     RUNIT_ASSERT(memcmp(pDataOut, pDataOutRef, dataOutLength) != 0);
251 #else
252     RUNIT_ASSERT(memcmp(pDataOut, pDataOutRef, dataOutLength) == 0);
253 #endif
254 
255     if (sizeof(userKeyDataOut) != 1)
256         RUNIT_ASSERT(memcmp(pDataOut, userKeyDataOut, dataOutLength) == 0);
257 
258 bail:
259 
260     FREE_IF_NOT_NULL(labelPtr);
261     FREE_IF_NOT_NULL(contextPtr);
262     FREE_IF_NOT_NULL(userKeyPtr);
263     FREE_IF_NOT_NULL(dataOutPtr);
264     FREE_IF_NOT_NULL(dataOutRefPtr);
265 
266     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] CONTEXT[%"PRIu32"B] LABEL[%"PRIu32"B]",
267                                    (uint32_t)keyData.keySize * 8, (uint32_t)sizeof(context), (uint32_t)sizeof(label));
268 
269 #endif /* !RUNIT_KDF_ROOT_KEY_SKIP_TEST */
270     return rc;
271 }
272 
runIt_hkdfKeyDerivTest(void)273 static RunItError_t runIt_hkdfKeyDerivTest(void)
274 {
275     RunItError_t rc = RUNIT_ERROR__OK;
276 
277     static uint8_t hkdf_IKM[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
278     static const uint32_t hkdf_IKMSize = 22;
279     static uint8_t hkdf_Salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
280     static const uint32_t hkdf_SaltSize = 13;
281     static uint8_t hkdf_Info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 };
282     static const uint32_t hkdf_InfoSize = 10;
283     static const uint8_t hkdf_ExpectOKM[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 };
284     static const uint32_t hkdf_LSize = 42;
285     const mbedtls_md_info_t *md = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
286     uint8_t* pOKMDataBuff = NULL;
287 
288     RunItPtr okmDataBuff;
289 
290     const char* TEST_NAME = "HKDF Key Derivation";
291     RUNIT_SUB_TEST_START(TEST_NAME);
292 
293     ALLOC(okmDataBuff, pOKMDataBuff, 4096);
294 
295     RUNIT_ASSERT_WITH_RESULT(mbedtls_hkdf(md,
296                                          hkdf_Salt,
297                                          (size_t)hkdf_SaltSize,
298                                          hkdf_IKM,
299                                          hkdf_IKMSize,
300                                          hkdf_Info,
301                                          hkdf_InfoSize,
302                                          pOKMDataBuff,
303                                          hkdf_LSize),
304                              CC_OK);
305 
306     /* compare the result and print result*/
307     RUNIT_ASSERT(memcmp(pOKMDataBuff, hkdf_ExpectOKM, hkdf_LSize) == 0);
308 
309 bail:
310     FREE_IF_NOT_NULL(okmDataBuff);
311 
312     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA256] IKM[%uB] SALT[%uB] INFO[%uB] OKM[%uB]",
313                                    (unsigned int)hkdf_IKMSize, (unsigned int)hkdf_SaltSize,
314                                    (unsigned int)hkdf_InfoSize, (unsigned int)hkdf_LSize);
315     return rc;
316 }
317 
318 /************************************************************
319  *
320  * public functions
321  *
322  ************************************************************/
runIt_keyDerivationTest(void)323 RunItError_t runIt_keyDerivationTest(void)
324 {
325     RunItError_t rc = RUNIT_ERROR__OK;
326 
327     const char* TEST_NAME = "Key Derivation";
328     RUNIT_TEST_START(TEST_NAME);
329 
330     RUNIT_ASSERT(runIt_hmacKeyDerivTest() == RUNIT_ERROR__OK);
331     RUNIT_ASSERT(runIt_cmacKeyDerivTest() == RUNIT_ERROR__OK);
332     RUNIT_ASSERT(runIt_cmacRootKeyDerivTest() == RUNIT_ERROR__OK);
333     RUNIT_ASSERT(runIt_hkdfKeyDerivTest() == RUNIT_ERROR__OK);
334 
335 bail:
336 
337     RUNIT_TEST_RESULT(TEST_NAME);
338     return rc;
339 }
340 
341 
342