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