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 /* cc lib */
16 #include "mbedtls_cc_ecies.h"
17 
18 /* mbedtls lib */
19 #include "mbedtls/timing.h"
20 #include "mbedtls/bignum.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 /************************************************************
29  *
30  * defines
31  *
32  ************************************************************/
33 #define RUNIT_PRINT_RANDOM_KEYS 0
34 
35 #define DIGEST_SIZE         64
36 #define ECP_GROUP_ID        MBEDTLS_ECP_DP_SECP256R1
37 /************************************************************
38  *
39  * static function prototypes
40  *
41  ************************************************************/
42 static int runIt_isEciesGrpSupported(mbedtls_ecp_group_id grpId);
43 static RunItError_t runIt_eciesRandom(void);
44 static RunItError_t runIt_eciesVector(void);
45 
46 /************************************************************
47  *
48  * variables
49  *
50  ************************************************************/
51 
52 /************************************************************
53  *
54  * static functions
55  *
56  ************************************************************/
runIt_eciesRandom(void)57 static RunItError_t runIt_eciesRandom(void)
58 {
59     RunItError_t rc = RUNIT_ERROR__OK;
60 
61     mbedtls_ecp_group *pGrp = NULL;
62     mbedtls_ecp_point *pQ = NULL;
63     mbedtls_mpi d;
64 
65     const char * testName = NULL;
66     uint8_t* pSenderSecret = NULL;
67     uint8_t* pRecieverSecret = NULL;
68     static const size_t SECRET_KEY_LEN_BYTES = 200;
69     uint8_t* pCipher = NULL;
70     size_t cipherDataSize = MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES;
71     uint32_t *pBuf = NULL;
72 
73     RunItPtr grpPtr;
74     RunItPtr senderSecretPtr;
75     RunItPtr recieverSecretPtr;
76     RunItPtr ciphertPtr;
77     RunItPtr qPtr;
78     RunItPtr bufPtr;
79 
80     const char* TEST_NAME = "ECIES Random";
81     RUNIT_SUB_TEST_START(TEST_NAME);
82 
83     if (runIt_isEciesGrpSupported(ECP_GROUP_ID) == 0)
84     {
85         testName = "UNKNOWN";
86         goto skip;
87     }
88 
89     ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
90     ALLOC(senderSecretPtr, pSenderSecret, SECRET_KEY_LEN_BYTES);
91     ALLOC(recieverSecretPtr, pRecieverSecret, SECRET_KEY_LEN_BYTES);
92     ALLOC(ciphertPtr, pCipher, MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES);
93     ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
94     ALLOC32(bufPtr, pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
95 
96     mbedtls_ecp_group_init(pGrp);
97     mbedtls_ecp_point_init(pQ);
98     mbedtls_mpi_init(&d);
99     memset(pBuf, 0, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
100     memset((uint8_t*)pSenderSecret, 0, SECRET_KEY_LEN_BYTES);
101     memset((uint8_t*)pRecieverSecret, 0, SECRET_KEY_LEN_BYTES);
102 
103     RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, ECP_GROUP_ID) == 0);
104     RUNIT_ASSERT(mbedtls_ecp_gen_keypair(pGrp, &d, pQ, gpRndContext->rndGenerateVectFunc, gpRndState) == 0);
105 
106     testName = mbedtls_ecp_curve_info_from_grp_id(ECP_GROUP_ID)->name;
107 
108 #if RUNIT_PRINT_RANDOM_KEYS
109     {
110         size_t olen = 0;
111         RUNIT_ASSERT_API(mbedtls_ecp_point_write_binary(pGrp, pQ, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES) == 0);
112         RUNIT_PRINT_BUF(pBuf, olen, "public binary");
113 
114         RUNIT_ASSERT_API(mbedtls_mpi_write_binary(&d, pBuf, mbedtls_mpi_size(&d)) == 0);
115         RUNIT_PRINT_BUF(pBuf, mbedtls_mpi_size(&d), "private binary");
116     }
117 #endif
118 
119     RUNIT_ASSERT_API(mbedtls_ecies_kem_encrypt(pGrp,
120                                                pQ,
121                                                CC_KDF_ISO18033_KDF1_DerivMode,
122                                                CC_HKDF_HASH_SHA256_mode,
123                                                1,
124                                                pSenderSecret,
125                                                SECRET_KEY_LEN_BYTES,
126                                                pCipher,
127                                                &cipherDataSize,
128                                                pBuf,
129                                                MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES,
130                                                gpRndContext->rndGenerateVectFunc,
131                                                gpRndContext->rndState) == 0);
132 
133     RUNIT_PRINT_BUF(pCipher, cipherDataSize, "pCipher");
134 
135     RUNIT_ASSERT_API(mbedtls_ecies_kem_decrypt(pGrp,
136                                                &d,
137                                                CC_KDF_ISO18033_KDF1_DerivMode,
138                                                CC_HKDF_HASH_SHA256_mode,
139                                                1,
140                                                pCipher,
141                                                cipherDataSize,
142                                                pRecieverSecret,
143                                                SECRET_KEY_LEN_BYTES,
144                                                pBuf,
145                                                MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES) == 0);
146 
147     RUNIT_PRINT_BUF(pSenderSecret, SECRET_KEY_LEN_BYTES, "pSenderSecret");
148     RUNIT_PRINT_BUF(pRecieverSecret, SECRET_KEY_LEN_BYTES, "pRecieverSecret");
149 
150     RUNIT_ASSERT(memcmp(pSenderSecret, pRecieverSecret, SECRET_KEY_LEN_BYTES) == 0);
151 
152 bail:
153     mbedtls_ecp_group_free(pGrp);
154     mbedtls_ecp_point_free(pQ);
155     mbedtls_mpi_free(&d);
156 
157     FREE_IF_NOT_NULL(grpPtr);
158     FREE_IF_NOT_NULL(senderSecretPtr);
159     FREE_IF_NOT_NULL(recieverSecretPtr);
160     FREE_IF_NOT_NULL(ciphertPtr);
161     FREE_IF_NOT_NULL(qPtr);
162     FREE_IF_NOT_NULL(bufPtr);
163 
164 skip:
165     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] DERIVE[ISO18033_KDF1] MD[SHA256]", testName);
166     return rc;
167 }
168 
runIt_isEciesGrpSupported(mbedtls_ecp_group_id grpId)169 static int runIt_isEciesGrpSupported(mbedtls_ecp_group_id grpId)
170 {
171     const mbedtls_ecp_group_id * pGrpIdList = mbedtls_ecp_grp_id_list();
172 
173     while (*pGrpIdList != MBEDTLS_ECP_DP_NONE)
174     {
175         RUNIT_PRINT_DBG("test %"PRIu32" pGrpIdList %"PRIu32"\n", (uint32_t)grpId, (uint32_t)*pGrpIdList);
176         if (grpId == *pGrpIdList)
177             return 1;
178 
179         pGrpIdList++;
180     }
181 
182     return 0;
183 }
184 
runIt_eciesVector(void)185 static RunItError_t runIt_eciesVector(void)
186 {
187     RunItError_t rc = RUNIT_ERROR__OK;
188 
189     static const char* INPUT_D = "895a6ff53cd45011b125cd22c3f578bd77f916402f01d96488e12ddfa7fc61ec";
190     static const char* INPUT_X = "efbbaee7568701f463187d7bf88d1dbf26dd597602f860512a0dea5842fd6cfa";
191     static const char* INPUT_Y = "c1276720f57d2cc777b51dea53c086fe1cf315dc899c948f169f2206da4f6b3b";
192 
193     static const char* INPUT_EPH_D = "2b74dd5215d265d8b2df0488d2a01586830a832f731ce5e1a3db9aa8f99f8cd5";
194     static const char* INPUT_EPH_X = "4b27901968c47b81f88116723ddd6a02be1d3bb6a820b69ee0198bc35606cabc";
195     static const char* INPUT_EPH_Y = "99e388fc709819ac66c5aafab3d250e1fbb247594ddb4b5b33bce91b91fa14f9";
196 
197     mbedtls_ecp_group *pGrp = NULL;
198     mbedtls_ecp_point *pQ = NULL;
199     mbedtls_mpi d;
200     mbedtls_ecp_point *pQEph = NULL;
201     mbedtls_mpi dEph;
202     uint32_t *pBuf = NULL;
203 
204     uint8_t* pSenderSecret = NULL;
205     uint8_t* pRecieverSecret = NULL;
206     static const size_t SECRET_KEY_LEN_BYTES = 128;
207     uint8_t* pCipher = NULL;
208     size_t cipherDataSize = MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES;
209     size_t olen = 0;
210 
211     RunItPtr grpPtr;
212     RunItPtr senderSecretPtr;
213     RunItPtr recieverSecretPtr;
214     RunItPtr ciphertPtr;
215     RunItPtr qPtr;
216     RunItPtr qEphPtr;
217     RunItPtr bufPtr;
218 
219     const char* TEST_NAME = "ECIES Vector";
220     RUNIT_SUB_TEST_START(TEST_NAME);
221 
222     ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
223     ALLOC(senderSecretPtr, pSenderSecret, SECRET_KEY_LEN_BYTES);
224     ALLOC(recieverSecretPtr, pRecieverSecret, SECRET_KEY_LEN_BYTES);
225     ALLOC(ciphertPtr, pCipher, MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES);
226     ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
227     ALLOC_STRUCT(mbedtls_ecp_point, qEphPtr, pQEph);
228     ALLOC32(bufPtr, pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
229 
230     mbedtls_ecp_group_init(pGrp);
231     mbedtls_ecp_point_init(pQ);
232     mbedtls_mpi_init(&d);
233     mbedtls_ecp_point_init(pQEph);
234     mbedtls_mpi_init(&dEph);
235 
236     memset(pBuf, 0, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
237     memset((uint8_t*)pSenderSecret, 0, SECRET_KEY_LEN_BYTES);
238     memset((uint8_t*)pRecieverSecret, 0, SECRET_KEY_LEN_BYTES);
239 
240     RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, ECP_GROUP_ID) == 0);
241     RUNIT_ASSERT(mbedtls_mpi_read_string(&d, 16, INPUT_D) == 0);
242     RUNIT_ASSERT(mbedtls_ecp_point_read_string(pQ, 16, INPUT_X, INPUT_Y) == 0);
243     RUNIT_ASSERT(mbedtls_mpi_read_string(&dEph, 16, INPUT_EPH_D) == 0);
244     RUNIT_ASSERT(mbedtls_ecp_point_read_string(pQEph, 16, INPUT_EPH_X, INPUT_EPH_Y) == 0);
245 
246     RUNIT_ASSERT(mbedtls_ecp_point_write_binary(pGrp, pQ, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, (uint8_t*)pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES) == 0);
247     RUNIT_PRINT_BUF(pBuf, olen, "public binary");
248 
249     RUNIT_ASSERT(mbedtls_mpi_write_binary(&dEph, (uint8_t*)pBuf, mbedtls_mpi_size(&dEph)) == 0);
250     RUNIT_PRINT_BUF(pBuf, mbedtls_mpi_size(&dEph), "private binary");
251 
252     RUNIT_ASSERT_API(mbedtls_ecies_kem_encrypt_full(pGrp,
253                                                     pQ,
254                                                     CC_KDF_ISO18033_KDF1_DerivMode,
255                                                     CC_HKDF_HASH_SHA256_mode,
256                                                     1,
257                                                     pQEph,
258                                                     &dEph,
259                                                     pSenderSecret,
260                                                     SECRET_KEY_LEN_BYTES,
261                                                     pCipher,
262                                                     &cipherDataSize,
263                                                     pBuf,
264                                                     MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES,
265                                                     gpRndContext->rndGenerateVectFunc,
266                                                     gpRndContext->rndState) == 0);
267 
268     RUNIT_PRINT_BUF(pCipher, cipherDataSize, "pCipher");
269 
270     RUNIT_ASSERT_WITH_RESULT(mbedtls_ecies_kem_decrypt(pGrp,
271                                                        &d,
272                                                        CC_KDF_ISO18033_KDF1_DerivMode,
273                                                        CC_HKDF_HASH_SHA256_mode,
274                                                        1,
275                                                        pCipher,
276                                                        cipherDataSize,
277                                                        pRecieverSecret,
278                                                        SECRET_KEY_LEN_BYTES,
279                                                        pBuf,
280                                                        MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES), 0);
281 
282     RUNIT_PRINT_BUF(pSenderSecret, SECRET_KEY_LEN_BYTES, "pSenderSecret");
283     RUNIT_PRINT_BUF(pRecieverSecret, SECRET_KEY_LEN_BYTES, "pRecieverSecret");
284 
285     RUNIT_ASSERT(memcmp(pRecieverSecret, pSenderSecret, SECRET_KEY_LEN_BYTES) == 0);
286 
287 bail:
288     mbedtls_ecp_group_free(pGrp);
289     mbedtls_ecp_point_free(pQ);
290     mbedtls_ecp_point_free(pQEph);
291     mbedtls_mpi_free(&d);
292     mbedtls_mpi_free(&dEph);
293 
294     FREE_IF_NOT_NULL(grpPtr);
295     FREE_IF_NOT_NULL(senderSecretPtr);
296     FREE_IF_NOT_NULL(recieverSecretPtr);
297     FREE_IF_NOT_NULL(ciphertPtr);
298     FREE_IF_NOT_NULL(qPtr);
299     FREE_IF_NOT_NULL(qEphPtr);
300     FREE_IF_NOT_NULL(bufPtr);
301 
302     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] DERIVE[ISO18033_KDF1] MD[SHA256]", mbedtls_ecp_curve_info_from_grp_id(ECP_GROUP_ID)->name);
303     return rc;
304 }
305 
306 /************************************************************
307  *
308  * public functions
309  *
310  ************************************************************/
runIt_eciesTest(void)311 RunItError_t runIt_eciesTest(void)
312 {
313     RunItError_t rc = RUNIT_ERROR__OK;
314 
315     const char* TEST_NAME = "ECIES";
316     RUNIT_TEST_START(TEST_NAME);
317 
318     RUNIT_ASSERT(runIt_eciesRandom() == RUNIT_ERROR__OK);
319     RUNIT_ASSERT(runIt_eciesVector() == RUNIT_ERROR__OK);
320 
321 bail:
322     RUNIT_TEST_RESULT(TEST_NAME);
323     return rc;
324 }
325