blob: e6f75de77702d0a6f5afb9b17182991a75feb716 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/dhm.h"
Gilles Peskine02db8f42021-03-30 23:28:51 +02003
Gilles Peskine449bd832023-01-11 14:50:10 +01004int check_get_value(const mbedtls_dhm_context *ctx,
5 mbedtls_dhm_parameter param,
6 const mbedtls_mpi *expected)
Gilles Peskine71acc6e2021-05-27 22:50:53 +02007{
8 mbedtls_mpi actual;
9 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +010010 mbedtls_mpi_init(&actual);
Gilles Peskine71acc6e2021-05-27 22:50:53 +020011
Gilles Peskine449bd832023-01-11 14:50:10 +010012 TEST_ASSERT(mbedtls_dhm_get_value(ctx, param, &actual) == 0);
13 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&actual, expected) == 0);
Gilles Peskine71acc6e2021-05-27 22:50:53 +020014 ok = 1;
15
16exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010017 mbedtls_mpi_free(&actual);
18 return ok;
Gilles Peskine71acc6e2021-05-27 22:50:53 +020019}
20
Gilles Peskine19e36202021-04-13 22:16:45 +020021/* Sanity checks on a Diffie-Hellman parameter: check the length-value
22 * syntax and check that the value is the expected one (taken from the
23 * DHM context by the caller). */
Gilles Peskine449bd832023-01-11 14:50:10 +010024static int check_dhm_param_output(const mbedtls_mpi *expected,
25 const unsigned char *buffer,
26 size_t size,
27 size_t *offset)
Gilles Peskine02db8f42021-03-30 23:28:51 +020028{
29 size_t n;
30 mbedtls_mpi actual;
31 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +010032 mbedtls_mpi_init(&actual);
Gilles Peskine02db8f42021-03-30 23:28:51 +020033
34 ++mbedtls_test_info.step;
35
Gilles Peskine449bd832023-01-11 14:50:10 +010036 TEST_ASSERT(size >= *offset + 2);
37 n = (buffer[*offset] << 8) | buffer[*offset + 1];
Gilles Peskine02db8f42021-03-30 23:28:51 +020038 *offset += 2;
Gilles Peskine03299dc2021-04-13 22:10:24 +020039 /* The DHM param output from Mbed TLS has leading zeros stripped, as
40 * permitted but not required by RFC 5246 \S4.4. */
Gilles Peskine449bd832023-01-11 14:50:10 +010041 TEST_EQUAL(n, mbedtls_mpi_size(expected));
42 TEST_ASSERT(size >= *offset + n);
43 TEST_EQUAL(0, mbedtls_mpi_read_binary(&actual, buffer + *offset, n));
44 TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(expected, &actual));
Gilles Peskine02db8f42021-03-30 23:28:51 +020045 *offset += n;
46
47 ok = 1;
48exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010049 mbedtls_mpi_free(&actual);
50 return ok;
Gilles Peskine02db8f42021-03-30 23:28:51 +020051}
52
Gilles Peskine19e36202021-04-13 22:16:45 +020053/* Sanity checks on Diffie-Hellman parameters: syntax, range, and comparison
54 * against the context. */
Gilles Peskine449bd832023-01-11 14:50:10 +010055static int check_dhm_params(const mbedtls_dhm_context *ctx,
56 size_t x_size,
57 const unsigned char *ske, size_t ske_len)
Gilles Peskine02db8f42021-03-30 23:28:51 +020058{
59 size_t offset = 0;
60
61 /* Check that ctx->X and ctx->GX are within range. */
Gilles Peskine449bd832023-01-11 14:50:10 +010062 TEST_ASSERT(mbedtls_mpi_cmp_int(&ctx->X, 1) > 0);
63 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->P) < 0);
64 TEST_ASSERT(mbedtls_mpi_size(&ctx->X) <= x_size);
65 TEST_ASSERT(mbedtls_mpi_cmp_int(&ctx->GX, 1) > 0);
66 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx->GX, &ctx->P) < 0);
Gilles Peskine02db8f42021-03-30 23:28:51 +020067
68 /* Check ske: it must contain P, G and G^X, each prefixed with a
69 * 2-byte size. */
Gilles Peskine449bd832023-01-11 14:50:10 +010070 if (!check_dhm_param_output(&ctx->P, ske, ske_len, &offset)) {
Gilles Peskine02db8f42021-03-30 23:28:51 +020071 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010072 }
73 if (!check_dhm_param_output(&ctx->G, ske, ske_len, &offset)) {
Gilles Peskine02db8f42021-03-30 23:28:51 +020074 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010075 }
76 if (!check_dhm_param_output(&ctx->GX, ske, ske_len, &offset)) {
Gilles Peskine02db8f42021-03-30 23:28:51 +020077 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010078 }
79 TEST_EQUAL(offset, ske_len);
Gilles Peskine02db8f42021-03-30 23:28:51 +020080
Gilles Peskine449bd832023-01-11 14:50:10 +010081 return 1;
Gilles Peskine02db8f42021-03-30 23:28:51 +020082exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010083 return 0;
Gilles Peskine02db8f42021-03-30 23:28:51 +020084}
85
Paul Bakker33b43f12013-08-20 11:48:36 +020086/* END_HEADER */
Paul Bakker5c60de22009-07-08 19:47:36 +000087
Paul Bakker33b43f12013-08-20 11:48:36 +020088/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020089 * depends_on:MBEDTLS_DHM_C:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020090 * END_DEPENDENCIES
91 */
Paul Bakker5690efc2011-05-26 13:16:06 +000092
Paul Bakker33b43f12013-08-20 11:48:36 +020093/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010094void dhm_do_dhm(char *input_P, int x_size,
95 char *input_G, int result)
Paul Bakker5c60de22009-07-08 19:47:36 +000096{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097 mbedtls_dhm_context ctx_srv;
98 mbedtls_dhm_context ctx_cli;
Paul Bakker5c60de22009-07-08 19:47:36 +000099 unsigned char ske[1000];
100 unsigned char *p = ske;
101 unsigned char pub_cli[1000];
102 unsigned char sec_srv[1000];
103 unsigned char sec_cli[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000104 size_t ske_len = 0;
105 size_t pub_cli_len = 0;
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100106 size_t sec_srv_len;
107 size_t sec_cli_len;
Gilles Peskine2baf2b02021-03-30 23:44:22 +0200108 int i;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200109 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker5c60de22009-07-08 19:47:36 +0000110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 mbedtls_dhm_init(&ctx_srv);
112 mbedtls_dhm_init(&ctx_cli);
113 memset(ske, 0x00, 1000);
114 memset(pub_cli, 0x00, 1000);
115 memset(sec_srv, 0x00, 1000);
116 memset(sec_cli, 0x00, 1000);
117 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker5c60de22009-07-08 19:47:36 +0000118
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200119 /*
120 * Set params
121 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 TEST_ASSERT(mbedtls_test_read_mpi(&ctx_srv.P, input_P) == 0);
123 TEST_ASSERT(mbedtls_test_read_mpi(&ctx_srv.G, input_G) == 0);
124 pub_cli_len = mbedtls_mpi_size(&ctx_srv.P);
125 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_P, &ctx_srv.P));
126 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_G, &ctx_srv.G));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200127
128 /*
129 * First key exchange
130 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 mbedtls_test_set_step(10);
132 TEST_ASSERT(mbedtls_dhm_make_params(&ctx_srv, x_size, ske, &ske_len,
133 &mbedtls_test_rnd_pseudo_rand,
134 &rnd_info) == result);
135 if (result != 0) {
Janos Follath4b151fa2017-09-20 13:46:37 +0100136 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 }
138 if (!check_dhm_params(&ctx_srv, x_size, ske, ske_len)) {
Gilles Peskine02db8f42021-03-30 23:28:51 +0200139 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 }
Janos Follath4b151fa2017-09-20 13:46:37 +0100141
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200142 ske[ske_len++] = 0;
143 ske[ske_len++] = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 TEST_ASSERT(mbedtls_dhm_read_params(&ctx_cli, &p, ske + ske_len) == 0);
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200145 /* The domain parameters must be the same on both side. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_P, &ctx_srv.P));
147 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_G, &ctx_srv.G));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 TEST_ASSERT(mbedtls_dhm_make_public(&ctx_cli, x_size, pub_cli, pub_cli_len,
150 &mbedtls_test_rnd_pseudo_rand,
151 &rnd_info) == 0);
152 TEST_ASSERT(mbedtls_dhm_read_public(&ctx_srv, pub_cli, pub_cli_len) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200153
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 TEST_ASSERT(mbedtls_dhm_calc_secret(&ctx_srv, sec_srv, sizeof(sec_srv),
155 &sec_srv_len,
156 &mbedtls_test_rnd_pseudo_rand,
157 &rnd_info) == 0);
158 TEST_ASSERT(mbedtls_dhm_calc_secret(&ctx_cli, sec_cli, sizeof(sec_cli),
159 &sec_cli_len,
160 &mbedtls_test_rnd_pseudo_rand,
161 &rnd_info) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200162
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 TEST_ASSERT(sec_srv_len == sec_cli_len);
164 TEST_ASSERT(sec_srv_len != 0);
165 TEST_ASSERT(memcmp(sec_srv, sec_cli, sec_srv_len) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200166
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200167 /* Internal value checks */
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_X, &ctx_cli.X));
169 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_X, &ctx_srv.X));
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200170 /* Cross-checks */
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_GX, &ctx_srv.GY));
172 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_GY, &ctx_srv.GX));
173 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_K, &ctx_srv.K));
174 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_GX, &ctx_cli.GY));
175 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_GY, &ctx_cli.GX));
176 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_K, &ctx_cli.K));
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200177
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200178 /* Re-do calc_secret on server a few times to test update of blinding values */
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 for (i = 0; i < 3; i++) {
180 mbedtls_test_set_step(20 + i);
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200181 sec_srv_len = 1000;
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 TEST_ASSERT(mbedtls_dhm_calc_secret(&ctx_srv, sec_srv,
183 sizeof(sec_srv), &sec_srv_len,
184 &mbedtls_test_rnd_pseudo_rand,
185 &rnd_info) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 TEST_ASSERT(sec_srv_len == sec_cli_len);
188 TEST_ASSERT(sec_srv_len != 0);
189 TEST_ASSERT(memcmp(sec_srv, sec_cli, sec_srv_len) == 0);
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200190 }
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200191
192 /*
193 * Second key exchange to test change of blinding values on server
194 */
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200195 p = ske;
Paul Bakker5c60de22009-07-08 19:47:36 +0000196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 mbedtls_test_set_step(30);
198 TEST_ASSERT(mbedtls_dhm_make_params(&ctx_srv, x_size, ske, &ske_len,
199 &mbedtls_test_rnd_pseudo_rand,
200 &rnd_info) == 0);
201 if (!check_dhm_params(&ctx_srv, x_size, ske, ske_len)) {
Gilles Peskine02db8f42021-03-30 23:28:51 +0200202 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 }
Paul Bakker5c60de22009-07-08 19:47:36 +0000204 ske[ske_len++] = 0;
205 ske[ske_len++] = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 TEST_ASSERT(mbedtls_dhm_read_params(&ctx_cli, &p, ske + ske_len) == 0);
Paul Bakker5c60de22009-07-08 19:47:36 +0000207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 TEST_ASSERT(mbedtls_dhm_make_public(&ctx_cli, x_size, pub_cli, pub_cli_len,
209 &mbedtls_test_rnd_pseudo_rand,
210 &rnd_info) == 0);
211 TEST_ASSERT(mbedtls_dhm_read_public(&ctx_srv, pub_cli, pub_cli_len) == 0);
Paul Bakker5c60de22009-07-08 19:47:36 +0000212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 TEST_ASSERT(mbedtls_dhm_calc_secret(&ctx_srv, sec_srv, sizeof(sec_srv),
214 &sec_srv_len,
215 &mbedtls_test_rnd_pseudo_rand,
216 &rnd_info) == 0);
217 TEST_ASSERT(mbedtls_dhm_calc_secret(&ctx_cli, sec_cli, sizeof(sec_cli),
218 &sec_cli_len,
219 &mbedtls_test_rnd_pseudo_rand,
220 &rnd_info) == 0);
Paul Bakker5c60de22009-07-08 19:47:36 +0000221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 TEST_ASSERT(sec_srv_len == sec_cli_len);
223 TEST_ASSERT(sec_srv_len != 0);
224 TEST_ASSERT(memcmp(sec_srv, sec_cli, sec_srv_len) == 0);
Paul Bakkerc43481a2011-02-20 16:34:26 +0000225
Paul Bakkerbd51b262014-07-10 15:26:12 +0200226exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 mbedtls_dhm_free(&ctx_srv);
228 mbedtls_dhm_free(&ctx_cli);
Paul Bakker5c60de22009-07-08 19:47:36 +0000229}
Paul Bakker33b43f12013-08-20 11:48:36 +0200230/* END_CASE */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200231
Chris Jonesd10b3312020-12-02 10:41:50 +0000232/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100233void dhm_make_public(int P_bytes, char *input_G, int result)
Chris Jonesd10b3312020-12-02 10:41:50 +0000234{
235 mbedtls_mpi P, G;
236 mbedtls_dhm_context ctx;
237 unsigned char output[MBEDTLS_MPI_MAX_SIZE];
238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 mbedtls_mpi_init(&P);
240 mbedtls_mpi_init(&G);
241 mbedtls_dhm_init(&ctx);
Chris Jonesd10b3312020-12-02 10:41:50 +0000242
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 TEST_ASSERT(mbedtls_mpi_lset(&P, 1) == 0);
244 TEST_ASSERT(mbedtls_mpi_shift_l(&P, (P_bytes * 8) - 1) == 0);
245 TEST_ASSERT(mbedtls_mpi_set_bit(&P, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +0000246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 TEST_ASSERT(mbedtls_test_read_mpi(&G, input_G) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +0000248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 TEST_ASSERT(mbedtls_dhm_set_group(&ctx, &P, &G) == 0);
250 TEST_ASSERT(mbedtls_dhm_make_public(&ctx, (int) mbedtls_mpi_size(&P),
251 output, sizeof(output),
252 &mbedtls_test_rnd_pseudo_rand,
253 NULL) == result);
Chris Jonesd10b3312020-12-02 10:41:50 +0000254
255exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 mbedtls_mpi_free(&P);
257 mbedtls_mpi_free(&G);
258 mbedtls_dhm_free(&ctx);
Chris Jonesd10b3312020-12-02 10:41:50 +0000259}
260/* END_CASE */
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100263void dhm_file(char *filename, char *p, char *g, int len)
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100264{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 mbedtls_dhm_context ctx;
266 mbedtls_mpi P, G;
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 mbedtls_dhm_init(&ctx);
269 mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100270
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 TEST_ASSERT(mbedtls_test_read_mpi(&P, p) == 0);
272 TEST_ASSERT(mbedtls_test_read_mpi(&G, g) == 0);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 TEST_ASSERT(mbedtls_dhm_parse_dhmfile(&ctx, filename) == 0);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100275
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 TEST_EQUAL(mbedtls_dhm_get_len(&ctx), (size_t) len);
277 TEST_EQUAL(mbedtls_dhm_get_bitlen(&ctx), mbedtls_mpi_bitlen(&P));
278 TEST_ASSERT(check_get_value(&ctx, MBEDTLS_DHM_PARAM_P, &P));
279 TEST_ASSERT(check_get_value(&ctx, MBEDTLS_DHM_PARAM_G, &G));
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100280
Paul Bakkerbd51b262014-07-10 15:26:12 +0200281exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
283 mbedtls_dhm_free(&ctx);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100284}
285/* END_CASE */
286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +0100288void dhm_selftest()
Paul Bakker40ce79f2013-09-15 17:43:54 +0200289{
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 TEST_ASSERT(mbedtls_dhm_self_test(1) == 0);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200291}
292/* END_CASE */