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/ecdh.h"
17 #include "mbedtls/ctr_drbg.h"
18
19 /* local */
20 #include "run_integration_pal_log.h"
21 #include "run_integration_test.h"
22 #include "run_integration_helper.h"
23 #include "mbedtls_cc_ecdh_edwards.h"
24
25 #if defined MBEDTLS_ECDH_C
26 /************************************************************
27 *
28 * defines
29 *
30 ************************************************************/
31
32 /************************************************************
33 *
34 * static function prototypes
35 *
36 ************************************************************/
37 static RunItError_t runIt_ecdhPrimRandom(void);
38 static RunItError_t runIt_ecdhExchange(void);
39 #if defined (MBEDTLS_ECP_DP_CURVE25519_ENABLED)
40 static RunItError_t runIt_ecdhExange25519(void);
41 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
42 /************************************************************
43 *
44 * static functions
45 *
46 ************************************************************/
runIt_ecdhPrimRandom(void)47 static RunItError_t runIt_ecdhPrimRandom(void)
48 {
49 RunItError_t rc = RUNIT_ERROR__OK;
50
51 static const char *dA_str = "C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433";
52 static const char *xA_str = "DAD0B65394221CF9B051E1FECA5787D098DFE637FC90B9EF945D0C3772581180";
53 static const char *yA_str = "5271A0461CDB8252D61F1C456FA3E59AB1F45B33ACCF5F58389E0577B8990BB3";
54 static const char *dB_str = "C6EF9C5D78AE012A011164ACB397CE2088685D8F06BF9BE0B283AB46476BEE53";
55 static const char *xB_str = "D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63";
56 static const char *yB_str = "56FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB";
57 static const char *z_str = "D6840F6B42F6EDAFD13116E0E12565202FEF8E9ECE7DCE03812464D04B9442DE";
58
59 mbedtls_ecp_group *pGrp = NULL;
60 mbedtls_ecp_point *pQA = NULL;
61 mbedtls_ecp_point *pQB = NULL;
62 unsigned char *pRndBufA = NULL;
63 unsigned char *pRndBufB = NULL;
64 mbedtls_mpi dA;
65 mbedtls_mpi dB;
66 mbedtls_mpi zA;
67 mbedtls_mpi zB;
68 mbedtls_mpi check;
69
70 RunItPtr grpPtr;
71 RunItPtr qAPtr;
72 RunItPtr qBPtr;
73 RunItPtr rndBufAPtr;
74 RunItPtr rndBufBPtr;
75
76 rnd_buf_info rnd_info_A;
77 rnd_buf_info rnd_info_B;
78
79 const char* TEST_NAME = "ECDH Vectors";
80 RUNIT_SUB_TEST_START(TEST_NAME);
81
82 ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
83 ALLOC_STRUCT(mbedtls_ecp_point, qAPtr, pQA);
84 ALLOC_STRUCT(mbedtls_ecp_point, qBPtr, pQB);
85 ALLOC(rndBufAPtr, pRndBufA, MBEDTLS_ECP_MAX_BYTES);
86 ALLOC(rndBufBPtr, pRndBufB, MBEDTLS_ECP_MAX_BYTES);
87
88 mbedtls_ecp_group_init(pGrp);
89 mbedtls_ecp_point_init(pQA);
90 mbedtls_ecp_point_init(pQB);
91 mbedtls_mpi_init(&dA);
92 mbedtls_mpi_init(&dB);
93 mbedtls_mpi_init(&zA);
94 mbedtls_mpi_init(&zB);
95 mbedtls_mpi_init(&check);
96
97 RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, MBEDTLS_ECP_DP_SECP256R1) == 0);
98
99 rnd_info_A.buf = pRndBufA;
100 rnd_info_A.length = runIt_unhexify(pRndBufA, dA_str);
101
102 /* Fix rnd_buf_A by shifting it left if necessary */
103 if (pGrp->nbits % 8 != 0)
104 {
105 unsigned char shift = 8 - (pGrp->nbits % 8);
106 size_t i;
107
108 for (i = 0; i < rnd_info_A.length - 1; i++)
109 pRndBufA[i] = pRndBufA[i] << shift | pRndBufA[i + 1] >> (8 - shift);
110
111 pRndBufA[rnd_info_A.length - 1] <<= shift;
112 }
113
114 rnd_info_B.buf = pRndBufB;
115 rnd_info_B.length = runIt_unhexify(pRndBufB, dB_str);
116
117 /* Fix rnd_buf_B by shifting it left if necessary */
118 if (pGrp->nbits % 8 != 0)
119 {
120 unsigned char shift = 8 - (pGrp->nbits % 8);
121 size_t i;
122
123 for (i = 0; i < rnd_info_B.length - 1; i++)
124 pRndBufB[i] = pRndBufB[i] << shift | pRndBufB[i + 1] >> (8 - shift);
125
126 pRndBufB[rnd_info_B.length - 1] <<= shift;
127 }
128
129 RUNIT_ASSERT_API(mbedtls_ecdh_gen_public(pGrp, &dA, pQA, runIt_rndBufferRand, &rnd_info_A) == 0);
130 RUNIT_ASSERT(mbedtls_ecp_is_zero(pQA) == 0);
131 RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, xA_str) == 0);
132 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQA->X, &check) == 0);
133 RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, yA_str) == 0);
134 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQA->Y, &check) == 0);
135
136 RUNIT_ASSERT_API(mbedtls_ecdh_gen_public(pGrp, &dB, pQB, runIt_rndBufferRand, &rnd_info_B) == 0);
137 RUNIT_ASSERT(mbedtls_ecp_is_zero(pQB) == 0);
138 RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, xB_str) == 0);
139 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQB->X, &check) == 0);
140 RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, yB_str) == 0);
141 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQB->Y, &check) == 0);
142
143 RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, z_str) == 0);
144 RUNIT_ASSERT_API(mbedtls_ecdh_compute_shared( pGrp, &zA, pQB, &dA, NULL, NULL ) == 0);
145 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&zA, &check) == 0);
146 RUNIT_ASSERT_API(mbedtls_ecdh_compute_shared( pGrp, &zB, pQA, &dB, NULL, NULL ) == 0);
147 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&zB, &check) == 0);
148
149 bail:
150
151 mbedtls_ecp_group_free(pGrp);
152 mbedtls_ecp_point_free(pQA);
153 mbedtls_ecp_point_free(pQB);
154
155 mbedtls_mpi_free(&dA);
156 mbedtls_mpi_free(&dB);
157 mbedtls_mpi_free(&zA);
158 mbedtls_mpi_free(&zB);
159 mbedtls_mpi_free(&check);
160
161 FREE_IF_NOT_NULL(grpPtr);
162 FREE_IF_NOT_NULL(qAPtr);
163 FREE_IF_NOT_NULL(qBPtr);
164 FREE_IF_NOT_NULL(rndBufAPtr);
165 FREE_IF_NOT_NULL(rndBufBPtr);
166
167 RUNIT_SUB_TEST_RESULT(TEST_NAME);
168
169 return rc;
170 }
171
runIt_ecdhExchange(void)172 static RunItError_t runIt_ecdhExchange(void)
173 {
174 RunItError_t rc = RUNIT_ERROR__OK;
175 static const uint32_t BUF_SIZE = 1000;
176
177 mbedtls_ecdh_context *pSrv = NULL;
178 mbedtls_ecdh_context *pCli = NULL;
179 unsigned char *pBuf = NULL;
180
181 RunItPtr srvPtr = {0};
182 RunItPtr cliPtr = {0};
183 RunItPtr bufPtr = {0};
184
185 const unsigned char *vbuf;
186 size_t len;
187
188 const char* TEST_NAME = "ECDH Exchange";
189 RUNIT_SUB_TEST_START(TEST_NAME);
190
191 ALLOC_STRUCT(mbedtls_ecdh_context, srvPtr, pSrv);
192 ALLOC_STRUCT(mbedtls_ecdh_context, cliPtr, pCli);
193 ALLOC(bufPtr, pBuf, BUF_SIZE);
194
195 RUNIT_API(mbedtls_ecdh_init(pSrv));
196 RUNIT_API(mbedtls_ecdh_init(pCli));
197
198 RUNIT_ASSERT(mbedtls_ecp_group_load(&pSrv->grp, MBEDTLS_ECP_DP_SECP256R1) == 0);
199
200 memset(pBuf, 0x00, BUF_SIZE);
201 vbuf = pBuf;
202 RUNIT_ASSERT_API(mbedtls_ecdh_make_params(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
203 RUNIT_ASSERT_API(mbedtls_ecdh_read_params(pCli, &vbuf, pBuf + len) == 0);
204
205 memset(pBuf, 0x00, BUF_SIZE);
206 RUNIT_ASSERT_API(mbedtls_ecdh_make_public(pCli, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
207 RUNIT_ASSERT_API(mbedtls_ecdh_read_public(pSrv, pBuf, len) == 0);
208 RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
209 RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pCli, &len, pBuf, BUF_SIZE, NULL, NULL) == 0);
210 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pSrv->z, &pCli->z) == 0);
211
212 bail:
213 RUNIT_API(mbedtls_ecdh_free(pSrv));
214 RUNIT_API(mbedtls_ecdh_free(pCli));
215
216 FREE_IF_NOT_NULL(srvPtr);
217 FREE_IF_NOT_NULL(cliPtr);
218 FREE_IF_NOT_NULL(bufPtr);
219
220 RUNIT_SUB_TEST_RESULT(TEST_NAME);
221 return rc;
222 }
223
224 #if defined (MBEDTLS_ECP_DP_CURVE25519_ENABLED)
runIt_ecdhExange25519(void)225 static RunItError_t runIt_ecdhExange25519(void)
226 {
227 RunItError_t rc = RUNIT_ERROR__OK;
228 static const uint32_t BUF_SIZE = 1000;
229
230 mbedtls_ecdh_context *pSrv = NULL;
231 mbedtls_ecdh_context *pCli = NULL;
232 unsigned char *pBuf = NULL;
233
234 RunItPtr srvPtr = {0};
235 RunItPtr cliPtr = {0};
236 RunItPtr bufPtr = {0};
237
238 const unsigned char *vbuf;
239 size_t len;
240
241 const char* TEST_NAME = "ECDH 25519 Exchange";
242 RUNIT_SUB_TEST_START(TEST_NAME);
243
244 ALLOC_STRUCT(mbedtls_ecdh_context, srvPtr, pSrv);
245 ALLOC_STRUCT(mbedtls_ecdh_context, cliPtr, pCli);
246 ALLOC(bufPtr, pBuf, BUF_SIZE);
247
248 RUNIT_API(mbedtls_ecdh_init(pSrv));
249 RUNIT_API(mbedtls_ecdh_init(pCli));
250
251 RUNIT_ASSERT(mbedtls_ecp_group_load(&pSrv->grp, MBEDTLS_ECP_DP_CURVE25519) == 0);
252
253 memset(pBuf, 0x00, BUF_SIZE);
254 vbuf = pBuf;
255
256 RUNIT_ASSERT_API(mbedtls_ecdh_make_params_edwards(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
257 RUNIT_ASSERT_API(mbedtls_ecdh_read_params_edwards(pCli, &vbuf, pBuf + len) == 0);
258
259 memset(pBuf, 0x00, BUF_SIZE);
260 RUNIT_ASSERT_API(mbedtls_ecdh_make_public(pCli, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
261 RUNIT_ASSERT_API(mbedtls_ecdh_read_public(pSrv, pBuf, len) == 0);
262
263 RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
264 RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pCli, &len, pBuf, BUF_SIZE, NULL, NULL) == 0);
265
266 RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pSrv->z, &pCli->z) == 0);
267
268 bail:
269 RUNIT_API(mbedtls_ecdh_free(pSrv));
270 RUNIT_API(mbedtls_ecdh_free(pCli));
271
272 FREE_IF_NOT_NULL(srvPtr);
273 FREE_IF_NOT_NULL(cliPtr);
274 FREE_IF_NOT_NULL(bufPtr);
275
276 RUNIT_SUB_TEST_RESULT(TEST_NAME);
277 return rc;
278
279 }
280 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
281 /************************************************************
282 *
283 * public functions
284 *
285 ************************************************************/
runIt_ecdhTest(void)286 RunItError_t runIt_ecdhTest(void)
287 {
288 RunItError_t rc = RUNIT_ERROR__OK;
289
290 const char* TEST_NAME = "ECDH";
291 RUNIT_TEST_START(TEST_NAME);
292
293 RUNIT_ASSERT(runIt_ecdhPrimRandom() == RUNIT_ERROR__OK);
294 RUNIT_ASSERT(runIt_ecdhExchange() == RUNIT_ERROR__OK);
295 #if defined (MBEDTLS_ECP_DP_CURVE25519_ENABLED)
296 RUNIT_ASSERT(runIt_ecdhExange25519() == RUNIT_ERROR__OK);
297 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
298 bail:
299 RUNIT_TEST_RESULT(TEST_NAME);
300 return rc;
301 }
302 #endif /* MBEDTLS_ECDH_C */
303