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