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