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/dhm.h"
17 #include "mbedtls/timing.h"
18 #include "mbedtls/ctr_drbg.h"
19 
20 /* CC pal */
21 
22 /* local */
23 #include "run_integration_pal_log.h"
24 #include "run_integration_test.h"
25 #include "run_integration_helper.h"
26 
27 /************************************************************
28  *
29  * static function prototypes
30  *
31  ************************************************************/
32 static RunItError_t runIt_dhm(void);
33 /************************************************************
34  *
35  * static functions
36  *
37  ************************************************************/
runIt_dhm(void)38 static RunItError_t runIt_dhm(void)
39 {
40     RunItError_t rc = RUNIT_ERROR__OK;
41 #if defined(MBEDTLS_DHM_C)
42 
43     static const int radix_P = 10;
44     static const char *input_P = "93450983094850938450983409623982317398171298719873918739182739712938719287391879381271";
45     static const int radix_G = 10;
46     static const char *input_G = "9345098309485093845098340962223981329819812792137312973297123912791271";
47 
48     static const int BUF_SIZE = 1000;
49 
50     mbedtls_dhm_context *pCtxSrv = NULL;
51     mbedtls_dhm_context *pCtxCli = NULL;
52     unsigned char *pSke = NULL;
53     unsigned char *pPubCli = NULL;
54     unsigned char *pSecSrv = NULL;
55     unsigned char *pSecCli = NULL;
56 
57     RunItPtr ctxSrvPtr;
58     RunItPtr ctxCliPtr;
59     RunItPtr skePrt;
60     RunItPtr pubCliPrt;
61     RunItPtr secSrvPrt;
62     RunItPtr secCliPrt;
63 
64     unsigned char *p = NULL;
65     size_t ske_len = 0;
66     size_t pub_cli_len = 0;
67     size_t sec_srv_len;
68     size_t sec_cli_len;
69     int x_size, i;
70 
71     const char* TEST_NAME = "DH";
72     RUNIT_SUB_TEST_START(TEST_NAME);
73 
74     ALLOC_STRUCT(mbedtls_dhm_context, ctxSrvPtr, pCtxSrv);
75     ALLOC_STRUCT(mbedtls_dhm_context, ctxCliPtr, pCtxCli);
76     ALLOC(skePrt, pSke, BUF_SIZE);
77     ALLOC(pubCliPrt, pPubCli, BUF_SIZE);
78     ALLOC(secSrvPrt, pSecSrv, BUF_SIZE);
79     ALLOC(secCliPrt, pSecCli, BUF_SIZE);
80 
81 
82     RUNIT_API(mbedtls_dhm_init(pCtxSrv));
83     RUNIT_API(mbedtls_dhm_init(pCtxCli));
84     memset(pSke, 0x00, BUF_SIZE);
85     memset(pPubCli, 0x00, BUF_SIZE);
86     memset(pSecSrv, 0x00, BUF_SIZE);
87     memset(pSecCli, 0x00, BUF_SIZE);
88 
89     /*
90      * Set params
91      */
92     RUNIT_ASSERT(mbedtls_mpi_read_string(&pCtxSrv->P, radix_P, input_P) == 0);
93     RUNIT_ASSERT(mbedtls_mpi_read_string(&pCtxSrv->G, radix_G, input_G) == 0);
94     x_size = mbedtls_mpi_size(&pCtxSrv->P);
95     pub_cli_len = x_size;
96 
97     /*
98      * First key exchange
99      */
100     p = pSke;
101 
102     RUNIT_ASSERT_API(mbedtls_dhm_make_params(pCtxSrv, x_size, pSke, &ske_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
103     pSke[ske_len++] = 0;
104     pSke[ske_len++] = 0;
105 
106     RUNIT_ASSERT_API(mbedtls_dhm_read_params(pCtxCli, &p, pSke + ske_len) == 0);
107 
108     RUNIT_ASSERT_API(mbedtls_dhm_make_public(pCtxCli, x_size, pPubCli, pub_cli_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
109     RUNIT_ASSERT_API(mbedtls_dhm_read_public(pCtxSrv, pPubCli, pub_cli_len) == 0);
110 
111     RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxSrv, pSecSrv, BUF_SIZE, &sec_srv_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
112     RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxCli, pSecCli, BUF_SIZE, &sec_cli_len, NULL, NULL ) == 0);
113 
114     RUNIT_ASSERT(sec_srv_len == sec_cli_len);
115     RUNIT_ASSERT(sec_srv_len != 0);
116     RUNIT_ASSERT(memcmp(pSecSrv, pSecCli, sec_srv_len) == 0);
117 
118     /* Re-do calc_secret on server a few times to test update of blinding values */
119     for (i = 0; i < 3; i++)
120     {
121         sec_srv_len = 1000;
122         RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxSrv, pSecSrv, BUF_SIZE, &sec_srv_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
123 
124         RUNIT_ASSERT(sec_srv_len == sec_cli_len);
125         RUNIT_ASSERT(sec_srv_len != 0);
126         RUNIT_ASSERT(memcmp(pSecSrv, pSecCli, sec_srv_len) == 0);
127     }
128 
129     /*
130      * Second key exchange to test change of blinding values on server
131      */
132     p = pSke;
133 
134     RUNIT_ASSERT_API(mbedtls_dhm_make_params(pCtxSrv, x_size, pSke, &ske_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
135     pSke[ske_len++] = 0;
136     pSke[ske_len++] = 0;
137     RUNIT_ASSERT_API(mbedtls_dhm_read_params(pCtxCli, &p, pSke + ske_len) == 0);
138 
139     RUNIT_ASSERT_API(mbedtls_dhm_make_public(pCtxCli, x_size, pPubCli, pub_cli_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
140     RUNIT_ASSERT_API(mbedtls_dhm_read_public(pCtxSrv, pPubCli, pub_cli_len) == 0);
141 
142     RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxSrv, pSecSrv, BUF_SIZE, &sec_srv_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
143     RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxCli, pSecCli, BUF_SIZE, &sec_cli_len, NULL, NULL ) == 0);
144 
145     RUNIT_ASSERT(sec_srv_len == sec_cli_len);
146     RUNIT_ASSERT(sec_srv_len != 0);
147     RUNIT_ASSERT(memcmp(pSecSrv, pSecCli, sec_srv_len) == 0);
148 
149 bail:
150     RUNIT_API(mbedtls_dhm_free(pCtxSrv));
151     RUNIT_API(mbedtls_dhm_free(pCtxCli));
152 
153     FREE_IF_NOT_NULL(ctxSrvPtr);
154     FREE_IF_NOT_NULL(ctxCliPtr);
155     FREE_IF_NOT_NULL(skePrt);
156     FREE_IF_NOT_NULL(pubCliPrt);
157     FREE_IF_NOT_NULL(secSrvPrt);
158     FREE_IF_NOT_NULL(secCliPrt);
159 
160     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "G[%"PRIu32"b]", (uint32_t)strlen(input_G) * 8);
161 #endif /* MBEDTLS_DHM_C */
162     return rc;
163 }
164 
runIt_dhmTest(void)165 RunItError_t runIt_dhmTest(void)
166 {
167     RunItError_t rc = RUNIT_ERROR__OK;
168     const char* TEST_NAME = "DH";
169     RUNIT_TEST_START(TEST_NAME);
170 
171     RUNIT_ASSERT(runIt_dhm() == RUNIT_ERROR__OK);
172 
173 bail:
174     RUNIT_TEST_RESULT(TEST_NAME);
175     return rc;
176 
177 }
178